From 3942a6c6e64998229e292d301ebcde8cb5e9b8bb Mon Sep 17 00:00:00 2001 From: Tanasart Date: Tue, 28 Jan 2025 17:32:44 +0700 Subject: [PATCH] [Line] Fix line cap rendering error. --- PixelComposer.resource_order | 59 ++-- PixelComposer.yyp | 1 + datafiles/data/Nodes/Internal.zip | Bin 9099746 -> 9100056 bytes .../Values/Path/Node_Path_3D_Camera/info.json | 8 + datafiles/data/Nodes/display_data.json | 1 + scripts/node_line/node_line.gml | 101 +++--- scripts/node_path/node_path.gml | 2 +- scripts/node_path_3d/node_path_3d.gml | 28 +- .../node_path_3d_camera.gml | 289 ++++++++++++++++++ .../node_path_3d_camera.yy | 13 + 10 files changed, 400 insertions(+), 102 deletions(-) create mode 100644 datafiles/data/Nodes/Internal/Values/Path/Node_Path_3D_Camera/info.json create mode 100644 scripts/node_path_3d_camera/node_path_3d_camera.gml create mode 100644 scripts/node_path_3d_camera/node_path_3d_camera.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 3e42d44c5..c146af096 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1006,34 +1006,35 @@ {"name":"node_palette_sort","order":2,"path":"scripts/node_palette_sort/node_palette_sort.yy",}, {"name":"node_palette","order":1,"path":"scripts/node_palette/node_palette.yy",}, {"name":"node_particle","order":10,"path":"scripts/node_particle/node_particle.yy",}, + {"name":"node_path_3d_camera","order":2,"path":"scripts/node_path_3d_camera/node_path_3d_camera.yy",}, {"name":"node_path_3d","order":1,"path":"scripts/node_path_3d/node_path_3d.yy",}, - {"name":"node_path_anchor","order":16,"path":"scripts/node_path_anchor/node_path_anchor.yy",}, - {"name":"node_path_array","order":14,"path":"scripts/node_path_array/node_path_array.yy",}, - {"name":"node_path_bake","order":19,"path":"scripts/node_path_bake/node_path_bake.yy",}, - {"name":"node_path_blend","order":5,"path":"scripts/node_path_blend/node_path_blend.yy",}, - {"name":"node_path_bridge","order":20,"path":"scripts/node_path_bridge/node_path_bridge.yy",}, - {"name":"node_path_builder","order":12,"path":"scripts/node_path_builder/node_path_builder.yy",}, - {"name":"node_path_fill","order":6,"path":"scripts/node_path_fill/node_path_fill.yy",}, - {"name":"node_path_from_mask","order":17,"path":"scripts/node_path_from_mask/node_path_from_mask.yy",}, - {"name":"node_path_l_system","order":13,"path":"scripts/node_path_l_system/node_path_l_system.yy",}, - {"name":"node_path_map_area","order":4,"path":"scripts/node_path_map_area/node_path_map_area.yy",}, - {"name":"node_path_map","order":21,"path":"scripts/node_path_map/node_path_map.yy",}, - {"name":"node_path_morph","order":22,"path":"scripts/node_path_morph/node_path_morph.yy",}, - {"name":"node_path_plot","order":15,"path":"scripts/node_path_plot/node_path_plot.yy",}, + {"name":"node_path_anchor","order":17,"path":"scripts/node_path_anchor/node_path_anchor.yy",}, + {"name":"node_path_array","order":15,"path":"scripts/node_path_array/node_path_array.yy",}, + {"name":"node_path_bake","order":20,"path":"scripts/node_path_bake/node_path_bake.yy",}, + {"name":"node_path_blend","order":6,"path":"scripts/node_path_blend/node_path_blend.yy",}, + {"name":"node_path_bridge","order":21,"path":"scripts/node_path_bridge/node_path_bridge.yy",}, + {"name":"node_path_builder","order":13,"path":"scripts/node_path_builder/node_path_builder.yy",}, + {"name":"node_path_fill","order":7,"path":"scripts/node_path_fill/node_path_fill.yy",}, + {"name":"node_path_from_mask","order":18,"path":"scripts/node_path_from_mask/node_path_from_mask.yy",}, + {"name":"node_path_l_system","order":14,"path":"scripts/node_path_l_system/node_path_l_system.yy",}, + {"name":"node_path_map_area","order":5,"path":"scripts/node_path_map_area/node_path_map_area.yy",}, + {"name":"node_path_map","order":22,"path":"scripts/node_path_map/node_path_map.yy",}, + {"name":"node_path_morph","order":23,"path":"scripts/node_path_morph/node_path_morph.yy",}, + {"name":"node_path_plot","order":16,"path":"scripts/node_path_plot/node_path_plot.yy",}, {"name":"node_path_profile","order":15,"path":"scripts/node_path_profile/node_path_profile.yy",}, - {"name":"node_path_repeat","order":26,"path":"scripts/node_path_repeat/node_path_repeat.yy",}, - {"name":"node_path_reverse","order":11,"path":"scripts/node_path_reverse/node_path_reverse.yy",}, - {"name":"node_path_sample","order":7,"path":"scripts/node_path_sample/node_path_sample.yy",}, - {"name":"node_path_scatter","order":25,"path":"scripts/node_path_scatter/node_path_scatter.yy",}, - {"name":"node_path_sdf","order":27,"path":"scripts/node_path_sdf/node_path_sdf.yy",}, + {"name":"node_path_repeat","order":27,"path":"scripts/node_path_repeat/node_path_repeat.yy",}, + {"name":"node_path_reverse","order":12,"path":"scripts/node_path_reverse/node_path_reverse.yy",}, + {"name":"node_path_sample","order":8,"path":"scripts/node_path_sample/node_path_sample.yy",}, + {"name":"node_path_scatter","order":26,"path":"scripts/node_path_scatter/node_path_scatter.yy",}, + {"name":"node_path_sdf","order":28,"path":"scripts/node_path_sdf/node_path_sdf.yy",}, {"name":"node_path_separate_folder","order":12,"path":"scripts/node_path_separate_folder/node_path_separate_folder.yy",}, - {"name":"node_path_shape","order":2,"path":"scripts/node_path_shape/node_path_shape.yy",}, - {"name":"node_path_shift","order":8,"path":"scripts/node_path_shift/node_path_shift.yy",}, - {"name":"node_path_smooth","order":24,"path":"scripts/node_path_smooth/node_path_smooth.yy",}, - {"name":"node_path_transform","order":3,"path":"scripts/node_path_transform/node_path_transform.yy",}, - {"name":"node_path_trim","order":9,"path":"scripts/node_path_trim/node_path_trim.yy",}, - {"name":"node_path_wave","order":10,"path":"scripts/node_path_wave/node_path_wave.yy",}, - {"name":"node_path_weight_adjust","order":30,"path":"scripts/node_path_weight_adjust/node_path_weight_adjust.yy",}, + {"name":"node_path_shape","order":3,"path":"scripts/node_path_shape/node_path_shape.yy",}, + {"name":"node_path_shift","order":9,"path":"scripts/node_path_shift/node_path_shift.yy",}, + {"name":"node_path_smooth","order":25,"path":"scripts/node_path_smooth/node_path_smooth.yy",}, + {"name":"node_path_transform","order":4,"path":"scripts/node_path_transform/node_path_transform.yy",}, + {"name":"node_path_trim","order":10,"path":"scripts/node_path_trim/node_path_trim.yy",}, + {"name":"node_path_wave","order":11,"path":"scripts/node_path_wave/node_path_wave.yy",}, + {"name":"node_path_weight_adjust","order":31,"path":"scripts/node_path_weight_adjust/node_path_weight_adjust.yy",}, {"name":"node_pb_box_contract","order":8,"path":"scripts/node_pb_box_contract/node_pb_box_contract.yy",}, {"name":"node_pb_box_divide_grid","order":7,"path":"scripts/node_pb_box_divide_grid/node_pb_box_divide_grid.yy",}, {"name":"node_pb_box_divide","order":5,"path":"scripts/node_pb_box_divide/node_pb_box_divide.yy",}, @@ -1123,7 +1124,7 @@ {"name":"node_scale","order":12,"path":"scripts/node_scale/node_scale.yy",}, {"name":"node_scatter_points","order":7,"path":"scripts/node_scatter_points/node_scatter_points.yy",}, {"name":"node_scatter","order":13,"path":"scripts/node_scatter/node_scatter.yy",}, - {"name":"node_segment_filter","order":29,"path":"scripts/node_segment_filter/node_segment_filter.yy",}, + {"name":"node_segment_filter","order":30,"path":"scripts/node_segment_filter/node_segment_filter.yy",}, {"name":"node_separate_color","order":42,"path":"scripts/node_separate_color/node_separate_color.yy",}, {"name":"node_sequence_anim","order":6,"path":"scripts/node_sequence_anim/node_sequence_anim.yy",}, {"name":"node_shadow_cast","order":28,"path":"scripts/node_shadow_cast/node_shadow_cast.yy",}, @@ -1660,7 +1661,7 @@ {"name":"sh_grid","order":3,"path":"shaders/sh_grid/sh_grid.yy",}, {"name":"sh_herringbone_tile","order":15,"path":"shaders/sh_herringbone_tile/sh_herringbone_tile.yy",}, {"name":"sh_high_pass","order":32,"path":"shaders/sh_high_pass/sh_high_pass.yy",}, - {"name":"sh_image_trace","order":18,"path":"shaders/sh_image_trace/sh_image_trace.yy",}, + {"name":"sh_image_trace","order":19,"path":"shaders/sh_image_trace/sh_image_trace.yy",}, {"name":"sh_interlaced","order":51,"path":"shaders/sh_interlaced/sh_interlaced.yy",}, {"name":"sh_interpret_number","order":9,"path":"shaders/sh_interpret_number/sh_interpret_number.yy",}, {"name":"sh_invert","order":17,"path":"shaders/sh_invert/sh_invert.yy",}, @@ -1737,8 +1738,8 @@ {"name":"sh_palette_replace","order":9,"path":"shaders/sh_palette_replace/sh_palette_replace.yy",}, {"name":"sh_palette_shift","order":31,"path":"shaders/sh_palette_shift/sh_palette_shift.yy",}, {"name":"sh_path_fill_profile","order":16,"path":"shaders/sh_path_fill_profile/sh_path_fill_profile.yy",}, - {"name":"sh_path_morph","order":23,"path":"shaders/sh_path_morph/sh_path_morph.yy",}, - {"name":"sh_path_sdf","order":28,"path":"shaders/sh_path_sdf/sh_path_sdf.yy",}, + {"name":"sh_path_morph","order":24,"path":"shaders/sh_path_morph/sh_path_morph.yy",}, + {"name":"sh_path_sdf","order":29,"path":"shaders/sh_path_sdf/sh_path_sdf.yy",}, {"name":"sh_pb_blob","order":1,"path":"shaders/sh_pb_blob/sh_pb_blob.yy",}, {"name":"sh_pb_brick","order":9,"path":"shaders/sh_pb_brick/sh_pb_brick.yy",}, {"name":"sh_pb_draw_mask","order":8,"path":"shaders/sh_pb_draw_mask/sh_pb_draw_mask.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index c4b98a7fa..ccf557c18 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -2202,6 +2202,7 @@ {"id":{"name":"node_palette_sort","path":"scripts/node_palette_sort/node_palette_sort.yy",},}, {"id":{"name":"node_palette","path":"scripts/node_palette/node_palette.yy",},}, {"id":{"name":"node_particle","path":"scripts/node_particle/node_particle.yy",},}, + {"id":{"name":"node_path_3d_camera","path":"scripts/node_path_3d_camera/node_path_3d_camera.yy",},}, {"id":{"name":"node_path_3d","path":"scripts/node_path_3d/node_path_3d.yy",},}, {"id":{"name":"node_path_anchor","path":"scripts/node_path_anchor/node_path_anchor.yy",},}, {"id":{"name":"node_path_array","path":"scripts/node_path_array/node_path_array.yy",},}, diff --git a/datafiles/data/Nodes/Internal.zip b/datafiles/data/Nodes/Internal.zip index 54c00c634d26c8f832d617af42c7ba8fc95b37a3..3220fea338f769bf365205ee07ba59a686aa127c 100644 GIT binary patch delta 3650 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/ {return new __vec2P(x, y, weight)}; + static toString = function() { return $"[__vec2P] ({x}, {y} | {weight})"; } } function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { diff --git a/scripts/node_path_3d/node_path_3d.gml b/scripts/node_path_3d/node_path_3d.gml index 291458390..741f30252 100644 --- a/scripts/node_path_3d/node_path_3d.gml +++ b/scripts/node_path_3d/node_path_3d.gml @@ -13,6 +13,11 @@ enum _ANCHOR3 { amount } +function __vec3P(_x = 0, _y = _x, _z = _x, _w = 1) : __vec3(_x, _y, _z) constructor { + weight = _w; + static clone = function() /*=>*/ {return new __vec3P(x, y, z, weight)}; +} + function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "3D Path"; is_3D = NODE_3D.polygon; @@ -579,15 +584,14 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor // surface_free(_surf); } - static getLineCount = function() { return 1; } - static getSegmentCount = function() { return array_length(lengths); } - static getBoundary = function() { return boundary; } - - static getLength = function() { return lengthTotal; } - static getAccuLength = function() { return lengthAccs; } + static getLineCount = function() /*=>*/ {return 1}; + static getSegmentCount = function() /*=>*/ {return array_length(lengths)}; + static getBoundary = function() /*=>*/ {return boundary}; + static getLength = function() /*=>*/ {return lengthTotal}; + static getAccuLength = function() /*=>*/ {return lengthAccs}; static getPointDistance = function(_dist, _ind = 0, out = undefined) { - if(out == undefined) out = new __vec3(); else { out.x = 0; out.y = 0; out.z = 0; } + if(out == undefined) out = new __vec3P(); else { out.x = 0; out.y = 0; out.z = 0; } if(array_empty(lengths)) return out; var _cKey = _dist; @@ -630,7 +634,7 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } - cached_pos[? _cKey] = new __vec3(out.x, out.y, out.z); + cached_pos[? _cKey] = new __vec3P(out.x, out.y, out.z); return out; } @@ -643,19 +647,19 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } static getPointSegment = function(_rat) { - if(array_empty(lengths)) return new __vec3(); + if(array_empty(lengths)) return new __vec3P(); var loop = getInputData(1); var ansize = array_length(inputs) - input_fix_len; - if(_rat < 0) return new __vec3(anchors[0][0], anchors[0][1], anchors[0][2]); + if(_rat < 0) return new __vec3P(anchors[0][0], anchors[0][1], anchors[0][2]); _rat = safe_mod(_rat, ansize); var _i0 = clamp(floor(_rat), 0, ansize - 1); var _i1 = (_i0 + 1) % ansize; var _t = frac(_rat); - if(_i1 >= ansize && !loop) return new __vec3(anchors[ansize - 1][0], anchors[ansize - 1][1], anchors[ansize - 1][2]); + if(_i1 >= ansize && !loop) return new __vec3P(anchors[ansize - 1][0], anchors[ansize - 1][1], anchors[ansize - 1][2]); var _a0 = anchors[_i0]; var _a1 = anchors[_i1]; @@ -673,7 +677,7 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } - return new __vec3(px, py, pz); + return new __vec3P(px, py, pz); } static update = function(frame = CURRENT_FRAME) { diff --git a/scripts/node_path_3d_camera/node_path_3d_camera.gml b/scripts/node_path_3d_camera/node_path_3d_camera.gml new file mode 100644 index 000000000..6693a96fb --- /dev/null +++ b/scripts/node_path_3d_camera/node_path_3d_camera.gml @@ -0,0 +1,289 @@ +function Node_Path_3D_Camera(_x, _y, _group = noone) : Node_3D_Object(_x, _y, _group) constructor { + name = "3D Path Camera"; + batch_output = true; + + object = new __3dCamera_object(); + camera = new __3dCamera(); + lookat = new __3dGizmoSphere(0.5, c_ltgray, 1); + lookLine = noone; + lookRad = new __3dGizmoCircleZ(0.5, c_yellow, 0.5); + + w = 128; + var i = in_d3d; + + setDimension(96, 48); + + newInput(i+0, nodeValue_Int("FOV", self, 60 )) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 10, 90, 0.1 ] }); + + newInput(i+1, nodeValue_Enum_Button("Projection", self, 1 , [ "Perspective", "Orthographic" ])); + + newInput(i+2, nodeValue_PathNode("Path", self, noone )) + .setVisible(true, true); + + newInput(i+3, nodeValue_Float("Orthographic Scale", self, 0.5 )) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 0.01, 4, 0.01 ] }); + + newInput(i+4, nodeValue_Enum_Scroll("Postioning Mode", self, 2, [ "Position + Rotation", "Position + Lookat", "Lookat + Rotation" ] )); + + newInput(i+5, nodeValue_Vec3("Lookat Position", self, [ 0, 0, 0 ] )); + + newInput(i+6, nodeValue_Rotation("Roll", self, 0)); + + newInput(i+7, nodeValue_Rotation("Horizontal Angle", self, 45 )); + + newInput(i+8, nodeValue_Float("Vertical Angle", self, 30 )) + .setDisplay(VALUE_DISPLAY.slider, { range: [0, 90, 0.1] }); + + newInput(i+9, nodeValue_Float("Distance", self, 4 )); + + newInput(i+10, nodeValue_Dimension(self)); + + newInput(i+11, nodeValue_Bool("Apply depth to weight", self, false)); + + newInput(i+12, nodeValue_Vec2("Depth range", self, [ 0.1, 100 ])); + + in_cam = array_length(inputs); + + newOutput(0, nodeValue_Output("Rendered", self, VALUE_TYPE.pathnode, self )); + + input_display_list = [ i+2, i+10, + ["Transform", false], i+4, 0, 1, i+5, i+6, i+7, i+8, i+9, + ["Camera", false], i+1, i+0, i+3, + ["Output", false], i+11, i+12, + ]; + + tool_lookat = new NodeTool( "Move Target", THEME.tools_3d_transform_object ); + + #region current data + cached_pos = ds_map_create(); + + is_path = false; + + curr_pos = noone; + curr_rot = noone; + + curr_fov = noone; + curr_proj = noone; + curr_path = noone; + curr_orts = noone; + + curr_posm = noone; + curr_look = noone; + curr_roll = noone; + curr_hAng = noone; + curr_vAng = noone; + curr_dist = noone; + curr_scal = [ 1, 1 ]; + curr_weig = false; + curr_dept = [ 1, 1 ]; + + curr_qi1 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(0, 1, 0), 90); + curr_qi2 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), -90); + curr_qi3 = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), 90); + #endregion + + ////- Preview + + static getToolSettings = function() { return curr_posm == 0? tool_settings : []; } + + static drawOverlay3D = function(active, params, _mx, _my, _snx, _sny, _panel) { + var preObj = getPreviewObjects(); + if(array_empty(preObj)) return; + preObj = preObj[0]; + + var _pos = inputs[0].getValue(,,, true); + var _vpos = new __vec3( _pos[0], _pos[1], _pos[2] ); + + if(isUsingTool("Transform")) drawGizmoPosition(0, preObj, _vpos, active, params, _mx, _my, _snx, _sny, _panel); + else if(isUsingTool("Rotate")) drawGizmoRotation(1, preObj, _vpos, active, params, _mx, _my, _snx, _sny, _panel); + else if(isUsingTool("Move Target")) { + var _lkpos = inputs[in_d3d + 5].getValue(,,, true); + var _lkvpos = new __vec3( _lkpos[0], _lkpos[1], _lkpos[2] ); + + drawGizmoPosition(in_d3d + 5, noone, _lkvpos, active, params, _mx, _my, _snx, _sny, _panel); + } + + if(drag_axis != noone && mouse_release(mb_left)) { + drag_axis = noone; + UNDO_HOLDING = false; + } + } + + ////- Path + + static getLineCount = function( ) /*=>*/ {return is_path? curr_path.getLineCount() : 1}; + static getSegmentCount = function(i=0) /*=>*/ {return is_path? curr_path.getSegmentCount(i) : 0}; + static getLength = function(i=0) /*=>*/ {return is_path? curr_path.getLength(i) : 0}; + static getAccuLength = function(i=0) /*=>*/ {return is_path? curr_path.getAccuLength(i) : []}; + static getBoundary = function(i=0) /*=>*/ {return is_path? curr_path.getBoundary(i) : new BoundingBox( 0, 0, 1, 1 )}; + + static getPointRatio = function(_rat, ind = 0, out = undefined) { + if(out == undefined) out = new __vec2P(); else { out.x = 0; out.y = 0; } + + var _cKey = $"{string_format(_rat, 0, 6)},{ind}"; + if(ds_map_exists(cached_pos, _cKey)) { + var _p = cached_pos[? _cKey]; + out.x = _p.x; + out.y = _p.y; + out.weight = _p.weight; + return out; + } + + if(!is_path) return out; + + var _p = curr_path.getPointRatio(_rat, ind); + var _w = _p.weight; + var _v = camera.worldPointToViewPoint(_p); + + out.x = _v.x * curr_scal[0] / 2; + out.y = _v.y * curr_scal[1] / 2; + out.weight = curr_weig? _v.z : _p.weight; + + cached_pos[? _cKey] = new __vec2P(out.x, out.y, out.weight); + + return out; + } + + static getPointDistance = function(_dist, ind = 0, out = undefined) { return getPointRatio(_dist / getLength(), ind, out); } + + ////- Update + + static onValueUpdate = function(index) { if(index == in_d3d + 4) PANEL_PREVIEW.tool_current = noone; } + + static step = function() { + inputs[in_d3d + 0].setVisible(curr_proj == 0); + inputs[in_d3d + 3].setVisible(curr_proj == 1); + + inputs[0].setVisible(curr_posm == 0 || curr_posm == 1); + inputs[1].setVisible(curr_posm == 0); + inputs[in_d3d + 5].setVisible(curr_posm == 1 || curr_posm == 2); + inputs[in_d3d + 6].setVisible(curr_posm == 1); + inputs[in_d3d + 7].setVisible(curr_posm == 2); + inputs[in_d3d + 8].setVisible(curr_posm == 2); + inputs[in_d3d + 9].setVisible(curr_posm == 2); + + switch(curr_posm) { + case 0 : + tools = [ tool_pos, tool_rot ]; + break; + + case 1 : + tools = [ tool_pos, tool_lookat ]; + tool_attribute.context = 1; + break; + + case 2 : + tools = [ tool_lookat ]; + tool_attribute.context = 1; + break; + } + } + + static preProcessData = function(_data) /*=>*/ {} + static submitShadow = function() /*=>*/ {} + static submitShader = function() /*=>*/ {} + + static processData = function(_outData, _data, _output_index, _array_index = 0) { + #region data + curr_pos = _data[0]; + curr_rot = _data[1]; + + curr_fov = _data[in_d3d + 0]; + curr_proj = _data[in_d3d + 1]; + curr_path = _data[in_d3d + 2]; + curr_orts = _data[in_d3d + 3]; + + curr_posm = _data[in_d3d + 4]; + curr_look = _data[in_d3d + 5]; + curr_roll = _data[in_d3d + 6]; + curr_hAng = _data[in_d3d + 7]; + curr_vAng = _data[in_d3d + 8]; + curr_dist = _data[in_d3d + 9]; + curr_scal = _data[in_d3d +10]; + curr_weig = _data[in_d3d +11]; + curr_dept = _data[in_d3d +12]; + #endregion + + switch(curr_posm) { // ++++ camera positioning ++++ + case 0 : + camera.useFocus = false; + camera.position.set(curr_pos); + camera.rotation.set(curr_rot[0], curr_rot[1], curr_rot[2], curr_rot[3]); + break; + + case 1 : + camera.useFocus = true; + camera.position.set(curr_pos); + camera.focus.set(curr_look); + camera.up.set(0, 0, -1); + + var _for = camera.focus.subtract(camera.position); + if(!_for.isZero()) camera.rotation = new BBMOD_Quaternion().FromLookRotation(_for, camera.up).Mul(curr_qi1).Mul(curr_qi2); + + lookat.transform.position.set(curr_look); + lookLine = new __3dGizmoLineDashed(camera.position, camera.focus, 0.25, c_gray, 1); + break; + + case 2 : + camera.useFocus = true; + camera.focus.set(curr_look); + camera.setFocusAngle(curr_hAng, curr_vAng, curr_dist); + camera.setCameraLookRotate(); + camera.up = camera.getUp()._multiply(-1); + + var _for = camera.focus.subtract(camera.position); + if(!_for.isZero()) camera.rotation = new BBMOD_Quaternion().FromLookRotation(_for, camera.up.multiply(-1)).Mul(curr_qi1).Mul(curr_qi3); + + lookat.transform.position.set(curr_look); + lookLine = new __3dGizmoLineDashed(camera.position, camera.focus, 0.25, c_gray, 1); + + var _camRad = camera.position.subtract(camera.focus); + var _rad = point_distance(0, 0, _camRad.x, _camRad.y) * 2; + lookRad.transform.scale.set(_rad, _rad, 1); + lookRad.transform.position.set(new __vec3(camera.focus.x, camera.focus.y, camera.position.z)); + break; + } + + #region camera view project + object.transform.position.set(camera.position); + object.transform.rotation = camera.rotation.Clone(); + + camera.projection = curr_proj; + camera.setViewFov(curr_fov, curr_dept[0], curr_dept[1]); + + if(curr_proj == 0) camera.setViewSize(curr_scal[0], curr_scal[1]); + else if(curr_proj == 1) camera.setViewSize(1 / curr_orts, curr_scal[0] / curr_scal[1] / curr_orts); + + camera.setMatrix(); + #endregion + + is_path = curr_path != noone && struct_has(curr_path, "getPointRatio"); + ds_map_clear(cached_pos); + return self; + } + + ////- Draw + + static getGraphPreviewSurface = function() { return noone; } + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + var bbox = drawGetBbox(xx, yy, _s); + draw_sprite_bbox_uniform(s_node_path_3d, 0, bbox); + } + + static getPreviewObject = function() { return noone; } + + static getPreviewObjects = function() { + switch(curr_posm) { + case 0 : return [ object ]; + case 1 : return [ object, lookat, lookLine ]; + case 2 : return [ object, lookat, lookLine, lookRad ]; + } + + return [ object ]; + } + + static getPreviewObjectOutline = function() { return isUsingTool("Move Target")? [ lookat ] : [ object ]; } + +} \ No newline at end of file diff --git a/scripts/node_path_3d_camera/node_path_3d_camera.yy b/scripts/node_path_3d_camera/node_path_3d_camera.yy new file mode 100644 index 000000000..fd62eb3e1 --- /dev/null +++ b/scripts/node_path_3d_camera/node_path_3d_camera.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"node_path_3d_camera", + "isCompatibility":false, + "isDnD":false, + "name":"node_path_3d_camera", + "parent":{ + "name":"path", + "path":"folders/nodes/data/value/path.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file