function Node_Warp_Perspective(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { name = "Perspective Warp"; newInput(0, nodeValue_Surface("Surface in", self)); newInput(1, nodeValue_Bool("Active", self, true)); active_index = 1; newInput(2, nodeValue_Vec2("Top left", self, [ 0, 0 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(3, nodeValue_Vec2("Top right", self, [ 1, 0 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(4, nodeValue_Vec2("Bottom left", self, [ 0, 1 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(5, nodeValue_Vec2("Bottom right", self, [ 1, 1 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(6, nodeValue_Vec2("Top left", self, [ 0, 0 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(7, nodeValue_Vec2("Top right", self, [ 1, 0 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(8, nodeValue_Vec2("Bottom left", self, [ 0, 1 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); newInput(9, nodeValue_Vec2("Bottom right", self, [ 1, 1 ] )) .setUnitRef(function(index) /*=>*/ {return getDimension(index)}, VALUE_UNIT.reference); outputs[0] = nodeValue_Output("Surface out", self, VALUE_TYPE.surface, noone); input_display_list = [ 1, ["Surfaces", false], 0, ["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]]; static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { PROCESSOR_OVERLAY_CHECK if(array_length(current_data) < array_length(inputs)) return; var _surf = outputs[0].getValue(); 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; 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]); 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]); 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; 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); inputs[tool * 4 + 2].setValue([ _tlx, _tly ]) if(inputs[tool * 4 + 3].setValue([ _trx, _try ])) UNDO_HOLDING = true; } 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); inputs[tool * 4 + 2].setValue([ _tlx, _tly ]); if(inputs[tool * 4 + 4].setValue([ _blx, _bly ])) UNDO_HOLDING = true; } 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); inputs[tool * 4 + 5].setValue([ _brx, _bry ]); if(inputs[tool * 4 + 3].setValue([ _trx, _try ])) UNDO_HOLDING = true; } 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); inputs[tool * 4 + 5].setValue([ _brx, _bry ]); if(inputs[tool * 4 + 4].setValue([ _blx, _bly ])) UNDO_HOLDING = true; } 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] ]; } } } 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); } static processData = function(_outSurf, _data, _output_index, _array_index) { var tl = _data[6]; var tr = _data[7]; var bl = _data[8]; var br = _data[9]; var sw = surface_get_width_safe(_data[0]); var sh = surface_get_height_safe(_data[0]); surface_set_shader(_outSurf, sh_warp_4points_pers); shader_set_interpolation(_data[0]); shader_set_f("t1", tl[0] / sw, tl[1] / sh); shader_set_f("t2", tr[0] / sw, tr[1] / sh); shader_set_f("t3", bl[0] / sw, bl[1] / sh); shader_set_f("t4", br[0] / sw, br[1] / sh); draw_surface_safe(_data[0]); surface_reset_shader(); return _outSurf; } }