mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-25 14:36:13 +01:00
reaching ik
This commit is contained in:
parent
95384584ab
commit
4251afa2e4
16 changed files with 422 additions and 279 deletions
|
@ -727,7 +727,7 @@
|
|||
{"name":"node_perlin_smear","order":9,"path":"scripts/node_perlin_smear/node_perlin_smear.yy",},
|
||||
{"name":"node_alpha_cutoff","order":10,"path":"scripts/node_alpha_cutoff/node_alpha_cutoff.yy",},
|
||||
{"name":"sh_channel_R","order":4,"path":"shaders/sh_channel_R/sh_channel_R.yy",},
|
||||
{"name":"draw_circle_border","order":3,"path":"scripts/draw_circle_border/draw_circle_border.yy",},
|
||||
{"name":"draw_circle_functions","order":3,"path":"scripts/draw_circle_functions/draw_circle_functions.yy",},
|
||||
{"name":"s_node_text_file_write","order":12,"path":"sprites/s_node_text_file_write/s_node_text_file_write.yy",},
|
||||
{"name":"sliderRange","order":16,"path":"scripts/sliderRange/sliderRange.yy",},
|
||||
{"name":"point_rect_overlap","order":2,"path":"scripts/point_rect_overlap/point_rect_overlap.yy",},
|
||||
|
@ -973,7 +973,6 @@
|
|||
{"name":"fd_rectangle_set_collision_mask_surface","order":2,"path":"scripts/fd_rectangle_set_collision_mask_surface/fd_rectangle_set_collision_mask_surface.yy",},
|
||||
{"name":"node_array_length","order":11,"path":"scripts/node_array_length/node_array_length.yy",},
|
||||
{"name":"node_erode","order":9,"path":"scripts/node_erode/node_erode.yy",},
|
||||
{"name":"draw_circle_angle","order":15,"path":"scripts/draw_circle_angle/draw_circle_angle.yy",},
|
||||
{"name":"node_wrap_mesh","order":6,"path":"scripts/node_wrap_mesh/node_wrap_mesh.yy",},
|
||||
{"name":"sh_alpha_hash","order":43,"path":"shaders/sh_alpha_hash/sh_alpha_hash.yy",},
|
||||
{"name":"panel_node_align","order":3,"path":"scripts/panel_node_align/panel_node_align.yy",},
|
||||
|
@ -1125,7 +1124,6 @@
|
|||
{"name":"draw_UI_scale","order":8,"path":"scripts/draw_UI_scale/draw_UI_scale.yy",},
|
||||
{"name":"s_node_strandSim_update","order":1,"path":"sprites/s_node_strandSim_update/s_node_strandSim_update.yy",},
|
||||
{"name":"s_node_RGB_combine","order":45,"path":"sprites/s_node_RGB_combine/s_node_RGB_combine.yy",},
|
||||
{"name":"draw_circle_prec","order":23,"path":"scripts/draw_circle_prec/draw_circle_prec.yy",},
|
||||
{"name":"s_node_shadow_cast","order":49,"path":"sprites/s_node_shadow_cast/s_node_shadow_cast.yy",},
|
||||
{"name":"fft_functions","order":1,"path":"scripts/fft_functions/fft_functions.yy",},
|
||||
{"name":"path_function","order":4,"path":"scripts/path_function/path_function.yy",},
|
||||
|
|
|
@ -448,6 +448,7 @@
|
|||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_anchor_scale.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_anchor_solid.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_anchor.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_IK.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_cursor_path_add.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_cursor_path_anchor.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_cursor_path_move.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/preview",},
|
||||
|
@ -464,6 +465,7 @@
|
|||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_3d_tool_transform.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_tool_add.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_tool_detach.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_tool_IK.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_tool_remove.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_bone_tool_transform.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_canvas_channel.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
|
||||
|
@ -1272,7 +1274,7 @@
|
|||
{"id":{"name":"node_alpha_cutoff","path":"scripts/node_alpha_cutoff/node_alpha_cutoff.yy",},},
|
||||
{"id":{"name":"pack_best_fit","path":"scripts/pack_best_fit/pack_best_fit.yy",},},
|
||||
{"id":{"name":"sh_channel_R","path":"shaders/sh_channel_R/sh_channel_R.yy",},},
|
||||
{"id":{"name":"draw_circle_border","path":"scripts/draw_circle_border/draw_circle_border.yy",},},
|
||||
{"id":{"name":"draw_circle_functions","path":"scripts/draw_circle_functions/draw_circle_functions.yy",},},
|
||||
{"id":{"name":"s_node_text_file_write","path":"sprites/s_node_text_file_write/s_node_text_file_write.yy",},},
|
||||
{"id":{"name":"sliderRange","path":"scripts/sliderRange/sliderRange.yy",},},
|
||||
{"id":{"name":"point_rect_overlap","path":"scripts/point_rect_overlap/point_rect_overlap.yy",},},
|
||||
|
@ -1546,7 +1548,6 @@
|
|||
{"id":{"name":"node_armature","path":"scripts/node_armature/node_armature.yy",},},
|
||||
{"id":{"name":"node_array_length","path":"scripts/node_array_length/node_array_length.yy",},},
|
||||
{"id":{"name":"node_erode","path":"scripts/node_erode/node_erode.yy",},},
|
||||
{"id":{"name":"draw_circle_angle","path":"scripts/draw_circle_angle/draw_circle_angle.yy",},},
|
||||
{"id":{"name":"node_wrap_mesh","path":"scripts/node_wrap_mesh/node_wrap_mesh.yy",},},
|
||||
{"id":{"name":"node_surface_to_buffer","path":"scripts/node_surface_to_buffer/node_surface_to_buffer.yy",},},
|
||||
{"id":{"name":"node_curve","path":"scripts/node_curve/node_curve.yy",},},
|
||||
|
@ -1730,7 +1731,6 @@
|
|||
{"id":{"name":"s_node_strandSim_update","path":"sprites/s_node_strandSim_update/s_node_strandSim_update.yy",},},
|
||||
{"id":{"name":"async_functions","path":"scripts/async_functions/async_functions.yy",},},
|
||||
{"id":{"name":"s_node_RGB_combine","path":"sprites/s_node_RGB_combine/s_node_RGB_combine.yy",},},
|
||||
{"id":{"name":"draw_circle_prec","path":"scripts/draw_circle_prec/draw_circle_prec.yy",},},
|
||||
{"id":{"name":"s_node_shadow_cast","path":"sprites/s_node_shadow_cast/s_node_shadow_cast.yy",},},
|
||||
{"id":{"name":"fft_functions","path":"scripts/fft_functions/fft_functions.yy",},},
|
||||
{"id":{"name":"path_function","path":"scripts/path_function/path_function.yy",},},
|
||||
|
|
Binary file not shown.
|
@ -10,6 +10,9 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
pose_angle = 0;
|
||||
pose_scale = 1;
|
||||
pose_posit = [ 0, 0 ];
|
||||
pose_local_angle = 0;
|
||||
pose_local_scale = 1;
|
||||
pose_local_posit = [ 0, 0 ];
|
||||
|
||||
self.is_main = false;
|
||||
self.parent_anchor = true;
|
||||
|
@ -27,6 +30,7 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
updated = false;
|
||||
|
||||
IKlength = 0;
|
||||
IKTarget = noone;
|
||||
|
||||
freeze_data = {};
|
||||
|
||||
|
@ -61,6 +65,19 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
childs[i].freeze();
|
||||
}
|
||||
|
||||
static findBone = function(_id) {
|
||||
if(id == _id)
|
||||
return self;
|
||||
|
||||
for( var i = 0; i < array_length(childs); i++ ) {
|
||||
var b = childs[i].findBone(_id);
|
||||
if(b != noone)
|
||||
return b;
|
||||
}
|
||||
|
||||
return noone;
|
||||
}
|
||||
|
||||
static getPoint = function(progress) {
|
||||
var len = length * progress;
|
||||
|
||||
|
@ -80,7 +97,16 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
return p;
|
||||
}
|
||||
|
||||
static draw = function(edit = false, _x = 0, _y = 0, _s = 1, _mx = 0, _my = 0, child = true, hovering = noone) {
|
||||
static draw = function(edit = false, _x = 0, _y = 0, _s = 1, _mx = 0, _my = 0, hovering = noone, selecting = noone) {
|
||||
var hover = _drawBone(edit, _x, _y, _s, _mx, _my, hovering, selecting);
|
||||
drawControl();
|
||||
return hover;
|
||||
}
|
||||
|
||||
control_x0 = 0; control_y0 = 0; control_i0 = 0;
|
||||
control_x1 = 0; control_y1 = 0; control_i1 = 0;
|
||||
|
||||
static _drawBone = function(edit = false, _x = 0, _y = 0, _s = 1, _mx = 0, _my = 0, hovering = noone, selecting = noone) {
|
||||
var hover = noone;
|
||||
|
||||
var p0 = getPoint(0);
|
||||
|
@ -91,10 +117,23 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
p1.x = _x + p1.x * _s;
|
||||
p1.y = _y + p1.y * _s;
|
||||
|
||||
control_x0 = p0.x; control_y0 = p0.y;
|
||||
control_x1 = p1.x; control_y1 = p1.y;
|
||||
|
||||
if(parent != noone) {
|
||||
var _boneHover = hovering != noone && hovering[0] == self && hovering[1] == 2;
|
||||
var aa = _boneHover? 1 : 0.75;
|
||||
draw_set_color(_boneHover? c_white : COLORS._main_accent);
|
||||
|
||||
if(hovering != noone && hovering[0] == self && hovering[1] == 2) {
|
||||
draw_set_color(c_white);
|
||||
draw_set_alpha(1);
|
||||
} else if(selecting == self) {
|
||||
draw_set_color(COLORS._main_value_positive);
|
||||
draw_set_alpha(0.75);
|
||||
} else {
|
||||
draw_set_color(COLORS._main_accent);
|
||||
draw_set_alpha(0.75);
|
||||
}
|
||||
|
||||
if(IKlength == 0) {
|
||||
if(!parent_anchor && parent.parent != noone) {
|
||||
var _p = parent.getPoint(0);
|
||||
_p.x = _x + _p.x * _s;
|
||||
|
@ -102,14 +141,30 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
draw_line_dashed(_p.x, _p.y, p0.x, p0.y, 1);
|
||||
}
|
||||
|
||||
draw_set_alpha(aa);
|
||||
var _ppx = lerp(p0.x, p1.x, 0.2);
|
||||
var _ppy = lerp(p0.y, p1.y, 0.2);
|
||||
draw_line_width2(p0.x, p0.y, _ppx, _ppy, 2, 12);
|
||||
draw_line_width2(_ppx, _ppy, p1.x, p1.y, 12, 2);
|
||||
|
||||
if((edit & 0b100) && distance_to_line(_mx, _my, p0.x, p0.y, p1.x, p1.y) <= 12) //drag bone
|
||||
hover = [ self, 2 ];
|
||||
} else {
|
||||
draw_set_color(c_white);
|
||||
if(!parent_anchor && parent.parent != noone) {
|
||||
var _p = parent.getPoint(1);
|
||||
_p.x = _x + _p.x * _s;
|
||||
_p.y = _y + _p.y * _s;
|
||||
draw_line_dashed(_p.x, _p.y, p0.x, p0.y, 1);
|
||||
}
|
||||
|
||||
draw_sprite_ui(THEME.preview_bone_IK, 0, p0.x, p0.y,,,, c_white, draw_get_alpha());
|
||||
|
||||
if((edit & 0b100) && point_in_circle(_mx, _my, p0.x, p0.y, 24))
|
||||
hover = [ self, 2 ];
|
||||
}
|
||||
draw_set_alpha(1.00);
|
||||
|
||||
if(attributes.display_name) {
|
||||
if(attributes.display_name && IKlength == 0) {
|
||||
if(abs(p0.y - p1.y) < abs(p0.x - p1.x)) {
|
||||
draw_set_text(f_p2, fa_center, fa_bottom, COLORS._main_accent);
|
||||
draw_text_add((p0.x + p1.x) / 2, (p0.y + p1.y) / 2 - 4, name);
|
||||
|
@ -119,33 +174,29 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
}
|
||||
}
|
||||
|
||||
if(edit && distance_to_line(_mx, _my, p0.x, p0.y, p1.x, p1.y) <= 12) //drag bone
|
||||
hover = [ self, 2 ];
|
||||
|
||||
if(IKlength == 0) {
|
||||
if(!parent_anchor) {
|
||||
if(edit && point_in_circle(_mx, _my, p0.x, p0.y, ui(16))) { //drag head
|
||||
draw_sprite_colored(THEME.anchor_selector, 0, p0.x, p0.y);
|
||||
control_i0 = (hovering != noone && hovering[0] == self && hovering[1] == 0)? 0 : 2;
|
||||
|
||||
if((edit & 0b001) && point_in_circle(_mx, _my, p0.x, p0.y, ui(16))) //drag head
|
||||
hover = [ self, 0 ];
|
||||
} else
|
||||
draw_sprite_colored(THEME.anchor_selector, 2, p0.x, p0.y);
|
||||
}
|
||||
|
||||
if(edit && point_in_circle(_mx, _my, p1.x, p1.y, ui(16))) { //drag tail
|
||||
draw_sprite_colored(THEME.anchor_selector, 0, p1.x, p1.y);
|
||||
control_i1 = (hovering != noone && hovering[0] == self && hovering[1] == 1)? 0 : 2;
|
||||
|
||||
if((edit & 0b010) && point_in_circle(_mx, _my, p1.x, p1.y, ui(16))) //drag tail
|
||||
hover = [ self, 1 ];
|
||||
} else
|
||||
draw_sprite_colored(THEME.anchor_selector, 2, p1.x, p1.y);
|
||||
}
|
||||
}
|
||||
|
||||
//var ph = getPoint(0.5);
|
||||
//ph.x = _x + ph.x * _s;
|
||||
//ph.y = _y + ph.y * _s;
|
||||
//draw_set_color(COLORS._main_accent);
|
||||
//draw_circle(ph.x, ph.y, 4, false);
|
||||
//draw_set_color(c_red);
|
||||
//for( var i = 0; i < array_length(FABRIK_result); i++ ) {
|
||||
// var pt = FABRIK_result[i];
|
||||
// draw_circle(_x + pt.x * _s, _y + pt.y * _s, 16, false);
|
||||
//}
|
||||
|
||||
if(child)
|
||||
for( var i = 0; i < array_length(childs); i++ ) {
|
||||
var h = childs[i].draw(edit, _x, _y, _s, _mx, _my, true, hovering);
|
||||
var h = childs[i]._drawBone(edit, _x, _y, _s, _mx, _my, hovering, selecting);
|
||||
if(hover == noone && h != noone)
|
||||
hover = h;
|
||||
}
|
||||
|
@ -153,6 +204,17 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
return hover;
|
||||
}
|
||||
|
||||
static drawControl = function() {
|
||||
if(parent != noone && IKlength == 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);
|
||||
}
|
||||
|
||||
for( var i = 0; i < array_length(childs); i++ )
|
||||
childs[i].drawControl();
|
||||
}
|
||||
|
||||
static resetPose = function() {
|
||||
pose_angle = 0;
|
||||
pose_scale = 1;
|
||||
|
@ -174,6 +236,10 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
return;
|
||||
}
|
||||
|
||||
pose_local_angle = pose_angle;
|
||||
pose_local_scale = pose_scale;
|
||||
pose_local_posit = pose_posit;
|
||||
|
||||
pose_posit[0] += _position[0];
|
||||
pose_posit[1] += _position[1];
|
||||
pose_angle += _angle;
|
||||
|
@ -182,8 +248,8 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
var _x = lengthdir_x(distance, direction) + pose_posit[0];
|
||||
var _y = lengthdir_y(distance, direction) + pose_posit[1];
|
||||
|
||||
direction = point_direction(0, 0, _x, _y);
|
||||
distance = point_distance(0, 0, _x, _y);
|
||||
direction = point_direction(0, 0, _x, _y) + _angle;
|
||||
distance = point_distance(0, 0, _x, _y) * _scale;
|
||||
|
||||
angle += pose_angle;
|
||||
length *= pose_scale;
|
||||
|
@ -197,7 +263,125 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
}
|
||||
|
||||
static setIKconstrain = function() {
|
||||
if(IKlength > 0 && IKTarget != noone) {
|
||||
var points = array_create(IKlength + 1);
|
||||
var lengths = array_create(IKlength);
|
||||
var bones = array_create(IKlength);
|
||||
var bn = IKTarget;
|
||||
|
||||
for( var i = IKlength; i > 0; i-- ) {
|
||||
var _p = bn.getPoint(1);
|
||||
bones[i - 1] = bn;
|
||||
points[i] = {
|
||||
x: _p.x,
|
||||
y: _p.y
|
||||
};
|
||||
bn = bn.parent;
|
||||
}
|
||||
|
||||
_p = bn.getPoint(1);
|
||||
points[0] = {
|
||||
x: _p.x,
|
||||
y: _p.y
|
||||
};
|
||||
|
||||
for( var i = 0; i < IKlength; i++ ) {
|
||||
var p0 = points[i];
|
||||
var p1 = points[i + 1];
|
||||
|
||||
lengths[i] = point_distance(p0.x, p0.y, p1.x, p1.y);
|
||||
}
|
||||
|
||||
var p = parent.getPoint(0, 0);
|
||||
p.x += lengthdir_x(distance, direction);
|
||||
p.y += lengthdir_y(distance, direction);
|
||||
|
||||
FABRIK(bones, points, lengths, p.x, p.y);
|
||||
}
|
||||
|
||||
for( var i = 0; i < array_length(childs); i++ )
|
||||
childs[i].setIKconstrain();
|
||||
}
|
||||
|
||||
FABRIK_result = [];
|
||||
static FABRIK = function(bones, points, lengths, dx, dy) {
|
||||
var threshold = 0.1;
|
||||
var _bo = array_create(array_length(points));
|
||||
for( var i = 0; i < array_length(points); i++ )
|
||||
_bo[i] = { x: points[i].x, y: points[i].y };
|
||||
var sx = points[0].x;
|
||||
var sy = points[0].y;
|
||||
var itr = 0;
|
||||
|
||||
do {
|
||||
FABRIK_backward(points, lengths, dx, dy);
|
||||
FABRIK_forward(points, lengths, sx, sy);
|
||||
|
||||
var delta = 0;
|
||||
var _bn = array_create(array_length(points));
|
||||
for( var i = 0; i < array_length(points); i++ ) {
|
||||
_bn[i] = { x: points[i].x, y: points[i].y };
|
||||
delta += point_distance(_bo[i].x, _bo[i].y, _bn[i].x, _bn[i].y);
|
||||
}
|
||||
|
||||
_bo = _bn;
|
||||
if(++itr >= 32) break;
|
||||
} until(delta <= threshold);
|
||||
|
||||
for( var i = 0; i < array_length(points) - 1; i++ ) {
|
||||
var bone = bones[i];
|
||||
var p0 = points[i];
|
||||
var p1 = points[i + 1];
|
||||
|
||||
var dir = point_direction(p0.x, p0.y, p1.x, p1.y);
|
||||
bone.angle = dir;
|
||||
|
||||
FABRIK_result[i] = p0;
|
||||
}
|
||||
|
||||
FABRIK_result[i] = p1;
|
||||
}
|
||||
|
||||
static FABRIK_backward = function(points, lengths, dx, dy) {
|
||||
var tx = dx;
|
||||
var ty = dy;
|
||||
|
||||
for( var i = array_length(points) - 1; i > 0; i-- ) {
|
||||
var p1 = points[i];
|
||||
var p0 = points[i - 1];
|
||||
var len = lengths[i - 1];
|
||||
var dir = point_direction(p0.x, p0.y, tx, ty);
|
||||
|
||||
p1.x = tx;
|
||||
p1.y = ty;
|
||||
|
||||
p0.x = p1.x + lengthdir_x(len, dir);
|
||||
p0.y = p1.y + lengthdir_y(len, dir);
|
||||
|
||||
tx = p0.x;
|
||||
ty = p0.y;
|
||||
}
|
||||
}
|
||||
|
||||
static FABRIK_forward = function(points, lengths, sx, sy) {
|
||||
var tx = sx;
|
||||
var ty = sy;
|
||||
|
||||
for( var i = 0; i < array_length(points) - 1; i++ ) {
|
||||
var p0 = points[i];
|
||||
var p1 = points[i + 1];
|
||||
var len = lengths[i];
|
||||
var dir = point_direction(tx, ty, p1.x, p1.y);
|
||||
|
||||
p0.x = tx;
|
||||
p0.y = ty;
|
||||
|
||||
p1.x = p0.x + lengthdir_x(len, dir);
|
||||
p1.y = p0.y + lengthdir_y(len, dir);
|
||||
|
||||
tx = p1.x;
|
||||
ty = p1.y;
|
||||
}
|
||||
}
|
||||
|
||||
static serialize = function() {
|
||||
|
@ -213,6 +397,9 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
bone.is_main = is_main;
|
||||
bone.parent_anchor = parent_anchor;
|
||||
|
||||
bone.IKlength = IKlength;
|
||||
bone.IKTarget = IKTarget == noone? "" : IKTarget.id;
|
||||
|
||||
bone.childs = [];
|
||||
for( var i = 0; i < array_length(childs); i++ )
|
||||
bone.childs[i] = childs[i].serialize();
|
||||
|
@ -234,6 +421,9 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
self.attributes = attributes;
|
||||
self.node = node;
|
||||
|
||||
IKlength = bone.IKlength;
|
||||
IKTarget = bone.IKTarget;
|
||||
|
||||
childs = [];
|
||||
for( var i = 0; i < array_length(bone.childs); i++ ) {
|
||||
var _b = new __Bone().deserialize(bone.childs[i], attributes, node);
|
||||
|
@ -243,6 +433,16 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
return self;
|
||||
}
|
||||
|
||||
static connect = function() {
|
||||
if(parent == noone || IKTarget == "")
|
||||
IKTarget = noone;
|
||||
else if(is_string(IKTarget))
|
||||
IKTarget = parent.findBone(IKTarget);
|
||||
|
||||
for( var i = 0; i < array_length(childs); i++ )
|
||||
childs[i].connect();
|
||||
}
|
||||
|
||||
static clone = function(attributes) {
|
||||
var _b = new __Bone(parent, distance, direction, angle, length, attributes);
|
||||
_b.id = id;
|
||||
|
@ -250,10 +450,15 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
|
|||
_b.is_main = is_main;
|
||||
_b.parent_anchor = parent_anchor;
|
||||
_b.IKlength = IKlength;
|
||||
_b.IKTarget = IKTarget == noone? "" : IKTarget.id;
|
||||
|
||||
for( var i = 0; i < array_length(childs); i++ )
|
||||
_b.addChild(childs[i].clone(attributes));
|
||||
|
||||
return _b;
|
||||
}
|
||||
|
||||
static toString = function() {
|
||||
return $"Bone {name} [{id}]";
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
function draw_circle_border(xx, yy, r, w) {
|
||||
var step = 32;
|
||||
var angle_step = 360 / step;
|
||||
|
||||
var px, py, _px, _py;
|
||||
|
||||
for(var i = 0; i <= step; i++){
|
||||
var px = xx + lengthdir_x(r, i * angle_step);
|
||||
var py = yy + lengthdir_y(r, i * angle_step);
|
||||
|
||||
if(i)
|
||||
draw_line_round(_px, _py, px, py, w);
|
||||
|
||||
_px = px;
|
||||
_py = py;
|
||||
}
|
||||
}
|
||||
|
||||
function draw_ellipse_border(x0, y0, x1, y1, w) {
|
||||
var step = 32;
|
||||
var angle_step = 360 / step;
|
||||
|
||||
var px, py, _px, _py;
|
||||
var cx = (x0 + x1) / 2;
|
||||
var cy = (y0 + y1) / 2;
|
||||
|
||||
var ww = abs(x0 - x1) / 2;
|
||||
var hh = abs(y0 - y1) / 2;
|
||||
|
||||
for(var i = 0; i <= step; i++){
|
||||
var px = cx + lengthdir_x(ww, i * angle_step);
|
||||
var py = cy + lengthdir_y(hh, i * angle_step);
|
||||
|
||||
if(i)
|
||||
draw_line_round(_px, _py, px, py, w);
|
||||
|
||||
_px = px;
|
||||
_py = py;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "draw_circle_border",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
||||
"name": "draw",
|
||||
"path": "folders/functions/draw.yy",
|
||||
},
|
||||
}
|
|
@ -1,10 +1,56 @@
|
|||
function draw_circle_prec(x, y, r, border, precision = 32) {
|
||||
draw_set_circle_precision(precision);
|
||||
draw_circle(x, y, r, border);
|
||||
}
|
||||
|
||||
function draw_circle_border(xx, yy, r, w) {
|
||||
var step = 32;
|
||||
var angle_step = 360 / step;
|
||||
|
||||
var px, py, _px, _py;
|
||||
|
||||
for(var i = 0; i <= step; i++){
|
||||
var px = xx + lengthdir_x(r, i * angle_step);
|
||||
var py = yy + lengthdir_y(r, i * angle_step);
|
||||
|
||||
if(i)
|
||||
draw_line_round(_px, _py, px, py, w);
|
||||
|
||||
_px = px;
|
||||
_py = py;
|
||||
}
|
||||
}
|
||||
|
||||
function draw_ellipse_border(x0, y0, x1, y1, w) {
|
||||
var step = 32;
|
||||
var angle_step = 360 / step;
|
||||
|
||||
var px, py, _px, _py;
|
||||
var cx = (x0 + x1) / 2;
|
||||
var cy = (y0 + y1) / 2;
|
||||
|
||||
var ww = abs(x0 - x1) / 2;
|
||||
var hh = abs(y0 - y1) / 2;
|
||||
|
||||
for(var i = 0; i <= step; i++){
|
||||
var px = cx + lengthdir_x(ww, i * angle_step);
|
||||
var py = cy + lengthdir_y(hh, i * angle_step);
|
||||
|
||||
if(i)
|
||||
draw_line_round(_px, _py, px, py, w);
|
||||
|
||||
_px = px;
|
||||
_py = py;
|
||||
}
|
||||
}
|
||||
|
||||
function draw_circle_angle(_x, _y, _r, _angSt, _angEd, precision = 32) {
|
||||
var ox, oy, nx, ny, oa, na;
|
||||
|
||||
draw_primitive_begin(pr_trianglelist);
|
||||
|
||||
for( var i = 0; i <= precision; i++ ) {
|
||||
na = lerp(_angSt, _angEd, i / precision);
|
||||
na = lerp_float_angle(_angSt, _angEd, i / precision);
|
||||
nx = _x + lengthdir_x(_r, na);
|
||||
ny = _y + lengthdir_y(_r, na);
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "draw_circle_angle",
|
||||
"name": "draw_circle_functions",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
|
@ -1,4 +0,0 @@
|
|||
function draw_circle_prec(x, y, r, border, precision = 32) {
|
||||
draw_set_circle_precision(precision);
|
||||
draw_circle(x, y, r, border);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "draw_circle_prec",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
||||
"name": "draw",
|
||||
"path": "folders/functions/draw.yy",
|
||||
},
|
||||
}
|
|
@ -1,9 +1,15 @@
|
|||
function draw_line_round(x1, y1, x2, y2, w) {
|
||||
draw_line_width(x1, y1, x2, y2, w);
|
||||
|
||||
draw_set_circle_precision(8);
|
||||
draw_circle(x1, y1, w/2, false);
|
||||
draw_circle(x2, y2, w/2, false);
|
||||
//draw_set_circle_precision(8);
|
||||
//draw_circle(x1, y1, w/2, false);
|
||||
//draw_circle(x2, y2, w/2, false);
|
||||
|
||||
var dir = point_direction(x1, y1, x2, y2) + 90;
|
||||
draw_circle_angle(x1 + 1, y1 + 1, w / 2, dir, dir + 90);
|
||||
draw_circle_angle(x1 + 1, y1 + 1, w / 2, dir + 90, dir + 180);
|
||||
draw_circle_angle(x2 + 1, y2 + 1, w / 2, dir, dir - 90);
|
||||
draw_circle_angle(x2 + 1, y2 + 1, w / 2, dir - 90, dir - 180);
|
||||
}
|
||||
|
||||
function draw_line_round_color(x1, y1, x2, y2, w, c1, c2) {
|
||||
|
|
|
@ -14,7 +14,6 @@ function lerp_float(from, to, speed) {
|
|||
}
|
||||
|
||||
function lerp_linear(from, to, speed) {
|
||||
if(fps < 15) return to;
|
||||
if(abs(from - to) < speed)
|
||||
return to;
|
||||
else
|
||||
|
@ -31,8 +30,11 @@ function lerp_angle(from, to, speed) {
|
|||
}
|
||||
|
||||
function lerp_angle_linear(from, to, speed) {
|
||||
if(fps < 15) return to;
|
||||
if(abs(angle_difference(to, from)) < speed) return to;
|
||||
|
||||
return from + sign(angle_difference(to, from)) * speed;
|
||||
}
|
||||
|
||||
function lerp_float_angle(from, to, ratio) {
|
||||
return from + angle_difference(to, from) * ratio;
|
||||
}
|
|
@ -38,22 +38,20 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
|
||||
if(!bone.is_main) {
|
||||
if(bone.parent_anchor)
|
||||
draw_sprite_ui(THEME.bone, 1, __x + 12, ty + 12,,,, COLORS._main_icon);
|
||||
draw_sprite_ui(THEME.bone, 1, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
else if(bone.IKlength)
|
||||
draw_sprite_ui(THEME.bone, 2, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
else {
|
||||
if(_hover && point_in_circle(_m[0], _m[1], __x + 12, ty + 12, 12)) {
|
||||
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 12,,,, COLORS._main_icon_light);
|
||||
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 14,,,, COLORS._main_icon_light);
|
||||
if(mouse_press(mb_left, _focus))
|
||||
bone_dragging = bone;
|
||||
} else
|
||||
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 12,,,, COLORS._main_icon);
|
||||
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
}
|
||||
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text);
|
||||
draw_text(__x + 24, ty + 12, bone.name);
|
||||
|
||||
//if(bone_dragging != noone && point_in_rectangle(_m[0], _m[1], _x, ty, _x + _w, ty + _hh - 1)) {
|
||||
// draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, ty, _w, _hh, COLORS._main_accent, 1);
|
||||
// hovering = bone;
|
||||
//}
|
||||
bone.tb_name.setFocusHover(_focus, _hover);
|
||||
bone.tb_name.draw(__x + 24, ty + 3, __w - 24 - 32, _hh - 6, bone.name, _m);
|
||||
|
||||
ty += _hh;
|
||||
|
||||
|
@ -103,11 +101,10 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
})]);
|
||||
|
||||
tools = [
|
||||
new NodeTool( "Transform", THEME.bone_tool_transform ),
|
||||
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_detach ),
|
||||
new NodeTool( "IK", THEME.bone_tool_IK ),
|
||||
];
|
||||
|
||||
anchor_selecting = noone;
|
||||
|
@ -119,6 +116,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
builder_my = 0;
|
||||
|
||||
bone_dragging = noone;
|
||||
ik_dragging = noone;
|
||||
|
||||
moving = false;
|
||||
scaling = false;
|
||||
|
@ -129,124 +127,8 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
|
||||
var _b = attributes.bones;
|
||||
|
||||
if(isUsingTool(0)) { //transform
|
||||
attributes.bones.draw(false, _x, _y, _s, _mx, _my);
|
||||
|
||||
var _bst = ds_stack_create();
|
||||
ds_stack_push(_bst, _b);
|
||||
|
||||
var minx = 999999;
|
||||
var miny = 999999;
|
||||
var maxx = -999999;
|
||||
var maxy = -999999;
|
||||
|
||||
while(!ds_stack_empty(_bst)) {
|
||||
var __b = ds_stack_pop(_bst);
|
||||
|
||||
if(!__b.is_main) {
|
||||
var p0 = __b.getPoint(0);
|
||||
var p1 = __b.getPoint(1);
|
||||
|
||||
minx = min(minx, p0.x);
|
||||
miny = min(miny, p0.y);
|
||||
maxx = max(maxx, p0.x);
|
||||
maxy = max(maxy, p0.y);
|
||||
|
||||
minx = min(minx, p1.x);
|
||||
miny = min(miny, p1.y);
|
||||
maxx = max(maxx, p1.x);
|
||||
maxy = max(maxy, p1.y);
|
||||
}
|
||||
|
||||
for( var i = 0; i < array_length(__b.childs); i++ )
|
||||
ds_stack_push(_bst, __b.childs[i]);
|
||||
}
|
||||
|
||||
ds_stack_destroy(_bst);
|
||||
|
||||
|
||||
var hvSc = false;
|
||||
var hvMv = false;
|
||||
|
||||
if(moving) {
|
||||
var dx = mx - builder_mx;
|
||||
var dy = my - builder_my;
|
||||
|
||||
builder_mx = mx;
|
||||
builder_my = my;
|
||||
|
||||
for( var i = 0; i < array_length(_b.childs); i++ ) {
|
||||
var bone = _b.childs[i];
|
||||
|
||||
var _bx = lengthdir_x(bone.distance, bone.direction) + dx;
|
||||
var _by = lengthdir_y(bone.distance, bone.direction) + dy;
|
||||
|
||||
bone.distance = point_distance(0, 0, _bx, _by);
|
||||
bone.direction = point_direction(0, 0, _bx, _by);
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left))
|
||||
moving = false;
|
||||
} else if(scaling) {
|
||||
var dir = point_direction(minx, miny, maxx, maxy);
|
||||
var ss = 1 + dot_product(lengthdir_x(1, dir), lengthdir_y(1, dir), mx - builder_mx, my - builder_my);
|
||||
|
||||
var _bst = ds_stack_create();
|
||||
ds_stack_push(_bst, _b);
|
||||
|
||||
while(!ds_stack_empty(_bst)) {
|
||||
var __b = ds_stack_pop(_bst);
|
||||
|
||||
if(!__b.is_main) {
|
||||
__b.distance = __b.freeze_data.distance * ss;
|
||||
__b.length = __b.freeze_data.length * ss;
|
||||
}
|
||||
|
||||
for( var i = 0; i < array_length(__b.childs); i++ )
|
||||
ds_stack_push(_bst, __b.childs[i]);
|
||||
}
|
||||
|
||||
ds_stack_destroy(_bst);
|
||||
|
||||
if(mouse_release(mb_left))
|
||||
scaling = false;
|
||||
} else {
|
||||
if(point_in_circle(_mx, _my, maxx, maxy, 16)) {
|
||||
hvSc = true;
|
||||
|
||||
if(mouse_press(mb_left)) {
|
||||
attributes.bones.freeze();
|
||||
|
||||
builder_mx = mx;
|
||||
builder_my = my;
|
||||
scaling = true;
|
||||
}
|
||||
} else if(point_in_circle(_mx, _my, maxx, maxy, 16)) {
|
||||
hvMv = true;
|
||||
|
||||
if(mouse_press(mb_left)) {
|
||||
builder_mx = mx;
|
||||
builder_my = my;
|
||||
moving = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_sprite_colored(THEME.anchor_scale, hvSc, maxx, maxy);
|
||||
|
||||
draw_set_color(COLORS._main_accent);
|
||||
draw_rectangle_border(minx, miny, maxx, maxy, hvMv);
|
||||
|
||||
triggerRender();
|
||||
return;
|
||||
}
|
||||
|
||||
anchor_selecting = attributes.bones.draw(active, _x, _y, _s, _mx, _my, true, anchor_selecting);
|
||||
//if(is_array(anchor_selecting)) print(anchor_selecting[1])
|
||||
|
||||
if(builder_bone != noone) {
|
||||
//draw_set_color(COLORS._main_accent);
|
||||
//draw_circle(_x + builder_sx * _s, _y + builder_sy * _s, 8, false);
|
||||
anchor_selecting = _b.draw(false, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
var dir = point_direction(builder_sx, builder_sy, mx, my);
|
||||
var dis = point_distance(builder_sx, builder_sy, mx, my);
|
||||
|
@ -298,7 +180,8 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
par_anc.x = _x + par_anc.x * _s;
|
||||
par_anc.y = _y + par_anc.y * _s;
|
||||
|
||||
if(!builder_bone.parent.is_main && point_in_circle(_mx, _my, par_anc.x, par_anc.y, 16) && mouse_release(mb_left))
|
||||
var inRange = point_in_circle(_mx, _my, par_anc.x, par_anc.y, 16) && mouse_release(mb_left);
|
||||
if(!builder_bone.parent.is_main && builder_bone.IKlength > 0 && inRange)
|
||||
builder_bone.parent_anchor = true;
|
||||
}
|
||||
} else if(builder_type == 1) {
|
||||
|
@ -313,9 +196,52 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
}
|
||||
|
||||
triggerRender();
|
||||
} else if(ik_dragging != noone) {
|
||||
anchor_selecting = _b.draw(active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting, ik_dragging);
|
||||
|
||||
if(anchor_selecting != noone && anchor_selecting[1] == 2) {
|
||||
var anc = anchor_selecting[0];
|
||||
|
||||
var reachable = false;
|
||||
var _bone = ik_dragging.parent;
|
||||
var len = 1;
|
||||
|
||||
while(_bone != noone) {
|
||||
if(_bone == anc) {
|
||||
reachable = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(isUsingTool(1)) { // builder
|
||||
len++;
|
||||
_bone = _bone.parent;
|
||||
}
|
||||
|
||||
if(reachable && mouse_release(mb_left)) {
|
||||
var p1 = ik_dragging.getPoint(1);
|
||||
var p0 = anc.getPoint(0);
|
||||
|
||||
var _len = point_distance(p0.x, p0.y, p1.x, p1.y);
|
||||
var _ang = point_direction(p0.x, p0.y, p1.x, p1.y);
|
||||
|
||||
var IKbone = new __Bone(anc, _len, _ang, ik_dragging.angle + 90, 0, attributes, self);
|
||||
anc.addChild(IKbone);
|
||||
IKbone.IKlength = len;
|
||||
IKbone.IKTarget = ik_dragging;
|
||||
|
||||
IKbone.name = "IK handle";
|
||||
IKbone.parent_anchor = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left)) {
|
||||
ik_dragging = noone;
|
||||
UNDO_HOLDING = false;
|
||||
}
|
||||
|
||||
triggerRender();
|
||||
} else if(isUsingTool(0)) { // builder
|
||||
anchor_selecting = _b.draw(active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
if(mouse_press(mb_left, active)) {
|
||||
if(anchor_selecting == noone) {
|
||||
builder_bone = createBone(attributes.bones, point_distance(0, 0, mx, my), point_direction(0, 0, mx, my));
|
||||
|
@ -351,12 +277,13 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
draw_sprite_ext(THEME.bone_tool_add, 1, _mx + 24, _my + 24, 1, 1, 0, c_white, 1);
|
||||
} else if(anchor_selecting[1] == 2)
|
||||
draw_sprite_ext(THEME.bone_tool_add, 0, _mx + 24, _my + 24, 1, 1, 0, c_white, 1);
|
||||
} else if(isUsingTool(2)) { //remover
|
||||
if(anchor_selecting != noone && anchor_selecting[0].parent != noone && mouse_press(mb_left, active)) {
|
||||
} else if(isUsingTool(1)) { //remover
|
||||
anchor_selecting = _b.draw(active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
if(anchor_selecting != noone && anchor_selecting[1] == 2 && anchor_selecting[0].parent != noone && mouse_press(mb_left, active)) {
|
||||
var _bone = anchor_selecting[0];
|
||||
var _par = _bone.parent;
|
||||
|
||||
if(anchor_selecting[1] == 2) {
|
||||
array_remove(_par.childs, _bone);
|
||||
|
||||
for( var i = 0; i < array_length(_bone.childs); i++ ) {
|
||||
|
@ -368,11 +295,12 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
|
||||
triggerRender();
|
||||
}
|
||||
}
|
||||
|
||||
if(anchor_selecting != noone)
|
||||
draw_sprite_ext(THEME.bone_tool_remove, 1, _mx + 24, _my + 24, 1, 1, 0, c_white, 1);
|
||||
} else if(isUsingTool(3)) { //detach
|
||||
} else if(isUsingTool(2)) { //detach
|
||||
anchor_selecting = _b.draw(active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
if(anchor_selecting != noone && anchor_selecting[1] == 2 && mouse_press(mb_left, active)) {
|
||||
builder_bone = anchor_selecting[0];
|
||||
builder_type = anchor_selecting[1];
|
||||
|
@ -390,9 +318,15 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
builder_my = my;
|
||||
UNDO_HOLDING = true;
|
||||
}
|
||||
} else if(isUsingTool(4)) { //IK
|
||||
} else if(isUsingTool(3)) { //IK
|
||||
anchor_selecting = _b.draw(active * 0b100, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
if(anchor_selecting != noone && anchor_selecting[1] == 2 && mouse_press(mb_left, active)) {
|
||||
ik_dragging = anchor_selecting[0];
|
||||
}
|
||||
} else { //mover
|
||||
anchor_selecting = _b.draw(active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
} else if(isNotUsingTool()) { //mover
|
||||
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
|
||||
builder_bone = anchor_selecting[0];
|
||||
builder_type = anchor_selecting[1];
|
||||
|
@ -441,6 +375,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
|
|||
if(!struct_has(load_map, "bones")) return;
|
||||
attributes.bones = new __Bone(,,,,, attributes, self);
|
||||
attributes.bones.deserialize(load_map.bones, attributes, self);
|
||||
attributes.bones.connect();
|
||||
}
|
||||
|
||||
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {
|
||||
|
|
|
@ -91,7 +91,13 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
|
|||
var __w = _st[2];
|
||||
|
||||
if(!bone.is_main) {
|
||||
draw_sprite_ui(THEME.bone, bone.parent_anchor, __x + 12, ty + 12,,,, COLORS._main_icon);
|
||||
if(bone.parent_anchor)
|
||||
draw_sprite_ui(THEME.bone, 1, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
else if(bone.IKlength)
|
||||
draw_sprite_ui(THEME.bone, 2, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
else
|
||||
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 14,,,, COLORS._main_icon);
|
||||
|
||||
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text);
|
||||
draw_text(__x + 24, ty + 12, bone.name);
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
posing_type = 0;
|
||||
posing_sx = 0;
|
||||
posing_sy = 0;
|
||||
posing_sz = 0;
|
||||
posing_mx = 0;
|
||||
posing_my = 0;
|
||||
|
||||
|
@ -111,15 +112,17 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
var _b = outputs[| 0].getValue();
|
||||
if(_b == noone) return;
|
||||
|
||||
anchor_selecting = _b.draw(active, _x, _y, _s, _mx, _my, true, anchor_selecting);
|
||||
anchor_selecting = _b.draw(active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
|
||||
|
||||
var mx = (_mx - _x) / _s;
|
||||
var my = (_my - _y) / _s;
|
||||
|
||||
if(posing_bone) {
|
||||
if(posing_type == 0) { //move
|
||||
var bx = posing_sx + (mx - posing_mx);
|
||||
var by = posing_sy + (my - posing_my);
|
||||
var ang = posing_bone.pose_angle;
|
||||
var pp = point_rotate(mx - posing_mx, my - posing_my, 0, 0, -ang);
|
||||
var bx = posing_sx + pp[0];
|
||||
var by = posing_sy + pp[1];
|
||||
|
||||
var val = posing_input.getValue();
|
||||
val[TRANSFORM.pos_x] = bx;
|
||||
|
@ -129,11 +132,15 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
|
||||
} else if(posing_type == 1) { //scale
|
||||
var ss = point_distance(posing_mx, posing_my, mx, my) / posing_sx;
|
||||
var rot = point_direction(posing_mx, posing_my, mx, my) - posing_sy;
|
||||
var ori = posing_bone.getPoint(0);
|
||||
var ang = point_direction(ori.x, ori.y, mx, my);
|
||||
var rot = angle_difference(ang, posing_sz);
|
||||
posing_sz = ang;
|
||||
posing_sy += rot;
|
||||
|
||||
var val = posing_input.getValue();
|
||||
val[TRANSFORM.sca_x] = ss;
|
||||
val[TRANSFORM.rot] = rot;
|
||||
val[TRANSFORM.rot] = posing_sy;
|
||||
if(posing_input.setValue(val))
|
||||
UNDO_HOLDING = true;
|
||||
|
||||
|
@ -159,7 +166,7 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
}
|
||||
|
||||
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
|
||||
if(anchor_selecting[1] == 0) { // move
|
||||
if(anchor_selecting[1] == 0 || anchor_selecting[0].IKlength) { // move
|
||||
posing_bone = anchor_selecting[0];
|
||||
if(!ds_map_exists(boneMap, posing_bone.id))
|
||||
setBone();
|
||||
|
@ -180,9 +187,11 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
posing_input = boneMap[? posing_bone.id];
|
||||
posing_type = 1;
|
||||
|
||||
var ori = posing_bone.getPoint(0);
|
||||
var val = posing_input.getValue();
|
||||
posing_sx = posing_bone.length / posing_bone.pose_scale;
|
||||
posing_sy = posing_bone.angle - posing_bone.pose_angle;
|
||||
posing_sx = posing_bone.length / posing_bone.pose_local_scale;
|
||||
posing_sy = val[TRANSFORM.rot];
|
||||
posing_sz = point_direction(ori.x, ori.y, mx, my);
|
||||
|
||||
var pnt = posing_bone.getPoint(0);
|
||||
posing_mx = pnt.x;
|
||||
|
@ -226,6 +235,8 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
if(_b == noone) return;
|
||||
|
||||
var _bone_pose = _b.clone(attributes);
|
||||
_bone_pose.connect();
|
||||
|
||||
_bone_pose.resetPose();
|
||||
var _bst = ds_stack_create();
|
||||
ds_stack_push(_bst, _bone_pose);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
global.EQUATION_PRES = ds_map_create();
|
||||
global.EQUATION_PRES[? "+"] = 1;
|
||||
global.EQUATION_PRES[? "-"] = 1;
|
||||
global.EQUATION_PRES[? "_"] = 9; //unary negative
|
||||
global.EQUATION_PRES[? "∸"] = 9; //unary negative
|
||||
global.EQUATION_PRES[? "*"] = 2;
|
||||
global.EQUATION_PRES[? "/"] = 2;
|
||||
global.EQUATION_PRES[? "$"] = 3;
|
||||
|
@ -162,7 +162,7 @@ function functionStringClean(fx) {
|
|||
return v1 + v2;
|
||||
return 0;
|
||||
case "-": return (is_real(v1) && is_real(v2))? v1 - v2 : 0;
|
||||
case "_": return is_real(v1)? -v1 : 0;
|
||||
case "∸": return is_real(v1)? -v1 : 0;
|
||||
case "*": return (is_real(v1) && is_real(v2))? v1 * v2 : 0;
|
||||
case "$": return (is_real(v1) && is_real(v2))? power(v1, v2) : 0;
|
||||
case "/": return (is_real(v1) && is_real(v2))? v1 / v2 : 0;
|
||||
|
@ -226,7 +226,7 @@ function functionStringClean(fx) {
|
|||
else {
|
||||
if(pres[? ch] > pres[? ds_stack_top(op)] || ds_stack_top(op) == "(") ds_stack_push(op, ch);
|
||||
else {
|
||||
if(ch == "-" && ds_map_exists(pres, _ch)) ch = "_"; //unary negative
|
||||
if(ch == "-" && ds_map_exists(pres, _ch)) ch = "∸"; //unary negative
|
||||
|
||||
while(pres[? ch] <= pres[? ds_stack_top(op)] && !ds_stack_empty(op))
|
||||
ds_stack_push(vl, buildFuncTree(ds_stack_pop(op), vl));
|
||||
|
@ -308,7 +308,7 @@ function functionStringClean(fx) {
|
|||
if(ds_stack_empty(vl)) return noone;
|
||||
|
||||
switch(operator) {
|
||||
case "-": //deal with preceeding megative number -5
|
||||
case "-": //deal with preceeding negative number -5
|
||||
if(ds_stack_size(vl) >= 2) {
|
||||
var _v1 = ds_stack_pop(vl);
|
||||
var _v2 = ds_stack_pop(vl);
|
||||
|
|
Loading…
Reference in a new issue