chaos caused by async
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
index a7698e9bf2fa6f33334d1d2d31de574286b6c873..861d69249efbbfa640412cbe35b216dbbd42229c 100644 (file)
@@ -68,7 +68,8 @@ class mdl_submesh(Structure):
                ("vertex_start",c_uint32),
                ("vertex_count",c_uint32),
                ("bbx",(c_float*3)*2),
-               ("material_id",c_uint32)]        # index into the material array
+               ("material_id",c_uint16), # index into the material array
+               ("flags",c_uint16)]
 #}
 
 class mdl_material(Structure):
@@ -329,6 +330,18 @@ class ent_font(Structure):
                ("glyph_utf32_base",c_uint32)]
 #}
 
+class ent_traffic(Structure):
+#{
+   _fields_ = [("transform",mdl_transform),
+               ("submesh_start",c_uint32),
+               ("submesh_count",c_uint32),
+               ("start_node",c_uint32),
+               ("node_count",c_uint32),
+               ("speed",c_float),
+               ("t",c_float),
+               ("index",c_uint32)]
+#}
+
 def obj_ent_type( obj ):
 #{
    if obj.type == 'ARMATURE': return 'mdl_armature'
@@ -664,25 +677,16 @@ def sr_armature_bones( armature ):
          yield from _recurse_bone( b )
 #}
 
-def sr_compile_mesh( obj ):
+# Returns submesh_start,count and armature_id
+def sr_compile_mesh_internal( obj ):
 #{
-   node=mdl_mesh()
-   compile_obj_transform(obj, node.transform)
-   node.pstr_name = sr_compile_string(obj.name)
-   ent_type = obj_ent_type( obj )
-
-   node.entity_id = 0
-
-   if ent_type != 'none':#{
-      ent_id_lwr = sr_compile.entity_ids[obj.name]
-      ent_id_upr = get_entity_enum_id( obj_ent_type(obj) )
-      node.entity_id = (ent_id_upr << 16) | ent_id_lwr
-   #}
-   print( node.entity_id )
-
    can_use_cache = True
    armature = None
 
+   submesh_start = 0
+   submesh_count = 0
+   armature_id = 0
+
    for mod in obj.modifiers:#{
       if mod.type == 'DATA_TRANSFER' or mod.type == 'SHRINKWRAP' or \
          mod.type == 'BOOLEAN' or mod.type == 'CURVE' or \
@@ -695,7 +699,7 @@ def sr_compile_mesh( obj ):
          armature = mod.object
          rig_weight_groups = \
                ['0 [ROOT]']+[_.name for _ in sr_armature_bones(mod.object)]
-         node.armature_id = sr_compile.entity_ids[armature.name]
+         armature_id = sr_compile.entity_ids[armature.name]
 
          POSE_OR_REST_CACHE = armature.data.pose_position
          armature.data.pose_position = 'REST'
@@ -706,16 +710,15 @@ def sr_compile_mesh( obj ):
    #
    if can_use_cache and (obj.data.name in sr_compile.mesh_cache):#{
       ref = sr_compile.mesh_cache[obj.data.name]
-      node.submesh_start = ref[0]
-      node.submesh_count = ref[1]
-      sr_compile.mesh_data.extend(bytearray(node))
-      return
+      submesh_start = ref[0]
+      submesh_count = ref[1]
+      return (submesh_start,submesh_count,armature_id)
    #}
 
    # Compile a whole new mesh
    #
-   node.submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh)
-   node.submesh_count = 0
+   submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh)
+   submesh_count = 0
 
    dgraph = bpy.context.evaluated_depsgraph_get()
    data = obj.evaluated_get(dgraph).data
@@ -899,16 +902,37 @@ def sr_compile_mesh( obj ):
       # Add submesh to encoder
       #
       sr_compile.submesh_data.extend( bytearray(sm) )
-      node.submesh_count += 1
+      submesh_count += 1
    #}
 
    if armature:#{
       armature.data.pose_position = POSE_OR_REST_CACHE
    #}
 
-   # Save a reference to this node since we want to reuse the submesh indices
+   # Save a reference to this mesh since we want to reuse the submesh indices
    # later.
-   sr_compile.mesh_cache[obj.data.name]=(node.submesh_start,node.submesh_count)
+   sr_compile.mesh_cache[obj.data.name]=(submesh_start,submesh_count)
+   return (submesh_start,submesh_count,armature_id)
+#}
+
+def sr_compile_mesh( obj ):
+#{
+   node=mdl_mesh()
+   compile_obj_transform(obj, node.transform)
+   node.pstr_name = sr_compile_string(obj.name)
+   ent_type = obj_ent_type( obj )
+
+   node.entity_id = 0
+
+   if ent_type != 'none':#{
+      ent_id_lwr = sr_compile.entity_ids[obj.name]
+      ent_id_upr = get_entity_enum_id( obj_ent_type(obj) )
+      node.entity_id = (ent_id_upr << 16) | ent_id_lwr
+   #}
+   
+   node.submesh_start, node.submesh_count, node.armature_id = \
+         sr_compile_mesh_internal( obj )
+
    sr_compile.mesh_data.extend(bytearray(node))
 #}
 
@@ -1274,7 +1298,9 @@ def sr_compile( collection ):
 
    mesh_count = 0
    for obj in collection.all_objects: #{
-      if obj.type == 'MESH': mesh_count += 1
+      if obj.type == 'MESH':#{
+         mesh_count += 1
+      #}
 
       ent_type = obj_ent_type( obj )
       if ent_type == 'none': continue
@@ -1289,6 +1315,16 @@ def sr_compile( collection ):
    for obj in collection.all_objects:#{
       if obj.type == 'MESH':#{
          i+=1
+
+         ent_type = obj_ent_type( obj )
+
+         # entity ignore mesh list
+         #
+         if ent_type == 'ent_traffic': continue
+         if ent_type == 'ent_font': continue
+         if ent_type == 'ent_font_variant': continue
+         #--------------------------
+
          print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' )
          sr_compile_mesh( obj )
       #}
@@ -1468,6 +1504,7 @@ def sr_compile( collection ):
       route_gates = []
       route_curves = []
       routes = []
+      traffics = []
 
       for obj in col.objects:#{
          if obj.type == 'ARMATURE': pass
@@ -1483,6 +1520,8 @@ def sr_compile( collection ):
             #}
             elif ent_type == 'ent_route':
                routes += [obj]
+            elif ent_type == 'ent_traffic':
+               traffics += [obj]
          #}
       #}
 
@@ -1541,6 +1580,52 @@ def sr_compile( collection ):
          sr_ent_push( route )
       #}
 
+      for obj in traffics:#{
+         traffic = ent_traffic()
+         compile_obj_transform( obj, traffic.transform )
+         traffic.submesh_start, traffic.submesh_count, _ = \
+               sr_compile_mesh_internal( obj )
+
+         # find best subsection
+         
+         graph_keys = list(dij.graph)
+         min_dist = 100.0
+         best_point = 0
+
+         for j in range(len(dij.points)):#{
+            point = dij.points[j]
+            dist = (point-obj.location).magnitude
+
+            if dist < min_dist:#{
+               min_dist = dist
+               best_point = j
+            #}
+         #}
+
+         # scan to each edge
+         best_begin = best_point
+         best_end = best_point
+
+         while True:#{
+            map0 = dij.subsections[best_begin]
+            if map0[1] == -1: break
+            best_begin = map0[1]
+         #}
+         while True:#{
+            map1 = dij.subsections[best_end]
+            if map1[2] == -1: break
+            best_end = map1[2]
+         #}
+
+         traffic.start_node = routenode_count + best_begin
+         traffic.node_count = best_end - best_begin
+         traffic.index = best_point - best_begin
+         traffic.speed = obj.SR_data.ent_traffic[0].speed
+         traffic.t = 0.0
+
+         sr_ent_push(traffic)
+      #}
+
       for point in dij.points:#{
          rn = ent_route_node()
          rn.co[0] =  point[0]
@@ -1552,7 +1637,6 @@ def sr_compile( collection ):
       routenode_count += len(dij.points)
    #}
 
-
    print( F"[SR] Writing file" )
 
    file_array_instructions = {}
@@ -1595,7 +1679,7 @@ def sr_compile( collection ):
 
    fp = open( path, "wb" )
    header = mdl_header()
-   header.version = 40
+   header.version = 100
    sr_array_title( header.arrays, \
                    'index', len(file_array_instructions), \
                    sizeof(mdl_array), header_size )
@@ -2492,9 +2576,7 @@ class SR_OBJECT_ENT_FONT(bpy.types.PropertyGroup):
 
 class SR_OBJECT_ENT_TRAFFIC(bpy.types.PropertyGroup):
 #{
-   track: bpy.props.PointerProperty(\
-               type=bpy.types.Object, name='track', \
-               poll=lambda self,obj: sr_filter_ent_type(obj,['ent_route_node']))
+   speed: bpy.props.FloatProperty(default=1.0)
 #}
 
 class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup):