diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 01b033540..fa5baaa44 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1781,6 +1781,7 @@ {"name":"s_bone_tool_add","order":4,"path":"sprites/s_bone_tool_add/s_bone_tool_add.yy",}, {"name":"s_bone_tool_detach","order":5,"path":"sprites/s_bone_tool_detach/s_bone_tool_detach.yy",}, {"name":"s_bone_tool_IK","order":6,"path":"sprites/s_bone_tool_IK/s_bone_tool_IK.yy",}, + {"name":"s_bone_tool_mirror","order":70,"path":"sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy",}, {"name":"s_bone_tool_move","order":7,"path":"sprites/s_bone_tool_move/s_bone_tool_move.yy",}, {"name":"s_bone_tool_pose","order":69,"path":"sprites/s_bone_tool_pose/s_bone_tool_pose.yy",}, {"name":"s_bone_tool_remove","order":8,"path":"sprites/s_bone_tool_remove/s_bone_tool_remove.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 8081b8a19..3c7bf096e 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -2478,6 +2478,7 @@ {"id":{"name":"s_bone_tool_add","path":"sprites/s_bone_tool_add/s_bone_tool_add.yy",},}, {"id":{"name":"s_bone_tool_detach","path":"sprites/s_bone_tool_detach/s_bone_tool_detach.yy",},}, {"id":{"name":"s_bone_tool_IK","path":"sprites/s_bone_tool_IK/s_bone_tool_IK.yy",},}, + {"id":{"name":"s_bone_tool_mirror","path":"sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy",},}, {"id":{"name":"s_bone_tool_move","path":"sprites/s_bone_tool_move/s_bone_tool_move.yy",},}, {"id":{"name":"s_bone_tool_pose","path":"sprites/s_bone_tool_pose/s_bone_tool_pose.yy",},}, {"id":{"name":"s_bone_tool_remove","path":"sprites/s_bone_tool_remove/s_bone_tool_remove.yy",},}, diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index 9e1f2cdf2..92cd43f30 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/scripts/__bone/__bone.gml b/scripts/__bone/__bone.gml index 322ca6f3a..a836fdda7 100644 --- a/scripts/__bone/__bone.gml +++ b/scripts/__bone/__bone.gml @@ -632,7 +632,7 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len for( var i = 0, n = array_length(childs); i < n; i++ ) childHash += childs[i].getHash() + ","; - var h = $"[{ID}] : {parent_anchor}, [{IKlength}, {IKTargetID}], [{apply_scale}, {apply_rotation}], [{childHash}]"; + var h = $"{name} [{ID}] : {parent_anchor}, [{IKlength}, {IKTargetID}], [{apply_scale}, {apply_rotation}], [{childHash}]"; return sha1_string_unicode(h); } diff --git a/scripts/node_armature/node_armature.gml b/scripts/node_armature/node_armature.gml index aaf7a68f9..8cb78fcc6 100644 --- a/scripts/node_armature/node_armature.gml +++ b/scripts/node_armature/node_armature.gml @@ -157,11 +157,12 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo #endregion tools = [ - new NodeTool( "Transform", THEME.bone_tool_move ), + new NodeTool( "Transform", THEME.bone_tool_move ), new NodeTool( "Add bones", THEME.bone_tool_add ), new NodeTool( "Remove bones", THEME.bone_tool_remove ), new NodeTool( "Detach bones", THEME.bone_tool_detach ), new NodeTool( "IK", THEME.bone_tool_IK ), + new NodeTool( "Mirror bones", THEME.bone_tool_mirror ), ]; anchor_selecting = noone; @@ -186,6 +187,8 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo bone_transform_bbox = -1; bone_transform_type = -1; + mirroring_bone = noone; + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _panel) { var mx = (_mx - _x) / _s; var my = (_my - _y) / _s; @@ -611,10 +614,58 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo if(ik_dragging == noone) anchor_selecting = _b.draw(attributes, active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting); - if(anchor_selecting != noone && anchor_selecting[1] == 2 && mouse_press(mb_left, active)) { + if(anchor_selecting != noone && anchor_selecting[1] == 2 && mouse_press(mb_left, active)) ik_dragging = anchor_selecting[0]; + + } else if(isUsingTool("Mirror bones")) { + if(builder_bone == noone) + anchor_selecting = _b.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting); + + if(mirroring_bone != noone) { + var _maxis = anchor_selecting == noone || anchor_selecting[0] == mirroring_bone? mirroring_bone.parent.angle : anchor_selecting[0].angle; + var _ori = mirroring_bone.getHead(); + + var _ox = _x + _ori.x * _s; + var _oy = _y + _ori.y * _s; + + var _x0 = _ox + lengthdir_x(64, _maxis); + var _y0 = _oy + lengthdir_y(64, _maxis); + var _x1 = _ox - lengthdir_x(64, _maxis); + var _y1 = _oy - lengthdir_y(64, _maxis); + + BLEND_ADD + draw_set_color(COLORS._main_accent); + draw_line_dashed(_x0, _y0, _x1, _y1, 3); + BLEND_NORMAL + + if(mouse_release(mb_left)) { + var _mirrored = mirroring_bone.clone(); + var _mirArr = _mirrored.toArray(); + + for( var i = 0, n = array_length(_mirArr); i < n; i++ ) { + var _bm = _mirArr[i]; + _bm.ID = UUID_generate(); + + if(string_pos(" L", _bm.name)) _bm.name = string_replace(_bm.name, " L", " R"); + else if(string_pos(" R", _bm.name)) _bm.name = string_replace(_bm.name, " R", " L"); + + _bm.angle = _maxis + angle_difference(_maxis, _bm.angle); + } + + mirroring_bone.parent.addChild(_mirrored); + mirroring_bone = noone; + + triggerRender(); + } + + } else if(anchor_selecting != noone) { + var _bne = anchor_selecting[0]; + var _typ = anchor_selecting[1]; + + if(_bne.parent && mouse_press(mb_left, active)) + mirroring_bone = _bne; } - + } else { // move tools if(builder_bone == noone) { anchor_selecting = _b.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting); diff --git a/scripts/node_armature_pose/node_armature_pose.gml b/scripts/node_armature_pose/node_armature_pose.gml index c66dc3d55..484df6af1 100644 --- a/scripts/node_armature_pose/node_armature_pose.gml +++ b/scripts/node_armature_pose/node_armature_pose.gml @@ -5,9 +5,7 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const newInput(0, nodeValue_Armature("Armature", self, noone)) .setVisible(true, true); - input_display_list = [ 0, - ["Bones", false] - ] + input_display_list = [ 0 ] newOutput(0, nodeValue_Output("Armature", self, VALUE_TYPE.armature, noone)); diff --git a/scripts/theme_definition/theme_definition.gml b/scripts/theme_definition/theme_definition.gml index 453fd6734..20c7a67f4 100644 --- a/scripts/theme_definition/theme_definition.gml +++ b/scripts/theme_definition/theme_definition.gml @@ -303,6 +303,7 @@ function Theme() constructor { bone_tool_pose = s_bone_tool_pose; bone_tool_remove = s_bone_tool_remove; bone_tool_scale = s_bone_tool_scale; + bone_tool_mirror = s_bone_tool_mirror; canvas_draw_layer = s_canvas_draw_layer; canvas_iso_angle = s_canvas_iso_angle; canvas_fill_type = s_canvas_fill_type; diff --git a/sprites/s_bone_scale/2de46b2b-d64b-4497-a785-81906d872c31.png b/sprites/s_bone_scale/2de46b2b-d64b-4497-a785-81906d872c31.png deleted file mode 100644 index a0e45fe54..000000000 Binary files a/sprites/s_bone_scale/2de46b2b-d64b-4497-a785-81906d872c31.png and /dev/null differ diff --git a/sprites/s_bone_scale/b3bac891-34ed-4f4b-b531-d215fc41ce83.png b/sprites/s_bone_scale/b3bac891-34ed-4f4b-b531-d215fc41ce83.png new file mode 100644 index 000000000..a5607c556 Binary files /dev/null and b/sprites/s_bone_scale/b3bac891-34ed-4f4b-b531-d215fc41ce83.png differ diff --git a/sprites/s_bone_scale/layers/2de46b2b-d64b-4497-a785-81906d872c31/dfa57967-60b1-4c24-ae6c-4f613947bdcd.png b/sprites/s_bone_scale/layers/2de46b2b-d64b-4497-a785-81906d872c31/dfa57967-60b1-4c24-ae6c-4f613947bdcd.png deleted file mode 100644 index a0e45fe54..000000000 Binary files a/sprites/s_bone_scale/layers/2de46b2b-d64b-4497-a785-81906d872c31/dfa57967-60b1-4c24-ae6c-4f613947bdcd.png and /dev/null differ diff --git a/sprites/s_bone_scale/layers/b3bac891-34ed-4f4b-b531-d215fc41ce83/6f7f34f2-0a28-4e6d-836a-9cbdbaddcb5c.png b/sprites/s_bone_scale/layers/b3bac891-34ed-4f4b-b531-d215fc41ce83/6f7f34f2-0a28-4e6d-836a-9cbdbaddcb5c.png new file mode 100644 index 000000000..a5607c556 Binary files /dev/null and b/sprites/s_bone_scale/layers/b3bac891-34ed-4f4b-b531-d215fc41ce83/6f7f34f2-0a28-4e6d-836a-9cbdbaddcb5c.png differ diff --git a/sprites/s_bone_scale/s_bone_scale.yy b/sprites/s_bone_scale/s_bone_scale.yy index 63e44d206..ef0b969c3 100644 --- a/sprites/s_bone_scale/s_bone_scale.yy +++ b/sprites/s_bone_scale/s_bone_scale.yy @@ -2,24 +2,24 @@ "$GMSprite":"", "%Name":"s_bone_scale", "bboxMode":0, - "bbox_bottom":32, - "bbox_left":8, - "bbox_right":42, - "bbox_top":15, + "bbox_bottom":34, + "bbox_left":14, + "bbox_right":35, + "bbox_top":13, "collisionKind":1, "collisionTolerance":0, "DynamicTexturePage":false, "edgeFiltering":false, "For3D":false, "frames":[ - {"$GMSpriteFrame":"","%Name":"2de46b2b-d64b-4497-a785-81906d872c31","name":"2de46b2b-d64b-4497-a785-81906d872c31","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + {"$GMSpriteFrame":"","%Name":"b3bac891-34ed-4f4b-b531-d215fc41ce83","name":"b3bac891-34ed-4f4b-b531-d215fc41ce83","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, ], "gridX":0, "gridY":0, "height":48, "HTile":false, "layers":[ - {"$GMImageLayer":"","%Name":"dfa57967-60b1-4c24-ae6c-4f613947bdcd","blendMode":0,"displayName":"default","isLocked":false,"name":"dfa57967-60b1-4c24-ae6c-4f613947bdcd","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, + {"$GMImageLayer":"","%Name":"6f7f34f2-0a28-4e6d-836a-9cbdbaddcb5c","blendMode":0,"displayName":"default","isLocked":false,"name":"6f7f34f2-0a28-4e6d-836a-9cbdbaddcb5c","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, ], "name":"s_bone_scale", "nineSlice":null, @@ -69,8 +69,8 @@ "tracks":[ {"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore":"","Keyframes":[ {"$Keyframe":"","Channels":{ - "0":{"$SpriteFrameKeyframe":"","Id":{"name":"2de46b2b-d64b-4497-a785-81906d872c31","path":"sprites/s_bone_scale/s_bone_scale.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, - },"Disabled":false,"id":"47cbaea7-265a-4656-960f-a01215b92edc","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"b3bac891-34ed-4f4b-b531-d215fc41ce83","path":"sprites/s_bone_scale/s_bone_scale.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"5f0e680f-0ddb-4862-8014-1b45a95fdb51","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, ],"resourceType":"KeyframeStore","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, ], "visibleRange":null, diff --git a/sprites/s_bone_tool_mirror/3f583b24-d2b0-4fb1-8600-42570017307f.png b/sprites/s_bone_tool_mirror/3f583b24-d2b0-4fb1-8600-42570017307f.png new file mode 100644 index 000000000..fe9ac7641 Binary files /dev/null and b/sprites/s_bone_tool_mirror/3f583b24-d2b0-4fb1-8600-42570017307f.png differ diff --git a/sprites/s_bone_tool_mirror/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a.png b/sprites/s_bone_tool_mirror/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a.png new file mode 100644 index 000000000..1a6766838 Binary files /dev/null and b/sprites/s_bone_tool_mirror/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a.png differ diff --git a/sprites/s_bone_tool_mirror/layers/3f583b24-d2b0-4fb1-8600-42570017307f/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png b/sprites/s_bone_tool_mirror/layers/3f583b24-d2b0-4fb1-8600-42570017307f/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png new file mode 100644 index 000000000..fe9ac7641 Binary files /dev/null and b/sprites/s_bone_tool_mirror/layers/3f583b24-d2b0-4fb1-8600-42570017307f/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png differ diff --git a/sprites/s_bone_tool_mirror/layers/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png b/sprites/s_bone_tool_mirror/layers/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png new file mode 100644 index 000000000..1a6766838 Binary files /dev/null and b/sprites/s_bone_tool_mirror/layers/b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a/eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d.png differ diff --git a/sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy b/sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy new file mode 100644 index 000000000..3283994b7 --- /dev/null +++ b/sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy @@ -0,0 +1,94 @@ +{ + "$GMSprite":"", + "%Name":"s_bone_tool_mirror", + "bboxMode":0, + "bbox_bottom":16, + "bbox_left":1, + "bbox_right":16, + "bbox_top":1, + "collisionKind":1, + "collisionTolerance":0, + "DynamicTexturePage":false, + "edgeFiltering":false, + "For3D":false, + "frames":[ + {"$GMSpriteFrame":"","%Name":"3f583b24-d2b0-4fb1-8600-42570017307f","name":"3f583b24-d2b0-4fb1-8600-42570017307f","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + {"$GMSpriteFrame":"","%Name":"b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a","name":"b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a","resourceType":"GMSpriteFrame","resourceVersion":"2.0",}, + ], + "gridX":0, + "gridY":0, + "height":18, + "HTile":false, + "layers":[ + {"$GMImageLayer":"","%Name":"eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d","blendMode":0,"displayName":"default","isLocked":false,"name":"eb06fcff-2331-4ae5-aa77-c96cd2fe6d0d","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,}, + ], + "name":"s_bone_tool_mirror", + "nineSlice":null, + "origin":4, + "parent":{ + "name":"tool", + "path":"folders/theme/tool.yy", + }, + "preMultiplyAlpha":false, + "resourceType":"GMSprite", + "resourceVersion":"2.0", + "sequence":{ + "$GMSequence":"", + "%Name":"s_bone_tool_mirror", + "autoRecord":true, + "backdropHeight":768, + "backdropImageOpacity":0.5, + "backdropImagePath":"", + "backdropWidth":1366, + "backdropXOffset":0.0, + "backdropYOffset":0.0, + "events":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "eventStubScript":null, + "eventToFunction":{}, + "length":2.0, + "lockOrigin":false, + "moments":{ + "$KeyframeStore":"", + "Keyframes":[], + "resourceType":"KeyframeStore", + "resourceVersion":"2.0", + }, + "name":"s_bone_tool_mirror", + "playback":1, + "playbackSpeed":30.0, + "playbackSpeedType":0, + "resourceType":"GMSequence", + "resourceVersion":"2.0", + "showBackdrop":true, + "showBackdropImage":false, + "timeUnits":1, + "tracks":[ + {"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore":"","Keyframes":[ + {"$Keyframe":"","Channels":{ + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"3f583b24-d2b0-4fb1-8600-42570017307f","path":"sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"7ab06af3-5187-46e9-b2e6-a6ff295168fa","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + {"$Keyframe":"","Channels":{ + "0":{"$SpriteFrameKeyframe":"","Id":{"name":"b30f665b-391e-4e70-bbe8-b0ec4e0a7e6a","path":"sprites/s_bone_tool_mirror/s_bone_tool_mirror.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",}, + },"Disabled":false,"id":"7549b53c-5dc2-431d-90bc-a95597afdd7a","IsCreationKey":false,"Key":1.0,"Length":1.0,"resourceType":"Keyframe","resourceVersion":"2.0","Stretch":false,}, + ],"resourceType":"KeyframeStore","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange":null, + "volume":1.0, + "xorigin":9, + "yorigin":9, + }, + "swatchColours":null, + "swfPrecision":0.5, + "textureGroupId":{ + "name":"Default", + "path":"texturegroups/Default", + }, + "type":0, + "VTile":false, + "width":18, +} \ No newline at end of file