arm new var pos cret

This commit is contained in:
Tanasart 2024-11-27 11:32:43 +07:00
parent 0e5d5cbd43
commit e7895f2de1
16 changed files with 373 additions and 304 deletions

Binary file not shown.

View file

@ -1,32 +1,26 @@
function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _length = 0, _node = noone) constructor {
ID = UUID_generate();
name = "New bone";
ID = UUID_generate();
name = "New bone";
node = _node;
parent = _parent;
self.distance = _distance;
self.direction = _direction;
self.angle = _angle;
self.length = _length;
self.node = _node;
distance = _distance; pose_distance = _distance;
direction = _direction; pose_direction = _direction;
angle = _angle; pose_angle = _angle;
length = _length; pose_length = _length;
init_length = _length;
init_angle = _angle;
init_direction = 0;
init_distance = 0;
pose_angle = 0;
pose_scale = 1;
pose_posit = [ 0, 0 ];
pose_rotate = 0;
pose_scale = 1;
pose_local_angle = 0;
pose_local_scale = 1;
pose_local_posit = [ 0, 0 ];
pose_local_posit = [ 0, 0 ]; pose_apply_posit = [ 0, 0 ];
pose_local_rotate = 0; pose_apply_rotate = 0;
pose_local_scale = 1; pose_apply_scale = 1;
angular_constrain = -1;
bone_head_init = new __vec2();
bone_head_pose = new __vec2();
bone_tail_init = new __vec2();
bone_tail_pose = new __vec2();
bone_head_init = new __vec2(); bone_head_pose = new __vec2();
bone_tail_init = new __vec2(); bone_tail_pose = new __vec2();
apply_scale = true;
apply_rotation = true;
@ -47,33 +41,15 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
freeze_data = {};
parent = _parent;
if(parent != noone) {
distance = parent.length;
direction = parent.angle;
}
control_x0 = 0; control_y0 = 0; control_i0 = 0;
control_x1 = 0; control_y1 = 0; control_i1 = 0;
static addChild = function(bone) {
array_push(childs, bone);
bone.parent = self;
return self;
}
static childCount = function() {
var amo = array_length(childs);
for( var i = 0, n = array_length(childs); i < n; i++ )
amo += childs[i].childCount();
return amo;
}
static addChild = function(bone) { array_push(childs, bone); bone.parent = self; return self; }
static childCount = function() { return array_reduce(childs, function(amo, ch) /*=>*/ { return amo + ch.childCount(); }, array_length(childs)); }
static freeze = function() {
freeze_data = { angle, length, distance, direction };
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].freeze();
array_foreach(childs, function(c) /*=>*/ {return c.freeze()});
}
static findBone = function(_id) {
@ -106,18 +82,18 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
var _dir, _dis, _len, _ang;
if(pose) {
_dir = pose_direction;
_dis = pose_distance;
_len = pose_length;
_ang = pose_angle;
} else {
_dir = direction;
_dis = distance;
_len = length;
_ang = angle;
} else {
_dir = init_direction;
_dis = init_distance;
_len = init_length;
_ang = init_angle;
}
var len = _len * progress;
@ -139,9 +115,7 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
}
static draw = function(attributes, edit = false, _x = 0, _y = 0, _s = 1, _mx = 0, _my = 0, _hover = noone, _select = noone, _blend = c_white, _alpha = 1) {
var hover = _drawBone(attributes, edit, _x, _y, _s, _mx, _my, _hover, _select, _blend, _alpha);
drawControl(attributes);
return hover;
return _drawBone(attributes, edit, _x, _y, _s, _mx, _my, _hover, _select, _blend, _alpha);
}
static _drawBone = function(attributes, edit = false, _x = 0, _y = 0, _s = 1, _mx = 0, _my = 0, _hover = noone, _select = noone, _blend = c_white, _alpha = 1) {
@ -188,8 +162,8 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
if(IKlength == 0) {
if(angular_constrain != -1) {
var _a0 = init_angle - angular_constrain;
var _a1 = init_angle + angular_constrain;
var _a0 = angle - angular_constrain;
var _a1 = angle + angular_constrain;
var ox, oy, nx, ny;
for( var i = 0; i <= 32; i++ ) {
@ -207,15 +181,15 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
}
}
if(pose_angle != 0) {
var nx = p0x + lengthdir_x(16, angle + pose_angle);
var ny = p0y + lengthdir_y(16, angle + pose_angle);
if(pose_rotate != 0) {
var nx = p0x + lengthdir_x(16, angle + pose_rotate);
var ny = p0y + lengthdir_y(16, angle + pose_rotate);
draw_line_width(p0x, p0y, nx, ny, 2);
}
if(!parent_anchor && parent.parent != noone) {
var _p = parent.getHead();
var _p = parent.getTail();
var _px = _x + _p.x * _s;
var _py = _y + _p.y * _s;
draw_line_dashed(_px, _py, p0x, p0y, 2, 8);
@ -285,13 +259,13 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
if(IKlength == 0) {
if(!parent_anchor) {
control_i0 = (_hover != noone && _hover[0] == self && _hover[1] == 0)? 0 : 2;
control_i0 = (_hover != noone && _hover[0] == self && _hover[1] == 0)? 1 : 0;
if((edit & 0b001) && point_in_circle(_mx, _my, p0x, p0y, ui(16))) //drag head
hover = [ self, 0, bone_head_pose ];
}
control_i1 = (_hover != noone && _hover[0] == self && _hover[1] == 1)? 0 : 2;
control_i1 = (_hover != noone && _hover[0] == self && _hover[1] == 1)? 1 : 0;
if((edit & 0b010) && point_in_circle(_mx, _my, p1x, p1y, ui(16))) //drag tail
hover = [ self, 1, bone_tail_pose ];
@ -302,16 +276,9 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
static drawControl = function(attributes) {
if(parent != noone && IKlength == 0) {
var spr, ind0, ind1;
if(attributes.display_bone == 0) {
if(!parent_anchor)
draw_sprite_colored(THEME.anchor_selector, control_i0, control_x0, control_y0);
draw_sprite_colored(THEME.anchor_selector, control_i1, control_x1, control_y1);
} else {
if(!parent_anchor)
draw_sprite_ext(THEME.anchor_bone_stick, control_i0 / 2, control_x0, control_y0, 1, 1, 0, COLORS._main_accent, 1);
draw_sprite_ext(THEME.anchor_bone_stick, control_i1 / 2, control_x1, control_y1, 1, 1, 0, COLORS._main_accent, 1);
}
if(!parent_anchor)
draw_anchor(control_i0 * .5, control_x0, control_y0, 8, attributes.display_bone);
draw_anchor(control_i1 * .5, control_x1, control_y1, 8, attributes.display_bone);
}
for( var i = 0, n = array_length(childs); i < n; i++ )
@ -319,15 +286,27 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
}
static resetPose = function() {
pose_angle = 0;
pose_scale = 1;
pose_posit = [ 0, 0 ];
pose_distance = distance;
pose_direction = direction;
pose_angle = angle;
pose_length = length;
init_direction = direction;
init_distance = distance;
pose_posit = [ 0, 0 ];
pose_rotate = 0;
pose_scale = 1;
pose_local_posit = [ 0, 0 ];
pose_local_rotate = 0;
pose_local_scale = 1;
pose_apply_posit = [ 0, 0 ];
pose_apply_rotate = 0;
pose_apply_scale = 1;
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].resetPose();
return self;
}
static __setPosition = function() {
@ -342,49 +321,50 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].setPosition();
return self;
}
static setPose = function(_position = [ 0, 0 ], _angle = 0, _scale = 1, _ik = true) {
static setPose = function(_ik = true) {
setPosition();
setPoseTransform(_position, _angle, _scale);
if(_ik) {
setPosition();
setIKconstrain();
}
setPoseTransform();
if(_ik) { setPosition(); setIKconstrain(); }
setPosition();
return self;
}
static setPoseTransform = function(_position = [ 0, 0 ], _angle = 0, _scale = 1) {
static setPoseTransform = function() {
if(is_main) {
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].setPoseTransform(_position, _angle, _scale);
array_foreach(childs, function(c) /*=>*/ {return c.setPoseTransform()});
return;
}
pose_posit[0] += _position[0];
pose_posit[1] += _position[1];
if(apply_rotation) pose_angle += _angle;
if(apply_scale) pose_scale *= _scale;
pose_apply_posit = [ pose_posit[0], pose_posit[1] ];
pose_apply_rotate = pose_rotate;
pose_apply_scale = pose_scale;
if(angular_constrain != -1) pose_angle = clamp(pose_angle, -angular_constrain, angular_constrain);
if(parent) { // do this instead of recursion.
pose_local_posit = parent.pose_apply_posit;
pose_local_rotate = parent.pose_apply_rotate;
pose_local_scale = parent.pose_apply_scale;
pose_apply_posit[0] += pose_local_posit[0];
pose_apply_posit[1] += pose_local_posit[1];
pose_apply_rotate += pose_local_rotate;
pose_apply_scale *= pose_local_scale;
}
pose_local_angle = pose_angle;
pose_local_scale = pose_scale;
pose_local_posit = pose_posit;
var ldx = lengthdir_x(distance, direction) + pose_posit[0];
var ldy = lengthdir_y(distance, direction) + pose_posit[1];
var _x = lengthdir_x(distance, direction) + pose_posit[0];
var _y = lengthdir_y(distance, direction) + pose_posit[1];
pose_direction = point_direction(0, 0, ldx, ldy) + pose_local_rotate;
pose_distance = point_distance(0, 0, ldx, ldy) * pose_local_scale;
direction = point_direction(0, 0, _x, _y) + _angle;
distance = point_distance(0, 0, _x, _y) * _scale;
pose_angle = angle + pose_apply_rotate;
pose_length = length * pose_apply_scale;
init_length = length;
init_angle = angle;
angle += pose_angle;
length *= pose_scale;
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].setPoseTransform(_position, pose_angle, pose_scale);
array_foreach(childs, function(c) /*=>*/ {return c.setPoseTransform()});
}
static setIKconstrain = function() {
@ -412,8 +392,8 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
}
var p = parent.getHead();
var px = p.x + lengthdir_x(distance, direction);
var py = p.y + lengthdir_y(distance, direction);
var px = p.x + lengthdir_x(pose_distance, pose_direction);
var py = p.y + lengthdir_y(pose_distance, pose_direction);
FABRIK(bones, points, lengths, px, py);
}
@ -457,13 +437,7 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
var dir = point_direction(p0.x, p0.y, p1.x, p1.y);
var dis = point_distance( p0.x, p0.y, p1.x, p1.y);
// _b.pose_scale = dis / _b.init_length;
// _b.length = dis;
// _b.pose_angle = dir - _b.init_angle;
// _b.angle = _b.init_angle + _b.pose_angle;
_b.angle = dir;
_b.pose_angle = dir;
FABRIK_result[i] = p0;
}
@ -504,7 +478,7 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
var len = lengths[i];
var dir = point_direction(tx, ty, p1.x, p1.y);
if(_b.angular_constrain != -1) dir = clamp(dir, _b.init_angle - _b.angular_constrain, _b.init_angle + _b.angular_constrain);
// if(_b.angular_constrain != -1) dir = clamp(dir, _b.angle - _b.angular_constrain, _b.angle + _b.angular_constrain);
p0.x = tx;
p0.y = ty;
@ -600,10 +574,8 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
angular_constrain = -1;
childs = [];
for( var i = 0, n = array_length(bone.childs); i < n; i++ ) {
var _b = new __Bone().deserialize(bone.childs[i], node);
addChild(_b);
}
for( var i = 0, n = array_length(bone.childs); i < n; i++ )
addChild(new __Bone().deserialize(bone.childs[i], node));
return self;
}
@ -615,17 +587,25 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
for( var i = 0, n = array_length(childs); i < n; i++ )
childs[i].connect();
return self;
}
static clone = function() {
var _b = new __Bone(parent, distance, direction, angle, length);
_b.ID = ID;
_b.name = name;
_b.is_main = is_main;
_b.angle = angle;
_b.length = length;
_b.distance = distance;
_b.direction = direction;
_b.ID = ID;
_b.name = name;
_b.is_main = is_main;
_b.parent_anchor = parent_anchor;
_b.IKlength = IKlength;
_b.IKTargetID = IKTargetID;
_b.IKlength = IKlength;
_b.IKTargetID = IKTargetID;
_b.apply_rotation = apply_rotation;
_b.apply_scale = apply_scale;
@ -637,7 +617,7 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
return _b;
}
static toString = function() { return $"Bone {name} [{ID}]"; }
static toString = function() { return $"Bone {name} [{ID}] : [{direction}, {distance}] / [{angle}, {length}]"; }
static toArray = function(arr = []) {
if(!is_main) array_push(arr, self);
@ -646,4 +626,14 @@ function __Bone(_parent = noone, _distance = 0, _direction = 0, _angle = 0, _len
return arr;
}
static getHash = function() {
var childHash = "";
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}]";
return sha1_string_unicode(h);
}
}

View file

@ -44,7 +44,7 @@
LATEST_VERSION = 1_18_00_0;
VERSION = 1_18_04_0;
SAVE_VERSION = 1_18_04_0;
VERSION_STRING = MAC? "1.18.003m" : "1.18.5.005";
VERSION_STRING = MAC? "1.18.003m" : "1.18.5.006";
BUILD_NUMBER = 1_18_04_1;
HOTKEYS = ds_map_create();

View file

@ -128,10 +128,15 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
static createBone = function(parent, distance, direction) {
recordAction(ACTION_TYPE.struct_modify, bones, bones.serialize());
var bone = new __Bone(parent, distance, direction,,, self);
var bone = new __Bone(parent, distance, direction, 0, 0, self);
parent.addChild(bone);
if(parent == bones) bone.parent_anchor = false;
if(parent == bones)
bone.parent_anchor = false;
bone.distance = distance;
bone.direction = direction;
return bone;
}
@ -181,7 +186,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
bone_transform_bbox = -1;
bone_transform_type = -1;
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _panel) {
var mx = (_mx - _x) / _s;
var my = (_my - _y) / _s;
@ -190,8 +195,11 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
var _b = bones;
if(builder_bone != noone) {
if(builder_bone != noone) {
gpu_set_texfilter(true);
anchor_selecting = _b.draw(attributes, false, _x, _y, _s, _mx, _my, anchor_selecting, builder_bone);
_b.drawControl(attributes);
var dir = point_direction(builder_sx, builder_sy, smx, smy);
var dis = point_distance(builder_sx, builder_sy, smx, smy);
@ -209,7 +217,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
builder_bone.length = point_distance(builder_sx, builder_sy, mx, my) / builder_sv;
orig = builder_bone.getPoint(0.75);
orig = builder_bone.getPoint(0.8);
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
draw_sprite_ext(s_bone_scale, 0, _rx, _ry, 1, 1, builder_bone.angle, COLORS._main_value_positive, 1);
@ -281,34 +289,39 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
UNDO_HOLDING = false;
}
gpu_set_texfilter(false);
triggerRender();
} else if(ik_dragging != noone) {
anchor_selecting = _b.draw(attributes, active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting, ik_dragging);
_b.drawControl(attributes);
var _bone = ik_dragging.parent;
var _bone = ik_dragging;
var p1 = ik_dragging.getTail();
var p1x = _x + p1.x * _s;
var p1y = _y + p1.y * _s;
if(anchor_selecting != noone && anchor_selecting[1] == 2) {
var anc = anchor_selecting[0];
var bne = anc;
var _reach = false;
var _blen = 0;
while(_bone != noone) {
if(_bone == anc.parent) {
_reach = true;
break;
}
_blen++;
_bone = _bone.parent;
if(_bone == anc.parent) {
_reach = true;
bne = anc;
anc = anc.parent;
break;
}
}
if(_reach) {
var p0 = anc.getHead();
var p0t = anc.getTail();
var p0t = bne.getHead();
var _px = _x + p0t.x * _s;
var _py = _y + p0t.y * _s;
draw_line_dashed(_px, _py, p1x, p1y, 2, 8);
@ -322,6 +335,9 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
var IKbone = new __Bone(anc, _len, _ang, ik_dragging.angle + 90, 0, self);
anc.addChild(IKbone);
IKbone.direction = _ang;
IKbone.distance = _len;
IKbone.IKlength = _blen;
IKbone.IKTargetID = ik_dragging.ID;
@ -491,13 +507,17 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
}
} else if(isUsingTool("Add bones")) { // builder
if(builder_bone == noone)
if(builder_bone == noone) {
anchor_selecting = _b.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
_b.drawControl(attributes);
}
if(mouse_press(mb_left, active)) {
if(anchor_selecting == noone) {
builder_bone = createBone(bones, point_distance(0, 0, smx, smy), point_direction(0, 0, smx, smy));
builder_type = 1;
builder_sx = smx;
builder_sy = smy;
UNDO_HOLDING = true;
@ -506,6 +526,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
} else if(anchor_selecting[1] == 1) {
builder_bone = createBone(anchor_selecting[0], 0, 0);
builder_type = 1;
builder_sx = smx;
builder_sy = smy;
UNDO_HOLDING = true;
@ -579,11 +600,10 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
builder_type = 0;
var head = par.getHead();
var tail = par.getTail();
builder_sx = head.x + (mx - tail.x);
builder_sy = head.y + (my - tail.y);
builder_mx = mx;
builder_my = my;
builder_sx = head.x;
builder_sy = head.y;
builder_mx = mx;
builder_my = my;
UNDO_HOLDING = true;
}
@ -595,31 +615,34 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
ik_dragging = anchor_selecting[0];
}
} else { //mo tools
if(builder_bone == noone)
} else { // move tools
if(builder_bone == noone) {
anchor_selecting = _b.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
_b.drawControl(attributes);
}
if(anchor_selecting != noone) {
var orig;
var _bne = anchor_selecting[0];
var _typ = anchor_selecting[1];
if(_bne.IKlength) _typ = 0;
gpu_set_texfilter(true);
if(_typ == 0) { // free move
orig = _bne.getHead();
var orig = _bne.getHead();
draw_sprite_ext(s_bone_move, 0, _x + _s * orig.x, _y + _s * orig.y, 1, 1, 0, COLORS._main_accent, 1);
} else if(_typ == 1) { // bone move
orig = _bne.getTail();
var orig = _bne.getTail();
draw_sprite_ext(s_bone_move, 0, _x + _s * orig.x, _y + _s * orig.y, 1, 1, 0, COLORS._main_accent, 1);
} else if(_typ == 2) { // bone rotate
orig = _bne.getHead();
var orig = _bne.getHead();
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
orig = _bne.getPoint(0.8);
var orig = _bne.getPoint(0.8);
var _sx = _x + _s * orig.x;
var _sy = _y + _s * orig.y;
@ -644,17 +667,17 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
recordAction(ACTION_TYPE.struct_modify, bones, bones.serialize());
if(_typ == 0) {
orig = _bne.parent.getHead();
var orig = _bne.parent.getHead();
builder_sx = orig.x;
builder_sy = orig.y;
} else if(_typ == 1) {
orig = _bne.getHead();
var orig = _bne.getHead();
builder_sx = orig.x;
builder_sy = orig.y;
} else if(_typ == 2) {
orig = _bne.getHead();
var orig = _bne.getHead();
builder_sv = point_direction(orig.x, orig.y, mx, my);
builder_sx = orig.x;
builder_sy = orig.y;
@ -662,7 +685,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
builder_my = my;
} else if(_typ == 3) {
orig = _bne.getHead();
var orig = _bne.getHead();
builder_sv = point_distance(orig.x, orig.y, mx, my) / _bne.length;
builder_sx = orig.x;
builder_sy = orig.y;
@ -677,7 +700,9 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
static step = function() {}
static update = function(frame = CURRENT_FRAME) {
bones.setPosition();
bones.resetPose()
.setPosition();
outputs[0].setValue(bones);
}

View file

@ -556,7 +556,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
_tran[TRANSFORM.rot] = sa;
} else if(drag_type == NODE_COMPOSE_DRAG.scale) {
var _rot = _aang * (_pang? _bone.angle : _bone.pose_local_angle) + _tran[TRANSFORM.rot];
var _rot = _aang * (_pang? _bone.angle : _bone.pose_local_rotate) + _tran[TRANSFORM.rot];
var _sw = surface_get_width_safe(_surf);
var _sh = surface_get_height_safe(_surf);
@ -621,7 +621,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
var _asca = current_data[index + 4];
var _psca = current_data[index + 5];
var _rot = _aang * (_pang? _bone.angle : _bone.pose_local_angle) + _tran[TRANSFORM.rot];
var _rot = _aang * (_pang? _bone.angle : _bone.pose_local_rotate) + _tran[TRANSFORM.rot];
var _anc = _bone.getPoint(0.5);
var _mov = point_rotate(_tran[TRANSFORM.pos_x], _tran[TRANSFORM.pos_y], 0, 0, _bone.angle);
var _sca = [ _tran[TRANSFORM.sca_x], _tran[TRANSFORM.sca_y] ];
@ -811,7 +811,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
var _ax = _p.sx - _bm.bone_head_pose.x;
var _ay = _p.sy - _bm.bone_head_pose.y;
point_rotate_origin(_ax, _ay, _b.pose_angle - _bm.pose_angle, _ar);
point_rotate_origin(_ax, _ay, _b.pose_rotate - _bm.pose_rotate, _ar);
var _nx = _b.bone_head_pose.x + _ar[0] * _b.pose_scale / _bm.pose_scale;
var _ny = _b.bone_head_pose.y + _ar[1] * _b.pose_scale / _bm.pose_scale;
@ -905,7 +905,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
var _asca = use_data? _bind[i].applySca : _data[_i + 4];
var _psca = use_data? _bind[i].applyScal : _data[_i + 5];
var _rot = _aang * (_pang? _b.angle : _b.pose_local_angle) + _tran[TRANSFORM.rot];
var _rot = _aang * (_pang? _b.angle : _b.pose_local_rotate) + _tran[TRANSFORM.rot];
var _anc = _b.getPoint(0.5);
var _mov = point_rotate(_tran[TRANSFORM.pos_x], _tran[TRANSFORM.pos_y], 0, 0, _b.angle);
var _sca = [ _tran[TRANSFORM.sca_x], _tran[TRANSFORM.sca_y] ];

View file

@ -200,7 +200,7 @@ function Node_Armature_Mesh_Rig(_x, _y, _group = noone) : Node(_x, _y, _group) c
if(posing_bone) {
if(posing_type == 0 && posing_bone.parent) { //move
var ang = posing_bone.parent.pose_angle;
var ang = posing_bone.parent.pose_rotate;
var pp = point_rotate(smx - posing_mx, smy - posing_my, 0, 0, -ang);
var bx = posing_sx + pp[0];
var by = posing_sy + pp[1];
@ -213,7 +213,7 @@ function Node_Armature_Mesh_Rig(_x, _y, _group = noone) : Node(_x, _y, _group) c
var ss = point_distance(posing_mx, posing_my, smx, smy) / posing_sx;
var ori = posing_bone.getHead();
var ang = point_direction(ori.x, ori.y, smx, smy);
var rot = ang - posing_sy - posing_bone.parent.pose_angle;
var rot = ang - posing_sy - posing_bone.parent.pose_rotate;
posing_input[TRANSFORM.sca_x] = ss;
posing_input[TRANSFORM.rot] = rot;
@ -260,7 +260,7 @@ function Node_Armature_Mesh_Rig(_x, _y, _group = noone) : Node(_x, _y, _group) c
var ori = posing_bone.getHead();
posing_sx = posing_bone.length / posing_bone.pose_scale * posing_bone.parent.pose_scale;
posing_sy = posing_bone.angle - posing_bone.pose_local_angle;
posing_sy = posing_bone.angle - posing_bone.pose_local_rotate;
posing_sz = point_direction(ori.x, ori.y, smx, smy);
var pnt = posing_bone.getHead();
@ -393,11 +393,11 @@ function Node_Armature_Mesh_Rig(_x, _y, _group = noone) : Node(_x, _y, _group) c
var _trn = attributes.bonePoseData[$ _b.ID];
_b.pose_posit = [ _trn[TRANSFORM.pos_x], _trn[TRANSFORM.pos_y] ];
_b.pose_angle = _trn[TRANSFORM.rot];
_b.pose_rotate = _trn[TRANSFORM.rot];
_b.pose_scale = _trn[TRANSFORM.sca_x];
}
bone_posed.setPose(,,, false);
bone_posed.setPose(false);
if(rigdata == noone) AutoWeightPaint(false);

View file

@ -11,7 +11,9 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
newOutput(0, nodeValue_Output("Armature", self, VALUE_TYPE.armature, noone));
boneMap = {};
boneHash = "";
bonePose = noone;
boneMap = {};
attributes.display_name = true;
attributes.display_bone = 0;
@ -36,25 +38,13 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
setDynamicInput(1, false);
static setBone = function() {
//print("Setting dem bones...");
// print("Setting dem bones...");
var _b = getInputData(0);
if(_b == noone) return;
var _bones = [];
var _bst = ds_stack_create();
ds_stack_push(_bst, _b);
while(!ds_stack_empty(_bst)) {
var __b = ds_stack_pop(_bst);
for( var i = 0, n = array_length(__b.childs); i < n; i++ ) {
array_push(_bones, __b.childs[i]);
ds_stack_push(_bst, __b.childs[i]);
}
}
ds_stack_destroy(_bst);
bonePose = _b.clone().connect();
var _bArr = _b.toArray();
var _inputs = [ inputs[0] ];
var _input_display_list = [
@ -62,8 +52,8 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
input_display_list[1]
];
for( var i = 0, n = array_length(_bones); i < n; i++ ) {
var bone = _bones[i];
for( var i = 0, n = array_length(_bArr); i < n; i++ ) {
var bone = _bArr[i];
var _idx = array_length(_inputs);
var _inp;
@ -72,8 +62,6 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
if(struct_exists(boneMap, bone.ID)) {
_inp = boneMap[$ bone.ID];
_inp.index = _idx;
array_push(_inputs, _inp);
} else
_inp = createNewInput(bone);
@ -82,7 +70,6 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
inputs = _inputs;
input_display_list = _input_display_list;
}
tools = [];
@ -91,17 +78,20 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
posing_bone = noone;
posing_input = 0;
posing_type = 0;
posing_sx = 0;
posing_sy = 0;
posing_sz = 0;
posing_mx = 0;
posing_my = 0;
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var _b = outputs[0].getValue();
if(_b == noone) return;
var _b = inputs[0].getValue();
anchor_selecting = _b.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting, posing_bone);
if(_b == noone) return;
if(bonePose == noone) return;
anchor_selecting = bonePose.draw(attributes, active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting, posing_bone);
bonePose.drawControl(attributes);
var mx = (_mx - _x) / _s;
var my = (_my - _y) / _s;
@ -110,32 +100,38 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
var smy = value_snap(my, _sny);
if(posing_bone) {
if(posing_type == 0 && posing_bone.parent) { //move
var ang = posing_bone.parent.pose_angle;
gpu_set_texfilter(true);
var val = array_clone(posing_input.getValue());
if(posing_type == 0) { //move
var ang = posing_bone.pose_local_rotate;
var pp = point_rotate(smx - posing_mx, smy - posing_my, 0, 0, -ang);
var bx = posing_sx + pp[0];
var by = posing_sy + pp[1];
var val = array_clone(posing_input.getValue());
val[TRANSFORM.pos_x] = bx;
val[TRANSFORM.pos_y] = by;
if(posing_input.setValue(val))
UNDO_HOLDING = true;
orig = posing_bone.getHead();
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
draw_sprite_ext(s_bone_move, 0, _rx, _ry, 1, 1, 0, COLORS._main_value_positive, 1);
} else if(posing_type == 1) { //scale
var ss = point_distance(posing_mx, posing_my, smx, smy) / posing_sx;
var ori = posing_bone.getHead();
var ang = point_direction(ori.x, ori.y, smx, smy);
var rot = ang - posing_sy - posing_bone.parent.pose_angle;
} else if(posing_type == 1) { //free move
var _direction = point_direction(posing_sx, posing_sy, smx, smy);
var _distance = point_distance(posing_sx, posing_sy, smx, smy);
var val = array_clone(posing_input.getValue());
val[TRANSFORM.sca_x] = ss;
val[TRANSFORM.rot] = rot;
var _scale = _distance / (posing_bone.length * posing_bone.pose_local_scale);
var _rotation = _direction - (posing_bone.angle + posing_bone.pose_local_rotate);
if(posing_input.setValue(val))
UNDO_HOLDING = true;
val[TRANSFORM.sca_x] = _scale;
val[TRANSFORM.rot] = _rotation;
orig = posing_bone.getTail();
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
draw_sprite_ext(s_bone_move, 0, _rx, _ry, 1, 1, 0, COLORS._main_value_positive, 1);
} else if(posing_type == 2) { //rotate
var ori = posing_bone.getHead();
var ang = point_direction(ori.x, ori.y, mx, my);
@ -143,115 +139,165 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
posing_sy = ang;
posing_sx += rot;
var val = array_clone(posing_input.getValue());
val[TRANSFORM.rot] = posing_sx;
if(posing_input.setValue(val))
UNDO_HOLDING = true;
}
orig = posing_bone.getHead();
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
draw_sprite_ext(s_bone_rotate, 0, _rx, _ry, 1, 1, posing_bone.pose_angle, COLORS._main_value_positive, 1);
} else if(posing_type == 3) { //scale
var ss = point_distance(posing_mx, posing_my, smx, smy) / posing_sx;
val[TRANSFORM.sca_x] = ss;
orig = posing_bone.getPoint(0.8);
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
draw_sprite_ext(s_bone_scale, 0, _rx, _ry, 1, 1, posing_bone.pose_angle, COLORS._main_value_positive, 1);
}
gpu_set_texfilter(false);
if(posing_input.setValue(val))
UNDO_HOLDING = true;
if(mouse_release(mb_left)) {
posing_bone = noone;
posing_type = noone;
UNDO_HOLDING = false;
}
}
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
posing_bone = anchor_selecting[0];
if(!struct_exists(boneMap, posing_bone.ID)) setBone();
posing_input = boneMap[$ posing_bone.ID];
if(anchor_selecting[1] == 0 || anchor_selecting[0].IKlength) { // move
} else if(anchor_selecting != noone) {
var _bne = anchor_selecting[0];
var _typ = anchor_selecting[1];
if(_bne.IKlength) _typ = 0;
gpu_set_texfilter(true);
if(_typ == 0) { // free move
var orig = _bne.getHead();
draw_sprite_ext(s_bone_move, 0, _x + _s * orig.x, _y + _s * orig.y, 1, 1, 0, COLORS._main_accent, 1);
posing_type = 0;
} else if(_typ == 1) { // bone move
var orig = _bne.getTail();
draw_sprite_ext(s_bone_move, 0, _x + _s * orig.x, _y + _s * orig.y, 1, 1, 0, COLORS._main_accent, 1);
var val = posing_input.getValue();
posing_sx = val[TRANSFORM.pos_x];
posing_sy = val[TRANSFORM.pos_y];
} else if(_typ == 2) { // bone rotate
var orig = _bne.getHead();
var _rx = _x + _s * orig.x;
var _ry = _y + _s * orig.y;
var _p = anchor_selecting[2];
posing_mx = _p.x;
posing_my = _p.y;
var orig = _bne.getPoint(0.8);
var _sx = _x + _s * orig.x;
var _sy = _y + _s * orig.y;
} else if(anchor_selecting[1] == 1) { // scale
if(point_in_circle(_mx, _my, _sx, _sy, 12)) {
draw_sprite_ext(s_bone_scale, 0, _sx, _sy, 1, 1, _bne.pose_angle, COLORS._main_accent, 1);
draw_sprite_ext(s_bone_rotate, 0, _rx, _ry, 1, 1, _bne.pose_angle, c_white, 1);
_typ = 3;
} else {
draw_sprite_ext(s_bone_scale, 0, _sx, _sy, 1, 1, _bne.pose_angle, c_white, 1);
draw_sprite_ext(s_bone_rotate, 0, _rx, _ry, 1, 1, _bne.pose_angle, COLORS._main_accent, 1);
_typ = 2;
}
}
gpu_set_texfilter(false);
posing_type = 1;
if(mouse_press(mb_left, active)) {
posing_bone = _bne;
posing_type = _typ;
var ori = posing_bone.getHead();
var val = posing_input.getValue();
posing_sx = posing_bone.length / posing_bone.pose_scale * posing_bone.parent.pose_scale;
posing_sy = posing_bone.angle - posing_bone.pose_local_angle;
posing_sz = point_direction(ori.x, ori.y, smx, smy);
if(!struct_exists(boneMap, _bne.ID)) setBone();
posing_input = boneMap[$ _bne.ID];
var pnt = posing_bone.getHead();
posing_mx = pnt.x;
posing_my = pnt.y;
} else if(anchor_selecting[1] == 2) { // rotate
posing_type = 2;
var ori = posing_bone.getHead();
var val = posing_input.getValue();
posing_sx = val[TRANSFORM.rot];
posing_sy = point_direction(ori.x, ori.y, mx, my);
posing_mx = mx;
posing_my = my;
if(_typ == 0) { // move
var val = posing_input.getValue();
var _p = anchor_selecting[2];
posing_sx = val[TRANSFORM.pos_x];
posing_sy = val[TRANSFORM.pos_y];
posing_mx = _p.x;
posing_my = _p.y;
} else if(_typ == 1) { // free move
var orig = _bne.getHead();
posing_sx = orig.x;
posing_sy = orig.y;
} else if(_typ == 2) { // rotate
var orig = _bne.getHead();
var val = posing_input.getValue();
posing_sx = val[TRANSFORM.rot];
posing_sy = point_direction(orig.x, orig.y, mx, my);
posing_mx = mx;
posing_my = my;
} else if(_typ == 3) { // scale
var orig = _bne.getHead();
var _sca = point_distance(orig.x, orig.y, mx, my) / _bne.pose_length;
posing_sx = _bne.length * _bne.pose_local_scale * _sca;
posing_mx = orig.x;
posing_my = orig.y;
}
}
}
}
bone_prev = noone;
static step = function() {
var _b = getInputData(0);
if(_b == noone) return;
if(bone_prev != _b) {
setBone();
bone_prev = _b;
return;
}
var _boneCount = array_length(inputs) - input_fix_len;
if(_boneCount != _b.childCount()) setBone();
}
static update = function(frame = CURRENT_FRAME) {
var _b = getInputData(0);
if(_b == noone) return;
var _bone_pose = _b.clone();
_bone_pose.connect();
_bone_pose.resetPose();
var _bst = ds_stack_create();
ds_stack_push(_bst, _bone_pose);
while(!ds_stack_empty(_bst)) {
var bone = ds_stack_pop(_bst);
var _id = bone.ID;
if(struct_exists(boneMap, _id)) {
var _inp = boneMap[$ _id];
_inp.updateName(bone.name);
var _trn = _inp.getValue();
bone.pose_posit = [ _trn[TRANSFORM.pos_x], _trn[TRANSFORM.pos_y] ];
bone.pose_angle = _trn[TRANSFORM.rot];
bone.pose_scale = _trn[TRANSFORM.sca_x];
}
for( var i = 0, n = array_length(bone.childs); i < n; i++ )
ds_stack_push(_bst, bone.childs[i]);
if(_b == noone) {
boneHash = "";
return;
}
ds_stack_destroy(_bst);
var _h = _b.getHash();
if(boneHash != _h) {
boneHash = _h;
setBone();
}
_bone_pose.setPose();
bonePose.resetPose()
.setPosition();
outputs[0].setValue(_bone_pose);
var _bArr = _b.toArray();
var bArr = bonePose.toArray();
for( var i = 0, n = array_length(bArr); i < n; i++ ) {
var _bone = _bArr[i];
var bone = bArr[i];
var _id = bone.ID;
if(!struct_exists(boneMap, _id)) continue;
var _inp = boneMap[$ _id];
_inp.updateName(bone.name);
var _trn = _inp.getValue();
bone.angle = _bone.angle;
bone.length = _bone.length;
bone.direction = _bone.direction;
bone.distance = _bone.distance;
bone.pose_posit = [ _trn[TRANSFORM.pos_x], _trn[TRANSFORM.pos_y] ];
bone.pose_rotate = _trn[TRANSFORM.rot];
bone.pose_scale = _trn[TRANSFORM.sca_x];
}
bonePose.setPose();
outputs[0].setValue(bonePose);
}
static getPreviewBoundingBox = function() {

View file

@ -48,7 +48,9 @@ function transformBox(_onModify) : widget() constructor {
static drawParam = function(params) {
setParam(params);
rot.setParam(params);
rot.setParam(params);
rot.tb_value.setParam(params);
for(var i = 0; i < 5; i++) tb[i].setParam(params);
return draw(params.x, params.y, params.w, params.h, params.data, params.m);

View file

@ -16,17 +16,23 @@ void main() {
a = smoothstep(.0, .1, dist);
c = mix(c, vec4(0., 0., 0., 1.), a);
a = smoothstep(.15, .2, dist);
a = smoothstep(.15, .3, dist);
c = mix(c, vec4(1., 1., 1., 1.), a);
a = smoothstep(.3, .4, dist);
a = smoothstep(.4, .5, dist);
c = mix(c, color, a);
} else if(type == 1) {
a = smoothstep(.3, .4, dist);
c = mix(c, color, a);
}
} else if(type == 2) {
a = smoothstep(.0, .15, dist);
c = mix(c, color, a);
a = smoothstep(.25, .35, dist);
c = mix(c, vec4(1., 1., 1., 1.), a);
}
gl_FragColor = c;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

View file

@ -2,25 +2,25 @@
"$GMSprite":"",
"%Name":"s_bone_IK",
"bboxMode":0,
"bbox_bottom":44,
"bbox_left":3,
"bbox_right":44,
"bbox_top":3,
"bbox_bottom":39,
"bbox_left":8,
"bbox_right":39,
"bbox_top":8,
"collisionKind":1,
"collisionTolerance":0,
"DynamicTexturePage":false,
"edgeFiltering":false,
"For3D":false,
"frames":[
{"$GMSpriteFrame":"","%Name":"4e6110f8-2b09-4d8c-b6b8-7abbbab4bfbe","name":"4e6110f8-2b09-4d8c-b6b8-7abbbab4bfbe","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"ffaa827f-36aa-4c2b-afb6-83e59e91703a","name":"ffaa827f-36aa-4c2b-afb6-83e59e91703a","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"cbf97cb1-6653-4c75-9be4-5101c2e9b3fa","name":"cbf97cb1-6653-4c75-9be4-5101c2e9b3fa","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
{"$GMSpriteFrame":"","%Name":"057b3896-f03a-4420-b1f1-7e4c9e862066","name":"057b3896-f03a-4420-b1f1-7e4c9e862066","resourceType":"GMSpriteFrame","resourceVersion":"2.0",},
],
"gridX":0,
"gridY":0,
"height":48,
"HTile":false,
"layers":[
{"$GMImageLayer":"","%Name":"34621c5e-ace8-4be5-ade5-dbaae800d244","blendMode":0,"displayName":"default","isLocked":false,"name":"34621c5e-ace8-4be5-ade5-dbaae800d244","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,},
{"$GMImageLayer":"","%Name":"3f968221-c1da-41cc-9c7d-7ad1be932e2a","blendMode":0,"displayName":"default","isLocked":false,"name":"3f968221-c1da-41cc-9c7d-7ad1be932e2a","opacity":100.0,"resourceType":"GMImageLayer","resourceVersion":"2.0","visible":true,},
],
"name":"s_bone_IK",
"nineSlice":null,
@ -70,11 +70,11 @@
"tracks":[
{"$GMSpriteFramesTrack":"","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"$KeyframeStore<SpriteFrameKeyframe>":"","Keyframes":[
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"4e6110f8-2b09-4d8c-b6b8-7abbbab4bfbe","path":"sprites/s_bone_IK/s_bone_IK.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"40fd8ce5-4341-46e3-84dc-5f887b50d84f","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"cbf97cb1-6653-4c75-9be4-5101c2e9b3fa","path":"sprites/s_bone_IK/s_bone_IK.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"60c64839-dcdb-4abb-89b6-ebfd207d6508","IsCreationKey":false,"Key":0.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
{"$Keyframe<SpriteFrameKeyframe>":"","Channels":{
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"ffaa827f-36aa-4c2b-afb6-83e59e91703a","path":"sprites/s_bone_IK/s_bone_IK.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"9b37fdc9-9538-4633-97a5-5c83b295881a","IsCreationKey":false,"Key":1.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
"0":{"$SpriteFrameKeyframe":"","Id":{"name":"057b3896-f03a-4420-b1f1-7e4c9e862066","path":"sprites/s_bone_IK/s_bone_IK.yy",},"resourceType":"SpriteFrameKeyframe","resourceVersion":"2.0",},
},"Disabled":false,"id":"2761fd6c-a0c4-4a3e-8683-b1db08d55ff9","IsCreationKey":false,"Key":1.0,"Length":1.0,"resourceType":"Keyframe<SpriteFrameKeyframe>","resourceVersion":"2.0","Stretch":false,},
],"resourceType":"KeyframeStore<SpriteFrameKeyframe>","resourceVersion":"2.0",},"modifiers":[],"name":"frames","resourceType":"GMSpriteFramesTrack","resourceVersion":"2.0","spriteId":null,"trackColour":0,"tracks":[],"traits":0,},
],
"visibleRange":null,