+ node_buffer = []
+ entdata_buffer = []
+ entdata_length = 0
+
+ def emplace_string( s ):
+ nonlocal string_cache, strings_buffer
+
+ if s in string_cache:
+ return string_cache[s]
+
+ string_cache[s] = len( strings_buffer )
+ strings_buffer += (s+'\0').encode('utf-8')
+ return string_cache[s]
+
+ def emplace_material( mat ):
+ nonlocal material_cache, material_buffer
+
+ if mat.name in material_cache:
+ return material_cache[mat.name]
+
+ material_cache[mat.name] = header.material_count
+ dest = mdl_material()
+ dest.pstr_name = emplace_string( mat.name )
+ material_buffer += [dest]
+
+ header.material_count += 1
+ return material_cache[mat.name]
+
+ # Create root or empty node and materials
+ #
+ none_material = c_uint32(69)
+ none_material.name = ""
+ emplace_material( none_material )
+
+ root = mdl_node()
+ root.co[0] = 0
+ root.co[1] = 0
+ root.co[2] = 0
+ root.q[0] = 0
+ root.q[1] = 0
+ root.q[2] = 0
+ root.q[3] = 1
+ root.s[0] = 1
+ root.s[1] = 1
+ root.s[2] = 1
+ root.pstr_name = emplace_string('')
+ root.submesh_start = 0
+ root.submesh_count = 0
+ root.offset = 0
+ root.classtype = 0
+ node_buffer += [root]
+
+ # Do exporting
+ #
+ print( " assigning ids" )
+ header.node_count = 1
+ for obj in collection.all_objects:
+ obj.cv_data.uid = header.node_count
+ header.node_count += 1
+
+ print( " compiling data" )
+ for obj in collection.all_objects:
+ print( F" [{obj.cv_data.uid}/{header.node_count-1}] {obj.name}" )
+
+ node = mdl_node()
+ node.co[0] = obj.location[0]
+ node.co[1] = obj.location[2]
+ node.co[2] = -obj.location[1]
+
+ # Convert rotation quat to our space type
+ quat = obj.matrix_world.to_quaternion()
+ node.q[0] = quat[1]
+ node.q[1] = quat[3]
+ node.q[2] = -quat[2]
+ node.q[3] = quat[0]
+
+ node.s[0] = obj.scale[0]
+ node.s[1] = obj.scale[2]
+ node.s[2] = obj.scale[1]
+ node.pstr_name = emplace_string( obj.name )
+
+ # Process entity data
+ #
+ node.offset = entdata_length
+ classtype = obj.cv_data.classtype
+
+ if classtype == 'k_classtype_none':
+ node.classtype = 0
+ node.offset = 0
+
+ elif classtype == 'k_classtype_gate':
+ node.classtype = 1
+ entdata_length += sizeof( classtype_gate )
+
+ gate = classtype_gate()
+ gate.target = 0
+ if obj.cv_data.target != None:
+ gate.target = obj.cv_data.target.cv_data.uid