well yeah i guess
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
index c069d7f925fa5412562eadee4e9bc5e27dd1e38e..2ed183aa075b7708b8f3b8b021700ea1e7e49ea5 100644 (file)
@@ -47,6 +47,7 @@ class mdl_node(Structure):
    _fields_ = [("co",c_float*3),
                ( "q",c_float*4),
                ( "s",c_float*3),
+               ("sub_uid",c_uint32),        # dont use
                ("submesh_start",c_uint32),
                ("submesh_count",c_uint32),
                ("classtype",c_uint32),
@@ -59,6 +60,8 @@ class mdl_header(Structure):
    _fields_ = [("identifier",c_uint32),
                ("version",c_uint32),
                ("file_length",c_uint32),
+               ("pad0",c_uint32),
+
                ("vertex_count",c_uint32),
                ("vertex_offset",c_uint32),
 
@@ -76,11 +79,16 @@ class mdl_header(Structure):
 
                ("anim_count",c_uint32),
                ("anim_offset",c_uint32),
-
+               
+               ("strings_length",c_uint32),
                ("strings_offset",c_uint32),
+
+               ("entdata_length",c_uint32),
                ("entdata_offset",c_uint32),
-               ("animdata_offset",c_uint32)
-               ]
+
+               ("keyframe_count",c_uint32),
+               ("keyframe_offset",c_uint32)]
+               
 
 class mdl_animation(Structure):
    _pack_ = 1
@@ -187,6 +195,10 @@ def write_model(collection_name):
    header.node_count = 0
    header.material_count = 0
    header.file_length = 0
+
+   header.strings_length = 0
+   header.entdata_length = 0
+   header.keyframe_count = 0
    
    mesh_cache = {}
    string_cache = {}
@@ -200,10 +212,8 @@ def write_model(collection_name):
    indice_buffer = []
    node_buffer = []
    entdata_buffer = []
-   entdata_length = 0
 
    anim_buffer = []
-   animdata_length = 0
    animdata_buffer = []
 
    def emplace_string( s ):
@@ -596,7 +606,7 @@ def write_model(collection_name):
 
       # Process entity data
       # ==================================================================
-      node.offset = entdata_length
+      node.offset = header.entdata_length
 
       if classtype != 'k_classtype_none':
          disptype = classtype
@@ -629,7 +639,7 @@ def write_model(collection_name):
          node.classtype = 12
 
          armature = armature_def['obj']
-         entdata_length += sizeof( classtype_skin )
+         header.entdata_length += sizeof( classtype_skin )
 
          skin = classtype_skin()
          skin.skeleton = armature.cv_data.uid
@@ -637,7 +647,7 @@ def write_model(collection_name):
       
       elif classtype == 'k_classtype_skeleton':
          node.classtype = 11
-         entdata_length += sizeof( classtype_skeleton )
+         header.entdata_length += sizeof( classtype_skeleton )
          skeleton = classtype_skeleton()
 
          armature_def = graph_lookup[obj]
@@ -669,7 +679,7 @@ def write_model(collection_name):
                   anim = mdl_animation()
                   anim.pstr_name = emplace_string( NLAStrip.action.name )
                   anim.rate = 30.0
-                  anim.offset = animdata_length
+                  anim.offset = header.keyframe_count
                   anim.length = anim_end-anim_start
                   
                   # Export the fucking keyframes
@@ -723,7 +733,7 @@ def write_model(collection_name):
                               kf.s[2] = sca[1]
 
                               animdata_buffer += [kf]
-                              animdata_length += sizeof(mdl_keyframe)
+                              header.keyframe_count += 1
                               break
 
                   anim_buffer += [anim]
@@ -739,7 +749,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_bone':
          node.classtype = 10
-         entdata_length += sizeof( classtype_bone )
+         header.entdata_length += sizeof( classtype_bone )
          
          bone = classtype_bone()
          bone.deform = node_def['deform']
@@ -789,7 +799,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_gate':
          node.classtype = 1
-         entdata_length += sizeof( classtype_gate )
+         header.entdata_length += sizeof( classtype_gate )
 
          gate = classtype_gate()
          gate.target = 0
@@ -809,7 +819,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_block':
          node.classtype = 2
-         entdata_length += sizeof( classtype_block )
+         header.entdata_length += sizeof( classtype_block )
 
          source = obj.data.cv_data
 
@@ -826,7 +836,7 @@ def write_model(collection_name):
       elif classtype == 'k_classtype_achievement_box':
          node.classtype = 13
 
-         entdata_length += sizeof( classtype_achievement_box )
+         header.entdata_length += sizeof( classtype_achievement_box )
          ach = classtype_achievement_box()
          ach.pstr_name = emplace_string( obj.cv_data.strp )
          ach.trigger = 0
@@ -839,7 +849,7 @@ def write_model(collection_name):
       elif classtype == 'k_classtype_audio':
          node.classtype = 14
 
-         entdata_length += sizeof( classtype_audio )
+         header.entdata_length += sizeof( classtype_audio )
          aud = classtype_audio()
          aud.pstr_file = emplace_string( obj.cv_data.strp )
          aud.flags = obj.cv_data.intp
@@ -855,7 +865,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_car_path':
          node.classtype = 5
-         entdata_length += sizeof( classtype_car_path )
+         header.entdata_length += sizeof( classtype_car_path )
 
          pn = classtype_car_path()
          pn.target = 0
@@ -872,7 +882,7 @@ def write_model(collection_name):
          target = obj.instance_collection
 
          node.classtype = 6
-         entdata_length += sizeof( classtype_instance )
+         header.entdata_length += sizeof( classtype_instance )
 
          inst = classtype_instance()
          inst.pstr_file = emplace_string( F"models/{target.name}.mdl" )
@@ -883,7 +893,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_route_node':
          node.classtype = 8
-         entdata_length += sizeof( classtype_route_node )
+         header.entdata_length += sizeof( classtype_route_node )
 
          rn = classtype_route_node()
          if obj.cv_data.target != None: 
@@ -895,7 +905,7 @@ def write_model(collection_name):
 
       elif classtype == 'k_classtype_route':
          node.classtype = 9
-         entdata_length += sizeof( classtype_route )
+         header.entdata_length += sizeof( classtype_route )
          r = classtype_route()
          r.colour[0] = obj.cv_data.colour[0]
          r.colour[1] = obj.cv_data.colour[1]
@@ -914,8 +924,7 @@ def write_model(collection_name):
       node_buffer += [node]
 
    # Write data arrays
-   #
-   header.anim_count = len(anim_buffer)
+   # TODO: 8 BYTE ALIGNMENT
 
    print( "Writing data" )
    fpos = sizeof(header)
@@ -932,13 +941,24 @@ def write_model(collection_name):
    header.material_offset = fpos
    fpos += sizeof(mdl_material)*header.material_count
 
-   print( F"Animation count: {header.anim_count}" )
+   print( F"Animation count: {len(anim_buffer)}" )
+   header.anim_count = len(anim_buffer)
    header.anim_offset = fpos
    fpos += sizeof(mdl_animation)*header.anim_count
 
-   print( F"Entdata length: {entdata_length}" )
+   print( F"Entdata length: {header.entdata_length}" )
    header.entdata_offset = fpos
-   fpos += entdata_length
+   fpos += header.entdata_length
+   
+   print( F"Strings length: {len(strings_buffer)}" )
+   header.strings_offset = fpos
+   header.strings_length = len(strings_buffer)
+   fpos += header.strings_length
+   
+   # Optional array things
+   print( F"Keyframe count: {header.keyframe_count}" )
+   header.keyframe_offset = fpos
+   fpos += sizeof(mdl_keyframe)*header.keyframe_count
    
    print( F"Vertex count: {header.vertex_count}" )
    header.vertex_offset = fpos
@@ -948,14 +968,6 @@ def write_model(collection_name):
    header.indice_offset = fpos
    fpos += sizeof(c_uint32)*header.indice_count
 
-   print( F"Keyframe count: {animdata_length}" )
-   header.animdata_offset = fpos
-   fpos += animdata_length
-   
-   print( F"Strings length: {len(strings_buffer)}" )
-   header.strings_offset = fpos
-   fpos += len(strings_buffer)
-
    header.file_length = fpos
 
    path = F"/home/harry/Documents/carve/models_src/{collection_name}.mdl"
@@ -973,14 +985,17 @@ def write_model(collection_name):
       fp.write( bytearray(a) )
    for ed in entdata_buffer:
       fp.write( bytearray(ed) )
+
+   fp.write( strings_buffer )
+
+   for kf in animdata_buffer:
+      fp.write( bytearray(kf) )
+
    for v in vertex_buffer:
       fp.write( bytearray(v) )
    for i in indice_buffer:
       fp.write( bytearray(i) )
-   for kf in animdata_buffer:
-      fp.write( bytearray(kf) )
 
-   fp.write( strings_buffer )
    fp.close()
 
    print( F"Completed {collection_name}.mdl" )