2023-03-29 15:02:03 +02:00
|
|
|
function Node_Warp_Perspective(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
|
|
|
|
name = "Perspective Warp";
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[0] = nodeValue_Surface("Surface in", self);
|
2023-03-29 15:02:03 +02:00
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[1] = nodeValue_Bool("Active", self, true);
|
2023-03-29 15:02:03 +02:00
|
|
|
active_index = 1;
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[2] = nodeValue_Vec2("Top left", self, [ 0, 0 ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[3] = nodeValue_Vec2("Top right", self, [ DEF_SURF_W, 0 ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[4] = nodeValue_Vec2("Bottom left", self, [ 0, DEF_SURF_H ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[5] = nodeValue_Vec2("Bottom right", self, DEF_SURF )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[6] = nodeValue_Vec2("Top left", self, [ 0, 0 ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[7] = nodeValue_Vec2("Top right", self, [ DEF_SURF_W, 0 ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[8] = nodeValue_Vec2("Bottom left", self, [ 0, DEF_SURF_H ] )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-12 13:42:05 +02:00
|
|
|
inputs[9] = nodeValue_Vec2("Bottom right", self, DEF_SURF )
|
2023-03-29 15:02:03 +02:00
|
|
|
.setUnitRef(function(index) { return getDimension(index); });
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
outputs[0] = nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone);
|
2023-03-29 15:02:03 +02:00
|
|
|
|
|
|
|
input_display_list = [ 1,
|
2023-11-08 14:37:51 +01:00
|
|
|
["Surfaces", false], 0,
|
2023-03-29 15:02:03 +02:00
|
|
|
["Origin", false], 2, 3, 4, 5,
|
|
|
|
["Warp", false], 6, 7, 8, 9,
|
|
|
|
]
|
|
|
|
|
|
|
|
attribute_surface_depth();
|
|
|
|
attribute_interpolation();
|
|
|
|
|
|
|
|
drag_side = -1;
|
|
|
|
drag_mx = 0;
|
|
|
|
drag_my = 0;
|
|
|
|
drag_s = [[0, 0], [0, 0]];
|
|
|
|
|
2024-03-14 14:35:19 +01:00
|
|
|
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
|
2024-05-10 04:01:14 +02:00
|
|
|
PROCESSOR_OVERLAY_CHECK
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
if(array_length(current_data) < array_length(inputs)) return;
|
2023-03-29 15:02:03 +02:00
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
var _surf = outputs[0].getValue();
|
2023-03-29 15:02:03 +02:00
|
|
|
if(is_array(_surf)) {
|
|
|
|
if(array_length(_surf) == 0) return;
|
|
|
|
_surf = _surf[preview_index];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(drag_side > -1) {
|
|
|
|
dx = (_mx - drag_mx) / _s;
|
|
|
|
dy = (_my - drag_my) / _s;
|
|
|
|
|
|
|
|
if(mouse_release(mb_left)) {
|
|
|
|
drag_side = -1;
|
|
|
|
UNDO_HOLDING = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var tool = 1;
|
|
|
|
|
2023-09-14 16:29:39 +02:00
|
|
|
var tl = array_clone(current_data[tool * 4 + 2]);
|
|
|
|
var tr = array_clone(current_data[tool * 4 + 3]);
|
|
|
|
var bl = array_clone(current_data[tool * 4 + 4]);
|
|
|
|
var br = array_clone(current_data[tool * 4 + 5]);
|
2023-03-29 15:02:03 +02:00
|
|
|
|
|
|
|
tl[0] = _x + tl[0] * _s;
|
|
|
|
tr[0] = _x + tr[0] * _s;
|
|
|
|
bl[0] = _x + bl[0] * _s;
|
|
|
|
br[0] = _x + br[0] * _s;
|
|
|
|
|
|
|
|
tl[1] = _y + tl[1] * _s;
|
|
|
|
tr[1] = _y + tr[1] * _s;
|
|
|
|
bl[1] = _y + bl[1] * _s;
|
|
|
|
br[1] = _y + br[1] * _s;
|
|
|
|
|
|
|
|
draw_set_color(COLORS._main_accent);
|
|
|
|
draw_line(tl[0], tl[1], tr[0], tr[1]);
|
|
|
|
draw_line(tl[0], tl[1], bl[0], bl[1]);
|
|
|
|
draw_line(br[0], br[1], tr[0], tr[1]);
|
|
|
|
draw_line(br[0], br[1], bl[0], bl[1]);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
if(inputs[tool * 4 + 2].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false;
|
|
|
|
if(inputs[tool * 4 + 3].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false;
|
|
|
|
if(inputs[tool * 4 + 4].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false;
|
|
|
|
if(inputs[tool * 4 + 5].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny)) active = false;
|
2023-03-29 15:02:03 +02:00
|
|
|
|
|
|
|
var dx = 0;
|
|
|
|
var dy = 0;
|
|
|
|
|
|
|
|
draw_set_color(COLORS.node_overlay_gizmo_inactive);
|
|
|
|
if(drag_side == tool * 4 + 2) {
|
|
|
|
draw_line_width(tl[0], tl[1], tr[0], tr[1], 3);
|
|
|
|
|
|
|
|
var _tlx = value_snap(drag_s[0][0] + dx, _snx);
|
|
|
|
var _tly = value_snap(drag_s[0][1] + dy, _sny);
|
|
|
|
|
|
|
|
var _trx = value_snap(drag_s[1][0] + dx, _snx);
|
|
|
|
var _try = value_snap(drag_s[1][1] + dy, _sny);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[tool * 4 + 2].setValue([ _tlx, _tly ])
|
|
|
|
if(inputs[tool * 4 + 3].setValue([ _trx, _try ])) UNDO_HOLDING = true;
|
2023-03-29 15:02:03 +02:00
|
|
|
} else if(drag_side == tool * 4 + 3) {
|
|
|
|
draw_line_width(tl[0], tl[1], bl[0], bl[1], 3);
|
|
|
|
|
|
|
|
var _tlx = value_snap(drag_s[0][0] + dx, _snx);
|
|
|
|
var _tly = value_snap(drag_s[0][1] + dy, _sny);
|
|
|
|
|
|
|
|
var _blx = value_snap(drag_s[1][0] + dx, _snx);
|
|
|
|
var _bly = value_snap(drag_s[1][1] + dy, _sny);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[tool * 4 + 2].setValue([ _tlx, _tly ]);
|
|
|
|
if(inputs[tool * 4 + 4].setValue([ _blx, _bly ])) UNDO_HOLDING = true;
|
2023-03-29 15:02:03 +02:00
|
|
|
} else if(drag_side == tool * 4 + 4) {
|
|
|
|
draw_line_width(br[0], br[1], tr[0], tr[1], 3);
|
|
|
|
|
|
|
|
var _brx = value_snap(drag_s[0][0] + dx, _snx);
|
|
|
|
var _bry = value_snap(drag_s[0][1] + dy, _sny);
|
|
|
|
|
|
|
|
var _trx = value_snap(drag_s[1][0] + dx, _snx);
|
|
|
|
var _try = value_snap(drag_s[1][1] + dy, _sny);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[tool * 4 + 5].setValue([ _brx, _bry ]);
|
|
|
|
if(inputs[tool * 4 + 3].setValue([ _trx, _try ])) UNDO_HOLDING = true;
|
2023-03-29 15:02:03 +02:00
|
|
|
} else if(drag_side == tool * 4 + 5) {
|
|
|
|
draw_line_width(br[0], br[1], bl[0], bl[1], 3);
|
|
|
|
|
|
|
|
var _brx = value_snap(drag_s[0][0] + dx, _snx);
|
|
|
|
var _bry = value_snap(drag_s[0][1] + dy, _sny);
|
|
|
|
|
|
|
|
var _blx = value_snap(drag_s[1][0] + dx, _snx);
|
|
|
|
var _bly = value_snap(drag_s[1][1] + dy, _sny);
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[tool * 4 + 5].setValue([ _brx, _bry ]);
|
|
|
|
if(inputs[tool * 4 + 4].setValue([ _blx, _bly ])) UNDO_HOLDING = true;
|
2023-03-29 15:02:03 +02:00
|
|
|
} else if(active) {
|
|
|
|
draw_set_color(COLORS._main_accent);
|
|
|
|
if(distance_to_line_infinite(_mx, _my, tl[0], tl[1], tr[0], tr[1]) < 12) {
|
|
|
|
draw_line_width(tl[0], tl[1], tr[0], tr[1], 3);
|
|
|
|
if(mouse_press(mb_left, active)) {
|
|
|
|
drag_side = tool * 4 + 2;
|
|
|
|
drag_mx = _mx;
|
|
|
|
drag_my = _my;
|
|
|
|
drag_s = [ current_data[tool * 4 + 2], current_data[tool * 4 + 3] ];
|
|
|
|
}
|
|
|
|
} else if(distance_to_line_infinite(_mx, _my, tl[0], tl[1], bl[0], bl[1]) < 12) {
|
|
|
|
draw_line_width(tl[0], tl[1], bl[0], bl[1], 3);
|
|
|
|
if(mouse_press(mb_left, active)) {
|
|
|
|
drag_side = tool * 4 + 3;
|
|
|
|
drag_mx = _mx;
|
|
|
|
drag_my = _my;
|
|
|
|
drag_s = [ current_data[tool * 4 + 2], current_data[tool * 4 + 4] ];
|
|
|
|
}
|
|
|
|
} else if(distance_to_line_infinite(_mx, _my, br[0], br[1], tr[0], tr[1]) < 12) {
|
|
|
|
draw_line_width(br[0], br[1], tr[0], tr[1], 3);
|
|
|
|
if(mouse_press(mb_left, active)) {
|
|
|
|
drag_side = tool * 4 + 4;
|
|
|
|
drag_mx = _mx;
|
|
|
|
drag_my = _my;
|
|
|
|
drag_s = [ current_data[tool * 4 + 5], current_data[tool * 4 + 3] ];
|
|
|
|
}
|
|
|
|
} else if(distance_to_line_infinite(_mx, _my, br[0], br[1], bl[0], bl[1]) < 12) {
|
|
|
|
draw_line_width(br[0], br[1], bl[0], bl[1], 3);
|
|
|
|
if(mouse_press(mb_left, active)) {
|
|
|
|
drag_side = tool * 4 + 5;
|
|
|
|
drag_mx = _mx;
|
|
|
|
drag_my = _my;
|
|
|
|
drag_s = [ current_data[tool * 4 + 5], current_data[tool * 4 + 4] ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[tool * 4 + 2].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
|
|
|
inputs[tool * 4 + 3].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
|
|
|
inputs[tool * 4 + 4].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
|
|
|
inputs[tool * 4 + 5].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
2023-03-29 15:02:03 +02:00
|
|
|
}
|
|
|
|
|
2023-08-17 16:56:54 +02:00
|
|
|
static processData = function(_outSurf, _data, _output_index, _array_index) {
|
2023-03-29 15:02:03 +02:00
|
|
|
var Ftl = _data[2];
|
|
|
|
var Ftr = _data[3];
|
|
|
|
var Fbl = _data[4];
|
|
|
|
var Fbr = _data[5];
|
|
|
|
|
|
|
|
var Ttl = _data[6];
|
|
|
|
var Ttr = _data[7];
|
|
|
|
var Tbl = _data[8];
|
|
|
|
var Tbr = _data[9];
|
|
|
|
|
2023-09-08 21:37:36 +02:00
|
|
|
var sw = surface_get_width_safe(_data[0]);
|
|
|
|
var sh = surface_get_height_safe(_data[0]);
|
2023-03-29 15:02:03 +02:00
|
|
|
|
|
|
|
surface_set_shader(_outSurf, sh_warp_4points_pers);
|
|
|
|
shader_set_interpolation(_data[0]);
|
|
|
|
shader_set_f("f1", Fbr[0] / sw, Fbr[1] / sh);
|
|
|
|
shader_set_f("f2", Ftr[0] / sw, Ftr[1] / sh);
|
|
|
|
shader_set_f("f3", Ftl[0] / sw, Ftl[1] / sh);
|
|
|
|
shader_set_f("f4", Fbl[0] / sw, Fbl[1] / sh);
|
|
|
|
|
|
|
|
shader_set_f("t1", Tbr[0] / sw, Tbr[1] / sh);
|
|
|
|
shader_set_f("t2", Ttr[0] / sw, Ttr[1] / sh);
|
|
|
|
shader_set_f("t3", Ttl[0] / sw, Ttl[1] / sh);
|
|
|
|
shader_set_f("t4", Tbl[0] / sw, Tbl[1] / sh);
|
|
|
|
|
2024-07-10 03:45:25 +02:00
|
|
|
draw_surface_safe(_data[0]);
|
2023-03-29 15:02:03 +02:00
|
|
|
surface_reset_shader();
|
|
|
|
|
|
|
|
return _outSurf;
|
|
|
|
}
|
|
|
|
}
|