Armature pose, bind

This commit is contained in:
Tanasart 2023-06-23 15:39:24 +02:00
parent 1a81c476d9
commit 1a8082e2b6
20 changed files with 655 additions and 463 deletions

View file

@ -391,7 +391,7 @@
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_prop_on_end.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/inspector",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_prop_selecting.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/inspector",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_rotator_bg.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/inspector",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_rotator_knob_strip2.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/inspector",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_rotator_knob.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/inspector",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"graphic.ai","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/meta",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"icon_bg.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/meta",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_icon_24.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/meta",},
@ -456,6 +456,10 @@
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_3d_tool_rotate.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_3d_tool_scale.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
{"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_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",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_canvas_tools_bucket.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_canvas_tools_ellip_fill.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/tool",},

Binary file not shown.

View file

@ -6,6 +6,10 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
self.angle = angle;
self.length = length;
pose_angle = 0;
pose_scale = 1;
pose_posit = [ 0, 0 ];
self.is_main = false;
self.parent_anchor = true;
self.childs = [];
@ -17,6 +21,8 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
self.attributes = attributes;
updated = false;
freeze_data = {};
self.parent = parent;
if(parent != noone) {
distance = parent.length;
@ -36,6 +42,18 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
return amo;
}
static freeze = function() {
freeze_data = {
angle: angle,
length: length,
distance: distance,
direction: direction
}
for( var i = 0; i < array_length(childs); i++ )
childs[i].freeze();
}
static getPoint = function(distance, direction) {
if(parent == noone)
return new Point(lengthdir_x(self.distance, self.direction), lengthdir_y(self.distance, self.direction))
@ -76,8 +94,13 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
draw_set_alpha(1.00);
if(attributes.display_name) {
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_accent);
draw_text((p0.x + p1.x) / 2 + 4, (p0.y + p1.y) / 2, name);
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((p0.x + p1.x) / 2, (p0.y + p1.y) / 2 - 4, name);
} else {
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_accent);
draw_text((p0.x + p1.x) / 2 + 4, (p0.y + p1.y) / 2, name);
}
}
if(edit && distance_to_line(_mx, _my, p0.x, p0.y, p1.x, p1.y) <= 12) //drag bone
@ -121,13 +144,46 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
draw_set_color(COLORS.node_composite_separator);
draw_line(_x + 16, _y, _x + _w - 16, _y);
for( var i = 0; i < array_length(childs); i++ ) {
for( var i = 0; i < array_length(childs); i++ )
_y = childs[i].drawInspector(_x + ui(16), _y, _w - ui(16), _m, _hover, _focus);
}
return _y;
}
static resetPose = function() {
pose_angle = 0;
pose_scale = 1;
pose_posit = [ 0, 0 ];
for( var i = 0; i < array_length(childs); i++ )
childs[i].resetPose();
}
static setPose = function(_position = [ 0, 0 ], _angle = 0, _scale = 1) {
if(is_main) {
for( var i = 0; i < array_length(childs); i++ )
childs[i].setPose(_position, _angle, _scale);
return;
}
pose_posit[0] += _position[0];
pose_posit[1] += _position[1];
pose_angle += _angle;
//pose_scale = _scale;
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);
angle += pose_angle;
length *= pose_scale;
for( var i = 0; i < array_length(childs); i++ )
childs[i].setPose(_position, _angle, _scale);
}
static serialize = function() {
var bone = {};
@ -137,7 +193,7 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
bone.direction = direction;
bone.angle = angle;
bone.length = length;
bone.is_main = is_main;
bone.parent_anchor = parent_anchor;
@ -172,6 +228,8 @@ function __Bone(parent = noone, distance = 0, direction = 0, angle = 0, length =
static clone = function(attributes) {
var _b = new __Bone(parent, distance, direction, angle, length, attributes);
_b.id = id;
_b.name = name;
_b.is_main = is_main;
_b.parent_anchor = parent_anchor;

View file

@ -19,5 +19,39 @@ function draw_circle_angle(_x, _y, _r, _angSt, _angEd, precision = 32) {
oy = ny;
}
draw_primitive_end();
}
function draw_arc_th(_x, _y, _r, _th, _angSt, _angEd) {
draw_primitive_begin(pr_trianglelist);
var oxI, oyI, oxO, oyO;
_angSt = _angSt % 360;
_angEd = _angEd % 360;
var diff = _angEd >= _angSt? _angEd - _angSt : _angEd + 360 - _angSt;
for(var i = 0; i <= abs(diff); i += 4) {
var as = _angSt + i * sign(diff);
var nxI = _x + lengthdir_x(_r - _th / 2, as);
var nyI = _y + lengthdir_y(_r - _th / 2, as);
var nxO = _x + lengthdir_x(_r + _th / 2, as);
var nyO = _y + lengthdir_y(_r + _th / 2, as);
if(i) {
draw_vertex(oxI, oyI);
draw_vertex(oxO, oyO);
draw_vertex(nxI, nyI);
draw_vertex(oxO, oyO);
draw_vertex(nxI, nyI);
draw_vertex(nxO, nyO);
}
oxI = nxI;
oyI = nyI;
oxO = nxO;
oyO = nyO;
}
draw_primitive_end();
}

View file

@ -252,7 +252,7 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc
case VALUE_DISPLAY.rotation :
case VALUE_DISPLAY.rotation_range :
jun.editWidget.draw(xc, _hsy, jun.showValue(), _m);
widH = ui(96);
widH = jun.editWidget.h;
break;
case VALUE_DISPLAY.slider :
case VALUE_DISPLAY.slider_range :

View file

@ -7,13 +7,14 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
var _b = attributes.bones;
var amo = _b.childCount();
var _h = ui(32 + 16) + amo * ui(28);
var __y = _y;
draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text);
draw_text_add(_x + ui(16), _y + ui(4), "Bones");
_y += ui(32);
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, _y, _w, _h, COLORS.node_composite_bg_blend, 1);
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, _y, _w, _h - ui(32), COLORS.node_composite_bg_blend, 1);
draw_set_color(COLORS.node_composite_separator);
draw_line(_x + 16, _y + ui(8), _x + _w - 16, _y + ui(8));
@ -56,9 +57,10 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
})]);
tools = [
new NodeTool( "Add bones", THEME.path_tools_transform ),
new NodeTool( "Remove bones", THEME.path_tools_transform ),
new NodeTool( "Detach bones", THEME.path_tools_transform ),
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 ),
];
anchor_selecting = noone;
@ -69,13 +71,128 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
builder_mx = 0;
builder_my = 0;
moving = false;
scaling = false;
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {
anchor_selecting = attributes.bones.draw(active, _x, _y, _s, _mx, _my, true, anchor_selecting);
//if(is_array(anchor_selecting)) print(anchor_selecting[1])
var mx = (_mx - _x) / _s;
var my = (_my - _y) / _s;
var _b = attributes.bones;
if(isUsingTool(0)) { //transform
attributes.bones.draw(active, _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, 0);
var p1 = __b.getPoint(__b.length, __b.angle);
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 _x = lengthdir_x(bone.distance, bone.direction) + dx;
var _y = lengthdir_y(bone.distance, bone.direction) + dy;
bone.distance = point_distance(0, 0, _x, _y);
bone.direction = point_direction(0, 0, _x, _y);
}
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);
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);
@ -136,7 +253,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
}
}
if(isUsingTool(0)) { // builder
if(isUsingTool(1)) { // builder
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));
@ -165,7 +282,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
UNDO_HOLDING = true;
}
}
} else if(isUsingTool(1)) { //remover
} else if(isUsingTool(2)) { //remover
if(anchor_selecting != noone && anchor_selecting[0].parent != noone && mouse_press(mb_left, active)) {
var _bone = anchor_selecting[0];
var _par = _bone.parent;
@ -197,7 +314,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
builder_my = my;
UNDO_HOLDING = true;
}
} else { //mover
} else if(isUsingTool(3) || isNotUsingTool()) { //mover
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
builder_bone = anchor_selecting[0];
builder_type = anchor_selecting[1];
@ -228,12 +345,7 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
}
static step = function() {
if(bone_update) {
attributes.bone.updated = true;
bone_update = false;
} else {
attributes.bone.updated = false;
}
}
static update = function(frame = ANIMATOR.current_frame) {
@ -241,12 +353,13 @@ function Node_Armature(_x, _y, _group = noone) : Node(_x, _y, _group) constructo
}
static doSerialize = function(_map) {
_map.bone = attributes.bones.serialize();
_map.bones = attributes.bones.serialize();
}
static postDeserialize = function() {
if(!struct_has(load_map, "bone")) return;
attributes.bones.deserialize(load_map.bone, attributes);
if(!struct_has(load_map, "bones")) return;
attributes.bones = new __Bone(,,,,, attributes);
attributes.bones.deserialize(load_map.bones, attributes);
}
}

View file

@ -1,62 +1,181 @@
function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
name = "Armature Bind";
name = "Armature Bind";
inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, def_surf_size2)
.setDisplay(VALUE_DISPLAY.vector);
inputs[| 1] = nodeValue("Armature", self, JUNCTION_CONNECT.input, VALUE_TYPE.armature, noone)
.setVisible(true, true)
.rejectArray();
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, [])
.rejectArrayProcess();
attribute_surface_depth();
attribute_interpolation();
input_fix_len = ds_list_size(inputs);
data_length = 4;
data_length = 2;
attributes.layer_visible = [];
attributes.layer_selectable = [];
attributes.display_bone = 0;
array_push(attributeEditors, ["Display bone", "display_bone",
new scrollBox(["Above", "Below", "Hide"], function(ind) {
attributes.display_bone = ind;
})]);
boneMap = ds_map_create();
surfMap = ds_map_create();
hold_visibility = true;
hold_select = true;
layer_dragging = noone;
layer_remove = -1;
layer_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) {
hold_select = true;
layer_dragging = noone;
layer_remove = -1;
layer_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region
ds_map_clear(surfMap);
for(var i = input_fix_len; i < ds_list_size(inputs) - data_length; i += data_length) {
var _surf = current_data[i];
var _id = inputs[| i].extra_data[0];
if(_id == "") continue;
if(ds_map_exists(surfMap, _id))
array_push(surfMap[? _id], _surf);
else
surfMap[? _id] = [ _surf ];
print($"Add {_surf} to {_id}");
}
#region draw bones
var _b = inputs[| 1].getValue();
var amo = _b.childCount();
var _hh = ui(28);
var bh = ui(32 + 16) + amo * _hh;
var ty = _y;
draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text);
draw_text_add(_x + ui(16), ty + ui(4), "Bones");
ty += ui(32);
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, ty, _w, bh - ui(32), COLORS.node_composite_bg_blend, 1);
draw_set_color(COLORS.node_composite_separator);
draw_line(_x + 16, ty + ui(8), _x + _w - 16, ty + ui(8));
ty += ui(8);
var hovering = noone;
var _bst = ds_stack_create();
ds_stack_push(_bst, [ _b, _x, _w ]);
while(!ds_stack_empty(_bst)) {
var _st = ds_stack_pop(_bst);
var bone = _st[0];
var __x = _st[1];
var __w = _st[2];
if(!bone.is_main) {
draw_sprite_ui(THEME.bone, 0, __x + 12, ty + 12,,,, COLORS._main_icon);
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text);
draw_text(__x + 24, ty + 12, bone.name);
if(ds_map_exists(surfMap, bone.id)) {
var _surf = surfMap[? bone.id];
print($"{_id} has surface {_surf}");
var _sx = __x + 24 + string_width(bone.name) + 8;
var _sy = ty + 4;
for( var i = 0; i < array_length(_surf); i++ ) {
var _sw = surface_get_width(_surf[i]);
var _sh = surface_get_height(_surf[i]);
var _ss = (_hh - 8) / _sh;
draw_surface_ext_safe(_surf[i], _sx, _sy, _ss, _ss, 0, c_white, 1);
draw_set_color(COLORS.node_composite_bg);
draw_rectangle(_sx, _sy, _sx + _sw * _ss, _sy + _sh * _ss, true);
_sy += _sh * _ss + 4;
}
}
if(layer_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;
}
ty += _hh;
draw_set_color(COLORS.node_composite_separator);
draw_line(_x + 16, ty, _x + _w - 16, ty);
}
for( var i = 0; i < array_length(bone.childs); i++ )
ds_stack_push(_bst, [ bone.childs[i], __x + 16, __w - 16 ]);
}
ds_stack_destroy(_bst);
if(layer_dragging != noone && hovering && mouse_release(mb_left)) {
var _lind = input_fix_len + layer_dragging * data_length;
inputs[| _lind].extra_data[0] = hovering.id;
layer_dragging = noone;
}
#endregion
var amo = (ds_list_size(inputs) - input_fix_len) / data_length - 1;
if(array_length(current_data) != ds_list_size(inputs)) return 0;
var ty = _y + bh + ui(8);
//draw_set_color(COLORS.node_composite_separator);
//draw_line(_x + 16, ty - ui(4), _x + _w - 16, ty - ui(4));
draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text);
draw_text_add(_x + ui(16), ty + ui(4), "Surfaces");
ty += ui(32);
var lh = 32;
var _h = 8 + max(1, amo) * (lh + 4) + 8;
layer_renderer.h = _h;
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, _y, _w, _h, COLORS.node_composite_bg_blend, 1);
var sh = 8 + max(1, amo) * (lh + 4) + 8;
draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, _x, ty, _w, sh, COLORS.node_composite_bg_blend, 1);
var _vis = attributes.layer_visible;
var _sel = attributes.layer_selectable;
var ly = _y + 8;
var ly = ty + 8;
var ssh = lh - 6;
var hoverIndex = noone;
draw_set_color(COLORS.node_composite_separator);
draw_line(_x + 16, ly, _x + _w - 16, ly);
layer_remove = -1;
for(var i = 0; i < amo; i++) {
var ind = amo - i - 1;
var index = input_fix_len + ind * data_length;
var _surf = current_data[index + 0];
var _pos = current_data[index + 1];
var index = -1;
for(var i = input_fix_len; i < ds_list_size(inputs) - data_length; i += data_length) {
var _surf = current_data[i];
index++;
var _bx = _x + _w - 24;
var _cy = ly + i * (lh + 4);
var _cy = ly + index * (lh + 4);
if(point_in_circle(_m[0], _m[1], _bx, _cy + lh / 2, 16)) {
draw_sprite_ui_uniform(THEME.icon_delete, 3, _bx, _cy + lh / 2, 1, COLORS._main_value_negative);
if(mouse_press(mb_left, _focus))
layer_remove = ind;
layer_remove = index;
} else
draw_sprite_ui_uniform(THEME.icon_delete, 3, _bx, _cy + lh / 2, 1, COLORS._main_icon);
if(!is_surface(_surf)) continue;
var aa = (ind != layer_dragging || layer_dragging == noone)? 1 : 0.5;
var vis = _vis[ind];
var sel = _sel[ind];
var aa = (index != layer_dragging || layer_dragging == noone)? 1 : 0.5;
var vis = _vis[index];
var sel = _sel[index];
var hover = point_in_rectangle(_m[0], _m[1], _x, _cy, _x + _w, _cy + lh);
draw_set_color(COLORS.node_composite_separator);
@ -67,10 +186,10 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
draw_sprite_ui_uniform(THEME.junc_visible, vis, _bx, _cy + lh / 2, 1, c_white);
if(mouse_press(mb_left, _focus))
hold_visibility = !_vis[ind];
hold_visibility = !_vis[index];
if(mouse_click(mb_left, _focus) && _vis[ind] != hold_visibility) {
_vis[@ ind] = hold_visibility;
if(mouse_click(mb_left, _focus) && _vis[index] != hold_visibility) {
_vis[@ index] = hold_visibility;
doUpdate();
}
} else
@ -81,10 +200,10 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
draw_sprite_ui_uniform(THEME.cursor_select, sel, _bx, _cy + lh / 2, 1, c_white);
if(mouse_press(mb_left, _focus))
hold_select = !_sel[ind];
hold_select = !_sel[index];
if(mouse_click(mb_left, _focus) && _sel[ind] != hold_select)
_sel[@ ind] = hold_select;
if(mouse_click(mb_left, _focus) && _sel[index] != hold_select)
_sel[@ index] = hold_select;
} else
draw_sprite_ui_uniform(THEME.cursor_select, sel, _bx, _cy + lh / 2, 1, COLORS._main_icon, 0.5 + 0.5 * sel);
@ -102,27 +221,27 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
draw_set_text(f_p1, fa_left, fa_center, hover? COLORS._main_text : COLORS._main_text);
draw_set_alpha(aa);
draw_text(_sx1 + 12, _cy + lh / 2, inputs[| index].name);
draw_text(_sx1 + 12, _cy + lh / 2, inputs[| i].name);
draw_set_alpha(1);
if(_hover && point_in_rectangle(_m[0], _m[1], _x, _cy, _x + _w, _cy + lh)) {
hoverIndex = ind;
hoverIndex = index;
if(layer_dragging != noone) {
draw_set_color(COLORS._main_accent);
if(layer_dragging > ind)
if(layer_dragging > index)
draw_line_width(_x + 16, _cy + lh + 2, _x + _w - 16, _cy + lh + 2, 2);
else if(layer_dragging < ind)
else if(layer_dragging < index)
draw_line_width(_x + 16, _cy - 2, _x + _w - 16, _cy - 2, 2);
}
}
if(layer_dragging == noone || layer_dragging == ind) {
if(layer_dragging == noone || layer_dragging == index) {
var _bx = _x + 24;
if(point_in_circle(_m[0], _m[1], _bx, _cy + lh / 2, 16)) {
draw_sprite_ui_uniform(THEME.hamburger, 3, _bx, _cy + lh / 2, .75, c_white);
if(mouse_press(mb_left, _focus))
layer_dragging = ind;
layer_dragging = index;
} else
draw_sprite_ui_uniform(THEME.hamburger, 3, _bx, _cy + lh / 2, .75, COLORS._main_icon);
}
@ -159,73 +278,60 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
layer_dragging = noone;
}
return _h;
layer_renderer.h = bh + ui(40) + sh;
return layer_renderer.h;
#endregion
});
input_display_list = [
["Output", true], 0,
["Layers", false], layer_renderer,
["Surfaces", true],
input_display_list = [ 1,
["Output", true], 0,
["Armature", false], layer_renderer,
["Surfaces", true],
];
input_display_list_len = array_length(input_display_list);
function deleteLayer(index) {
function deleteLayer(index) { #region
var idx = input_fix_len + index * data_length;
for( var i = 0; i < data_length; i++ ) {
ds_list_delete(inputs, idx);
array_remove(input_display_list, idx + i);
}
for( var i = input_display_list_len; i < array_length(input_display_list); i++ ) {
if(input_display_list[i] > idx)
input_display_list[i] = input_display_list[i] - data_length;
}
doUpdate();
#endregion
}
function createNewSurface() {
function createNewSurface() { #region
var index = ds_list_size(inputs);
var _s = floor((index - input_fix_len) / data_length);
inputs[| index + 0] = nodeValue(_s? ("Surface " + string(_s)) : "Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
inputs[| index + 0] = nodeValue("Surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
inputs[| index + 0].surface_index = index;
inputs[| index + 0].hover_effect = 0;
inputs[| index + 0].extra_data[0] = "";
inputs[| index + 1] = nodeValue("Position " + string(_s), self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] )
.setDisplay(VALUE_DISPLAY.vector)
.setUnitRef(function(index) { return [ overlay_w, overlay_h ]; });
inputs[| index + 1].surface_index = index;
inputs[| index + 2] = nodeValue("Rotation " + string(_s), self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0 )
.setDisplay(VALUE_DISPLAY.rotation);
inputs[| index + 2].surface_index = index;
inputs[| index + 3] = nodeValue("Scale " + string(_s), self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1 ] )
.setDisplay(VALUE_DISPLAY.vector);
inputs[| index + 3].surface_index = index;
inputs[| index + 1] = nodeValue("Transform", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0, 1, 1 ] )
.setDisplay(VALUE_DISPLAY.transform);
array_push(input_display_list, index + 0);
array_push(input_display_list, index + 1);
array_push(input_display_list, index + 2);
array_push(input_display_list, index + 3);
while(_s >= array_length(attributes.layer_visible))
array_push(attributes.layer_visible, true);
while(_s >= array_length(attributes.layer_selectable))
array_push(attributes.layer_selectable, true);
#endregion
}
if(!LOADING && !APPENDING) createNewSurface();
//function getInput() { return inputs[| ds_list_size(inputs) - data_length]; }
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, [])
.rejectArrayProcess();
temp_surface = [ surface_create(1, 1), surface_create(1, 1) ];
surf_dragging = -1;
input_dragging = -1;
drag_type = 0;
dragging_sx = 0;
dragging_sy = 0;
@ -264,178 +370,43 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
h = max(min_h, (preview_surface && previewable)? 128 : 0, _hi, _ho);
}
static drawJunctions = function(_x, _y, _mx, _my, _s) {
if(!active) return;
var hover = noone;
var amo = array_length(input_display_list);
var hov = PANEL_GRAPH._junction_hovering;
var ind = -1;
if(hov != noone && struct_has(hov, "surface_index"))
ind = hov.surface_index;
for( var i = 0; i < getInputAmount(); i++ ) {
var idx = getInputIndex(i);
if(!inputs[| idx].isVisible()) continue;
if(inputs[| idx].drawJunction(_s, _mx, _my, 1.5))
hover = inputs[| idx];
if(idx >= input_fix_len && inputs[| idx].hover_effect > 0) {
var _px0 = 999999;
var _py0 = 999999;
var _px1 = -999999;
var _py1 = -999999;
var _drw = false;
var _hov = inputs[| idx].hover_effect;
for( var j = 1; j < data_length; j++ ) {
if(!inputs[| idx + j].isVisible()) continue;
_px0 = min( _px0, inputs[| idx + j].x );
_py0 = min( _py0, inputs[| idx + j].y );
_px1 = max( _px1, inputs[| idx + j].x );
_py1 = max( _py1, inputs[| idx + j].y );
_drw = true;
}
if(!_drw) continue;
//if(_hov > 0.5) {
// var pilx = _px0 - 16 * _s;
// var pily = _py0 - 16 * _s;
// var pilw = _px1 - _px0 + 32 * _s;
// var pilh = _py1 - _py0 + 32 * _s;
// draw_sprite_stretched_ext(THEME.node_bg_pill, 0, pilx, pily, pilw, pilh, COLORS._main_icon_dark, (_hov - 0.5) * 2);
//}
for( var j = 1; j < data_length; j++ ) {
if(inputs[| idx + j].drawJunction(_s, _mx, _my, 1.5))
hover = inputs[| idx + j];
}
}
}
for(var i = 0; i < ds_list_size(outputs); i++)
if(outputs[| i].drawJunction(_s, _mx, _my))
hover = outputs[| i];
return hover;
}
static drawJunctionNames = function(_x, _y, _mx, _my, _s) {
if(!active) return;
var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list);
var jun;
var xx = x * _s + _x;
var yy = y * _s + _y;
show_input_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx - 8 * _s, yy + 20 * _s, xx + 8 * _s, yy + h * _s);
show_output_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx + (w - 8) * _s, yy + 20 * _s, xx + (w + 8) * _s, yy + h * _s);
var hov = PANEL_GRAPH._junction_hovering;
var ind = -1;
if(hov != noone && struct_has(hov, "surface_index"))
ind = hov.surface_index;
if(ind != -1) {
for( var j = 1; j < data_length; j++ ) {
if(ind + j >= ds_list_size(inputs)) break;
inputs[| ind + j].drawNameBG(_s);
}
for( var j = 1; j < data_length; j++ ) {
if(ind + j >= ds_list_size(inputs)) break;
inputs[| ind + j].drawName(_s, _mx, _my);
}
} else if(show_input_name) {
for( var i = 0; i < getInputAmount(); i++ ) {
var idx = getInputIndex(i);
if(idx == ind) continue;
inputs[| idx].drawNameBG(_s);
}
for( var i = 0; i < getInputAmount(); i++ ) {
var idx = getInputIndex(i);
if(idx == ind) continue;
inputs[| idx].drawName(_s, _mx, _my);
}
}
if(show_output_name) {
for(var i = 0; i < ds_list_size(outputs); i++)
outputs[| i].drawNameBG(_s);
for(var i = 0; i < ds_list_size(outputs); i++)
outputs[| i].drawName(_s, _mx, _my);
}
}
static preDraw = function(_x, _y, _s) {
var xx = x * _s + _x;
var yy = y * _s + _y;
var jun;
var inamo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list);
var _in = yy + ui(32) * _s;
var hov = PANEL_GRAPH._junction_hovering;
var ind = -1;
if(hov != noone && struct_has(hov, "surface_index"))
ind = hov.surface_index;
for( var i = 0; i < getInputAmount(); i++ ) {
var idx = getInputIndex(i);
jun = ds_list_get(inputs, idx, noone);
if(jun == noone || is_undefined(jun)) continue;
jun.x = xx;
jun.y = _in;
if(i >= input_fix_len) {
jun.hover_effect = lerp_float(jun.hover_effect, ind == idx, 3);
var sp = jun.hover_effect * 24;
var sx = xx - sp * _s;
var sy = _in;
for( var j = 1; j < data_length; j++ ) {
var _jun = ds_list_get(inputs, idx + j, noone);
_jun.x = sx;
_jun.y = sy;
sy += sp * _s * _jun.isVisible();
}
}
_in += 24 * _s * jun.isVisible();
}
var outamo = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list);
xx = xx + w * _s;
_in = yy + ui(32) * _s;
for(var i = 0; i < outamo; i++) {
var idx = getOutputJunctionIndex(i);
jun = outputs[| idx];
jun.x = xx;
jun.y = _in;
_in += 24 * _s * jun.isVisible();
}
}
static onValueFromUpdate = function(index) {
static onValueFromUpdate = function(index) { #region
if(LOADING || APPENDING) return;
if(index + data_length >= ds_list_size(inputs))
createNewSurface();
#endregion
}
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {
static setBone = function() { #region
ds_map_clear(boneMap);
var _b = inputs[| 1].getValue();
if(_b == noone) return;
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++ ) {
boneMap[? __b.id] = __b;
ds_stack_push(_bst, __b.childs[i]);
}
}
ds_stack_destroy(_bst);
#endregion
}
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
var dim = inputs[| 0].getValue();
var _b = inputs[| 1].getValue();
if(attributes.display_bone == 1)
_b.draw(active, _x, _y, _s, _mx, _my);
var ww = dim[0];
var hh = dim[1];
@ -444,70 +415,25 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
var y0 = _y;
var y1 = _y + hh * _s;
if(input_dragging > -1) {
if(surf_dragging > -1) {
var input_dragging = surf_dragging + 1;
var _surf = current_data[surf_dragging];
var _tran = current_data[input_dragging];
var _bone = inputs[| surf_dragging].extra_data[0];
_bone = boneMap[? _bone];
if(drag_type == NODE_COMPOSE_DRAG.move) {
var _dx = (_mx - dragging_mx) / _s;
var _dy = (_my - dragging_my) / _s;
if(key_mod_press(SHIFT)) {
if(abs(_dx) > abs(_dy) + ui(16))
_dy = 0;
else if(abs(_dy) > abs(_dx) + ui(16))
_dx = 0;
else {
_dx = max(_dx, _dy);
_dy = _dx;
}
}
var _p = point_rotate(_dx, _dy, 0, 0, -_bone.angle);
var pos_x = value_snap(dragging_sx + _dx, _snx);
var pos_y = value_snap(dragging_sy + _dy, _sny);
var pos_x = dragging_sx + _p[0];
var pos_y = dragging_sy + _p[1];
if(key_mod_press(ALT)) {
var _surf = current_data[input_dragging - 1];
var _sw = surface_get_width(_surf);
var _sh = surface_get_height(_surf);
var x0 = pos_x, x1 = pos_x + _sw;
var y0 = pos_y, y1 = pos_y + _sh;
var xc = (x0 + x1) / 2;
var yc = (y0 + y1) / 2;
var snap = 4;
draw_set_color(COLORS._main_accent);
if(abs(x0 - 0) < snap) {
pos_x = 0;
draw_line_width(_x + _s * 0, 0, _x + _s * 0, WIN_H, 2);
}
if(abs(y0 - 0) < snap) {
pos_y = 0;
draw_line_width(0, _y + _s * 0, WIN_W, _y + _s * 0, 2);
}
if(abs(x1 - ww) < snap) {
pos_x = ww - _sw;
draw_line_width(_x + _s * ww, 0, _x + _s * ww, WIN_H, 2);
}
if(abs(y1 - hh) < snap) {
pos_y = hh - _sh;
draw_line_width(0, _y + _s * hh, WIN_W, _y + _s * hh, 2);
}
if(abs(xc - ww / 2) < snap) {
pos_x = ww / 2 - _sw / 2;
draw_line_width(_x + _s * ww / 2, 0, _x + _s * ww / 2, WIN_H, 2);
}
if(abs(yc - hh / 2) < snap) {
pos_y = hh / 2 - _sh / 2;
draw_line_width(0, _y + _s * hh / 2, WIN_W, _y + _s * hh / 2, 2);
}
}
if(inputs[| input_dragging].setValue([ pos_x, pos_y ]))
UNDO_HOLDING = true;
_tran[TRANSFORM.pos_x] = pos_x;
_tran[TRANSFORM.pos_y] = pos_y;
} else if(drag_type == NODE_COMPOSE_DRAG.rotate) {
var aa = point_direction(rot_anc_x, rot_anc_y, _mx, _my);
var da = angle_difference(dragging_mx, aa);
@ -517,14 +443,12 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
sa = round((dragging_sx - da) / 15) * 15;
else
sa = dragging_sx - da;
if(inputs[| input_dragging].setValue(sa))
UNDO_HOLDING = true;
_tran[TRANSFORM.rot] = sa;
} else if(drag_type == NODE_COMPOSE_DRAG.scale) {
var _surf = inputs[| surf_dragging + 0].getValue();
var _rot = inputs[| surf_dragging + 2].getValue();
var _rot = _bone.angle + _tran[TRANSFORM.rot];
var _sw = surface_get_width(_surf);
var _sh = surface_get_width(_surf);
var _sh = surface_get_height(_surf);
var _p = point_rotate(_mx - dragging_mx, _my - dragging_my, 0, 0, -_rot);
var sca_x = _p[0] / _s / _sw * 2;
@ -532,13 +456,16 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(key_mod_press(SHIFT)) {
sca_x = min(sca_x, sca_y);
sca_y = min(sca_x, sca_y);
sca_y = sca_x;
}
if(inputs[| input_dragging].setValue([ sca_x, sca_y ]))
UNDO_HOLDING = true;
_tran[TRANSFORM.sca_x] = sca_x;
_tran[TRANSFORM.sca_y] = sca_y;
}
if(inputs[| input_dragging].setValue(_tran))
UNDO_HOLDING = true;
if(mouse_release(mb_left)) {
input_dragging = -1;
UNDO_HOLDING = false;
@ -561,9 +488,16 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
var index = input_fix_len + i * data_length;
var _surf = current_data[index + 0];
var _pos = current_data[index + 1];
var _rot = current_data[index + 2];
var _sca = current_data[index + 3];
var _bone = inputs[| index].extra_data[0];
if(!ds_map_exists(boneMap, _bone)) continue;
_bone = boneMap[? _bone];
var _tran = current_data[index + 1];
var _rot = _bone.angle + _tran[TRANSFORM.rot];
var _anc = _bone.getPoint(_bone.length / 2, _bone.angle);
var _pos = point_rotate(_tran[TRANSFORM.pos_x], _tran[TRANSFORM.pos_y], _anc.x, _anc.y, _rot);
var _sca = [ _tran[TRANSFORM.sca_x], _tran[TRANSFORM.sca_y] ];
if(!_surf || is_array(_surf)) continue;
@ -619,9 +553,14 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(hovering != -1) {
var _surf = current_data[hovering];
var _pos = current_data[hovering + 1];
var _rot = current_data[hovering + 2];
var _sca = current_data[hovering + 3];
var _bone = inputs[| hovering].extra_data[0];
_bone = boneMap[? _bone];
var _tran = current_data[hovering + 1];
var _rot = _bone.angle + _tran[TRANSFORM.rot];
var _anc = _bone.getPoint(_bone.length / 2, _bone.angle);
var _pos = point_rotate(_tran[TRANSFORM.pos_x], _tran[TRANSFORM.pos_y], _anc.x, _anc.y, _rot);
var _sca = [ _tran[TRANSFORM.sca_x], _tran[TRANSFORM.sca_y] ];
var _ww = surface_get_width(_surf);
var _hh = surface_get_height(_surf);
@ -655,7 +594,6 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(mouse_press(mb_left, active)) {
surf_dragging = hovering;
input_dragging = hovering + 1;
drag_type = hovering_type;
dragging_sx = _pos[0];
dragging_sy = _pos[1];
@ -665,7 +603,6 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
} else if(hovering_type == NODE_COMPOSE_DRAG.rotate) { //rot
if(mouse_press(mb_left, active)) {
surf_dragging = hovering;
input_dragging = hovering + 2;
drag_type = hovering_type;
dragging_sx = _rot;
rot_anc_x = _dx0 + _ww / 2 * _s;
@ -675,7 +612,6 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
} else if(hovering_type == NODE_COMPOSE_DRAG.scale) { //sca
if(mouse_press(mb_left, active)) {
surf_dragging = hovering;
input_dragging = hovering + 3;
drag_type = hovering_type;
dragging_sx = _sca[0];
dragging_sy = _sca[1];
@ -689,11 +625,21 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
deleteLayer(layer_remove);
layer_remove = -1;
}
if(attributes.display_bone == 0)
_b.draw(active, _x, _y, _s, _mx, _my);
#endregion
}
bone_prev = noone;
static step = function() {
var _dim_type = getSingleValue(1);
var _b = inputs[| 1].getValue();
if(bone_prev != _b) {
setBone();
bone_prev = _b;
}
var _dim_type = getSingleValue(1);
inputs[| 2].setVisible(_dim_type == COMPOSE_OUTPUT_SCALING.constant);
}
@ -701,16 +647,14 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(_output_index == 1) return atlas_data;
if(_output_index == 0 && _array_index == 0) atlas_data = [];
if(array_length(_data) < 4) return _outSurf;
var _dim = _data[0];
var cDep = attrDepth();
var ww = _dim[0], hh = _dim[1];
var _dim = _data[0];
var _bone = _data[1];
var cDep = attrDepth();
overlay_w = ww;
overlay_h = hh;
overlay_w = _dim[0];
overlay_h = _dim[1];
if(is_surface(base))
_outSurf = surface_size_to(_outSurf, ww, hh, cDep);
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1], cDep);
for(var i = 0; i < 2; i++) {
temp_surface[i] = surface_verify(temp_surface[i], surface_get_width(_outSurf), surface_get_height(_outSurf), cDep);
@ -731,26 +675,33 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
if(!vis) continue;
var startDataIndex = input_fix_len + i * data_length;
var _s = _data[startDataIndex + 0];
var _pos = _data[startDataIndex + 1];
var _rot = _data[startDataIndex + 2];
var _sca = _data[startDataIndex + 3];
var _s = _data[startDataIndex];
var _bone = inputs[| startDataIndex].extra_data[0];
if(!_s || is_array(_s)) continue;
if(!ds_map_exists(boneMap, _bone)) continue;
_bone = boneMap[? _bone];
var _tran = _data[startDataIndex + 1];
var _rot = _bone.angle + _tran[TRANSFORM.rot];
var _anc = _bone.getPoint(_bone.length / 2, _bone.angle);
var _pos = point_rotate(_tran[TRANSFORM.pos_x], _tran[TRANSFORM.pos_y], _anc.x, _anc.y, _rot);
var _sca = [ _tran[TRANSFORM.sca_x], _tran[TRANSFORM.sca_y] ];
if(!is_surface(_s)) continue;
var _ww = surface_get_width(_s);
var _hh = surface_get_height(_s);
var _sw = _ww * _sca[0];
var _sh = _hh * _sca[1];
var cx = _pos[0] + _ww / 2;
var cy = _pos[1] + _hh / 2;
var cx = _pos[0];
var cy = _pos[1];
var _d0 = point_rotate(cx - _sw / 2, cy - _sh / 2, cx, cy, _rot);
shader_set_interpolation(_s);
array_push(atlas_data, new SurfaceAtlas(_s, [ _d0[0], _d0[1] ], _rot, [ _sca[0], _sca[1] ]));
array_push(atlas_data, new SurfaceAtlas(_s, _d0, _rot, _sca));
draw_surface_ext_safe(_s, _d0[0], _d0[1], _sca[0], _sca[1], _rot);
}
surface_reset_shader();

View file

@ -1,7 +1,8 @@
function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Armature Pose";
inputs[| 0] = nodeValue("Armature", self, JUNCTION_CONNECT.input, VALUE_TYPE.armature, noone);
inputs[| 0] = nodeValue("Armature", self, JUNCTION_CONNECT.input, VALUE_TYPE.armature, noone)
.setVisible(true, true);
input_display_list = [ 0,
["Bones", false]
@ -31,9 +32,12 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
boneMap[? bone.id] = inputs[| index];
array_push(input_display_list, index);
return inputs[| index];
}
function setBone() {
static setBone = function() { #region
//print("Setting dem bones...");
var _b = inputs[| 0].getValue();
if(_b == noone) return;
@ -51,6 +55,7 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
}
ds_stack_destroy(_bst);
//print($"Bone counts: {array_length(_bones)}");
var _inputs = ds_list_create();
_inputs[| 0] = inputs[| 0];
@ -62,20 +67,27 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
for( var i = 0; i < array_length(_bones); i++ ) {
var bone = _bones[i];
var _idx = ds_list_size(_inputs);
array_push(_input_display_list, _idx);
//print($" > Adding bone id: {bone.id}");
if(ds_map_exists(boneMap, bone.id)) {
var _inp = boneMap[? bone.id];
var _idx = ds_list_size(_inputs);
_inp.index = _idx;
array_append(_input_display_list, _idx);
ds_list_add(_inputs, _inp);
} else
createNewControl(bone);
} else {
var _inp = createNewControl(bone);
ds_list_add(_inputs, _inp);
}
}
ds_list_destroy(inputs);
inputs = _inputs;
input_display_list = _input_display_list;
//print(_input_display_list);
#endregion
}
tools = [
@ -101,7 +113,7 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
var my = (_my - _y) / _s;
if(posing_bone) {
if(posing_bone == 0) { //move
if(posing_type == 0) { //move
var bx = posing_sx + (mx - posing_mx);
var by = posing_sy + (my - posing_my);
@ -111,20 +123,25 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
if(posing_input.setValue(val))
UNDO_HOLDING = true;
} else if(posing_bone == 1) { //scale
var ss = point_distance(posing_mx, posing_my, mx, my) / posing_sx;
} 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 val = posing_input.getValue();
val[TRANSFORM.sca_x] = ss;
val[TRANSFORM.rot] = rot;
if(posing_input.setValue(val))
UNDO_HOLDING = true;
} else if(posing_bone == 2) { //rotate
} else if(posing_type == 2) { //rotate
var ori = posing_bone.getPoint(0, 0);
var rot = angle_difference(point_direction(ori.x, ori.y, mx, my), posing_bone.angle);
var ang = point_direction(ori.x, ori.y, mx, my);
var rot = angle_difference(ang, posing_sy);
posing_sy = ang;
posing_sx += rot;
var val = posing_input.getValue();
val[TRANSFORM.rot] = rot;
val[TRANSFORM.rot] = posing_sx;
if(posing_input.setValue(val))
UNDO_HOLDING = true;
@ -132,11 +149,12 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
if(mouse_release(mb_left)) {
posing_bone = noone;
posing_type = noone;
UNDO_HOLDING = false;
}
}
if(anchor_selecting != noone && mouse_click(mb_left, active)) {
if(anchor_selecting != noone && mouse_press(mb_left, active)) {
if(anchor_selecting[1] == 0) { // move
posing_bone = anchor_selecting[0];
if(!ds_map_exists(boneMap, posing_bone.id))
@ -159,10 +177,12 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
posing_type = 1;
var val = posing_input.getValue();
posing_sx = val[TRANSFORM.sca_x];
posing_sx = posing_bone.length / posing_bone.pose_scale;
posing_sy = posing_bone.angle - posing_bone.pose_angle;
posing_mx = mx;
posing_my = my;
var pnt = posing_bone.getPoint(0, 0);
posing_mx = pnt.x;
posing_my = pnt.y;
} else if(anchor_selecting[1] == 2) { // rotate
posing_bone = anchor_selecting[0];
@ -171,8 +191,10 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
posing_input = boneMap[? posing_bone.id];
posing_type = 2;
var ori = posing_bone.getPoint(0, 0);
var val = posing_input.getValue();
posing_sx = posing_bone.angle;
posing_sx = val[TRANSFORM.rot];
posing_sy = point_direction(ori.x, ori.y, mx, my);
posing_mx = mx;
posing_my = my;
@ -181,9 +203,15 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
}
}
bone_prev = noone;
static step = function() {
var _b = inputs[| 0].getValue();
if(_b == noone) return;
if(bone_prev != _b) {
setBone();
bone_prev = _b;
return;
}
var _boneCount = ds_list_size(inputs) - input_fix_len;
if(_boneCount != _b.childCount()) setBone();
@ -193,8 +221,8 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
var _b = inputs[| 0].getValue();
if(_b == noone) return;
var _bone_pose = _b.clone();
var _bone_pose = _b.clone(attributes);
_bone_pose.resetPose();
var _bst = ds_stack_create();
ds_stack_push(_bst, _bone_pose);
@ -209,30 +237,17 @@ function Node_Armature_Pose(_x, _y, _group = noone) : Node(_x, _y, _group) const
var _trn = _inp.getValue();
var px = _trn[0];
var py = _trn[1];
var rot = _trn[2];
var sca = _trn[3];
var _x = lengthdir_x(bone.distance, bone.direction);
var _y = lengthdir_y(bone.distance, bone.direction);
_x += px;
_y += py;
bone.distance = point_distance(0, 0, _x, _y);
bone.direction = point_direction(0, 0, _x, _y);
bone.angle += rot;
bone.length *= sca;
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; i < array_length(bone.childs); i++ ) {
for( var i = 0; i < array_length(bone.childs); i++ )
ds_stack_push(_bst, bone.childs[i]);
}
}
ds_stack_destroy(_bst);
_bone_pose.setPose();
outputs[| 0].setValue(_bone_pose);
}

View file

@ -550,7 +550,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
var _surf = inputs[| surf_dragging + 0].getValue();
var _rot = inputs[| surf_dragging + 2].getValue();
var _sw = surface_get_width(_surf);
var _sh = surface_get_width(_surf);
var _sh = surface_get_height(_surf);
var _p = point_rotate(_mx - dragging_mx, _my - dragging_my, 0, 0, -_rot);
var sca_x = _p[0] / _s / _sw * 2;
@ -758,8 +758,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
overlay_w = ww;
overlay_h = hh;
if(is_surface(base))
_outSurf = surface_size_to(_outSurf, ww, hh, cDep);
_outSurf = surface_verify(_outSurf, ww, hh, cDep);
for(var i = 0; i < 2; i++) {
temp_surface[i] = surface_verify(temp_surface[i], surface_get_width(_outSurf), surface_get_height(_outSurf), cDep);

View file

@ -110,7 +110,7 @@ function value_color(i) {
$976bff, //atlas
#c1007c, //d3vertex
$5dde8f, //gradient
$5dde8f, //armature //////////////////////
$6691ff, //armature
];
if(i == 99) return $5dde8f;
@ -185,6 +185,7 @@ function typeArray(_type) {
case VALUE_DISPLAY.area :
case VALUE_DISPLAY.puppet_control :
case VALUE_DISPLAY.kernel :
case VALUE_DISPLAY.transform :
case VALUE_DISPLAY.curve :
@ -735,7 +736,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
extract_node = "";
break;
case VALUE_DISPLAY.transform :
editWidget = new transformBox(function(index, _val) {
editWidget = new transformBox(function(index, val) {
var _val = animator.getValue();
_val[index] = val;
return setValueDirect(_val);
@ -1221,8 +1222,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
updated = animator.setValue(val, connect_type == JUNCTION_CONNECT.input && record, time);
}
if(type == VALUE_TYPE.gradient) updated = true;
if(display_type == VALUE_DISPLAY.palette) updated = true;
if(type == VALUE_TYPE.gradient) updated = true;
if(display_type == VALUE_DISPLAY.palette) updated = true;
if(display_type == VALUE_DISPLAY.transform) updated = true;
if(updated) {
if(connect_type == JUNCTION_CONNECT.input) {

View file

@ -15,7 +15,7 @@ function Panel_Animation() : PanelContent() constructor {
min_h = ui(48);
tool_width = ui(224);
function initSize() {
static initSize = function() {
timeline_w = w - tool_width - ui(80);
timeline_surface = surface_create_valid(timeline_w, timeline_h);
timeline_mask = surface_create_valid(timeline_w, timeline_h);

View file

@ -7,7 +7,7 @@ function Panel_Collection() : PanelContent() constructor {
group_w_sx = false;
group_w_mx = false;
function initSize() {
static initSize = function() {
content_w = w - ui(8) - group_w;
content_h = h - ui(40) - ui(16);
}

View file

@ -838,7 +838,7 @@ function PanelContent() constructor {
function onFocusBegin() {}
function onFocusEnd() {}
function initSize() {}
static initSize = function() {}
function setPanelSize(panel) {
x = panel.tx;

View file

@ -121,7 +121,7 @@ function Panel_Graph() : PanelContent() constructor {
//print(title + ": Center " + string(graph_x) + ", " + string(graph_y));
}
function initSize() { toCenterNode(); }
static initSize = function() { toCenterNode(); }
initSize();
toolbars = [

View file

@ -22,7 +22,7 @@ function Panel_Inspector() : PanelContent() constructor {
prop_sel_drag_x = 0;
prop_sel_drag_y = 0;
function initSize() {
static initSize = function() {
content_w = w - ui(32);
content_h = h - top_bar_h - ui(12);
}

View file

@ -5,12 +5,14 @@ function Panel_Preview() : PanelContent() constructor {
last_focus = noone;
function initSize() {
canvas_x = w / 2 - ui(64);
canvas_y = h / 2 - ui(64);
static initSize = function() {
canvas_x = w / 2;
canvas_y = h / 2;
}
initSize();
run_in(1, function() { initSize() });
canvas_x = 0;
canvas_y = 0;
canvas_s = ui(1);
canvas_w = ui(128);
canvas_h = ui(128);
@ -847,6 +849,10 @@ function Panel_Preview() : PanelContent() constructor {
else
draw_clear(canvas_bg);
draw_set_color(COLORS._main_icon_dark);
draw_line_width(canvas_x, 0, canvas_x, h, 1);
draw_line_width(0, canvas_y, w, canvas_y, 1);
title = __txt("Preview");
dragCanvas();

View file

@ -28,20 +28,24 @@ function rotator(_onModify, _step = -1) : widget() constructor {
x = _x;
y = _y;
w = 0;
h = ui(96);
h = ui(64);
if(!is_real(_data)) return;
var knob_y = _y + ui(48) * scale;
var knob_y = _y + h / 2;
var _r = ui(28);
if(draw_tb) {
tb_value.setFocusHover(active, hover);
tb_value.draw(_x + ui(64), knob_y - ui(17), ui(64), TEXTBOX_HEIGHT, _data, _m);
}
draw_sprite_ui_uniform(spr_bg, 0, _x, knob_y, scale);
draw_sprite(spr_bg, 0, _x, knob_y);
var px = _x + lengthdir_x(ui(36) * scale, _data);
var py = knob_y + lengthdir_y(ui(36) * scale, _data);
draw_set_color(COLORS.widget_rotator_guide);
draw_line(_x, knob_y, _x + lengthdir_x(ui(20), _data) - 1, knob_y + lengthdir_y(ui(20), _data) - 1);
var px = _x + lengthdir_x(_r, _data);
var py = knob_y + lengthdir_y(_r, _data);
if(dragging) {
var delta = angle_difference(point_direction(_x, knob_y, _m[0], _m[1]), drag_sa);
@ -56,7 +60,7 @@ function rotator(_onModify, _step = -1) : widget() constructor {
if(step != -1)
val = round(real_val / step) * step;
draw_sprite_ui_uniform(spr_knob, 1, px, py, scale);
draw_sprite(spr_knob, 1, px, py);
if(val != drag_sv) {
if(onModify(val))
@ -71,8 +75,8 @@ function rotator(_onModify, _step = -1) : widget() constructor {
UNDO_HOLDING = false;
}
} else if(hover && point_in_circle(_m[0], _m[1], _x, knob_y, ui(48) * scale)) {
draw_sprite_ui_uniform(spr_knob, 1, px, py, scale);
} else if(hover && point_in_circle(_m[0], _m[1], _x, knob_y, _r + ui(16))) {
draw_sprite(spr_knob, 1, px, py);
if(mouse_press(mb_left, active)) {
dragging = true;
@ -80,11 +84,11 @@ function rotator(_onModify, _step = -1) : widget() constructor {
drag_sa = point_direction(_x, knob_y, _m[0], _m[1]);
}
} else {
draw_sprite_ui_uniform(spr_knob, 0, px, py, scale);
draw_sprite(spr_knob, 0, px, py);
}
draw_set_text(f_p0, fa_center, fa_center, COLORS._main_text);
draw_text(_x, knob_y, string(_data));
//draw_set_text(f_p0, fa_center, fa_center, COLORS._main_text);
//draw_text(_x, knob_y, string(_data));
resetFocus();
}

View file

@ -29,11 +29,12 @@ function rotatorRange(_onModify) : widget() constructor {
x = _x;
y = _y;
w = 0;
h = ui(96);
h = ui(64);
if(!is_real(_data[0])) return;
if(!is_real(_data[1])) return;
var knob_y = _y + ui(48);
var knob_y = _y + h / 2;
var _r = ui(28);
tb_min.setFocusHover(active, hover);
tb_max.setFocusHover(active, hover);
@ -41,45 +42,34 @@ function rotatorRange(_onModify) : widget() constructor {
tb_min.draw(_x - ui(40 + 16 + 80), knob_y - TEXTBOX_HEIGHT / 2, ui(80), TEXTBOX_HEIGHT, array_safe_get(_data, 0), _m);
tb_max.draw(_x + ui(40 + 16), knob_y - TEXTBOX_HEIGHT / 2, ui(80), TEXTBOX_HEIGHT, array_safe_get(_data, 1), _m);
draw_sprite_ui_uniform(THEME.rotator_bg, 0, _x, knob_y);
var px, py;
for(var i = 0; i < 2; i++) {
px[i] = _x + lengthdir_x(_r, _data[i]);
py[i] = knob_y + lengthdir_y(_r, _data[i]);
}
draw_sprite(THEME.rotator_bg, 0, _x, knob_y);
draw_set_color(COLORS.widget_rotator_guide);
draw_line(_x, knob_y, _x + lengthdir_x(ui(20), _data[0]) - 1, knob_y + lengthdir_y(ui(20), _data[0]) - 1);
draw_line(_x, knob_y, _x + lengthdir_x(ui(20), _data[1]) - 1, knob_y + lengthdir_y(ui(20), _data[1]) - 1);
#region draw arc
var hover_arc = false;
var diss = point_distance(_m[0], _m[1], _x, knob_y);
if(diss >= ui(32) && diss <= ui(40) || dragging == 2)
if(abs(diss - _r) < 6 || dragging == 2)
hover_arc = true;
var ans = _data[0] % 360;
var ane = _data[1] % 360;
var diff = ane >= ans? ane - ans : ane + 360 - ans;
draw_set_color(COLORS.widget_rotator_range);
for(var i = 0; i < abs(diff); i += 4) {
var as = ans + i * sign(diff);
var ae = ans + (i + 4) * sign(diff);
var sx = _x + lengthdir_x(ui(36), as);
var sy = knob_y + lengthdir_y(ui(36), as);
var ex = _x + lengthdir_x(ui(36), ae);
var ey = knob_y + lengthdir_y(ui(36), ae);
draw_set_alpha(0.5 + 0.5 * hover_arc);
draw_line_width(sx, sy, ex, ey, ui(8));
draw_set_alpha(1);
draw_circle_prec(ex, ey, ui(4), 0);
for(var i = 0; i < 2; i++) {
if(point_in_circle(_m[0], _m[1], px[i], py[i], ui(20)))
hover_arc = false;
}
draw_set_color(hover_arc? COLORS.widget_rotator_range_hover : COLORS.widget_rotator_range);
draw_arc_th(_x, knob_y, _r, 3, _data[0], _data[1]);
#endregion
var px, py;
for(var i = 0; i < 2; i++) {
px[i] = _x + lengthdir_x(ui(36), _data[i]);
py[i] = knob_y + lengthdir_y(ui(36), _data[i]);
draw_sprite_ui_uniform(THEME.rotator_knob, 0, px[i], py[i]);
}
for(var i = 0; i < 2; i++)
draw_sprite(THEME.rotator_knob, 0, px[i], py[i]);
if(dragging > -1) {
var val = point_direction(_x, knob_y, _m[0], _m[1]);
@ -105,7 +95,7 @@ function rotatorRange(_onModify) : widget() constructor {
real_val = round(delta + drag_sv);
val = key_mod_press(CTRL)? round(real_val / 15) * 15 : real_val;
draw_sprite_ui_uniform(THEME.rotator_knob, 1, px[dragging], py[dragging]);
draw_sprite(THEME.rotator_knob, 1, px[dragging], py[dragging]);
if(_data[dragging] != val) {
var modi = false;
@ -132,8 +122,8 @@ function rotatorRange(_onModify) : widget() constructor {
}
} else if(hover) {
for(var i = 0; i < 2; i++) {
if(point_in_circle(_m[0], _m[1], px[i], py[i], ui(10))) {
draw_sprite_ui_uniform(THEME.rotator_knob, 1, px[i], py[i]);
if(point_in_circle(_m[0], _m[1], px[i], py[i], ui(20))) {
draw_sprite(THEME.rotator_knob, 1, px[i], py[i]);
if(mouse_press(mb_left, active)) {
dragging = i;
@ -150,9 +140,9 @@ function rotatorRange(_onModify) : widget() constructor {
}
}
draw_set_text(f_p0, fa_center, fa_center, COLORS._main_text);
draw_text(_x, knob_y - ui(12), string(_data[0]));
draw_text(_x, knob_y + ui(12), string(_data[1]));
//draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text);
//draw_text(_x, knob_y - ui(8), string(_data[0]));
//draw_text(_x, knob_y + ui(8), string(_data[1]));
resetFocus();
}

View file

@ -348,6 +348,7 @@ function functionStringClean(fx) {
}
function evaluateFunction(fx, params = {}) {
if(isNumber(fx)) return toNumber(fx);
return evaluateFunctionTree(fx).eval(params);
}
#endregion

View file

@ -11,10 +11,12 @@ function transformBox(_onModify) : widget() constructor {
onModifySingle[TRANSFORM.pos_x] = function(val) { onModify(TRANSFORM.pos_x, val); }
onModifySingle[TRANSFORM.pos_y] = function(val) { onModify(TRANSFORM.pos_y, val); }
onModifySingle[TRANSFORM.rot ] = function(val) { onModify(TRANSFORM.rot , val); }
onModifySingle[TRANSFORM.rot ] = function(val) { onModify(TRANSFORM.rot , val); } //unused
onModifySingle[TRANSFORM.sca_x] = function(val) { onModify(TRANSFORM.sca_x, val); }
onModifySingle[TRANSFORM.sca_y] = function(val) { onModify(TRANSFORM.sca_y, val); }
rot = new rotator(function(val) { onModify(TRANSFORM.rot , val); });
for(var i = 0; i < 5; i++) {
tb[i] = new textBox(TEXTBOX_INPUT.number, onModifySingle[i]);
tb[i].slidable = true;
@ -24,12 +26,16 @@ function transformBox(_onModify) : widget() constructor {
self.interactable = interactable;
for( var i = 0; i < array_length(tb); i++ )
tb[i].interactable = interactable;
tb[i].setInteract(interactable);
rot.setInteract(interactable);
}
static register = function(parent = noone) {
for( var i = 0; i < array_length(tb); i++ )
tb[i].register(parent);
tb[TRANSFORM.pos_x].register(parent);
tb[TRANSFORM.pos_y].register(parent);
rot.register(parent);
tb[TRANSFORM.sca_x].register(parent);
tb[TRANSFORM.sca_y].register(parent);
}
static drawParam = function(param) {
@ -40,30 +46,39 @@ function transformBox(_onModify) : widget() constructor {
x = _x;
y = _y;
w = _w;
h = ui(192);
h = ui(148);
rot.setFocusHover(active, hover);
for(var i = 0; i < array_length(_data); i++)
tb[i].setFocusHover(active, hover);
var tbh = TEXTBOX_HEIGHT;
var lbw = ui(80);
draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text_inner);
draw_text(_x + ui(8), _y + tbh / 2, "Position");
draw_text_add(_x, _y + tbh / 2, "Position");
var tbw = (_w - ui(64)) / 2 - ui(4);
tb[TRANSFORM.pos_x].draw(_x + ui(64), _y, tbw, tbh, _data[TRANSFORM.pos_x], _m);
tb[TRANSFORM.pos_y].draw(_x + ui(64 + 8) + tbw, _y, tbw, tbh, _data[TRANSFORM.pos_y], _m);
var tbw = (_w - lbw) / 2 - ui(4);
tb[TRANSFORM.pos_x].draw(_x + lbw, _y, tbw, tbh, _data[TRANSFORM.pos_x], _m);
tb[TRANSFORM.pos_y].draw(_x + lbw + ui(8) + tbw, _y, tbw, tbh, _data[TRANSFORM.pos_y], _m);
_y += ui(80);
_y += ui(40);
rot.draw(_x + _w / 2, _y, _data[TRANSFORM.rot], _m);
//draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text_inner);
//draw_text_add(_x + ui(8), _y + tbh / 2, "Rotation");
_y += ui(72);
draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text_inner);
draw_text(_x + ui(8), _y + tbh / 2, "Scale");
draw_text_add(_x, _y + tbh / 2, "Scale");
var tbw = array_length(_data) > 4? (_w - ui(64)) / 2 - ui(4) : _w - ui(64);
var tbw = array_length(_data) > 4? (_w - lbw) / 2 - ui(4) : _w - lbw;
tb[TRANSFORM.sca_x].draw(_x + ui(64), _y, tbw, tbh, _data[TRANSFORM.sca_x], _m);
tb[TRANSFORM.sca_x].draw(_x + lbw, _y, tbw, tbh, _data[TRANSFORM.sca_x], _m);
if(array_length(_data) > 4)
tb[TRANSFORM.sca_y].draw(_x + ui(64 + 8) + tbw, _y, tbw, tbh, _data[TRANSFORM.sca_y], _m);
tb[TRANSFORM.sca_y].draw(_x + lbw + ui(8) + tbw, _y, tbw, tbh, _data[TRANSFORM.sca_y], _m);
resetFocus();