Pixel-Composer/scripts/node_armature_pose/node_armature_pose.gml

294 lines
7.4 KiB
Plaintext
Raw Normal View History

function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Armature Pose";
2023-06-25 20:12:17 +02:00
w = 96;
h = 72;
min_h = h;
2023-06-23 15:39:24 +02:00
inputs[| 0] = nodeValue("Armature", self, JUNCTION_CONNECT.input, VALUE_TYPE.armature, noone)
.setVisible(true, true);
2023-06-21 20:36:53 +02:00
input_display_list = [ 0,
["Bones", false]
]
input_fix_len = ds_list_size(inputs);
data_length = 1;
outputs[| 0] = nodeValue("Armature", self, JUNCTION_CONNECT.output, VALUE_TYPE.armature, noone);
2023-06-21 20:36:53 +02:00
boneMap = ds_map_create();
attributes.display_name = true;
array_push(attributeEditors, ["Display name", "display_name",
new checkBox(function() {
attributes.display_name = !attributes.display_name;
})]);
function createNewControl(bone = noone) {
var index = ds_list_size(inputs);
inputs[| index] = nodeValue(bone != noone? bone.name : "bone", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0, 1 ] )
.setDisplay(VALUE_DISPLAY.transform);
inputs[| index].extra_data[0] = bone != noone? bone.id : noone;
if(bone != noone)
boneMap[? bone.id] = inputs[| index];
array_push(input_display_list, index);
2023-06-23 15:39:24 +02:00
return inputs[| index];
2023-06-21 20:36:53 +02:00
}
2023-06-23 15:39:24 +02:00
static setBone = function() { #region
//print("Setting dem bones...");
2023-06-21 20:36:53 +02:00
var _b = inputs[| 0].getValue();
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; i < array_length(__b.childs); i++ ) {
array_push(_bones, __b.childs[i]);
ds_stack_push(_bst, __b.childs[i]);
}
}
ds_stack_destroy(_bst);
2023-06-23 15:39:24 +02:00
//print($"Bone counts: {array_length(_bones)}");
2023-06-21 20:36:53 +02:00
var _inputs = ds_list_create();
_inputs[| 0] = inputs[| 0];
var _input_display_list = [
input_display_list[0],
input_display_list[1]
];
for( var i = 0; i < array_length(_bones); i++ ) {
var bone = _bones[i];
2023-06-23 15:39:24 +02:00
var _idx = ds_list_size(_inputs);
array_push(_input_display_list, _idx);
//print($" > Adding bone id: {bone.id}");
2023-06-21 20:36:53 +02:00
if(ds_map_exists(boneMap, bone.id)) {
var _inp = boneMap[? bone.id];
_inp.index = _idx;
ds_list_add(_inputs, _inp);
2023-06-23 15:39:24 +02:00
} else {
var _inp = createNewControl(bone);
ds_list_add(_inputs, _inp);
}
2023-06-21 20:36:53 +02:00
}
ds_list_destroy(inputs);
inputs = _inputs;
input_display_list = _input_display_list;
2023-06-23 15:39:24 +02:00
//print(_input_display_list);
#endregion
2023-06-21 20:36:53 +02:00
}
tools = [
];
2023-06-21 20:36:53 +02:00
anchor_selecting = noone;
posing_bone = noone;
posing_input = 0;
posing_type = 0;
posing_sx = 0;
posing_sy = 0;
2023-06-26 18:55:41 +02:00
posing_sz = 0;
2023-06-21 20:36:53 +02:00
posing_mx = 0;
posing_my = 0;
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {
2023-06-21 20:36:53 +02:00
var _b = outputs[| 0].getValue();
if(_b == noone) return;
2023-06-26 18:55:41 +02:00
anchor_selecting = _b.draw(active * 0b111, _x, _y, _s, _mx, _my, anchor_selecting);
2023-06-21 20:36:53 +02:00
var mx = (_mx - _x) / _s;
var my = (_my - _y) / _s;
if(posing_bone) {
2023-06-23 15:39:24 +02:00
if(posing_type == 0) { //move
2023-06-26 18:55:41 +02:00
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];
2023-06-21 20:36:53 +02:00
var val = posing_input.getValue();
val[TRANSFORM.pos_x] = bx;
val[TRANSFORM.pos_y] = by;
if(posing_input.setValue(val))
UNDO_HOLDING = true;
2023-06-23 15:39:24 +02:00
} else if(posing_type == 1) { //scale
var ss = point_distance(posing_mx, posing_my, mx, my) / posing_sx;
2023-06-26 18:55:41 +02:00
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;
2023-06-21 20:36:53 +02:00
var val = posing_input.getValue();
val[TRANSFORM.sca_x] = ss;
2023-06-26 18:55:41 +02:00
val[TRANSFORM.rot] = posing_sy;
2023-06-21 20:36:53 +02:00
if(posing_input.setValue(val))
UNDO_HOLDING = true;
2023-06-23 15:39:24 +02:00
} else if(posing_type == 2) { //rotate
2023-06-25 20:12:17 +02:00
var ori = posing_bone.getPoint(0);
2023-06-23 15:39:24 +02:00
var ang = point_direction(ori.x, ori.y, mx, my);
var rot = angle_difference(ang, posing_sy);
posing_sy = ang;
posing_sx += rot;
2023-06-21 20:36:53 +02:00
var val = posing_input.getValue();
2023-06-23 15:39:24 +02:00
val[TRANSFORM.rot] = posing_sx;
2023-06-21 20:36:53 +02:00
if(posing_input.setValue(val))
UNDO_HOLDING = true;
}
if(mouse_release(mb_left)) {
posing_bone = noone;
2023-06-23 15:39:24 +02:00
posing_type = noone;
2023-06-21 20:36:53 +02:00
UNDO_HOLDING = false;
}
}
2023-06-23 15:39:24 +02:00
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
2023-06-26 18:55:41 +02:00
if(anchor_selecting[1] == 0 || anchor_selecting[0].IKlength) { // move
2023-06-21 20:36:53 +02:00
posing_bone = anchor_selecting[0];
if(!ds_map_exists(boneMap, posing_bone.id))
setBone();
posing_input = boneMap[? posing_bone.id];
posing_type = 0;
var val = posing_input.getValue();
posing_sx = val[TRANSFORM.pos_x];
posing_sy = val[TRANSFORM.pos_y];
posing_mx = mx;
posing_my = my;
} else if(anchor_selecting[1] == 1) { // scale
posing_bone = anchor_selecting[0];
if(!ds_map_exists(boneMap, posing_bone.id))
setBone();
posing_input = boneMap[? posing_bone.id];
posing_type = 1;
2023-06-26 18:55:41 +02:00
var ori = posing_bone.getPoint(0);
2023-06-21 20:36:53 +02:00
var val = posing_input.getValue();
2023-06-26 18:55:41 +02:00
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);
2023-06-21 20:36:53 +02:00
2023-06-25 20:12:17 +02:00
var pnt = posing_bone.getPoint(0);
2023-06-23 15:39:24 +02:00
posing_mx = pnt.x;
posing_my = pnt.y;
2023-06-21 20:36:53 +02:00
} else if(anchor_selecting[1] == 2) { // rotate
posing_bone = anchor_selecting[0];
if(!ds_map_exists(boneMap, posing_bone.id))
setBone();
posing_input = boneMap[? posing_bone.id];
posing_type = 2;
2023-06-25 20:12:17 +02:00
var ori = posing_bone.getPoint(0);
2023-06-21 20:36:53 +02:00
var val = posing_input.getValue();
2023-06-23 15:39:24 +02:00
posing_sx = val[TRANSFORM.rot];
posing_sy = point_direction(ori.x, ori.y, mx, my);
2023-06-21 20:36:53 +02:00
posing_mx = mx;
posing_my = my;
}
}
}
2023-06-23 15:39:24 +02:00
bone_prev = noone;
2023-06-21 20:36:53 +02:00
static step = function() {
var _b = inputs[| 0].getValue();
if(_b == noone) return;
2023-06-23 15:39:24 +02:00
if(bone_prev != _b) {
setBone();
bone_prev = _b;
return;
}
2023-06-21 20:36:53 +02:00
var _boneCount = ds_list_size(inputs) - input_fix_len;
if(_boneCount != _b.childCount()) setBone();
}
static update = function(frame = ANIMATOR.current_frame) {
2023-06-21 20:36:53 +02:00
var _b = inputs[| 0].getValue();
if(_b == noone) return;
2023-06-23 15:39:24 +02:00
var _bone_pose = _b.clone(attributes);
2023-06-26 18:55:41 +02:00
_bone_pose.connect();
2023-06-23 15:39:24 +02:00
_bone_pose.resetPose();
2023-06-21 20:36:53 +02:00
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(ds_map_exists(boneMap, _id)) {
var _inp = boneMap[? _id];
_inp.name = bone.name;
_inp.updateName();
var _trn = _inp.getValue();
2023-06-23 15:39:24 +02:00
bone.pose_posit = [ _trn[TRANSFORM.pos_x], _trn[TRANSFORM.pos_y] ];
bone.pose_angle = _trn[TRANSFORM.rot];
bone.pose_scale = _trn[TRANSFORM.sca_x];
2023-06-21 20:36:53 +02:00
}
2023-06-23 15:39:24 +02:00
for( var i = 0; i < array_length(bone.childs); i++ )
2023-06-21 20:36:53 +02:00
ds_stack_push(_bst, bone.childs[i]);
}
2023-06-21 20:36:53 +02:00
ds_stack_destroy(_bst);
2023-06-23 15:39:24 +02:00
_bone_pose.setPose();
2023-06-21 20:36:53 +02:00
outputs[| 0].setValue(_bone_pose);
}
static postDeserialize = function() {
var _inputs = load_map.inputs;
2023-06-21 20:36:53 +02:00
for( var i = input_fix_len; i < array_length(_inputs); i += data_length )
createNewControl();
}
static doApplyDeserialize = function() {
for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) {
var inp = inputs[| i];
var idx = array_safe_get(inp.extra_data, 0);
boneMap[? idx] = inp;
}
2023-06-25 20:12:17 +02:00
setBone();
}
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) {
var bbox = drawGetBbox(xx, yy, _s);
draw_sprite_fit(s_node_armature_pose, 0, bbox.xc, bbox.yc, bbox.w, bbox.h);
}
}