diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 1e68ae0e6..2aa7b2880 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -698,7 +698,7 @@ {"name":"buttonColor","order":3,"path":"scripts/buttonColor/buttonColor.yy",}, {"name":"notification_system","order":7,"path":"scripts/notification_system/notification_system.yy",}, {"name":"buffer_object","order":1,"path":"scripts/buffer_object/buffer_object.yy",}, - {"name":"node_3d_mesh_sphere","order":4,"path":"scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.yy",}, + {"name":"node_3d_mesh_uvsphere","order":4,"path":"scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.yy",}, {"name":"s_node_audio_trim","order":3,"path":"sprites/s_node_audio_trim/s_node_audio_trim.yy",}, {"name":"s_node_pb_fx_highlight","order":7,"path":"sprites/s_node_pb_fx_highlight/s_node_pb_fx_highlight.yy",}, {"name":"node_color_from_hsv","order":8,"path":"scripts/node_color_from_hsv/node_color_from_hsv.yy",}, @@ -797,6 +797,7 @@ {"name":"clipboard","order":9,"path":"extensions/clipboard/clipboard.yy",}, {"name":"__node_3d_light","order":1,"path":"scripts/__node_3d_light/__node_3d_light.yy",}, {"name":"rotator","order":11,"path":"scripts/rotator/rotator.yy",}, + {"name":"d3d_icosphere","order":4,"path":"scripts/d3d_icosphere/d3d_icosphere.yy",}, {"name":"s_node_edge_detect","order":22,"path":"sprites/s_node_edge_detect/s_node_edge_detect.yy",}, {"name":"node_fluid_add_collider","order":6,"path":"scripts/node_fluid_add_collider/node_fluid_add_collider.yy",}, {"name":"node_atlas_get","order":1,"path":"scripts/node_atlas_get/node_atlas_get.yy",}, @@ -1251,6 +1252,7 @@ {"name":"node_3d_displace","order":1,"path":"scripts/node_3d_displace/node_3d_displace.yy",}, {"name":"node_vector_dot","order":9,"path":"scripts/node_vector_dot/node_vector_dot.yy",}, {"name":"node_path_map_area","order":1,"path":"scripts/node_path_map_area/node_path_map_area.yy",}, + {"name":"node_3d_mesh_icosphere","order":5,"path":"scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.yy",}, {"name":"s_node_timeline_preview","order":2,"path":"sprites/s_node_timeline_preview/s_node_timeline_preview.yy",}, {"name":"node_csv_file_read","order":9,"path":"scripts/node_csv_file_read/node_csv_file_read.yy",}, {"name":"scrollPane","order":14,"path":"scripts/scrollPane/scrollPane.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index b679afaba..13c1d3dd9 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1290,7 +1290,7 @@ {"id":{"name":"buttonColor","path":"scripts/buttonColor/buttonColor.yy",},}, {"id":{"name":"notification_system","path":"scripts/notification_system/notification_system.yy",},}, {"id":{"name":"buffer_object","path":"scripts/buffer_object/buffer_object.yy",},}, - {"id":{"name":"node_3d_mesh_sphere","path":"scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.yy",},}, + {"id":{"name":"node_3d_mesh_uvsphere","path":"scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.yy",},}, {"id":{"name":"s_node_audio_trim","path":"sprites/s_node_audio_trim/s_node_audio_trim.yy",},}, {"id":{"name":"s_node_pb_fx_highlight","path":"sprites/s_node_pb_fx_highlight/s_node_pb_fx_highlight.yy",},}, {"id":{"name":"sh_shadow_cast","path":"shaders/sh_shadow_cast/sh_shadow_cast.yy",},}, @@ -1404,6 +1404,7 @@ {"id":{"name":"clipboard","path":"extensions/clipboard/clipboard.yy",},}, {"id":{"name":"__node_3d_light","path":"scripts/__node_3d_light/__node_3d_light.yy",},}, {"id":{"name":"rotator","path":"scripts/rotator/rotator.yy",},}, + {"id":{"name":"d3d_icosphere","path":"scripts/d3d_icosphere/d3d_icosphere.yy",},}, {"id":{"name":"s_node_edge_detect","path":"sprites/s_node_edge_detect/s_node_edge_detect.yy",},}, {"id":{"name":"node_fluid_add_collider","path":"scripts/node_fluid_add_collider/node_fluid_add_collider.yy",},}, {"id":{"name":"node_atlas_get","path":"scripts/node_atlas_get/node_atlas_get.yy",},}, @@ -1919,6 +1920,7 @@ {"id":{"name":"o_dialog_arrayBox","path":"objects/o_dialog_arrayBox/o_dialog_arrayBox.yy",},}, {"id":{"name":"node_path_transform","path":"scripts/node_path_transform/node_path_transform.yy",},}, {"id":{"name":"node_path_map_area","path":"scripts/node_path_map_area/node_path_map_area.yy",},}, + {"id":{"name":"node_3d_mesh_icosphere","path":"scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.yy",},}, {"id":{"name":"s_node_timeline_preview","path":"sprites/s_node_timeline_preview/s_node_timeline_preview.yy",},}, {"id":{"name":"node_csv_file_read","path":"scripts/node_csv_file_read/node_csv_file_read.yy",},}, {"id":{"name":"scrollPane","path":"scripts/scrollPane/scrollPane.yy",},}, diff --git a/objects/o_dialog_add_node/Create_0.gml b/objects/o_dialog_add_node/Create_0.gml index 8944c9bb1..6cc720fa2 100644 --- a/objects/o_dialog_add_node/Create_0.gml +++ b/objects/o_dialog_add_node/Create_0.gml @@ -433,7 +433,7 @@ event_inherited(); draw_sprite_ui_uniform(THEME.node_new_badge, 1, _boxx + grid_size - ui(12), yy + ui(6)); } - if(_node.deprecated) { + if(struct_try_get(_node, "deprecated")) { draw_sprite_ui_uniform(THEME.node_deprecated_badge, 0, _boxx + grid_size - ui(12), yy + ui(6),, COLORS._main_value_negative); draw_sprite_ui_uniform(THEME.node_deprecated_badge, 1, _boxx + grid_size - ui(12), yy + ui(6)); } @@ -551,7 +551,7 @@ event_inherited(); tx += ui(40); } - if(_node.deprecated) { + if(struct_try_get(_node, "deprecated")) { draw_sprite_ui_uniform(THEME.node_deprecated_badge, 0, tx + ui(16), yy + list_height / 2 + ui(1),, COLORS._main_value_negative); draw_sprite_ui_uniform(THEME.node_deprecated_badge, 1, tx + ui(16), yy + list_height / 2 + ui(1)); tx += ui(40); @@ -645,7 +645,7 @@ event_inherited(); if(is_string(_node)) continue; if(ds_map_exists(search_map, _node.node)) continue; - if(_node[$ "deprecated"]) continue; + if(struct_try_get(_node, "deprecated")) continue; var match = string_partial_match(string_lower(_node.getName()), search_lower); var param = ""; diff --git a/scripts/d3d_icosphere/d3d_icosphere.gml b/scripts/d3d_icosphere/d3d_icosphere.gml new file mode 100644 index 000000000..43a483d79 --- /dev/null +++ b/scripts/d3d_icosphere/d3d_icosphere.gml @@ -0,0 +1,155 @@ +function __vec3Sub(_x = 0, _y = _x, _z = _x) : __vec3(_x, _y, _z) constructor { + old = false; + connected = []; + + static smooth = function() { + if(array_empty(connected)) return; + + var _k = array_length(connected) / 2; + var beta = 3 / (5 * _k); + var _s = self.multiply(1 - _k * beta); + var _c = new __vec3(); + + for( var i = 0; i < array_length(connected); i++ ) + _c._add(connected[i]); + _c._multiply(0.5 * beta)._add(_s); + set(_c); + } + + static connectTo = function(point) { array_push(connected, point); } + + static clearConnect = function() { connected = []; } +} + +function __3dICOSphere(radius = 0.5, level = 2, smt = false) : __3dObject() constructor { + VF = global.VF_POS_NORM_TEX_COL; + render_type = pr_trianglelist; + + self.radius = radius; + self.level = level; + self.smooth = smt; + + _vhash = ds_map_create(); + + static getVertex = function(vertex) { + var _hash = string(vertex); + if(ds_map_exists(_vhash, _hash)) + return _vhash[? _hash]; + _vhash[? _hash] = vertex; + return vertex; + } + + static initModel = function() { // swap H, V because fuck me + var _vertices = ds_list_create(); + var _normals = ds_list_create(); + var _uvs = ds_list_create(); + + var phi = (1 + sqrt(5)) * 0.5; // golden ratio + var a = 1.0; + var b = 1.0 / phi; + + icoverts = [ + new __vec3Sub( 1, 1, 1)._normalize(), + new __vec3Sub( 0, b, -a)._normalize(), + new __vec3Sub( b, a, 0)._normalize(), + new __vec3Sub(-b, a, 0)._normalize(), + new __vec3Sub( 0, b, a)._normalize(), + new __vec3Sub( 0, -b, a)._normalize(), + new __vec3Sub(-a, 0, b)._normalize(), + new __vec3Sub( 0, -b, -a)._normalize(), + new __vec3Sub( a, 0, -b)._normalize(), + new __vec3Sub( a, 0, b)._normalize(), + new __vec3Sub(-a, 0, -b)._normalize(), + new __vec3Sub( b, -a, 0)._normalize(), + new __vec3Sub(-b, -a, 0)._normalize(), + ] + + array_foreach(icoverts, function(vert) { vert.old = true; }) + + // Generate icosphere vertices + ds_list_add(_vertices, icoverts[ 3], icoverts[ 2], icoverts[ 1]); + ds_list_add(_vertices, icoverts[ 2], icoverts[ 3], icoverts[ 4]); + ds_list_add(_vertices, icoverts[ 6], icoverts[ 5], icoverts[ 4]); + ds_list_add(_vertices, icoverts[ 5], icoverts[ 9], icoverts[ 4]); + ds_list_add(_vertices, icoverts[ 8], icoverts[ 7], icoverts[ 1]); + ds_list_add(_vertices, icoverts[ 7], icoverts[10], icoverts[ 1]); + ds_list_add(_vertices, icoverts[12], icoverts[11], icoverts[ 5]); + ds_list_add(_vertices, icoverts[11], icoverts[12], icoverts[ 7]); + ds_list_add(_vertices, icoverts[10], icoverts[ 6], icoverts[ 3]); + ds_list_add(_vertices, icoverts[ 6], icoverts[10], icoverts[12]); + ds_list_add(_vertices, icoverts[ 9], icoverts[ 8], icoverts[ 2]); + ds_list_add(_vertices, icoverts[ 8], icoverts[ 9], icoverts[11]); + ds_list_add(_vertices, icoverts[ 3], icoverts[ 6], icoverts[ 4]); + ds_list_add(_vertices, icoverts[ 9], icoverts[ 2], icoverts[ 4]); + ds_list_add(_vertices, icoverts[10], icoverts[ 3], icoverts[ 1]); + ds_list_add(_vertices, icoverts[ 2], icoverts[ 8], icoverts[ 1]); + ds_list_add(_vertices, icoverts[12], icoverts[10], icoverts[ 7]); + ds_list_add(_vertices, icoverts[ 8], icoverts[11], icoverts[ 7]); + ds_list_add(_vertices, icoverts[ 6], icoverts[12], icoverts[ 5]); + ds_list_add(_vertices, icoverts[11], icoverts[ 9], icoverts[ 5]); + + for( var w = 1; w <= level; w++ ) { #region subdivide + ds_map_clear(_vhash); + var newVertices = ds_list_create(); + + for (var i = 0, n = ds_list_size(_vertices) / 3; i < n; i++) { + var v1 = _vertices[| i * 3 + 0]; + var v2 = _vertices[| i * 3 + 1]; + var v3 = _vertices[| i * 3 + 2]; + + var mid12Pos = getVertex(new __vec3Sub(v1.add(v2).divide(2))); + var mid23Pos = getVertex(new __vec3Sub(v2.add(v3).divide(2))); + var mid31Pos = getVertex(new __vec3Sub(v3.add(v1).divide(2))); + + v1.connectTo(mid12Pos); v1.connectTo(mid31Pos); + v2.connectTo(mid12Pos); v2.connectTo(mid23Pos); + v3.connectTo(mid23Pos); v3.connectTo(mid31Pos); + + ds_list_add(newVertices, v1, mid12Pos, mid31Pos); + ds_list_add(newVertices, mid12Pos, v2, mid23Pos); + ds_list_add(newVertices, mid31Pos, mid23Pos, v3); + ds_list_add(newVertices, mid12Pos, mid23Pos, mid31Pos); + } + + for (var i = 0, n = ds_list_size(newVertices); i < n; i++) { + var _v = newVertices[| i]; + if(_v.old) _v.smooth(); + + _v.old = true; + _v.clearConnect(); + } + + ds_list_destroy(_vertices); + _vertices = newVertices; + } #endregion + + for( var i = 0, n = ds_list_size(_vertices) / 3; i < n; i++ ) { #region normal, uv generation + var _v0 = _vertices[| i * 3 + 0]; + var _v1 = _vertices[| i * 3 + 1]; + var _v2 = _vertices[| i * 3 + 2]; + var _n = _v1.subtract(_v0).cross(_v2.subtract(_v0)); + var _u = [ 0, 0 ]; + + ds_list_add(_normals, _n, _n, _n); + ds_list_add(_uvs, _u, _u, _u); + } #endregion + + vertex = array_create(ds_list_size(_vertices)); + normals = array_create(ds_list_size(_normals)); + uv = ds_list_to_array(_uvs); + + for( var i = 0, n = ds_list_size(_vertices); i < n; i++ ) + vertex[i] = _vertices[| i].toArray(); + + for( var i = 0, n = ds_list_size(_normals); i < n; i++ ) + normals[i] = _normals[| i].toArray(); + + ds_list_destroy(_vertices); + ds_list_destroy(_normals); + ds_list_destroy(_uvs); + + VB = build(); + } initModel(); + + static onParameterUpdate = initModel; +} \ No newline at end of file diff --git a/scripts/d3d_icosphere/d3d_icosphere.yy b/scripts/d3d_icosphere/d3d_icosphere.yy new file mode 100644 index 000000000..9903e5bce --- /dev/null +++ b/scripts/d3d_icosphere/d3d_icosphere.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "d3d_icosphere", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "mesh", + "path": "folders/functions/3d/mesh.yy", + }, +} \ No newline at end of file diff --git a/scripts/ds_list/ds_list.gml b/scripts/ds_list/ds_list.gml index de40c2862..e96d73b65 100644 --- a/scripts/ds_list/ds_list.gml +++ b/scripts/ds_list/ds_list.gml @@ -10,9 +10,8 @@ function ds_list_to_array(list) { if(!ds_exists(list, ds_type_list)) return []; var a = array_create(ds_list_size(list)); - for( var i = 0; i < ds_list_size(list); i++ ) { + for( var i = 0; i < ds_list_size(list); i++ ) a[i] = list[| i]; - } return a; } diff --git a/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.gml b/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.gml new file mode 100644 index 000000000..b71b767a5 --- /dev/null +++ b/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.gml @@ -0,0 +1,33 @@ +function Node_3D_Mesh_Sphere_Ico(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) constructor { + name = "3D Icosphere"; + + object_class = __3dICOSphere; + + inputs[| in_mesh + 0] = nodeValue("Subdivision", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1 ); + + inputs[| in_mesh + 1] = nodeValue("Texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone ); + + inputs[| in_mesh + 2] = nodeValue("Smooth Normal", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ); + + input_display_list = [ + __d3d_input_list_mesh, in_mesh + 0, in_mesh + 2, + __d3d_input_list_transform, + ["Texture", false], in_mesh + 1, + ] + + static processData = function(_output, _data, _output_index, _array_index = 0) { #region + var _sub = _data[in_mesh + 0]; + var _tex = _data[in_mesh + 1]; + var _smt = _data[in_mesh + 2]; + + var object = getObject(_array_index); + object.checkParameter({level: _sub, smooth: _smt}); + object.texture = surface_texture(_tex); + + setTransform(object, _data); + + return object; + } #endregion + + static getPreviewValues = function() { return array_safe_get(all_inputs, in_mesh + 1, noone); } +} \ No newline at end of file diff --git a/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.yy b/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.yy new file mode 100644 index 000000000..3b569bc96 --- /dev/null +++ b/scripts/node_3d_mesh_icosphere/node_3d_mesh_icosphere.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "node_3d_mesh_icosphere", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "d3d mesh", + "path": "folders/nodes/data/3D/d3d mesh.yy", + }, +} \ No newline at end of file diff --git a/scripts/node_3d_mesh_sphere/node_counter.yy b/scripts/node_3d_mesh_icosphere/node_counter.yy similarity index 100% rename from scripts/node_3d_mesh_sphere/node_counter.yy rename to scripts/node_3d_mesh_icosphere/node_counter.yy diff --git a/scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.gml b/scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.gml similarity index 90% rename from scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.gml rename to scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.gml index 08f30c248..e3ead837c 100644 --- a/scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.gml +++ b/scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.gml @@ -1,5 +1,5 @@ -function Node_3D_Mesh_Sphere(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) constructor { - name = "3D Sphere"; +function Node_3D_Mesh_Sphere_UV(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) constructor { + name = "3D UV Sphere"; object_class = __3dUVSphere; diff --git a/scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.yy b/scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.yy similarity index 85% rename from scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.yy rename to scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.yy index b995ce581..b8f4e1857 100644 --- a/scripts/node_3d_mesh_sphere/node_3d_mesh_sphere.yy +++ b/scripts/node_3d_mesh_uvsphere/node_3d_mesh_uvsphere.yy @@ -1,7 +1,7 @@ { "resourceType": "GMScript", "resourceVersion": "1.0", - "name": "node_3d_mesh_sphere", + "name": "node_3d_mesh_uvsphere", "isCompatibility": false, "isDnD": false, "parent": { diff --git a/scripts/node_3d_mesh_uvsphere/node_counter.yy b/scripts/node_3d_mesh_uvsphere/node_counter.yy new file mode 100644 index 000000000..10832a0b0 --- /dev/null +++ b/scripts/node_3d_mesh_uvsphere/node_counter.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "variable", + "path": "folders/nodes/data/variable.yy", + }, + "resourceVersion": "1.0", + "name": "node_counter", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_action_object/node_action_object.gml b/scripts/node_action_object/node_action_object.gml index 48c6bc02e..286eca0fd 100644 --- a/scripts/node_action_object/node_action_object.gml +++ b/scripts/node_action_object/node_action_object.gml @@ -20,7 +20,7 @@ static getName = function() { return name; /*__txt_node_name(node, name); */ } static getTooltip = function() { return tooltip; /*__txt_node_tooltip(node, tooltip); */ } - static build = function(_x, _y, _group = PANEL_GRAPH.getCurrentContext(), _param = "") { + static build = function(_x = 0, _y = 0, _group = PANEL_GRAPH.getCurrentContext(), _param = "") { var _n = []; for( var i = 0, n = array_length(nodes); i < n; i++ ) { var __n = nodes[i]; diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 1ab8c514c..484a3131f 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -35,7 +35,7 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { static getName = function() { return name; /*__txt_node_name(node, name); */ } static getTooltip = function() { return tooltip; /*__txt_node_tooltip(node, tooltip); */ } - function build(_x, _y, _group = PANEL_GRAPH.getCurrentContext(), _param = "") { + static build = function(_x = 0, _y = 0, _group = PANEL_GRAPH.getCurrentContext(), _param = "") { var _node = createNode[0]? new createNode[1](_x, _y, _group, _param) : createNode[1](_x, _y, _group, _param); if(!_node) return noone; @@ -363,7 +363,8 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { addNodeObject(threeD, "3D Object", s_node_3d_obj, "Node_3D_Mesh_Obj", [0, Node_create_3D_Obj],, "Load .obj file from your computer as a 3D object."); addNodeObject(threeD, "3D Cube", s_node_3d_cube, "Node_3D_Mesh_Cube", [1, Node_3D_Mesh_Cube]); addNodeObject(threeD, "3D Cylinder", s_node_3d_cylinder, "Node_3D_Mesh_Cylinder", [1, Node_3D_Mesh_Cylinder]); - addNodeObject(threeD, "3D Sphere", s_node_3d_sphere, "Node_3D_Mesh_Sphere", [1, Node_3D_Mesh_Sphere]); + addNodeObject(threeD, "3D UV Sphere", s_node_3d_sphere, "Node_3D_Mesh_Sphere_UV", [1, Node_3D_Mesh_Sphere_UV]); + addNodeObject(threeD, "3D Icosphere", s_node_3d_sphere, "Node_3D_Mesh_Sphere_Ico", [1, Node_3D_Mesh_Sphere_Ico]); ds_list_add(threeD, "Light"); addNodeObject(threeD, "Directional Light", s_node_3d_cube, "Node_3D_Light_Directional", [1, Node_3D_Light_Directional]);