From 47d22ea379895dcaabadfe80d360d04cbcb10052 Mon Sep 17 00:00:00 2001 From: t3du <32546729+t3du@users.noreply.github.com> Date: Sun, 17 Nov 2024 02:49:34 +0000 Subject: [PATCH] get object geom node + exporter --- Sources/armory/logicnode/GetObjectGeomNode.hx | 122 ++++++++++++++++++ blender/arm/exporter.py | 21 +++ .../logicnode/object/LN_get_object_geom.py | 32 +++++ 3 files changed, 175 insertions(+) create mode 100644 Sources/armory/logicnode/GetObjectGeomNode.hx create mode 100644 blender/arm/logicnode/object/LN_get_object_geom.py diff --git a/Sources/armory/logicnode/GetObjectGeomNode.hx b/Sources/armory/logicnode/GetObjectGeomNode.hx new file mode 100644 index 0000000000..d9213b55df --- /dev/null +++ b/Sources/armory/logicnode/GetObjectGeomNode.hx @@ -0,0 +1,122 @@ +package armory.logicnode; + +import iron.object.MeshObject; +import iron.math.Vec4; + +class GetObjectGeomNode extends LogicNode { + + public function new(tree: LogicTree) { + super(tree); + } + + override function get(from: Int): Dynamic { + var object: MeshObject = inputs[0].get(); + + if (object == null) return null; + + if (from == 5) + return object.vertex_groups; + + if (from == 6){ + var keys = []; + if (object.vertex_groups != null) + for (key in object.vertex_groups.keys()) + keys.push(key); + + return keys; + } + + if (object.data == null) return null; + + var pos: Array = []; + var nor: Array = []; + + var positions = object.data.geom.positions.values; + var scl = object.data.scalePos; + var normals = object.data.geom.normals.values; + + for (i in 0...Std.int(positions.length/4)){ + pos.push(new Vec4(positions[i*4]*scl/32767, positions[i*4+1]*scl/32767, positions[i*4+2]*scl/32767, 1)); + nor.push(new Vec4(normals[i*2]/32767, normals[i*2+1]/32767, positions[i*4+3]/32767, 1)); + } + + if (from == 0) + return pos; + + if (from == 1) + return nor; + + + if (from == 2){ + var index = []; + for (i in 0...pos.length) + index.push(i); + + var unique: Array = []; + + for (item in pos) + if (unique.indexOf(Std.string(item)) == -1) + unique.push(Std.string(item)); + + for (u in 0...unique.length) + for (i in 0...pos.length) + if(Std.string(pos[i]) == unique[u]) index[i] = u; + + return index; + } + + var ind: Array = []; + + if (from == 3 || from == 4){ + var matInd: Array = []; + + var indices = object.data.geom.indices; + + for (i in 0...indices.length){ + for(j in 0...Std.int(indices[i].length)) + matInd.push(i); + for (j in 0...indices[i].length) + ind.push(indices[i][j]); + } + + var matIndex = []; + for (i in 0...pos.length) + matIndex.push(matInd[ind.indexOf(i)]); + + if (from == 3) + return matIndex; + } + + + if (from == 4){ + var face = 0; + var faceIndex = []; + + for(i in 0...Std.int(ind.length/3)-1){ + var ar = ind.slice(i*3, i*3+3).concat(ind.slice((i+1)*3, (i+1)*3+3)); + var unique = []; + for (item in ar) + if (unique.indexOf(item) == -1) + unique.push(item); + faceIndex.push(face); + if (unique.length == ar.length) + face+=1; + } + faceIndex.push(face); + + var faceIndexF = []; + for (f in faceIndex) + for (i in 0...3) + faceIndexF.push(f); + + var faceInd = []; + for (i in 0...pos.length) + faceInd.push(faceIndexF[ind.indexOf(i)]); + + return faceInd; + } + + return null; + + } +} \ No newline at end of file diff --git a/blender/arm/exporter.py b/blender/arm/exporter.py index 27c64399a7..20b6533209 100644 --- a/blender/arm/exporter.py +++ b/blender/arm/exporter.py @@ -786,6 +786,25 @@ def export_object(self, bobject: bpy.types.Object, out_parent: Dict = None) -> N out_object['tilesheet_ref'] = bobject.arm_tilesheet out_object['tilesheet_action_ref'] = bobject.arm_tilesheet_action + + if len(bobject.vertex_groups) > 0: + out_object['vertex_groups'] = [] + for group in bobject.vertex_groups: + verts = [] + for v in bobject.data.vertices: + for g in v.groups: + if g.group == group.index: + verts.append(str(v.co.x)) + verts.append(str(v.co.y)) + verts.append(str(v.co.z)) + + out_vertex_groups = { + 'name': group.name, + 'value': verts + } + out_object['vertex_groups'].append(out_vertex_groups) + + if len(bobject.arm_propertylist) > 0: out_object['properties'] = [] for proplist_item in bobject.arm_propertylist: @@ -2688,6 +2707,7 @@ def post_export_object(self, bobject: bpy.types.Object, o, type): ArmoryExporter.export_physics = True rb = bobject.rigid_body shape = 0 # BOX + if rb.collision_shape == 'SPHERE': shape = 1 elif rb.collision_shape == 'CONVEX_HULL': @@ -2700,6 +2720,7 @@ def post_export_object(self, bobject: bpy.types.Object, o, type): shape = 5 elif rb.collision_shape == 'CAPSULE': shape = 6 + body_mass = rb.mass is_static = self.rigid_body_static(rb) if is_static: diff --git a/blender/arm/logicnode/object/LN_get_object_geom.py b/blender/arm/logicnode/object/LN_get_object_geom.py new file mode 100644 index 0000000000..c968066ee2 --- /dev/null +++ b/blender/arm/logicnode/object/LN_get_object_geom.py @@ -0,0 +1,32 @@ +from arm.logicnode.arm_nodes import * + +class GetObjectGeomNode(ArmLogicTreeNode): + """Returns the vertex geometry info of the given object and the vertex groups info. + + @input Object: object geometry to retrieve. + + @output Vertices Positions: an array with the vertices positions. + @output Vertices Normals: an array with vertices normals directions. + @output Vertices Indices: an array with vertices indices. + @output Vertices Material Indices: an array with material indices per vertex. + @output Vertices Vertices Face Indices: an array with face index per vertex. + @output Vertex Groups Maps: maps with vertex group names and vertices positions. + @output Vertex Groups Names: an array with the names of the vertex gruops. + + """ + + bl_idname = 'LNGetObjectGeomNode' + bl_label = 'Get Object Geometry Node' + arm_section = 'relations' + arm_version = 1 + + def arm_init(self, context): + self.add_input('ArmNodeSocketObject', 'Object') + + self.add_output('ArmNodeSocketArray', 'Vertices Positions') + self.add_output('ArmNodeSocketArray', 'Vertices Normals') + self.add_output('ArmNodeSocketArray', 'Vertices Indices') + self.add_output('ArmNodeSocketArray', 'Vertices Material Indices') + self.add_output('ArmNodeSocketArray', 'Vertices Face Indices') + self.add_output('ArmDynamicSocket', 'Vertex Groups Maps') + self.add_output('ArmNodeSocketArray', 'Vertex Groups Names') \ No newline at end of file