diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index f4fe0418f..0cbeade7e 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -478,9 +478,10 @@ {"name":"d3d_bbox","order":8,"path":"scripts/d3d_bbox/d3d_bbox.yy",}, {"name":"d3d_camera_object","order":1,"path":"scripts/d3d_camera_object/d3d_camera_object.yy",}, {"name":"d3d_cone","order":5,"path":"scripts/d3d_cone/d3d_cone.yy",}, - {"name":"d3d_cube","order":1,"path":"scripts/d3d_cube/d3d_cube.yy",}, - {"name":"d3d_cylinder_nocaps","order":9,"path":"scripts/d3d_cylinder_nocaps/d3d_cylinder_nocaps.yy",}, - {"name":"d3d_cylinder","order":2,"path":"scripts/d3d_cylinder/d3d_cylinder.yy",}, + {"name":"d3d_cube_faces","order":1,"path":"scripts/d3d_cube_faces/d3d_cube_faces.yy",}, + {"name":"d3d_cube","order":2,"path":"scripts/d3d_cube/d3d_cube.yy",}, + {"name":"d3d_cylinder_nocaps","order":10,"path":"scripts/d3d_cylinder_nocaps/d3d_cylinder_nocaps.yy",}, + {"name":"d3d_cylinder","order":3,"path":"scripts/d3d_cylinder/d3d_cylinder.yy",}, {"name":"d3d_gizmo_axis","order":7,"path":"scripts/d3d_gizmo_axis/d3d_gizmo_axis.yy",}, {"name":"d3d_gizmo_circle_z","order":4,"path":"scripts/d3d_gizmo_circle_z/d3d_gizmo_circle_z.yy",}, {"name":"d3d_gizmo_line_dashed","order":3,"path":"scripts/d3d_gizmo_line_dashed/d3d_gizmo_line_dashed.yy",}, @@ -488,24 +489,25 @@ {"name":"d3d_gizmo_plane_falloff","order":6,"path":"scripts/d3d_gizmo_plane_falloff/d3d_gizmo_plane_falloff.yy",}, {"name":"d3d_gizmo_plane","order":5,"path":"scripts/d3d_gizmo_plane/d3d_gizmo_plane.yy",}, {"name":"d3d_group","order":3,"path":"scripts/d3d_group/d3d_group.yy",}, - {"name":"d3d_icosphere","order":4,"path":"scripts/d3d_icosphere/d3d_icosphere.yy",}, + {"name":"d3d_icosphere","order":5,"path":"scripts/d3d_icosphere/d3d_icosphere.yy",}, {"name":"d3d_light_directional","order":1,"path":"scripts/d3d_light_directional/d3d_light_directional.yy",}, {"name":"d3d_light_point","order":2,"path":"scripts/d3d_light_point/d3d_light_point.yy",}, {"name":"d3d_material","order":4,"path":"scripts/d3d_material/d3d_material.yy",}, {"name":"d3d_object_instancer","order":5,"path":"scripts/d3d_object_instancer/d3d_object_instancer.yy",}, {"name":"d3d_object","order":1,"path":"scripts/d3d_object/d3d_object.yy",}, - {"name":"d3d_path_extrude","order":10,"path":"scripts/d3d_path_extrude/d3d_path_extrude.yy",}, - {"name":"d3d_plane_mesh","order":6,"path":"scripts/d3d_plane_mesh/d3d_plane_mesh.yy",}, + {"name":"d3d_path_extrude","order":11,"path":"scripts/d3d_path_extrude/d3d_path_extrude.yy",}, + {"name":"d3d_plane_mesh","order":7,"path":"scripts/d3d_plane_mesh/d3d_plane_mesh.yy",}, {"name":"d3d_plane","order":2,"path":"scripts/d3d_plane/d3d_plane.yy",}, {"name":"d3d_ray","order":9,"path":"scripts/d3d_ray/d3d_ray.yy",}, {"name":"d3d_rot3","order":3,"path":"scripts/d3d_rot3/d3d_rot3.yy",}, {"name":"d3d_scene","order":2,"path":"scripts/d3d_scene/d3d_scene.yy",}, - {"name":"d3d_surface_extrude","order":7,"path":"scripts/d3d_surface_extrude/d3d_surface_extrude.yy",}, - {"name":"d3d_terrain","order":8,"path":"scripts/d3d_terrain/d3d_terrain.yy",}, - {"name":"d3d_torus","order":11,"path":"scripts/d3d_torus/d3d_torus.yy",}, + {"name":"d3d_surface_extrude","order":8,"path":"scripts/d3d_surface_extrude/d3d_surface_extrude.yy",}, + {"name":"d3d_terrain","order":9,"path":"scripts/d3d_terrain/d3d_terrain.yy",}, + {"name":"d3d_torus","order":12,"path":"scripts/d3d_torus/d3d_torus.yy",}, {"name":"d3d_transformation","order":12,"path":"scripts/d3d_transformation/d3d_transformation.yy",}, - {"name":"d3d_uvsphere","order":3,"path":"scripts/d3d_uvsphere/d3d_uvsphere.yy",}, + {"name":"d3d_uvsphere","order":4,"path":"scripts/d3d_uvsphere/d3d_uvsphere.yy",}, {"name":"d3d_vertex","order":10,"path":"scripts/d3d_vertex/d3d_vertex.yy",}, + {"name":"d3d_wall_builder","order":1,"path":"scripts/d3d_wall_builder/d3d_wall_builder.yy",}, {"name":"debug","order":10,"path":"scripts/debug/debug.yy",}, {"name":"delaunay","order":1,"path":"scripts/delaunay/delaunay.yy",}, {"name":"dialog_management","order":2,"path":"scripts/dialog_management/dialog_management.yy",}, @@ -700,6 +702,7 @@ {"name":"node_3d_mesh_stack_slice","order":7,"path":"scripts/node_3d_mesh_stack_slice/node_3d_mesh_stack_slice.yy",}, {"name":"node_3d_mesh_terrain","order":9,"path":"scripts/node_3d_mesh_terrain/node_3d_mesh_terrain.yy",}, {"name":"node_3d_mesh_torus","order":12,"path":"scripts/node_3d_mesh_torus/node_3d_mesh_torus.yy",}, + {"name":"node_3d_mesh_wall_builder","order":13,"path":"scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.yy",}, {"name":"node_3d_point_affector","order":11,"path":"scripts/node_3d_point_affector/node_3d_point_affector.yy",}, {"name":"node_3d_repeat","order":1,"path":"scripts/node_3d_repeat/node_3d_repeat.yy",}, {"name":"node_3d_round_vertex","order":1,"path":"scripts/node_3d_round_vertex/node_3d_round_vertex.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index e5987d2f5..9f12a8461 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -1017,6 +1017,7 @@ {"id":{"name":"d3d_transformation","path":"scripts/d3d_transformation/d3d_transformation.yy",},}, {"id":{"name":"d3d_uvsphere","path":"scripts/d3d_uvsphere/d3d_uvsphere.yy",},}, {"id":{"name":"d3d_vertex","path":"scripts/d3d_vertex/d3d_vertex.yy",},}, + {"id":{"name":"d3d_wall_builder","path":"scripts/d3d_wall_builder/d3d_wall_builder.yy",},}, {"id":{"name":"debug","path":"scripts/debug/debug.yy",},}, {"id":{"name":"delau_helper","path":"scripts/delau_helper/delau_helper.yy",},}, {"id":{"name":"delaunay","path":"scripts/delaunay/delaunay.yy",},}, @@ -1242,6 +1243,7 @@ {"id":{"name":"node_3d_mesh_stack_slice","path":"scripts/node_3d_mesh_stack_slice/node_3d_mesh_stack_slice.yy",},}, {"id":{"name":"node_3d_mesh_terrain","path":"scripts/node_3d_mesh_terrain/node_3d_mesh_terrain.yy",},}, {"id":{"name":"node_3d_mesh_torus","path":"scripts/node_3d_mesh_torus/node_3d_mesh_torus.yy",},}, + {"id":{"name":"node_3d_mesh_wall_builder","path":"scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.yy",},}, {"id":{"name":"node_3d_particle","path":"scripts/node_3d_particle/node_3d_particle.yy",},}, {"id":{"name":"node_3d_point_affector","path":"scripts/node_3d_point_affector/node_3d_point_affector.yy",},}, {"id":{"name":"node_3d_repeat","path":"scripts/node_3d_repeat/node_3d_repeat.yy",},}, diff --git a/scripts/d3d_object/d3d_object.gml b/scripts/d3d_object/d3d_object.gml index c3c7a12f1..f76d1fbbc 100644 --- a/scripts/d3d_object/d3d_object.gml +++ b/scripts/d3d_object/d3d_object.gml @@ -36,6 +36,13 @@ function __3dObject() constructor { static checkParameter = function(params = {}, forceUpdate = false) { var _keys = struct_get_names(params); + + if(forceUpdate) { + struct_override(self, params); + onParameterUpdate(); + return; + } + var check = false; for( var i = 0, n = array_length(_keys); i < n; i++ ) { var key = _keys[i]; @@ -44,7 +51,7 @@ function __3dObject() constructor { self[$ key] = params[$ key]; } - if(forceUpdate || check) onParameterUpdate(); + if(check) onParameterUpdate(); } static onParameterUpdate = function() {} diff --git a/scripts/d3d_wall_builder/d3d_wall_builder.gml b/scripts/d3d_wall_builder/d3d_wall_builder.gml new file mode 100644 index 000000000..051ebf681 --- /dev/null +++ b/scripts/d3d_wall_builder/d3d_wall_builder.gml @@ -0,0 +1,165 @@ +function __3dWall_builder() : __3dObject() constructor { + VF = global.VF_POS_NORM_TEX_COL; + render_type = pr_trianglelist; + + points = []; + offset = .1; + height = 1; + smooth = false; + loop = false; + + static initModel = function() { + if(array_empty(points)) return; + + var ofl = []; + var ofr = []; + var len = array_length(points); + + for (var i = 0; i < len - 1; i++) { + var p1 = points[i]; + var p2 = points[i + 1]; + + var dx = p2[0] - p1[0]; + var dy = p2[1] - p1[1]; + + var px = -dy; + var py = dx; + + var l = sqrt(px * px + py * py); + px /= l; + py /= l; + + var olx = p1[0] + px * offset; + var oly = p1[1] + py * offset; + var orx = p1[0] - px * offset; + var ory = p1[1] - py * offset; + + array_push(ofl, [ olx, oly ]); + array_push(ofr, [ orx, ory ]); + } + + if(loop) { + array_push(ofl, ofl[0]); + array_push(ofr, ofr[0]); + + len++; + } + + ofr = array_reverse(ofr); + len -= 2; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var z = height; + var vbl = array_create((len) * 2 * 3); + for( var i = 0, n = len; i < n; i++ ) { + var p0 = ofl[i ]; + var p1 = ofl[i + 1]; + + var x0 = p0[0], y0 = p0[1]; + var x1 = p1[0], y1 = p1[1]; + + var u0 = i / len; + var u1 = (i + 1) / len; + + vbl[i * 6 + 0] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(u0, 0); + vbl[i * 6 + 1] = new __vertex(x1, y1, 0).setNormal(-y1, x1, 0).setUV(u1, 0); + vbl[i * 6 + 2] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(u1, 1); + + vbl[i * 6 + 3] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(u0, 0); + vbl[i * 6 + 4] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(u1, 1); + vbl[i * 6 + 5] = new __vertex(x0, y0, z).setNormal(-y0, x0, 0).setUV(u0, 1); + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var vbr = array_create((len) * 2 * 3); + for( var i = 0, n = len; i < n; i++ ) { + var p0 = ofr[i ]; + var p1 = ofr[i + 1]; + + var x0 = p0[0], y0 = p0[1]; + var x1 = p1[0], y1 = p1[1]; + + var u0 = i / len; + var u1 = (i + 1) / len; + + vbr[i * 6 + 0] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(u0, 0); + vbr[i * 6 + 1] = new __vertex(x1, y1, 0).setNormal(-y1, x1, 0).setUV(u1, 0); + vbr[i * 6 + 2] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(u1, 1); + + vbr[i * 6 + 3] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(u0, 0); + vbr[i * 6 + 4] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(u1, 1); + vbr[i * 6 + 5] = new __vertex(x0, y0, z).setNormal(-y0, x0, 0).setUV(u0, 1); + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + if(loop) { + vbs = []; + } else { + var vbs = array_create(4 * 3); + + var p0 = ofl[0]; + var p1 = ofr[len]; + + var x0 = p0[0], y0 = p0[1]; + var x1 = p1[0], y1 = p1[1]; + + vbs[0] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(0, 0); + vbs[1] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(1, 1); + vbs[2] = new __vertex(x1, y1, 0).setNormal(-y1, x1, 0).setUV(1, 0); + + vbs[3] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(0, 0); + vbs[4] = new __vertex(x0, y0, z).setNormal(-y0, x0, 0).setUV(0, 1); + vbs[5] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(1, 1); + + var p0 = ofl[len]; + var p1 = ofr[0]; + + var x0 = p0[0], y0 = p0[1]; + var x1 = p1[0], y1 = p1[1]; + + vbs[6] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(0, 0); + vbs[7] = new __vertex(x1, y1, 0).setNormal(-y1, x1, 0).setUV(1, 0); + vbs[8] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(1, 1); + + vbs[ 9] = new __vertex(x0, y0, 0).setNormal(-y0, x0, 0).setUV(0, 0); + vbs[10] = new __vertex(x1, y1, z).setNormal(-y1, x1, 0).setUV(1, 1); + vbs[11] = new __vertex(x0, y0, z).setNormal(-y0, x0, 0).setUV(0, 1); + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var vbt = array_create((len) * 2 * 3); + for( var i = 0, n = len; i < n; i++ ) { + var p0 = ofl[i ]; + var p1 = ofl[i + 1]; + var p2 = ofr[len - 1 - i ]; + var p3 = ofr[len - 1 - i + 1]; + + var x0 = p0[0], y0 = p0[1]; + var x1 = p1[0], y1 = p1[1]; + var x2 = p2[0], y2 = p2[1]; + var x3 = p3[0], y3 = p3[1]; + + var u0 = i / len; + var u1 = (i + 1) / len; + + vbt[i * 6 + 0] = new __vertex(x0, y0, z).setNormal(0, 0, 1).setUV(u0, 0); + vbt[i * 6 + 1] = new __vertex(x1, y1, z).setNormal(0, 0, 1).setUV(u1, 0); + vbt[i * 6 + 2] = new __vertex(x3, y3, z).setNormal(0, 0, 1).setUV(u1, 1); + + vbt[i * 6 + 3] = new __vertex(x1, y1, z).setNormal(0, 0, 1).setUV(u1, 0); + vbt[i * 6 + 4] = new __vertex(x2, y2, z).setNormal(0, 0, 1).setUV(u0, 1); + vbt[i * 6 + 5] = new __vertex(x3, y3, z).setNormal(0, 0, 1).setUV(u1, 1); + } + + vertex = [ vbl, vbr, vbs, vbt ]; + object_counts = array_length(vertex); + VB = build(); + + } initModel(); + + static onParameterUpdate = initModel; +} \ No newline at end of file diff --git a/scripts/d3d_wall_builder/d3d_wall_builder.yy b/scripts/d3d_wall_builder/d3d_wall_builder.yy new file mode 100644 index 000000000..8cc633847 --- /dev/null +++ b/scripts/d3d_wall_builder/d3d_wall_builder.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"d3d_wall_builder", + "isCompatibility":false, + "isDnD":false, + "name":"d3d_wall_builder", + "parent":{ + "name":"mesh", + "path":"folders/nodes/data/3D/d3d_mesh/mesh.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/node_3d_mesh_cone/node_3d_mesh_cone.gml b/scripts/node_3d_mesh_cone/node_3d_mesh_cone.gml index d38975393..4963e26b4 100644 --- a/scripts/node_3d_mesh_cone/node_3d_mesh_cone.gml +++ b/scripts/node_3d_mesh_cone/node_3d_mesh_cone.gml @@ -20,7 +20,7 @@ function Node_3D_Mesh_Cone(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group ["Material", false], in_mesh + 3, in_mesh + 1, in_mesh + 2, ] - static processData = function(_output, _data, _output_index, _array_index = 0) { #region + static processData = function(_output, _data, _output_index, _array_index = 0) { var _side = _data[in_mesh + 0]; var _mat_bot = _data[in_mesh + 1]; var _mat_sid = _data[in_mesh + 2]; @@ -33,7 +33,7 @@ function Node_3D_Mesh_Cone(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group setTransform(object, _data); return object; - } #endregion + } static getPreviewValues = function() { return getSingleValue(in_mesh + 1); } } \ No newline at end of file diff --git a/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.gml b/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.gml new file mode 100644 index 000000000..61da0bf3f --- /dev/null +++ b/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.gml @@ -0,0 +1,76 @@ +function Node_3D_Mesh_Wall_Builder(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _group) constructor { + name = "3D Wall"; + object_class = __3dWall_builder; + + newInput(in_mesh + 0, nodeValue_PathNode("Path", self, noone)) + .setVisible(true, true); + + newInput(in_mesh + 1, nodeValue_Int("Segments", self, 16 )); + + newInput(in_mesh + 2, nodeValue_Float("Height", self, 1 )); + + newInput(in_mesh + 3, nodeValue_Float("Thickness", self, 0.1 )) + .setDisplay(VALUE_DISPLAY.slider); + + newInput(in_mesh + 4, nodeValue_Bool("Material per side", self, false )); + + newInput(in_mesh + 5, nodeValue_D3Material("Side Material", self, new __d3dMaterial())) + .setVisible(true, true); + + newInput(in_mesh + 6, nodeValue_Float("Path Scale", self, .01 )); + + newInput(in_mesh + 7, nodeValue_D3Material("Side Material 2", self, new __d3dMaterial())) + .setVisible(true, true); + + newInput(in_mesh + 8, nodeValue_D3Material("Cap Material", self, new __d3dMaterial())) + .setVisible(true, true); + + newInput(in_mesh + 9, nodeValue_Bool("Loop", self, false )); + + input_display_list = [ + __d3d_input_list_mesh, in_mesh + 0, in_mesh + 6, in_mesh + 9, in_mesh + 1, in_mesh + 2, in_mesh + 3, + __d3d_input_list_transform, + ["Material", false], in_mesh + 4, in_mesh + 5, in_mesh + 7, in_mesh + 8, + ] + + static processData = function(_output, _data, _output_index, _array_index = 0) { + var _paths = _data[in_mesh + 0]; + var _segment = _data[in_mesh + 1]; + var _loop = _data[in_mesh + 9]; + var _height = _data[in_mesh + 2]; + var _thick = _data[in_mesh + 3]; + var _pscale = _data[in_mesh + 6]; + + var _side2 = _data[in_mesh + 4]; + var _mat_sid = _data[in_mesh + 5]; + var _mat_sid2 = _data[in_mesh + 7]; + var _mat_cap = _data[in_mesh + 8]; + + inputs[in_mesh + 7].setVisible(_side2, _side2); + + if(_paths == noone) return noone; + + var points = array_create(_segment + 1); + var p = new __vec2(); + + for( var i = 0; i <= _segment; i++ ) { + p = _paths.getPointRatio(i / _segment, 0, p); + points[i] = [ p.x * _pscale, -p.y * _pscale ]; + } + + var object = getObject(_array_index); + object.checkParameter({ + points : points, + offset : _thick, + height : _height, + loop : _loop, + }); + object.materials = _side2? [ _mat_sid, _mat_sid2, _mat_cap, _mat_cap ] : [ _mat_sid, _mat_sid, _mat_cap, _mat_cap ]; + + setTransform(object, _data); + + return object; + } + + static getPreviewValues = function() { return getSingleValue(in_mesh + 1); } +} \ No newline at end of file diff --git a/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.yy b/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.yy new file mode 100644 index 000000000..f777810bf --- /dev/null +++ b/scripts/node_3d_mesh_wall_builder/node_3d_mesh_wall_builder.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"v1", + "%Name":"node_3d_mesh_wall_builder", + "isCompatibility":false, + "isDnD":false, + "name":"node_3d_mesh_wall_builder", + "parent":{ + "name":"d3d_mesh", + "path":"folders/nodes/data/3D/d3d_mesh.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/node_3d_mesh_wall_builder/node_counter.yy b/scripts/node_3d_mesh_wall_builder/node_counter.yy new file mode 100644 index 000000000..10832a0b0 --- /dev/null +++ b/scripts/node_3d_mesh_wall_builder/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_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 60a4f2e26..ccb882ae0 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -703,8 +703,9 @@ function __initNodes() { addNodeObject(d3d, "3D UV Sphere", s_node_3d_sphere_uv, "Node_3D_Mesh_Sphere_UV", [1, Node_3D_Mesh_Sphere_UV]).setVersion(11510); addNodeObject(d3d, "3D Icosphere", s_node_3d_sphere_ico, "Node_3D_Mesh_Sphere_Ico", [1, Node_3D_Mesh_Sphere_Ico]).setVersion(11510); addNodeObject(d3d, "3D Cone", s_node_3d_cone, "Node_3D_Mesh_Cone", [1, Node_3D_Mesh_Cone]).setVersion(11510); - addNodeObject(d3d, "3D Torus", s_node_3d_torus, "Node_3D_Mesh_Torus", [1, Node_3D_Mesh_Torus]).setVersion(1_18_01_0); + addNodeObject(d3d, "3D Torus", s_node_3d_torus, "Node_3D_Mesh_Torus", [1, Node_3D_Mesh_Torus]).setVersion(1_18_01_0); addNodeObject(d3d, "3D Terrain", s_node_3d_displace, "Node_3D_Mesh_Terrain", [1, Node_3D_Mesh_Terrain],, "Create 3D terrain from height map.").setVersion(11560); + addNodeObject(d3d, "3D Wall Builder", s_node_3d_wall, "Node_3D_Mesh_Wall_Builder",[1, Node_3D_Mesh_Wall_Builder]).setVersion(1_18_01_0); addNodeObject(d3d, "Surface Extrude", s_node_3d_extrude, "Node_3D_Mesh_Extrude", [1, Node_3D_Mesh_Extrude],, "Extrude 2D image into 3D object.").setVersion(11510); addNodeObject(d3d, "Path Extrude", s_node_3d_path_extrude, "Node_3D_Mesh_Path_Extrude",[1, Node_3D_Mesh_Path_Extrude],, "Extrude path into 3D object.").setVersion(11750);