Metascene compiler & load in-game for player. (BREAKS NPC ANIMATIONS) master
authorhgn <hgodden00@gmail.com>
Thu, 19 Sep 2024 20:02:21 +0000 (21:02 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 19 Sep 2024 20:02:21 +0000 (21:02 +0100)
63 files changed:
build.c
content_skaterift/metascenes/skater.ms [new file with mode: 0644]
scene_desc.md.html [new file with mode: 0644]
skaterift_blender/__init__.py
skaterift_blender/sr_bin.py [new file with mode: 0644]
skaterift_blender/sr_main.py
skaterift_blender/sr_mat.py
skaterift_blender/sr_metascene.py [new file with mode: 0644]
src/array_file.c [new file with mode: 0644]
src/array_file.h [new file with mode: 0644]
src/build_control_overlay.c
src/control_overlay.c
src/ent_challenge.c
src/ent_glider.c
src/ent_miniworld.c
src/ent_npc.c
src/ent_objective.c
src/ent_region.c
src/ent_relay.c
src/ent_route.c
src/ent_skateshop.c
src/ent_tornado.c
src/ent_traffic.c
src/entity.c
src/entity.h
src/font.h
src/gui.h
src/menu.c
src/metascene.c [new file with mode: 0644]
src/metascene.h [new file with mode: 0644]
src/model.c
src/model.h
src/player.c
src/player.h
src/player_api.h
src/player_dead.c
src/player_dead.h
src/player_drive.c
src/player_drive.h
src/player_glide.c
src/player_glide.h
src/player_ragdoll.c
src/player_render.c
src/player_render.h
src/player_skate.c
src/player_skate.h
src/player_walk.c
src/player_walk.h
src/scene.c
src/skaterift.c
src/skeleton.h
src/workshop.c
src/world.h
src/world_entity.c
src/world_gate.c
src/world_gen.c
src/world_load.c
src/world_map.c
src/world_render.c
src/world_routes.c
src/world_routes_ui.c
src/world_sfd.c
src/world_volumes.c

diff --git a/build.c b/build.c
index 692e94104e3485d5e0ecfd63422b3a71af350a72..dea267cbdba7dcbcabccd1202084cba79a118eec 100644 (file)
--- a/build.c
+++ b/build.c
@@ -10,6 +10,7 @@
 #include "vg/vg_m.h"
 #include "src/model.h"
 #include "src/model.c"
+#include "src/array_file.c"
 
 /* 
  * Addon metadata utilities 
@@ -143,6 +144,7 @@ void build_game_content( struct vg_project *proj )
    vg_symlink( proj, "content_skaterift/maps", "maps" );
    vg_symlink( proj, "content_skaterift/sound", "sound" );
    vg_symlink( proj, "content_skaterift/playermodels", "playermodels" );
+   vg_symlink( proj, "content_skaterift/metascenes", "metascenes" );
    vg_syscall( "mkdir -p bin/%s/cfg", proj->uid.buffer );
    vg_syscall( "mkdir -p bin/%s/savedata", proj->uid.buffer );
    vg_syscall( "mkdir -p bin/%s/tools", proj->uid.buffer );
diff --git a/content_skaterift/metascenes/skater.ms b/content_skaterift/metascenes/skater.ms
new file mode 100644 (file)
index 0000000..d14e956
Binary files /dev/null and b/content_skaterift/metascenes/skater.ms differ
diff --git a/scene_desc.md.html b/scene_desc.md.html
new file mode 100644 (file)
index 0000000..2d2b07e
--- /dev/null
@@ -0,0 +1,32 @@
+**VG Scene setup**
+
+********************************************************************************
+*         Source .blend tree                      ┊      Output Directory
+*-------------------------------------------------------------------------------
+*                                                 ┊        
+*                                                 ┊        models/
+* characters.blend -----------------------------------+----> ch_Marc.mdl         
+*  |                                              ┊   '----> ch_Jeff.mdl
+*  +--Marc-----.                                  ┊        
+*  '--Jeff      |                scenes.blend --------+----> mp_Home.mdl 
+*               |                |                ┊   '----> mp_River.mdl 
+*               |                +--Home          ┊                 
+*               |                '--River----.    ┊
+*               |                             |   ┊        metascenes/
+*               |    cutscene.001.blend ------)------------> cutscene.001.ms
+*               |     |                       |   ┊         
+*               |'--> +--<->Marc              |   ┊         
+*               |     '--<->River <----------'    ┊
+*               |                                 ┊
+*               |    skaterift_anims.blend ----------------> skaterift_anims.ms
+*               |     |                           ┊
+*                '--> +--<->Marc                  ┊
+*                                                 ┊
+********************************************************************************
+
+- Metascenes export all the animations for every object in the blend file
+- The only things that are *in* metascene files are references to other files,
+  cameras, and animation data.
+- Geometry is exported using the regular Skate-Rift Exporter
+
+<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js"></script><script src="https://casual-effects.com/markdeep/latest/markdeep.min.js?"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>
index 32857326a051773ee9d5cff851a56697f44e30f9..3017a739592e0d2620893471da09aee8e1b1b350 100644 (file)
@@ -25,10 +25,12 @@ def _include( file ):
    src.close()
 #}
 
+_include( "sr_bin.py" )
 _include( "sr_main.py" )
 _include( "sr_so.py" )
 _include( "sr_shader.py" )
 _include( "sr_mat.py" )
+_include( "sr_metascene.py" )
 
 out.close()
 
diff --git a/skaterift_blender/sr_bin.py b/skaterift_blender/sr_bin.py
new file mode 100644 (file)
index 0000000..cd91873
--- /dev/null
@@ -0,0 +1,150 @@
+from ctypes import *
+
+print( "sr_bin" )
+
+class bin_string_cache:
+#{
+   def __init__(_, alignment):
+   #{
+      _.table = {}
+      _.buffer = bytearray()
+      _.alignment = alignment
+   #}
+#}
+
+def int_align_to( v, align ):
+#{
+   while(v%align)!=0: v += 1
+   return v
+#}
+
+def bytearray_align_to( buffer, align, w=b'\xaa' ):
+#{
+   while (len(buffer) % align) != 0: buffer.extend(w)
+#}
+
+def fp_align( fp, align, w=b'\xaa' ):
+#{
+   while (fp.tell() % align) != 0: fp.write(w)
+#}
+
+def bytearray_print_hex( s, w=16 ):
+#{
+   for r in range((len(s)+(w-1))//w):#{
+      i0=(r+0)*w
+      i1=min((r+1)*w,len(s))
+      print( F'{r*w:06x}| \x1B[31m', end='')
+      print( F"{' '.join('{:02x}'.format(x) for x in s[i0:i1]):<48}",end='' )
+      print( "\x1B[0m", end='')
+      print( ''.join(chr(x) if (x>=33 and x<=126) else '.' for x in s[i0:i1] ) )
+   #}
+#}
+
+def pack_string( cache, s ):
+#{
+   if s in cache.table: return cache.table[s]
+   
+   index = len( cache.buffer )
+   cache.table[s] = index
+   cache.buffer.extend( c_uint32(hash_djb2(s)) )
+   cache.buffer.extend( s.encode('utf-8') )
+   cache.buffer.extend( b'\0' )
+
+   bytearray_align_to( cache.buffer, cache.alignment )
+   return index
+#}
+
+def vg_str_bin( s ):
+#{
+   decoded = bytearray()
+   for i in range(len(s)//2):#{
+      c  = (ord(s[i*2+0])-0x41)
+      c |= (ord(s[i*2+1])-0x41)<<4
+      decoded.extend(bytearray(c_uint8(c))) #??
+   #}
+   return decoded
+#}
+
+#
+# Array file type.
+# -----------------------------------------------
+#
+
+class array_file_meta(Structure):
+#{
+   _fields_ = [("file_offset",c_uint32),
+               ("item_count",c_uint32),
+               ("item_size",c_uint32),
+               ("name",c_byte*16)]
+#}
+
+def str_into_buf( str, buf ):
+#{
+   for i in range(len(str)):
+      buf[i] = ord(str[i])
+#}
+
+#
+# header must have the attribute 'index' which is an array_file_meta()
+# arrays must be a dictionary with entries of bytearray or ctypes struct arrays
+#
+def array_file_write( path, header, arrays, padding=8 ):
+#{
+   num_arrays = len(arrays)
+   header_size = int_align_to( sizeof(header), padding )
+   index_size = int_align_to( sizeof(array_file_meta)*num_arrays, padding )
+
+   fp = open( path, "wb" )
+
+   # Header & index ptr
+   # 
+   header.index.file_offset = header_size
+   header.index.item_count = len(arrays)
+   header.index.item_size = sizeof(array_file_meta)
+   str_into_buf( 'index', header.index.name )
+   fp.write( header )
+   fp_align( fp, padding )
+   
+   # Create index
+   #
+   file_offset = header_size + index_size
+   for name, arr in arrays.items():
+   #{
+      meta = array_file_meta()
+      str_into_buf( name, meta.name )
+      meta.file_offset = file_offset
+      meta.item_count = len(arr)
+
+      if type(arr) is bytearray:
+         meta.item_size = 1 
+      else:
+         meta.item_size = sizeof(arr[0]) if len(arr) else 0
+
+      print( F'[AF] {name:>16}| {meta.item_count: 8}  0x{file_offset:02x}' )
+      file_offset += int_align_to( meta.item_size*meta.item_count, padding )
+
+      fp.write( meta )
+   #}
+   fp_align( fp, padding )
+
+   # Write actual arrays
+   #
+   for name, arr in arrays.items():
+   #{
+      if type(arr) is bytearray:
+      #{
+         fp.write( arr )
+      #}
+      else:
+      #{
+         for item in arr:
+         #{
+            fp.write( bytearray(item) )
+         #}
+      #}
+
+      fp_align( fp, padding )
+   #}
+
+   fp.close()
+#}
index e35e675c0cf6ff710d7742656fc2642f5a46ee3f..1ec554fd3e65e2e6eaffa57613267db963ede1bc 100644 (file)
@@ -39,7 +39,7 @@ sr_entity_list = [
    ('ent_npc',          'npc',            '', 27 )
 ]
 
-MDL_VERSION_NR = 106
+MDL_VERSION_NR = 107
 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \
                    'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\
                    'ent_miniworld', 'ent_region', 'ent_glider', 'ent_list',\
@@ -143,8 +143,10 @@ class mdl_armature(Structure):
    _fields_ = [("transform",mdl_transform),
                ("bone_start",c_uint32),
                ("bone_count",c_uint32),
-               ("anim_start",c_uint32),
-               ("anim_count",c_uint32)]
+               ("anim_start",c_uint32), # obsolete 107+
+               ("anim_count",c_uint32), # .
+               # v107+
+               ("pstr_name",c_uint32)]
 #}
 
 class mdl_animation(Structure):
@@ -171,18 +173,10 @@ class mdl_texture(Structure):
                ("glname",c_uint32)]
 #}
 
-class mdl_array(Structure):
-#{
-   _fields_ = [("file_offset",c_uint32),
-               ("item_count",c_uint32),
-               ("item_size",c_uint32),
-               ("name",c_byte*16)]
-#}
-
 class mdl_header(Structure):
 #{
    _fields_ = [("version",c_uint32),
-               ("arrays",mdl_array)]
+               ("index",array_file_meta)]
 #}
 
 class ent_spawn(Structure):
@@ -682,87 +676,28 @@ def compile_obj_transform( obj, transform ):
    transform.s[2] = s[1]
 #}
 
-def int_align_to( v, align ):
-#{
-   while(v%align)!=0: v += 1
-   return v
-#}
-
-def bytearray_align_to( buffer, align, w=b'\xaa' ):
-#{
-   while (len(buffer) % align) != 0: buffer.extend(w)
-   return buffer
-#}
-
-def bytearray_print_hex( s, w=16 ):
-#{
-   for r in range((len(s)+(w-1))//w):#{
-      i0=(r+0)*w
-      i1=min((r+1)*w,len(s))
-      print( F'{r*w:06x}| \x1B[31m', end='')
-      print( F"{' '.join('{:02x}'.format(x) for x in s[i0:i1]):<48}",end='' )
-      print( "\x1B[0m", end='')
-      print( ''.join(chr(x) if (x>=33 and x<=126) else '.' for x in s[i0:i1] ) )
-   #}
-#}
-
-def sr_compile_string( s ):
-#{
-   if s in sr_compile.string_cache: return sr_compile.string_cache[s]
-   
-   index = len( sr_compile.string_data )
-   sr_compile.string_cache[s] = index
-   sr_compile.string_data.extend( c_uint32(hash_djb2(s)) )
-   sr_compile.string_data.extend( s.encode('utf-8') )
-   sr_compile.string_data.extend( b'\0' )
-
-   bytearray_align_to( sr_compile.string_data, 4 )
-   return index
-#}
-
-def vg_str_bin( s ):
-#{
-   decoded = bytearray()
-   for i in range(len(s)//2):#{
-      c  = (ord(s[i*2+0])-0x41)
-      c |= (ord(s[i*2+1])-0x41)<<4
-      decoded.extend(bytearray(c_uint8(c))) #??
-   #}
-   return decoded
-#}
-
-def sr_pack_file( file, path, data ):
-#{
-   file.path = sr_compile_string( path )
-   file.pack_offset = len( sr_compile.pack_data )
-   file.pack_size = len( data )
-
-   sr_compile.pack_data.extend( data )
-   bytearray_align_to( sr_compile.pack_data, 16 )
-#}
-
 def sr_compile_texture( img ):
 #{
    if img == None:
       return 0
 
    name = os.path.splitext( img.name )[0]
-
    if name in sr_compile.texture_cache:
       return sr_compile.texture_cache[name]
 
-   texture_index = (len(sr_compile.texture_data)//sizeof(mdl_texture)) +1
+   texture_index = len(sr_compile.textures) +1
 
    tex = mdl_texture()
    tex.glname = 0
 
-   if sr_compile.pack_textures:#{
+   if sr_compile.pack_textures:
+   #{
       filedata = qoi_encode( img )
       sr_pack_file( tex.file, name, filedata )
    #}
 
    sr_compile.texture_cache[name] = texture_index
-   sr_compile.texture_data.extend( bytearray(tex) )
+   sr_compile.textures.append( tex )
    return texture_index
 #}
 
@@ -828,13 +763,15 @@ def sr_compile_mesh_internal( obj ):
 
    # Compile a whole new mesh
    #
-   submesh_start = len(sr_compile.submesh_data)//sizeof(mdl_submesh)
+   submesh_start = len( sr_compile.submeshes )
    submesh_count = 0
 
    dgraph = bpy.context.evaluated_depsgraph_get()
    data = obj.evaluated_get(dgraph).data
    data.calc_loop_triangles()
-   data.calc_normals_split()
+
+   if bpy.app.version < (4,1,0):
+      data.calc_normals_split()
    
    # Mesh is split into submeshes based on their material
    #
@@ -843,8 +780,8 @@ def sr_compile_mesh_internal( obj ):
       mref = {}
 
       sm = mdl_submesh()
-      sm.indice_start = len(sr_compile.indice_data)//sizeof(c_uint32)
-      sm.vertex_start = len(sr_compile.vertex_data)//sizeof(mdl_vert)
+      sm.indice_start = len( sr_compile.indices )
+      sm.vertex_start = len( sr_compile.vertices )
       sm.vertex_count = 0
       sm.indice_count = 0
       sm.material_id = sr_compile_material( mat )
@@ -964,7 +901,7 @@ def sr_compile_mesh_internal( obj ):
             if key in vertex_reference:
                index = vertex_reference[key]
             else:#{
-               index = bytearray(c_uint32(sm.vertex_count))
+               index = c_uint32(sm.vertex_count)
                sm.vertex_count+=1
                
                vertex_reference[key] = index
@@ -995,11 +932,11 @@ def sr_compile_mesh_internal( obj ):
                   sm.bbx[1][i] = max( sm.bbx[1][i], v.co[i] )
                #}
 
-               sr_compile.vertex_data.extend(bytearray(v))
+               sr_compile.vertices.append(v)
             #}
             
             sm.indice_count += 1
-            sr_compile.indice_data.extend( index )
+            sr_compile.indices.append( index )
          #}
       #}
       
@@ -1012,7 +949,7 @@ def sr_compile_mesh_internal( obj ):
 
       # Add submesh to encoder
       #
-      sr_compile.submesh_data.extend( bytearray(sm) )
+      sr_compile.submeshes.append( sm )
       submesh_count += 1
    #}
 
@@ -1044,7 +981,7 @@ def sr_compile_mesh( obj ):
    node.submesh_start, node.submesh_count, node.armature_id = \
          sr_compile_mesh_internal( obj )
 
-   sr_compile.mesh_data.extend(bytearray(node))
+   sr_compile.meshes.append( node )
 #}
 
 def sr_compile_fonts( collection ):
@@ -1103,7 +1040,7 @@ def sr_compile_fonts( collection ):
          for j in range(glyph_range):#{
             data_glyph = data.glyphs[j]
             glyph = ent_glyph()
-            glyph.indice_start = len(sr_compile.indice_data)//sizeof(c_uint32)
+            glyph.indice_start = len( sr_compile.indices )
             glyph.indice_count = 0
             glyph.size[0] = data_glyph.bounds[2]
             glyph.size[1] = data_glyph.bounds[3]
@@ -1148,8 +1085,8 @@ def sr_compile_fonts( collection ):
                      if key in vertex_reference:
                         index = vertex_reference[key]
                      else:#{
-                        vindex = len(sr_compile.vertex_data)//sizeof(mdl_vert)
-                        index = bytearray(c_uint32(vindex))
+                        vindex = len( sr_compile.vertices )
+                        index = c_uint32(vindex)
                         vertex_reference[key] = index
                         v = mdl_vert()
                         v.co[0]   =  co[0]
@@ -1161,11 +1098,11 @@ def sr_compile_fonts( collection ):
                         v.uv[0]   =  uv[0]
                         v.uv[1]   =  uv[1]
                         
-                        sr_compile.vertex_data.extend(bytearray(v))
+                        sr_compile.vertices.append( v )
                      #}
                      
                      glyph.indice_count += 1
-                     sr_compile.indice_data.extend( index )
+                     sr_compile.indices.append( index )
                   #}
                #}
             #}
@@ -1259,22 +1196,25 @@ def sr_compile_menus( collection ):
 def sr_compile_armature( obj ):
 #{
    node = mdl_armature()
-   node.bone_start = len(sr_compile.bone_data)//sizeof(mdl_bone)
+   node.pstr_name = sr_compile_string( obj.name )
+   node.bone_start = len( sr_compile.bones )
    node.bone_count = 0
-   node.anim_start = len(sr_compile.anim_data)//sizeof(mdl_animation)
-   node.anim_count = 0
+   node.anim_start = len(sr_compile.anim_data)//sizeof(mdl_animation)
+   node.anim_count = 0
    
    bones = [_ for _ in sr_armature_bones(obj)]
    bones_names = [None]+[_.name for _ in bones]
 
-   for b in bones:#{
+   for b in bones:
+   #{
       bone = mdl_bone()
       if b.use_deform: bone.flags = 0x1
       if b.parent: bone.parent = bones_names.index(b.parent.name)
 
       bone.collider = int(b.SR_data.collider)
 
-      if bone.collider>0:#{
+      if bone.collider>0:
+      #{
          bone.hitbox[0][0] =  b.SR_data.collider_min[0]
          bone.hitbox[0][1] =  b.SR_data.collider_min[2]
          bone.hitbox[0][2] = -b.SR_data.collider_max[1]
@@ -1283,7 +1223,8 @@ def sr_compile_armature( obj ):
          bone.hitbox[1][2] = -b.SR_data.collider_min[1]
       #}
   
-      if b.SR_data.cone_constraint:#{
+      if b.SR_data.cone_constraint:
+      #{
          bone.flags |= 0x4
          bone.conevx[0] =  b.SR_data.conevx[0]
          bone.conevx[1] =  b.SR_data.conevx[2]
@@ -1305,8 +1246,10 @@ def sr_compile_armature( obj ):
       bone.end[2] = -b.tail_local[1] - bone.co[2]
       bone.pstr_name = sr_compile_string( b.name )
 
-      for c in obj.pose.bones[b.name].constraints:#{
-         if c.type == 'IK':#{
+      for c in obj.pose.bones[b.name].constraints:
+      #{
+         if c.type == 'IK':
+         #{
             bone.flags |= 0x2
             bone.ik_target = bones_names.index(c.subtarget)
             bone.ik_pole = bones_names.index(c.pole_subtarget)
@@ -1314,139 +1257,125 @@ def sr_compile_armature( obj ):
       #}
 
       node.bone_count += 1
-      sr_compile.bone_data.extend(bytearray(bone))
-   #}
-
-   # Compile anims
-   #
-   if obj.animation_data and sr_compile.pack_animations: #{
-      # So we can restore later
-      #
-      previous_frame  = bpy.context.scene.frame_current
-      previous_action = obj.animation_data.action
-      POSE_OR_REST_CACHE = obj.data.pose_position
-      obj.data.pose_position = 'POSE'
-
-      for NLALayer in obj.animation_data.nla_tracks:#{
-         for NLAStrip in NLALayer.strips:#{
-            # set active
-            #
-            for a in bpy.data.actions:#{
-               if a.name == NLAStrip.name:#{
-                  obj.animation_data.action = a
-                  break
-               #}
-            #}
-            
-            # Clip to NLA settings
-            #
-            anim_start = int(NLAStrip.action_frame_start)
-            anim_end   = int(NLAStrip.action_frame_end)
-
-            # Export strips
-            #
-            anim = mdl_animation()
-            anim.pstr_name = sr_compile_string( NLAStrip.action.name )
-            anim.rate = 30.0
-            anim.keyframe_start = len(sr_compile.keyframe_data)//\
-                                      sizeof(mdl_transform)
-            anim.length = anim_end-anim_start
-            
-            i = 0
-            # Export the keyframes
-            for frame in range(anim_start,anim_end):#{
-               bpy.context.scene.frame_set(frame)
-               
-               for rb in bones:#{
-                  pb = obj.pose.bones[rb.name]
-                  
-                  # relative bone matrix
-                  if rb.parent is not None:#{
-                     offset_mtx = rb.parent.matrix_local
-                     offset_mtx = offset_mtx.inverted_safe() @ \
-                                  rb.matrix_local
-
-                     inv_parent = pb.parent.matrix @ offset_mtx
-                     inv_parent.invert_safe()
-                     fpm = inv_parent @ pb.matrix 
-                  #}
-                  else:#{
-                     bone_mtx = rb.matrix.to_4x4()
-                     local_inv = rb.matrix_local.inverted_safe()
-                     fpm = bone_mtx @ local_inv @ pb.matrix
-                  #}
-
-                  loc, rot, sca = fpm.decompose()
-                  
-                  # rotation
-                  lc_m = pb.matrix_channel.to_3x3()
-                  if pb.parent is not None:#{
-                     smtx = pb.parent.matrix_channel.to_3x3()
-                     lc_m = smtx.inverted() @ lc_m
-                  #}
-                  rq = lc_m.to_quaternion()
-                  q_normalize( rq )
-
-                  kf = mdl_transform()
-                  kf.co[0] =  loc[0]
-                  kf.co[1] =  loc[2]
-                  kf.co[2] = -loc[1]
-                  kf.q[0]  =  rq[1]
-                  kf.q[1]  =  rq[3]
-                  kf.q[2]  = -rq[2]
-                  kf.q[3]  =  rq[0]
-                  kf.s[0]  = sca[0]
-                  kf.s[1]  = sca[1]
-                  kf.s[2]  = sca[2]
-                  sr_compile.keyframe_data.extend(bytearray(kf))
-                  
-                  i+=1
-               #}
-            #}
-            
-            # Add to animation buffer
-            #
-            sr_compile.anim_data.extend(bytearray(anim))
-            node.anim_count += 1
-
-            # Report progress
-            #
-            print( F"[SR]    | anim( {NLAStrip.action.name} )" )
-         #}
-      #}
-      
-      # Restore context to how it was before
-      #
-      bpy.context.scene.frame_set( previous_frame )
-      obj.animation_data.action = previous_action
-      obj.data.pose_position = POSE_OR_REST_CACHE
+      sr_compile.bones.append( bone )
    #}
 
-   sr_compile.armature_data.extend(bytearray(node))
+   ### # Compile anims
+   ### #
+   ### if obj.animation_data and sr_compile.pack_animations: #{
+   ###    # So we can restore later
+   ###    #
+   ###    previous_frame  = bpy.context.scene.frame_current
+   ###    previous_action = obj.animation_data.action
+   ###    POSE_OR_REST_CACHE = obj.data.pose_position
+   ###    obj.data.pose_position = 'POSE'
+
+   ###    for NLALayer in obj.animation_data.nla_tracks:#{
+   ###       for NLAStrip in NLALayer.strips:#{
+   ###          # set active
+   ###          #
+   ###          for a in bpy.data.actions:#{
+   ###             if a.name == NLAStrip.name:#{
+   ###                obj.animation_data.action = a
+   ###                break
+   ###             #}
+   ###          #}
+   ###          
+   ###          # Clip to NLA settings
+   ###          #
+   ###          anim_start = int(NLAStrip.action_frame_start)
+   ###          anim_end   = int(NLAStrip.action_frame_end)
+
+   ###          # Export strips
+   ###          #
+   ###          anim = mdl_animation()
+   ###          anim.pstr_name = sr_compile_string( NLAStrip.action.name )
+   ###          anim.rate = 30.0
+   ###          anim.keyframe_start = len(sr_compile.keyframe_data)//\
+   ###                                    sizeof(mdl_transform)
+   ###          anim.length = anim_end-anim_start
+   ###          
+   ###          i = 0
+   ###          # Export the keyframes
+   ###          for frame in range(anim_start,anim_end):#{
+   ###             bpy.context.scene.frame_set(frame)
+   ###             
+   ###             for rb in bones:#{
+   ###                pb = obj.pose.bones[rb.name]
+   ###                
+   ###                # relative bone matrix
+   ###                if rb.parent is not None:#{
+   ###                   offset_mtx = rb.parent.matrix_local
+   ###                   offset_mtx = offset_mtx.inverted_safe() @ \
+   ###                                rb.matrix_local
+
+   ###                   inv_parent = pb.parent.matrix @ offset_mtx
+   ###                   inv_parent.invert_safe()
+   ###                   fpm = inv_parent @ pb.matrix 
+   ###                #}
+   ###                else:#{
+   ###                   bone_mtx = rb.matrix.to_4x4()
+   ###                   local_inv = rb.matrix_local.inverted_safe()
+   ###                   fpm = bone_mtx @ local_inv @ pb.matrix
+   ###                #}
+
+   ###                loc, rot, sca = fpm.decompose()
+   ###                
+   ###                # rotation
+   ###                lc_m = pb.matrix_channel.to_3x3()
+   ###                if pb.parent is not None:#{
+   ###                   smtx = pb.parent.matrix_channel.to_3x3()
+   ###                   lc_m = smtx.inverted() @ lc_m
+   ###                #}
+   ###                rq = lc_m.to_quaternion()
+   ###                q_normalize( rq )
+
+   ###                kf = mdl_transform()
+   ###                kf.co[0] =  loc[0]
+   ###                kf.co[1] =  loc[2]
+   ###                kf.co[2] = -loc[1]
+   ###                kf.q[0]  =  rq[1]
+   ###                kf.q[1]  =  rq[3]
+   ###                kf.q[2]  = -rq[2]
+   ###                kf.q[3]  =  rq[0]
+   ###                kf.s[0]  = sca[0]
+   ###                kf.s[1]  = sca[1]
+   ###                kf.s[2]  = sca[2]
+   ###                sr_compile.keyframes.append(kf)
+   ###                
+   ###                i+=1
+   ###             #}
+   ###          #}
+   ###          
+   ###          # Add to animation buffer
+   ###          #
+   ###          sr_compile.anim_data.extend(bytearray(anim))
+   ###          node.anim_count += 1
+
+   ###          # Report progress
+   ###          #
+   ###          print( F"[SR]    | anim( {NLAStrip.action.name} )" )
+   ###       #}
+   ###    #}
+   ###    
+   ###    # Restore context to how it was before
+   ###    #
+   ###    bpy.context.scene.frame_set( previous_frame )
+   ###    obj.animation_data.action = previous_action
+   ###    obj.data.pose_position = POSE_OR_REST_CACHE
+   ### #}
+
+   sr_compile.armatures.append( node )
 #}
 
 def sr_ent_push( struct ):
 #{
    clase = type(struct).__name__
 
-   if clase not in sr_compile.entity_data:#{
-      sr_compile.entity_data[ clase ] = bytearray()
-      sr_compile.entity_info[ clase ] = { 'size': sizeof(struct) }
-   #}
-
-   index = len(sr_compile.entity_data[ clase ])//sizeof(struct)
-   sr_compile.entity_data[ clase ].extend( bytearray(struct) )
-   return index
-#}
-
-def sr_array_title( arr, name, count, size, offset ):
-#{
-   for i in range(len(name)):#{
-      arr.name[i] = ord(name[i])
-   #}
-   arr.file_offset = offset
-   arr.item_count = count
-   arr.item_size = size
+   if clase not in sr_compile.entity_data:
+      sr_compile.entity_data[ clase ] = [ struct ]
+   else:
+      sr_compile.entity_data[ clase ].append( struct )
 #}
 
 def hash_djb2(s):
@@ -1458,6 +1387,22 @@ def hash_djb2(s):
    return picadillo
 #}
 
+def sr_pack_file( file, path, data ):
+#{
+   file.path = sr_compile_string( path )
+   file.pack_offset = len( sr_compile.pack_data )
+   file.pack_size = len( data )
+
+   sr_compile.pack_data.extend( data )
+   bytearray_align_to( sr_compile.pack_data, 16 )
+#}
+
+# Smol wrapper so we don't have to edit everything
+def sr_compile_string( string ):
+#{
+   return pack_string( sr_compile.string_cache, string )
+#}
+
 def sr_compile( collection ):
 #{
    print( F"[SR] compiler begin ({collection.name}.mdl)" )
@@ -1468,26 +1413,25 @@ def sr_compile( collection ):
    sr_compile.pack_animations = collection.SR_data.animations
 
    # caches
-   sr_compile.string_cache = {}
+   sr_compile.string_cache = bin_string_cache(alignment=4)
    sr_compile.mesh_cache = {}
    sr_compile.material_cache = {}
    sr_compile.texture_cache = {}
    
    # compiled data
-   sr_compile.mesh_data = bytearray()
-   sr_compile.submesh_data = bytearray()
-   sr_compile.vertex_data = bytearray()
-   sr_compile.indice_data = bytearray()
-   sr_compile.bone_data = bytearray()
-   sr_compile.material_data = bytearray()
+   sr_compile.meshes = []
+   sr_compile.submeshes = []
+   sr_compile.vertices = []
+   sr_compile.indices = []
+   sr_compile.bones = []
+   sr_compile.materials = []
    sr_compile.shader_data = bytearray()
-   sr_compile.armature_data = bytearray()
-   sr_compile.anim_data = bytearray()
-   sr_compile.keyframe_data = bytearray()
-   sr_compile.texture_data = bytearray()
+   sr_compile.armatures = []
+   #sr_compile.anim_data = bytearray()
+   #sr_compile.keyframe_data = bytearray()
+   sr_compile.textures = []
    
    # just bytes not structures
-   sr_compile.string_data = bytearray()
    sr_compile.pack_data = bytearray()
 
    # variable
@@ -1519,8 +1463,10 @@ def sr_compile( collection ):
 
    print( F"[SR] Compiling geometry" )
    i=0
-   for obj in collection.all_objects:#{
-      if obj.type == 'MESH':#{
+   for obj in collection.all_objects:
+   #{
+      if obj.type == 'MESH':
+      #{
          i+=1
 
          ent_type = obj_ent_type( obj )
@@ -1536,7 +1482,8 @@ def sr_compile( collection ):
          if ent_type == 'ent_region': continue
 
          #TODO: This is messy.
-         if ent_type == 'ent_gate':#{
+         if ent_type == 'ent_gate':
+         #{
             obj_data = obj.SR_data.ent_gate[0]
             if obj_data.custom: continue
          #}
@@ -2058,74 +2005,35 @@ def sr_compile( collection ):
 
    print( F"[SR] Writing file" )
 
-   file_array_instructions = {}
-   file_offset = 0
-
-   def _write_array( name, item_size, data ):#{
-      nonlocal file_array_instructions, file_offset
-
-      count = len(data)//item_size
-      file_array_instructions[name] = {'count':count, 'size':item_size,\
-                                       'data':data, 'offset': file_offset}
-      file_offset += len(data)
-      file_offset = int_align_to( file_offset, 8 )
-   #}
-
-   _write_array( 'strings', 1, sr_compile.string_data )
-   _write_array( 'mdl_mesh', sizeof(mdl_mesh), sr_compile.mesh_data )
-   _write_array( 'mdl_submesh', sizeof(mdl_submesh), sr_compile.submesh_data )
-   _write_array( 'mdl_material', sizeof(mdl_material), sr_compile.material_data)
-   _write_array( 'mdl_texture', sizeof(mdl_texture), sr_compile.texture_data)
-   _write_array( 'mdl_armature', sizeof(mdl_armature), sr_compile.armature_data)
-   _write_array( 'mdl_bone', sizeof(mdl_bone), sr_compile.bone_data )
-
-   for name, buffer in sr_compile.entity_data.items():#{
-      _write_array( name, sr_compile.entity_info[name]['size'], buffer )
+   arrays = {
+      'strings': sr_compile.string_cache.buffer,
+      'mdl_mesh': sr_compile.meshes,
+      'mdl_submesh': sr_compile.submeshes,
+      'mdl_material': sr_compile.materials,
+      'mdl_texture': sr_compile.textures,
+      'mdl_armature': sr_compile.armatures,
+      'mdl_bone': sr_compile.bones
+   }
+
+   for name, buf in sr_compile.entity_data.items():
+   #{
+      arrays[name] = buf
    #}
 
-   _write_array( 'mdl_animation', sizeof(mdl_animation), sr_compile.anim_data)
-   _write_array( 'mdl_keyframe', sizeof(mdl_transform),sr_compile.keyframe_data)
-   _write_array( 'mdl_vert', sizeof(mdl_vert), sr_compile.vertex_data )
-   _write_array( 'mdl_indice', sizeof(c_uint32), sr_compile.indice_data )
-   _write_array( 'pack', 1, sr_compile.pack_data )
-   _write_array( 'shader_data', 1, sr_compile.shader_data )
-
-   header_size = int_align_to( sizeof(mdl_header), 8 )
-   index_size = int_align_to( sizeof(mdl_array)*len(file_array_instructions),8 )
+   arrays[ 'mdl_vert' ] = sr_compile.vertices
+   arrays[ 'mdl_indice' ] = sr_compile.indices
+   arrays[ 'pack' ] = sr_compile.pack_data
+   arrays[ 'shader_data' ] = sr_compile.shader_data
 
    folder = bpy.path.abspath(bpy.context.scene.SR_data.export_dir)
    path = F"{folder}{collection.name}.mdl"
    print( path )
 
    os.makedirs(os.path.dirname(path),exist_ok=True)
-   fp = open( path, "wb" )
+
    header = mdl_header()
    header.version = MDL_VERSION_NR
-   sr_array_title( header.arrays, \
-                   'index', len(file_array_instructions), \
-                   sizeof(mdl_array), header_size )
-
-   fp.write( bytearray_align_to( bytearray(header), 8 ) )
-
-   print( F'[SR] {"name":>16}|    count | offset' )
-   index = bytearray()
-   for name,info in file_array_instructions.items():#{
-      arr = mdl_array()
-      offset = info['offset'] + header_size + index_size
-      sr_array_title( arr, name, info['count'], info['size'], offset )
-      index.extend( bytearray(arr) )
-
-      print( F'[SR] {name:>16}| {info["count"]: 8} '+\
-             F'  0x{info["offset"]:02x}' )
-   #}
-   fp.write( bytearray_align_to( index, 8 ) )
-   #bytearray_print_hex( index )
-
-   for name,info in file_array_instructions.items():#{
-      fp.write( bytearray_align_to( info['data'], 8 ) )
-   #}
-
-   fp.close()
+   array_file_write( path, header, arrays )
 
    print( '[SR] done' )
 #}
@@ -2134,14 +2042,16 @@ class SR_SCENE_SETTINGS(bpy.types.PropertyGroup):
 #{
    use_hidden: bpy.props.BoolProperty( name="use hidden", default=False )
    export_dir: bpy.props.StringProperty( name="Export Dir", subtype='DIR_PATH' )
+   file_name: bpy.props.StringProperty( name="File Name", default='untitled')
    gizmos: bpy.props.BoolProperty( name="Draw Gizmos", default=False )
 
    panel: bpy.props.EnumProperty(
         name='Panel',
         description='',
         items=[
-            ('EXPORT', 'Export', '', 'MOD_BUILD',0),
             ('ENTITY', 'Entity', '', 'MONKEY',1),
+            ('EXPORT', 'Export', '', 'MOD_BUILD',0),
+            ('META', 'Meta', '', 'NORMALIZE_FCURVES', 3),
             ('SETTINGS', 'Settings', 'Settings', 'PREFERENCES',2),
         ],
     )
@@ -2218,10 +2128,12 @@ class SR_COMPILE(bpy.types.Operator):
 
    def execute(_,context):
    #{
-      view_layer = bpy.context.view_layer
-      for col in view_layer.layer_collection.children["export"].children:
-         if not col.hide_viewport or bpy.context.scene.SR_data.use_hidden:
-            sr_compile( bpy.data.collections[col.name] )
+      export_col = _get_export_collection()
+
+      if export_col:
+         for col in export_col.children:
+            if not col.hide_viewport or bpy.context.scene.SR_data.use_hidden:
+               sr_compile( bpy.data.collections[col.name] )
 
       return {'FINISHED'}
    #}
@@ -2241,6 +2153,32 @@ class SR_COMPILE_THIS(bpy.types.Operator):
    #}
 #}
 
+class SR_COMPILE_METASCENE(bpy.types.Operator):
+#{
+   bl_idname="skaterift.compile_metascene"
+   bl_label="Compile whole blend as meta-scene"
+
+   def execute(_,context):
+   #{
+      folder = bpy.path.abspath(bpy.context.scene.SR_data.export_dir)
+      file = bpy.context.scene.SR_data.file_name
+      path = F"{folder}{file}.ms"
+
+      os.makedirs(os.path.dirname(path),exist_ok=True)
+      _sr_export_metascene( path )
+
+      return {'FINISHED'}
+   #}
+#}
+
+def _get_export_collection():
+#{
+   view_layer = bpy.context.view_layer
+   lcc = view_layer.layer_collection.children
+   if 'export' in lcc: return lcc['export']
+   else: return None
+#}
+
 class SR_INTERFACE(bpy.types.Panel):
 #{
    bl_idname = "VIEW3D_PT_skate_rift"
@@ -2260,19 +2198,32 @@ class SR_INTERFACE(bpy.types.Panel):
       if context.scene.SR_data.panel == 'SETTINGS': #{
          _.layout.prop( context.scene.SR_data, 'gizmos' )
       #}
+      elif context.scene.SR_data.panel == 'META':
+      #{
+         _.layout.prop( context.scene.SR_data, "export_dir" )
+         _.layout.prop( context.scene.SR_data, "file_name" )
+         row = _.layout.row()
+         row.operator( "skaterift.compile_metascene" )
+         _.layout.row().label( text=F'Status: {_ms_compiler.status}' )
+      #}
       elif context.scene.SR_data.panel == 'EXPORT': #{
          _.layout.prop( context.scene.SR_data, "export_dir" )
          col = bpy.context.collection
 
          found_in_export = False
          export_count = 0
-         view_layer = bpy.context.view_layer
-         for c1 in view_layer.layer_collection.children["export"].children: #{
-            if not c1.hide_viewport or bpy.context.scene.SR_data.use_hidden:
-               export_count += 1
 
-            if c1.name == col.name: #{
-               found_in_export = True
+         export_col = _get_export_collection()
+
+         if export_col:
+         #{
+            for c1 in export_col.children: #{
+               if not c1.hide_viewport or bpy.context.scene.SR_data.use_hidden:
+                  export_count += 1
+
+               if c1.name == col.name: #{
+                  found_in_export = True
+               #}
             #}
          #}
 
@@ -2284,7 +2235,7 @@ class SR_INTERFACE(bpy.types.Panel):
          if found_in_export: #{
             row.label( text=col.name + ".mdl" )
             box.prop( col.SR_data, "pack_textures" )
-            box.prop( col.SR_data, "animations" )
+            box.prop( col.SR_data, "animations" )
             box.operator( "skaterift.compile_this" )
          #}
          else: #{
@@ -2295,12 +2246,16 @@ class SR_INTERFACE(bpy.types.Panel):
             row.enabled=False
             row.alignment = 'CENTER'
             row.scale_y = 1.5
-            row.label( text="This collection is not in the export group" )
+
+            if export_col:
+               row.label( text="This collection is not a child of the export collection" )
+            else:
+               row.label( text="There is no master collection named 'export'" )
          #}
 
          box = _.layout.box()
-         row = box.row()
 
+         row = box.row()
          split = row.split( factor=0.3, align=True )
          split.prop( context.scene.SR_data, "use_hidden", text="hidden" )
          
@@ -4753,7 +4708,7 @@ def cv_draw_pixel():#{
 
 classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\
             SR_COLLECTION_SETTINGS, SR_SCENE_SETTINGS, \
-            SR_COMPILE, SR_COMPILE_THIS, SR_MIRROR_BONE_X,\
+            SR_COMPILE, SR_COMPILE_THIS,SR_COMPILE_METASCENE, SR_MIRROR_BONE_X,\
             \
             SR_OBJECT_ENT_GATE, SR_MESH_ENT_GATE, SR_OBJECT_ENT_SPAWN, \
             SR_OBJECT_ENT_ROUTE_ENTRY, SR_UL_ROUTE_NODE_LIST, \
index c599936aaceecffa4417df752ad20864e256eaa9..8859ecf73b23671aec92979fccc1bf0cefd1a250 100644 (file)
@@ -141,7 +141,7 @@ def sr_compile_material( mat ):
 
    print( F'[SR] Compiling material {mat.name}' )
 
-   index = (len(sr_compile.material_data)//sizeof(mdl_material))+1
+   index = len( sr_compile.materials ) +1
    sr_compile.material_cache[mat.name] = index
 
    m = mdl_material()
@@ -239,7 +239,7 @@ def sr_compile_material( mat ):
    m.props.kvs.size = msg.cur.co
 
    sr_compile.shader_data.extend( bytearray(buf[:msg.cur.co]) )
-   sr_compile.material_data.extend( bytearray(m) )
+   sr_compile.materials.append( m )
    return index
 #}
 
diff --git a/skaterift_blender/sr_metascene.py b/skaterift_blender/sr_metascene.py
new file mode 100644 (file)
index 0000000..73d3b91
--- /dev/null
@@ -0,0 +1,433 @@
+print( "sr_metascene" )
+
+#
+# As the playhead walks through the strip list (which is sorted by start frame),
+# it will activate/deactivate tracks into the sampler list. Samplers can be of 
+# float or integer type.
+#
+# On the animation update, we evaluate all samplers at once. As the playhead 
+# moves across keyframe sections, it caches the curve handles into the sampler
+# to reduce memory pressure.
+#
+# No samplers exist by default in the streamer, and you build up the samplers at
+# construction time. One it starts playing the samplers are locked in. The
+# samplers can be name-matching (against the data path), or semantic integer
+# matching.
+#
+# All curves for all objects of all properties will be compiled. The semantics
+# list is built up on the client side.
+# 
+# The animation mode of the file will either be keyframe blocks, or will be
+# curves. This is a per-file choice.
+#
+
+class _ms_compiler: 
+   status = "None"
+
+def _ms_compiler_init():
+#{
+   _ms_compiler.strings = bin_string_cache(alignment=4)
+
+   _ms_compiler.action_cache = {} # actions point to (our) strips
+   _ms_compiler.strips = []
+   _ms_compiler.tracks = []
+   _ms_compiler.keyframes = []
+   _ms_compiler.curve_keyframes = []
+   _ms_compiler.instances = []
+   _ms_compiler.overrides = []
+#}
+
+class ms_header(Structure):
+#{
+   _fields_ = [("version",c_uint32),
+               ("framerate",c_float),
+               ("index",array_file_meta)]
+#}
+
+class ms_curve_keyframe(Structure):
+#{
+   _fields_ = [("co",c_float*2),
+               ("l", c_float*2),
+               ("r", c_float*2)]
+#}
+
+class ms_keyframe(Structure):
+#{
+   _fields_ = [("co",c_float*3),
+               ("s", c_float*3),
+               ("q", c_float*4)]
+#}
+
+class ms_track(Structure):
+#{
+   _fields_ = [("keyframe_start",c_uint32),
+               ("keyframe_count",c_uint32),
+               ("pstr_datapath",c_uint32),
+               ("semantic_type",c_uint32)]   # runtime
+#}
+
+class ms_strip(Structure):
+#{
+   _fields_ = [("data_start",c_uint32), # keyframes in block mode, or tracks in
+                                        # curves mode.
+               ("data_count",c_uint32), # tracks in curves, bone count in kfs
+               ("data_mode",c_uint32),
+               ("offset",c_uint32),
+               ("length",c_uint32),
+               ("pstr_name",c_uint32),          #AKA Blender NLAStrip name
+               ("pstr_internal_name",c_uint32), #AKA Blender action name
+               ("instance_id",c_uint32),# 0 ... 0xfffffffe, or 0xffffffff
+               ("object_id",c_uint32) ] # First class: SR entity ID,
+                                        # Second class: instance override index
+#}
+
+class ms_instance(Structure):
+#{
+   _fields_ = [("pstr_name",c_uint32),
+               ("override_start",c_uint32),
+               ("override_count",c_uint32)]
+#}
+
+class ms_override(Structure):
+#{
+   _fields_ = [("pstr_name",c_uint32),
+               ("transform",mdl_transform)]
+#}
+
+def _metascene_action_cache( out_strip, action ):
+#{
+   if action.name in _ms_compiler.action_cache:
+   #{
+      print( "      Using cached action data" )
+      ref = _ms_compiler.action_cache[ action.name ]
+      out_strip.data_start = ref.data_start
+      out_strip.data_count = ref.data_count
+      out_strip.data_mode = ref.data_mode
+      out_strip.pstr_internal_name = ref.pstr_internal_name
+      return True
+   #}
+   else: return False
+#}
+
+def _metascene_armature_anims( obj, instance_id, override_id ):
+#{
+   bones = [_ for _ in sr_armature_bones(obj)]
+   bones_names = [None]+[_.name for _ in bones]
+
+   # So we can restore later
+   #
+   previous_frame  = bpy.context.scene.frame_current
+   previous_action = obj.animation_data.action
+   previous_pose_position = obj.data.pose_position
+   obj.data.pose_position = 'POSE'
+
+   for NLALayer in obj.animation_data.nla_tracks:
+   #{
+      for NLAStrip in NLALayer.strips:
+      #{
+         # set active
+         #
+         action = NLAStrip.action
+         obj.animation_data.action = action
+
+         out_strip = ms_strip()
+         out_strip.offset = math.floor( NLAStrip.frame_start )
+         out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
+         out_strip.pstr_name = \
+               pack_string( _ms_compiler.strings, NLAStrip.name )
+         out_strip.instance_id = instance_id
+         out_strip.object_id = override_id
+
+         if _metascene_action_cache( out_strip, action ): continue
+
+         out_strip.data_mode = 0
+         out_strip.data_start = len( _ms_compiler.keyframes )
+         out_strip.data_count = len( bones )
+         out_strip.pstr_internal_name = \
+            pack_string( _ms_compiler.strings, action.name )
+         
+         # Clip to NLA settings
+         #
+         anim_start = int(NLAStrip.action_frame_start)
+         anim_end   = int(NLAStrip.action_frame_end)
+         
+         i = 0
+         # Export the keyframes
+         for frame in range(anim_start,anim_end):
+         #{
+            bpy.context.scene.frame_set(frame)
+            
+            for rb in bones:
+            #{
+               pb = obj.pose.bones[rb.name]
+               
+               # relative bone matrix
+               if rb.parent is not None:
+               #{
+                  offset_mtx = rb.parent.matrix_local
+                  offset_mtx = offset_mtx.inverted_safe() @ rb.matrix_local
+                  inv_parent = pb.parent.matrix @ offset_mtx
+                  inv_parent.invert_safe()
+                  fpm = inv_parent @ pb.matrix 
+               #}
+               else:
+               #{
+                  bone_mtx = rb.matrix.to_4x4()
+                  local_inv = rb.matrix_local.inverted_safe()
+                  fpm = bone_mtx @ local_inv @ pb.matrix
+               #}
+
+               loc, rot, sca = fpm.decompose()
+               
+               # rotation
+               lc_m = pb.matrix_channel.to_3x3()
+               if pb.parent is not None:
+               #{
+                  smtx = pb.parent.matrix_channel.to_3x3()
+                  lc_m = smtx.inverted() @ lc_m
+               #}
+               rq = lc_m.to_quaternion()
+               q_normalize( rq )
+
+               kf = mdl_transform()
+               kf.co[0] =  loc[0]
+               kf.co[1] =  loc[2]
+               kf.co[2] = -loc[1]
+               kf.q[0]  =  rq[1]
+               kf.q[1]  =  rq[3]
+               kf.q[2]  = -rq[2]
+               kf.q[3]  =  rq[0]
+               kf.s[0]  = sca[0]
+               kf.s[1]  = sca[1]
+               kf.s[2]  = sca[2]
+               
+               _ms_compiler.keyframes.append(kf)
+            #}
+         #}
+         
+         # Add to animation buffer
+         #
+         _ms_compiler.strips.append( out_strip )
+         print( F"[MS]    | anim( {NLAStrip.action.name} )" )
+      #}
+   #}
+   
+   # Restore context to how it was before
+   #
+   bpy.context.scene.frame_set( previous_frame )
+   obj.animation_data.action = previous_action
+   obj.data.pose_position = previous_pose_position
+#}
+
+def _metascene_compile_action_curves( out_strip, action ):
+#{
+   if _metascene_action_cache( out_strip, action ): return
+
+   out_strip.data_mode = 1
+   out_strip.data_start = len(_ms_compiler.tracks)
+   out_strip.data_count = len(action.fcurves)
+   out_strip.pstr_internal_name = \
+         pack_string( _ms_compiler.strings, action.name )
+
+   for fcurve in action.fcurves:
+   #{
+      id = F"{fcurve.data_path}:{fcurve.array_index}"
+      print( F"      Appending curve '{id}'" )
+      
+      out_track = ms_track()
+      out_track.keyframe_start = len( _ms_compiler.curve_keyframes )
+      out_track.keyframe_count = 0
+      out_track.pstr_datapath = pack_string( _ms_compiler.strings, id )
+      out_track.semantic_type = 0
+
+      for kf in fcurve.keyframe_points:
+      #{
+         out_keyframe = ms_curve_keyframe()
+         out_keyframe.co[0] = kf.co[0]
+         out_keyframe.co[1] = kf.co[1]
+         out_keyframe.l[0] = kf.handle_left[0]  #TODO: clipping.
+         out_keyframe.l[1] = kf.handle_left[1]
+         out_keyframe.r[0] = kf.handle_right[0]
+         out_keyframe.r[1] = kf.handle_right[1]
+
+         _ms_compiler.curve_keyframes.append(out_keyframe)
+         out_track.keyframe_count += 1
+      #}
+      
+      _ms_compiler.tracks.append( out_track )
+   #}
+
+   _ms_compiler.action_cache[ action.name ] = out_strip
+#}
+
+#
+# Camera animation:
+#  co: xyz, fov
+#
+def _metascene_camera_anims( obj, entity_id ):
+#{
+   if obj.animation_data == None: return
+
+   for NLALayer in obj.animation_data.nla_tracks:
+   #{
+      print( F"  looking into {NLALayer.name}" )
+      for NLAStrip in NLALayer.strips:
+      #{
+         print( F"    have strip {NLAStrip.name}" )
+
+         out_strip = ms_strip()
+         _metascene_compile_action_curves( out_strip, NLAStrip.action )
+         out_strip.offset = math.floor( NLAStrip.frame_start )
+         out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset )
+         out_strip.pstr_name = \
+               pack_string( _ms_compiler.strings, NLAStrip.name )
+
+         _ms_compiler.strips.append( out_strip )
+      #}
+   #}
+
+   for NLALayer in obj.data.animation_data.nla_tracks:
+   #{
+      print( F"  looking into {NLALayer.name}" )
+      for NLAStrip in NLALayer.strips:
+      #{
+         print( F"    have strip {NLAStrip.name}" )
+      #}
+   #}
+#}
+
+def obj_realname( obj ):
+#{
+   if obj.override_library:
+      return obj.override_library.reference.name
+   else:
+      return obj.name
+#}
+
+def _sr_export_metascene( path ):
+#{
+   print( "\nCompiling meta-scene\n----------------------------------------" )
+   _ms_compiler_init()
+   
+   def descend( col, depth=0, instance=None, instance_id=-1 ):
+   #{
+      created_instance = False
+      col_name = obj_realname(col)
+
+      if col.override_library and not col.override_library.is_system_override:
+      #{
+         if not instance:
+         #{
+            instance_id = len( _ms_compiler.instances )
+            instance = ms_instance()
+            instance.pstr_name = pack_string( _ms_compiler.strings, col_name )
+            instance.override_start = len( _ms_compiler.overrides )
+            instance.override_count = 0
+            created_instance = True
+         #}
+      #}
+
+      print( "  "*depth + F"col '{col_name}' ms_instance: {created_instance}" )
+      depth += 1
+
+      for o in col.objects:
+      #{
+         data_mode = 'regular'
+         if o.override_library:
+         #{
+            if o.override_library.is_system_override:
+               data_mode = 'system_override'
+            else:
+               data_mode = 'override'
+         #}
+
+         obj_name = obj_realname(o)
+         print( "  "*depth + F"{obj_name} ('{o.type}') {data_mode}" )
+
+         if data_mode == 'override':
+         #{
+            key = col_name + ':' + obj_name
+            print( "  "*depth + F" key: {key}" )
+
+            co = o.location
+            print( "  "*depth + F" co: {co.x:.2} {co.y:.2} {co.z:.2}" )
+            
+            override_id = instance.override_count
+            init = ms_override()
+            init.pstr_name = pack_string( _ms_compiler.strings, obj_name )
+            compile_obj_transform( o, init.transform )
+
+            if o.type == 'ARMATURE':
+            #{
+               _metascene_armature_anims( o, instance_id, override_id )
+            #}
+
+            _ms_compiler.overrides.append(init)
+            instance.override_count += 1
+         #}
+
+         if o.type == 'CAMERA' and not instance:
+         #{
+            if o.rotation_mode != 'ZXY':
+            #{
+               print( F"  Camera '{o.name}' needs to be 'ZXY' rotation mode" )
+               return False
+            #}
+
+            if abs(o.delta_rotation_euler[0] - math.pi/2.0) > 0.001 or \
+               abs(o.delta_rotation_euler[1] - 0.0) > 0.001 or \
+               abs(o.delta_rotation_euler[2] - 0.0) > 0.001:
+            #{
+               print( F"  Camera '{o.name}' needs this delta rotation: 90,0,0" )
+               return False
+            #}
+
+            _metascene_camera_anims( o )
+         #}
+      #}
+
+      for c in col.children:
+      #{
+         if not descend( c, depth, instance ):
+            return False
+      #}
+
+      if created_instance:
+      #{
+         _ms_compiler.instances.append(instance)
+      #}
+
+      return True
+   #}
+
+   if not descend( bpy.context.scene.collection ):
+   #{
+      print( "Compilation Failed" )
+      _ms_compiler.status = "Compilation failed (check console)"
+      return False
+   #}
+
+   for marker in bpy.context.scene.timeline_markers:
+   #{
+      print( F"Marker {marker.name}: {marker.camera}" )
+   #}
+
+   arrays = {
+      'strings': _ms_compiler.strings.buffer,
+      'ms_strip': _ms_compiler.strips,
+      'ms_track': _ms_compiler.tracks,
+      'ms_keyframe': _ms_compiler.keyframes,
+      'ms_curves': _ms_compiler.curve_keyframes,
+      'ms_instance': _ms_compiler.instances,
+      'ms_override': _ms_compiler.overrides
+   }
+
+   header = ms_header()
+   header.version = 1
+   header.framerate = bpy.context.scene.render.fps
+   array_file_write( path, header, arrays )
+
+   _ms_compiler.status = F"Written to {path}"
+
+   return True
+#}
diff --git a/src/array_file.c b/src/array_file.c
new file mode 100644 (file)
index 0000000..080b85c
--- /dev/null
@@ -0,0 +1,123 @@
+#include "array_file.h"
+
+const char *ps_get( array_file_ptr *strings, u32 pstr )
+{
+   return ((char *)af_arritm( strings, pstr )) + 4;
+}
+
+bool ps_consteq( array_file_ptr *strings, u32 pstr, const char *str, u32 djb2 )
+{
+   u32 hash = *((u32 *)af_arritm( strings, pstr ));
+   if( hash == djb2 )
+   {
+      if( !strcmp( str, ps_get( strings, pstr ))) return 1;
+      else return 0;
+   }
+   else return 0;
+}
+
+static void af_load_array_file_buffer( FILE *fp, array_file_meta *arr, 
+                                       void *buffer, u32 stride )
+{
+   if( arr->item_count )
+   {
+      fseek( fp, arr->file_offset, SEEK_SET );
+
+      if( stride == arr->item_size )
+      {
+         u64 l = fread( buffer, arr->item_size*arr->item_count, 1, fp );
+         if( l != 1 ) 
+         {
+            vg_file_error_info( fp );
+            fclose( fp );
+            vg_fatal_exit();
+         }
+      }
+      else 
+      {
+         vg_warn( "Applying alignment fixup to array @%p [%u -> %u] x %u\n", 
+                  buffer, arr->item_size, stride, arr->item_count );
+
+         if( stride > arr->item_size )
+            memset( buffer, 0, stride*arr->item_count );
+
+         u32 read_size = VG_MIN( stride, arr->item_size );
+
+         for( u32 i=0; i<arr->item_count; i++ )
+         {
+            u64 l = fread( buffer+i*stride, read_size, 1, fp );
+            if( stride < arr->item_size )
+               fseek( fp, arr->item_size - stride, SEEK_CUR );
+
+            if( l != 1 ) 
+            {
+               vg_file_error_info( fp );
+               fclose( fp );
+               vg_fatal_exit();
+            }
+         }
+      }
+   }
+}
+
+void af_load_array_file( FILE *fp, array_file_ptr *ptr, 
+                         array_file_meta *arr, void *lin_alloc, 
+                         u32 stride )
+{
+   if( arr->item_count )
+   {
+      u32 size = stride*arr->item_count;
+      ptr->data = lin_alloc? vg_linear_alloc( lin_alloc, vg_align8(size) ):
+                             malloc( size );
+      af_load_array_file_buffer( fp, arr, ptr->data, stride );
+   }
+   else
+   {
+      ptr->data = NULL;
+   }
+   
+   ptr->stride = stride;
+   ptr->count = arr->item_count;
+}
+
+void *af_arritm( array_file_ptr *arr, u32 index )
+{
+   return ((u8 *)arr->data) + index*arr->stride;
+}
+
+u32 af_arrcount( array_file_ptr *arr )
+{
+   return arr->count;
+}
+
+array_file_meta *af_find_array( array_file_ptr *index, const char *name )
+{
+   for( u32 i=0; i<af_arrcount(index); i++ )
+   {
+      array_file_meta *arr = af_arritm( index, i );
+      
+      if( !strncmp(arr->name,name,16) )
+         return arr;
+   }
+
+   return NULL;
+}
+
+int af_load_array( FILE *fp, array_file_ptr *index, array_file_ptr *ptr,
+                   const char *name, void *lin_alloc, u32 stride )
+{
+   array_file_meta *arr = af_find_array( index, name );
+
+   if( arr )
+   {
+      af_load_array_file( fp, ptr, arr, lin_alloc, stride );
+      return 1;
+   }
+   else
+   {
+      ptr->data = NULL;
+      ptr->count = 0;
+      ptr->stride = 0;
+      return 0;
+   }
+}
diff --git a/src/array_file.h b/src/array_file.h
new file mode 100644 (file)
index 0000000..1678541
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma once
+
+typedef struct array_file_ptr array_file_ptr;
+typedef struct array_file_meta array_file_meta;
+
+struct array_file_ptr
+{
+   void *data;
+   u32 count, stride;
+};
+
+struct array_file_meta
+{
+   u32 file_offset,
+       item_count,
+       item_size;
+
+   char name[16];
+};
+
+/* array loading */
+array_file_meta *af_find_array( array_file_ptr *index, const char *name );
+void af_load_array_file( FILE *fp, array_file_ptr *ptr, 
+                         array_file_meta *arr, void *lin_alloc, 
+                         u32 stride );
+int af_load_array( FILE *fp, array_file_ptr *index, array_file_ptr *ptr,
+                   const char *name, void *lin_alloc, u32 stride );
+
+#define AF_LOAD_ARRAY_STRUCT( FP, INDEX, PTR, STRUCT, ALLOCATOR ) \
+   af_load_array( FP, INDEX, PTR, #STRUCT, ALLOCATOR, sizeof(STRUCT) )
+
+/* array access */
+void *af_arritm( array_file_ptr *arr, u32 index );
+u32 af_arrcount( array_file_ptr *arr );
+
+/* packed string buffer access (with djb2 hash prefix) */
+const char *ps_get( array_file_ptr *strings, u32 pstr );
+bool ps_consteq( array_file_ptr *strings, u32 pstr, const char *str, u32 djb2 );
+
+#define PS_EQ( STRINGS, PSTR, CONSTR ) \
+   ps_consteq( STRINGS, PSTR, CONSTR, vg_strdjb2( CONSTR ) )
index 320595562ebe1bbffb0caa7cfb1e039dca804eeb..86106b3656c50b506b74a158b576f00032401f69 100644 (file)
@@ -10,11 +10,11 @@ void build_control_overlay(void)
    mdl_load_metadata_block( &ctx, NULL );
    mdl_close( &ctx );
 
-   for( u32 i=0; i<mdl_arrcount( &ctx.meshs ); i ++ )
+   for( u32 i=0; i<af_arrcount( &ctx.meshs ); i ++ )
    {
-      mdl_mesh *mesh = mdl_arritm( &ctx.meshs, i );
+      mdl_mesh *mesh = af_arritm( &ctx.meshs, i );
       fprintf( hdr, "   %s = %u,\n", 
-                  mdl_pstr( &ctx, mesh->pstr_name ), mesh->submesh_start );
+                  ps_get( &ctx.strings,mesh->pstr_name ), mesh->submesh_start );
    }
 
    fclose( hdr );
index a39d77b697c1f15a03211f94005f7d8547ac8a2e..f0df413e616f6602aad84bafaafcfe4ec9182205 100644 (file)
@@ -13,7 +13,7 @@ struct control_overlay control_overlay = { .enabled = 1 };
 
 static void render_overlay_mesh( enum control_overlay_mesh index )
 {
-   mdl_draw_submesh( mdl_arritm( &control_overlay.mdl.submeshs, index ) );
+   mdl_draw_submesh( af_arritm( &control_overlay.mdl.submeshs, index ) );
 }
 
 void control_overlay_init(void)
@@ -28,9 +28,9 @@ void control_overlay_init(void)
 
    vg_async_stall();
 
-   if( mdl_arrcount( &mdl->textures ) )
+   if( af_arrcount( &mdl->textures ) )
    {
-      mdl_texture *tex = mdl_arritm( &mdl->textures, 0 );
+      mdl_texture *tex = af_arritm( &mdl->textures, 0 );
       control_overlay.tex = tex->glname;
    }
    else
index d30a5dcd90d3994af9fd1e43a71f8c1f136a00ab..a04066c154f32bc53820c19255fe5b821402d9d5 100644 (file)
@@ -7,14 +7,14 @@
 entity_call_result ent_challenge_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+   ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
    if( call->function == 0 ) /* unlock() */
    {
       if( !challenge->status )
       {
          vg_info( "challenge( '%s' )\n", 
-                  mdl_pstr( &world->meta, challenge->pstr_alias) );
+                  ps_get( &world->meta.strings, challenge->pstr_alias) );
          ent_call call;
          call.data = NULL;
          call.function = challenge->target_event;
@@ -49,7 +49,7 @@ entity_call_result ent_challenge_call( world_instance *world, ent_call *call )
 void ent_challenge_preupdate( ent_focus_context *ctx )
 {
    world_instance *world = ctx->world;
-   ent_challenge *challenge = mdl_arritm( &world->ent_challenge, ctx->index );
+   ent_challenge *challenge = af_arritm( &world->ent_challenge, ctx->index );
 
    /* maximum distance from active challenge */
    if( !ctx->active )
@@ -61,7 +61,7 @@ void ent_challenge_preupdate( ent_focus_context *ctx )
          u32 next = challenge->first;
          while( mdl_entity_id_type(next) == k_ent_objective ){
             u32 index = mdl_entity_id_id( next );
-            ent_objective *objective = mdl_arritm(&world->ent_objective,index);
+            ent_objective *objective = af_arritm(&world->ent_objective,index);
             next = objective->id_next;
 
             f32 d2 = v3_dist2( localplayer.rb.co, objective->transform.co );
@@ -88,7 +88,7 @@ void ent_challenge_preupdate( ent_focus_context *ctx )
    if( mdl_entity_id_type( challenge->first ) == k_ent_objective ){
       if( button_down( k_srbind_maccept ) ){
          u32 index = mdl_entity_id_id( challenge->first );
-         world_static.challenge_target = mdl_arritm( &world->ent_objective, 
+         world_static.challenge_target = af_arritm( &world->ent_objective, 
                                                      index );
          world_static.challenge_timer = 0.0f;
          world_entity_exit_modal();
@@ -97,7 +97,7 @@ void ent_challenge_preupdate( ent_focus_context *ctx )
          u32 next = challenge->first;
          while( mdl_entity_id_type(next) == k_ent_objective ){
             u32 index = mdl_entity_id_id( next );
-            ent_objective *objective = mdl_arritm(&world->ent_objective,index);
+            ent_objective *objective = af_arritm(&world->ent_objective,index);
             objective->flags &= ~k_ent_objective_passed;
             next = objective->id_next;
             v3_fill( objective->transform.s, 1.0f );
index 12b05757cd1ce1c30e9ab933361d69bb475fd9a2..2148b3dd099b7399330823b8ffd694644be77673 100644 (file)
@@ -5,7 +5,7 @@
 entity_call_result ent_glider_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_glider *glider = mdl_arritm( &world->ent_glider, index );
+   ent_glider *glider = af_arritm( &world->ent_glider, index );
 
    if( call->function == 0 )
    {
index 19c88d0dcac8eb22b7bcaba508e8ff2e6f01b51b..7a134081fe64f24dab1a4b538b34c453d0b0d9db 100644 (file)
@@ -11,14 +11,14 @@ struct global_miniworld global_miniworld;
 
 entity_call_result ent_miniworld_call( world_instance *world, ent_call *call )
 {
-   ent_miniworld *miniworld = mdl_arritm( &world->ent_miniworld, 
+   ent_miniworld *miniworld = af_arritm( &world->ent_miniworld, 
                                           mdl_entity_id_id(call->id) );
 
    int world_id = world - world_static.instances;
 
    if( call->function == 0 ) /* zone() */
    {
-      const char *uid = mdl_pstr( &world->meta, miniworld->pstr_world );
+      const char *uid = ps_get( &world->meta.strings, miniworld->pstr_world );
       skaterift_load_world_command( 1, (const char *[]){ uid } );
 
       mdl_transform_m4x3( &miniworld->transform, global_miniworld.mmdl );
@@ -39,7 +39,7 @@ entity_call_result ent_miniworld_call( world_instance *world, ent_call *call )
 
       if( miniworld->proxy )
       {
-         ent_prop *prop = mdl_arritm( &world->ent_prop, 
+         ent_prop *prop = af_arritm( &world->ent_prop, 
                                       mdl_entity_id_id(miniworld->proxy) );
          prop->flags &= ~0x1;
       }
@@ -91,7 +91,7 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
       rendering = 0;
 
    if( miniworld->proxy ){
-      ent_prop *prop = mdl_arritm( &host_world->ent_prop, 
+      ent_prop *prop = af_arritm( &host_world->ent_prop, 
                                    mdl_entity_id_id(miniworld->proxy) );
       if( !rendering )
          prop->flags &= ~0x1;
@@ -121,8 +121,8 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
    miniworld_icon( cam, k_gui_icon_player, dest_world->player_co, 
                   1.0f + sinf(vg.time)*0.2f );
 
-   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_challenge); i++ ){
-      ent_challenge *challenge = mdl_arritm( &dest_world->ent_challenge, i );
+   for( u32 i=0; i<af_arrcount(&dest_world->ent_challenge); i++ ){
+      ent_challenge *challenge = af_arritm( &dest_world->ent_challenge, i );
 
       enum gui_icon icon = k_gui_icon_exclaim;
       if( challenge->status )
@@ -131,8 +131,8 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
       miniworld_icon( cam, icon, challenge->transform.co, 1.0f );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &dest_world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&dest_world->ent_route); i++ ){
+      ent_route *route = af_arritm( &dest_world->ent_route, i );
 
       if( route->flags & k_ent_route_flag_achieve_gold ){
          miniworld_icon( cam, k_gui_icon_rift_run_gold, 
@@ -144,8 +144,8 @@ void ent_miniworld_render( world_instance *host_world, vg_camera *cam )
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&dest_world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &dest_world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&dest_world->ent_route); i++ ){
+      ent_route *route = af_arritm( &dest_world->ent_route, i );
 
       v4f colour;
       v4_copy( route->colour, colour );
index 7a4b484b534f22d389e3e3793cc15739a311109f..ce0ac3de47a4d75a94f26afc53c315fec3ccde7d 100644 (file)
@@ -6,9 +6,9 @@
 #include "gui.h"
 
 struct npc npc_gumpa, npc_slowmo, npc_volc_flight;
-static struct skeleton_anim *gumpa_idle;
-static struct skeleton_anim *slowmo_momentum, *slowmo_slide, *slowmo_rewind,
-                            *anim_tutorial_cam;
+static struct skeleton_anim gumpa_idle;
+static struct skeleton_anim slowmo_momentum, slowmo_slide, slowmo_rewind,
+                            anim_tutorial_cam;
 static float slowmo_opacity = 0.0f;
 static f64 volc_start_preview = 0.0;
 
@@ -19,7 +19,6 @@ void npc_load_model( struct npc *npc, const char *path )
    mdl_context *meta = &npc->meta;
    mdl_open( meta, path, vg_mem.rtmemory );
    mdl_load_metadata_block( meta, vg_mem.rtmemory );
-   mdl_load_animation_block( meta, vg_mem.rtmemory );
 
    struct skeleton *sk = &npc->skeleton;
    skeleton_setup( sk, vg_mem.rtmemory, meta );
@@ -27,9 +26,9 @@ void npc_load_model( struct npc *npc, const char *path )
    u32 mtx_size = sizeof(m4x3f)*sk->bone_count;
    npc->final_mtx = vg_linear_alloc( vg_mem.rtmemory, mtx_size );
 
-   if( mdl_arrcount( &meta->textures ) )
+   if( af_arrcount( &meta->textures ) )
    {
-      mdl_texture *tex0 = mdl_arritm( &meta->textures, 0 );
+      mdl_texture *tex0 = af_arritm( &meta->textures, 0 );
       void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
       mdl_fread_pack_file( meta, &tex0->file, data );
 
@@ -48,6 +47,7 @@ void npc_load_model( struct npc *npc, const char *path )
 
 void npc_init(void)
 {
+#if 0
    npc_load_model( &npc_gumpa, "models/gumpa.mdl" );
    gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" );
 
@@ -60,6 +60,7 @@ void npc_init(void)
    npc_load_model( &npc_volc_flight, "models/volc_flight.mdl" );
    anim_tutorial_cam = 
       skeleton_get_anim( &npc_volc_flight.skeleton, "tutorial" );
+#endif
 }
 
 static struct npc *npc_resolve( u32 id )
@@ -111,7 +112,7 @@ static entity_call_result npc_slowmo_call( ent_npc *npc, ent_call *call )
 entity_call_result ent_npc_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+   ent_npc *npc = af_arritm( &world->ent_npc, index );
 
    if( npc->id == 2 )
    {
@@ -180,7 +181,7 @@ entity_call_result ent_npc_call( world_instance *world, ent_call *call )
 void ent_npc_preupdate( ent_focus_context *ctx )
 {
    world_instance *world = ctx->world;
-   ent_npc *ent = mdl_arritm( &world->ent_npc, ctx->index );
+   ent_npc *ent = af_arritm( &world->ent_npc, ctx->index );
 
    if( !ctx->active )
    {
@@ -204,9 +205,9 @@ void ent_npc_preupdate( ent_focus_context *ctx )
       struct skeleton *sk = &npc_volc_flight.skeleton;
 
       f64 t = (vg.time - volc_start_preview) * 0.5;
-      skeleton_sample_anim_clamped( sk, anim_tutorial_cam, t, pose.keyframes );
+      skeleton_sample_anim_clamped( sk, &anim_tutorial_cam, t, pose.keyframes );
       
-      ent_camera *cam = mdl_arritm( &world->ent_camera, 
+      ent_camera *cam = af_arritm( &world->ent_camera, 
                                      mdl_entity_id_id(ent->camera) );
       v3_copy( pose.keyframes[0].co, cam->transform.co );
 
@@ -243,20 +244,20 @@ void npc_update( ent_npc *ent )
 
    if( ent->id == 1 )
    {
-      skeleton_sample_anim( sk, gumpa_idle, vg.time, pose.keyframes );
+      skeleton_sample_anim( sk, &gumpa_idle, vg.time, pose.keyframes );
    }
    else if( ent->id == 2 )
    {
       struct skeleton_anim *anim = NULL;
-      if( ent->context == 1 ) anim = slowmo_momentum;
-      else if( ent->context == 2 ) anim = slowmo_slide;
-      else if( ent->context == 3 ) anim = slowmo_rewind;
+      if( ent->context == 1 ) anim = &slowmo_momentum;
+      else if( ent->context == 2 ) anim = &slowmo_slide;
+      else if( ent->context == 3 ) anim = &slowmo_rewind;
 
       VG_ASSERT( anim );
 
       f32 t        = vg.time*0.5f,
-          animtime = fmodf( t*anim->rate, anim->length ),
-          lt       = animtime / (f32)anim->length;
+          animtime = fmodf( t*anim->framerate, anim->strip->length ),
+          lt       = animtime / (f32)anim->strip->length;
       skeleton_sample_anim( sk, anim, t, pose.keyframes );
       slowmo_opacity = vg_clampf(fabsf(lt-0.5f)*9.0f-3.0f,0,1);
    }
index 6a8bbe5bef6a2afb3224cc388e1fd101fbbc97e7..1e43e871aa7e848c769fe3b8d697bda5a99ea606 100644 (file)
@@ -13,7 +13,7 @@ static void ent_objective_pass( world_instance *world,
       world_static.challenge_timer += objective->filter;
 
       u32 index = mdl_entity_id_id( objective->id_next );
-      ent_objective *next = mdl_arritm( &world->ent_objective, index );
+      ent_objective *next = af_arritm( &world->ent_objective, index );
       world_static.challenge_target = next;
       objective->flags |= k_ent_objective_passed;
 
@@ -84,7 +84,7 @@ static int ent_objective_check_filter( ent_objective *objective ){
 entity_call_result ent_objective_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+   ent_objective *objective = af_arritm( &world->ent_objective, index );
 
    if( call->function == 0 )
    {
index 5e0ec03dd2349891f09ee00bfca3c07aa3a19081..91fd1aa078baf1ff7a2e913cfba4ffd70d30c600 100644 (file)
@@ -18,19 +18,19 @@ u32 region_spark_colour( u32 flags )
 entity_call_result ent_region_call( world_instance *world, ent_call *call )
 {
    ent_region *region = 
-      mdl_arritm( &world->ent_region, mdl_entity_id_id(call->id) );
+      af_arritm( &world->ent_region, mdl_entity_id_id(call->id) );
 
    if( !region->zone_volume )
       return k_entity_call_result_invalid;
 
    ent_volume *volume = 
-      mdl_arritm( &world->ent_volume, mdl_entity_id_id(region->zone_volume) );
+      af_arritm( &world->ent_volume, mdl_entity_id_id(region->zone_volume) );
 
    if( call->function == 0 ) /* enter */
    {
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ )
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i ++ )
       {
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+         ent_route *route = af_arritm( &world->ent_route, i );
 
          v3f local;
          m4x3_mulv( volume->to_local, route->board_transform[3], local );
@@ -47,9 +47,9 @@ entity_call_result ent_region_call( world_instance *world, ent_call *call )
       }
 
       gui_location_print_ccmd( 1, (const char *[]){
-            mdl_pstr(&world->meta,region->pstr_title)} );
+            ps_get( &world->meta.strings, region->pstr_title)} );
 
-      vg_strncpy( mdl_pstr(&world->meta,region->pstr_title), 
+      vg_strncpy( ps_get( &world->meta.strings, region->pstr_title ), 
                   global_ent_region.location, NETWORK_REGION_MAX,
                   k_strncpy_always_add_null );
       global_ent_region.flags = region->flags;
@@ -60,9 +60,9 @@ entity_call_result ent_region_call( world_instance *world, ent_call *call )
    }
    else if( call->function == 1 ) /* leave */
    {
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ )
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i ++ )
       {
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+         ent_route *route = af_arritm( &world->ent_route, i );
          route->flags |= k_ent_route_flag_out_of_zone;
       }
       localplayer.effect_data.spark.colour = 0x00;
@@ -80,20 +80,20 @@ void ent_region_re_eval( world_instance *world )
    u32 world_total = k_ent_route_flag_achieve_gold | 
                      k_ent_route_flag_achieve_silver;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_region); i ++ ){
-      ent_region *region = mdl_arritm(&world->ent_region, i);
+   for( u32 i=0; i<af_arrcount(&world->ent_region); i ++ ){
+      ent_region *region = af_arritm(&world->ent_region, i);
 
       if( !region->zone_volume )
          continue;
 
-      ent_volume *volume = mdl_arritm(&world->ent_volume,
+      ent_volume *volume = af_arritm(&world->ent_volume,
             mdl_entity_id_id(region->zone_volume));
 
       u32 combined = k_ent_route_flag_achieve_gold | 
                      k_ent_route_flag_achieve_silver;
 
-      for( u32 j=0; j<mdl_arrcount(&world->ent_route); j ++ ){
-         ent_route *route = mdl_arritm(&world->ent_route, j );
+      for( u32 j=0; j<af_arrcount(&world->ent_route); j ++ ){
+         ent_route *route = af_arritm(&world->ent_route, j );
 
          v3f local;
          m4x3_mulv( volume->to_local, route->board_transform[3], local );
@@ -106,8 +106,8 @@ void ent_region_re_eval( world_instance *world )
          combined &= route->flags;
       }
 
-      for( u32 j=0; j<mdl_arrcount(&world->ent_challenge); j ++ ){
-         ent_challenge *challenge = mdl_arritm( &world->ent_challenge, j );
+      for( u32 j=0; j<af_arrcount(&world->ent_challenge); j ++ ){
+         ent_challenge *challenge = af_arritm( &world->ent_challenge, j );
 
          v3f local;
          m4x3_mulv( volume->to_local, challenge->transform.co, local );
index b22b0b59634eae9049294c52fedc2ec237f2a488..e770ad5b416b8235ba2a64a91ef16b3f0d3a03d1 100644 (file)
@@ -3,7 +3,7 @@
 entity_call_result ent_relay_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_relay *relay = mdl_arritm( &world->ent_relay, index );
+   ent_relay *relay = af_arritm( &world->ent_relay, index );
 
    if( call->function == 0 )
    {
index 8564eed3c5c8c60400c2eb69e5a71b7ad599e1b1..5cf48467e924406b3e3badbe3bf5a591a145fe5e 100644 (file)
@@ -7,7 +7,7 @@ struct global_ent_route global_ent_route;
 entity_call_result ent_route_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_route *route = mdl_arritm( &world->ent_route, index );
+   ent_route *route = af_arritm( &world->ent_route, index );
 
    if( call->function == 0 )
    { /* view() */
@@ -43,7 +43,7 @@ void ent_route_preupdate( ent_focus_context *ctx )
       return;
 
    world_instance *world = ctx->world;
-   ent_route *route = mdl_arritm( &world->ent_route, ctx->index );
+   ent_route *route = af_arritm( &world->ent_route, ctx->index );
 
    u32 cam_id = 0;
    
index ded707c1064da2296db3a7152b04bc9bbc6855c4..19ec5184eb025c23c8ebbfb4c7a554f17ca1f91d 100644 (file)
@@ -215,10 +215,10 @@ void ent_skateshop_preupdate( ent_focus_context *ctx )
       return;
 
    world_instance *world = ctx->world;
-   ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, ctx->index );
+   ent_skateshop *shop = af_arritm( &world->ent_skateshop, ctx->index );
 
    /* camera positioning */
-   ent_camera *ref = mdl_arritm( &world->ent_camera, 
+   ent_camera *ref = af_arritm( &world->ent_camera, 
                                  mdl_entity_id_id(shop->id_camera) );
       
    v3f dir = {0.0f,-1.0f,0.0f};
@@ -228,7 +228,7 @@ void ent_skateshop_preupdate( ent_focus_context *ctx )
    v3f lookat;
    if( shop->type == k_skateshop_type_boardshop ||
        shop->type == k_skateshop_type_worldshop ){
-      ent_marker *display = mdl_arritm( &world->ent_marker,
+      ent_marker *display = af_arritm( &world->ent_marker,
                                     mdl_entity_id_id(shop->boards.id_display) );
       v3_sub( display->transform.co, localplayer.rb.co, lookat );
    }
@@ -236,7 +236,7 @@ void ent_skateshop_preupdate( ent_focus_context *ctx )
       v3_sub( ref->transform.co, localplayer.rb.co, lookat );
    }
    else if( shop->type == k_skateshop_type_server ){
-      ent_prop *prop = mdl_arritm( &world->ent_prop,
+      ent_prop *prop = af_arritm( &world->ent_prop,
             mdl_entity_id_id(shop->server.id_lever) );
       v3_sub( prop->transform.co, localplayer.rb.co, lookat );
    }
@@ -425,8 +425,8 @@ void ent_skateshop_preupdate( ent_focus_context *ctx )
 
 void skateshop_world_preupdate( world_instance *world )
 {
-   for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ ){
-      ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_skateshop); i++ ){
+      ent_skateshop *shop = af_arritm( &world->ent_skateshop, i );
 
       if( shop->type == k_skateshop_type_server ){
          f32 a = network_client.user_intent;
@@ -434,7 +434,7 @@ void skateshop_world_preupdate( world_instance *world )
          vg_slewf( &network_client.fintent, a, vg.time_frame_delta );
          a = (vg_smoothstepf( network_client.fintent ) - 0.5f) * (VG_PIf/2.0f);
 
-         ent_prop *lever = mdl_arritm( &world->ent_prop,
+         ent_prop *lever = af_arritm( &world->ent_prop,
                mdl_entity_id_id(shop->server.id_lever) );
 
          /* we need parent transforms now? */
@@ -447,9 +447,9 @@ static void skateshop_render_boardshop( ent_skateshop *shop ){
    world_instance *world = world_current_instance();
    u32 slot_count = VG_ARRAY_LEN(global_skateshop.shop_view_slots);
 
-   ent_marker *mark_rack = mdl_arritm( &world->ent_marker, 
+   ent_marker *mark_rack = af_arritm( &world->ent_marker, 
                                   mdl_entity_id_id(shop->boards.id_rack)),
-              *mark_display = mdl_arritm( &world->ent_marker,
+              *mark_display = af_arritm( &world->ent_marker,
                                   mdl_entity_id_id(shop->boards.id_display));
 
    SDL_AtomicLock( &addon_system.sl_cache_using_resources );
@@ -498,7 +498,7 @@ fade_out:;
       slot->view_blend = vg_lerpf( slot->view_blend, selected, rate );
    }
 
-   ent_marker *mark_info = mdl_arritm( &world->ent_marker, 
+   ent_marker *mark_info = af_arritm( &world->ent_marker, 
                                         mdl_entity_id_id(shop->boards.id_info));
    m4x3f mtext, mrack;
    mdl_transform_m4x3( &mark_info->transform, mtext );
@@ -601,9 +601,9 @@ static void skateshop_render_charshop( ent_skateshop *shop ){
 static void skateshop_render_worldshop( ent_skateshop *shop ){
    world_instance *world = world_current_instance();
 
-   ent_marker *mark_display = mdl_arritm( &world->ent_marker,
+   ent_marker *mark_display = af_arritm( &world->ent_marker,
                                   mdl_entity_id_id(shop->worlds.id_display)),
-              *mark_info = mdl_arritm( &world->ent_marker, 
+              *mark_info = af_arritm( &world->ent_marker, 
                                   mdl_entity_id_id(shop->boards.id_info));
 
    if( global_skateshop.render.world_reg != global_skateshop.selected_world_id){
@@ -717,9 +717,9 @@ void skateshop_render( ent_skateshop *shop )
 
 void skateshop_render_nonfocused( world_instance *world, vg_camera *cam )
 {
-   for( u32 j=0; j<mdl_arrcount( &world->ent_skateshop ); j ++ )
+   for( u32 j=0; j<af_arrcount( &world->ent_skateshop ); j ++ )
    {
-      ent_skateshop *shop = mdl_arritm(&world->ent_skateshop, j );
+      ent_skateshop *shop = af_arritm(&world->ent_skateshop, j );
 
       if( shop->type != k_skateshop_type_boardshop ) continue;
 
@@ -727,7 +727,7 @@ void skateshop_render_nonfocused( world_instance *world, vg_camera *cam )
           maxdist = 50.0f;
 
       if( dist2 > maxdist*maxdist ) continue;
-      ent_marker *mark_rack = mdl_arritm( &world->ent_marker, 
+      ent_marker *mark_rack = af_arritm( &world->ent_marker, 
                                      mdl_entity_id_id(shop->boards.id_rack));
 
       if( !mark_rack ) 
@@ -801,7 +801,7 @@ static void world_scan_thread( void *_args )
 entity_call_result ent_skateshop_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, index );
+   ent_skateshop *shop = af_arritm( &world->ent_skateshop, index );
    vg_info( "skateshop_call\n" );
 
    if( (skaterift.activity != k_skaterift_default) || 
index f9fca03e8928db2c982dc2d4bbbfe2dfa053ec21..b86f61e54d23350fe6c18f49ca41cc48c7b5070a 100644 (file)
@@ -18,10 +18,12 @@ void ent_tornado_init(void)
 void ent_tornado_debug(void) 
 {
    world_instance *world = world_current_instance();
-   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
-      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_marker); i ++ )
+   {
+      ent_marker *marker = af_arritm( &world->ent_marker, i );
 
-      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+      if( PS_EQ( &world->meta.strings, marker->pstr_alias, "tornado" ) )
+      {
          v3f p1;
          v3_add( marker->transform.co, (v3f){0,20,0}, p1 );
          vg_line( marker->transform.co, p1, VG__RED );
@@ -39,10 +41,12 @@ void ent_tornado_forces( v3f co, v3f cv, v3f out_a )
    world_instance *world = world_current_instance();
    v3_zero( out_a );
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
-      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_marker); i ++ )
+   {
+      ent_marker *marker = af_arritm( &world->ent_marker, i );
 
-      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+      if( PS_EQ( &world->meta.strings, marker->pstr_alias, "tornado" ) )
+      {
          v3f d, dir;
          v3_sub( co, marker->transform.co, d );
          d[1] = 0.0f;
@@ -67,10 +71,12 @@ void ent_tornado_forces( v3f co, v3f cv, v3f out_a )
 void ent_tornado_pre_update(void)
 {
    world_instance *world = world_current_instance();
-   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i ++ ){
-      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_marker); i ++ )
+   {
+      ent_marker *marker = af_arritm( &world->ent_marker, i );
 
-      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tornado" ) ){
+      if( PS_EQ( &world->meta.strings, marker->pstr_alias, "tornado" ) )
+      {
          v3f co;
          vg_rand_sphere( &vg.rand, co );
 
index 8bb19b9f673c166f9b2e6f582972e69bd2d05866..a14f62f7aeebffe5349ded118a988507496e1aeb 100644 (file)
@@ -2,8 +2,8 @@
 
 void ent_traffic_update( world_instance *world, v3f pos )
 {
-   for( u32 i=0; i<mdl_arrcount( &world->ent_traffic ); i++ ){
-      ent_traffic *traffic = mdl_arritm( &world->ent_traffic, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_traffic ); i++ ){
+      ent_traffic *traffic = af_arritm( &world->ent_traffic, i );
       
       u32 i1 = traffic->index,
           i0,
@@ -20,9 +20,9 @@ void ent_traffic_update( world_instance *world, v3f pos )
       
       v3f h[3];
 
-      ent_route_node *rn0 = mdl_arritm( &world->ent_route_node, i0 ),
-                     *rn1 = mdl_arritm( &world->ent_route_node, i1 ),
-                     *rn2 = mdl_arritm( &world->ent_route_node, i2 );
+      ent_route_node *rn0 = af_arritm( &world->ent_route_node, i0 ),
+                     *rn1 = af_arritm( &world->ent_route_node, i1 ),
+                     *rn2 = af_arritm( &world->ent_route_node, i2 );
 
       v3_copy( rn1->co, h[1] );
       v3_lerp( rn0->co, rn1->co, 0.5f, h[0] );
index 797e29d2361687ef12a0be35ac95253829915a44..dcae73876d8990af7e49332897f77ef622e37954 100644 (file)
@@ -59,14 +59,14 @@ void entity_call( world_instance *world, ent_call *call )
    }
 }
 
-ent_marker *ent_find_marker( mdl_context *mdl, mdl_array_ptr *arr, 
+ent_marker *ent_find_marker( mdl_context *mdl, array_file_ptr *arr, 
                              const char *alias )
 {
-   for( u32 i=0; i<mdl_arrcount(arr); i++ )
+   for( u32 i=0; i<af_arrcount(arr); i++ )
    {
-      ent_marker *marker = mdl_arritm( arr, i );
+      ent_marker *marker = af_arritm( arr, i );
 
-      if( !strcmp( mdl_pstr( mdl, marker->pstr_alias ), alias ) )
+      if( !strcmp( ps_get( &mdl->strings, marker->pstr_alias ), alias ) )
       {
          return marker;
       }
index 6d503f9b9f334728bbd895033939fcbcfadb3c57..5120052586965c29c725a83678b36f3ee97d9ffd 100644 (file)
@@ -429,7 +429,7 @@ struct ent_worldinfo{
    u32 flags;
 };
 
-ent_marker *ent_find_marker( mdl_context *mdl, mdl_array_ptr *arr, 
+ent_marker *ent_find_marker( mdl_context *mdl, array_file_ptr *arr, 
                              const char *alias );
 
 enum channel_behaviour{
index fa144c40576a8c5079dc930b04ea12aea2ceb225..98142c08bc4b47ec40f899e3f02f4ec5f8cc080e 100644 (file)
@@ -75,44 +75,48 @@ struct font3d{
    glmesh mesh;
 
    ent_font info;
-   mdl_array_ptr font_variants,
+   array_file_ptr font_variants,
                  glyphs;
 };
 
-static void font3d_load( font3d *font, const char *mdl_path, void *alloc ){
-   mdl_open( &font->mdl, mdl_path, alloc );
-   mdl_load_metadata_block( &font->mdl, alloc );
+static void font3d_load( font3d *font, const char *mdl_path, void *alloc )
+{
+   mdl_context *mdl = &font->mdl;
+   mdl_open( mdl, mdl_path, alloc );
+   mdl_load_metadata_block( mdl, alloc );
 
    vg_linear_clear( vg_mem.scratch );
-   mdl_array_ptr fonts;
-   MDL_LOAD_ARRAY( &font->mdl, &fonts, ent_font, vg_mem.scratch );
-   font->info = *((ent_font *)mdl_arritm(&fonts,0));
+   array_file_ptr fonts;
+   MDL_LOAD_ARRAY_STRUCT( mdl, &fonts, ent_font, vg_mem.scratch );
+   font->info = *((ent_font *)af_arritm(&fonts,0));
 
-   MDL_LOAD_ARRAY( &font->mdl, &font->font_variants, ent_font_variant, alloc);
-   MDL_LOAD_ARRAY( &font->mdl, &font->glyphs, ent_glyph, alloc );
+   MDL_LOAD_ARRAY_STRUCT( mdl, &font->font_variants, ent_font_variant, alloc);
+   MDL_LOAD_ARRAY_STRUCT( mdl, &font->glyphs, ent_glyph, alloc );
 
    vg_linear_clear( vg_mem.scratch );
 
-   if( !mdl_arrcount( &font->mdl.textures ) )
+   if( !af_arrcount( &font->mdl.textures ) )
       vg_fatal_error( "No texture in font file" );
 
-   mdl_texture *tex0 = mdl_arritm( &font->mdl.textures, 0 );
+   mdl_texture *tex0 = af_arritm( &mdl->textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
-   mdl_fread_pack_file( &font->mdl, &tex0->file, data );
+   mdl_fread_pack_file( mdl, &tex0->file, data );
 
-   mdl_async_load_glmesh( &font->mdl, &font->mesh, NULL );
+   mdl_async_load_glmesh( mdl, &font->mesh, NULL );
    vg_tex2d_load_qoi_async( data, tex0->file.pack_size, 
                             VG_TEX2D_LINEAR|VG_TEX2D_CLAMP,
                             &font->texture );
 
-   mdl_close( &font->mdl );
+   mdl_close( mdl );
 }
 
-static u32 font3d_find_variant( font3d *font, const char *name ){
-   for( u32 i=0; i<mdl_arrcount( &font->font_variants ); i ++ ){
-      ent_font_variant *variant = mdl_arritm( &font->font_variants, i );
+static u32 font3d_find_variant( font3d *font, const char *name )
+{
+   for( u32 i=0; i<af_arrcount( &font->font_variants ); i ++ )
+   {
+      ent_font_variant *variant = af_arritm( &font->font_variants, i );
 
-      if( !strcmp( mdl_pstr( &font->mdl, variant->name ), name ) ){
+      if( !strcmp( ps_get( &font->mdl.strings, variant->name ), name ) ){
          return i;
       }
    }
@@ -184,7 +188,7 @@ static ent_glyph *font3d_glyph( font3d *font, u32 variant_id, u32 utf32 ){
    u32 index = utf32 - font->info.glyph_utf32_base;
        index += font->info.glyph_start;
        index += font->info.glyph_count * variant_id;
-   return mdl_arritm( &font->glyphs, index );
+   return af_arritm( &font->glyphs, index );
 }
 
 static void font3d_set_transform( const char *text,
index 46e2e1ecf72344ae6cb7f6ed317903f6efe84cc8..a760cac3e38a595f9d1a1db85b122d27d55f6e60 100644 (file)
--- a/src/gui.h
+++ b/src/gui.h
@@ -308,7 +308,7 @@ static mdl_submesh *gui_find_icon( const char *name ){
    mdl_mesh *mesh = mdl_find_mesh( &gui.model_icons, name );
    if( mesh ){
       if( mesh->submesh_count ){
-         return mdl_arritm( &gui.model_icons.submeshs, mesh->submesh_start );
+         return af_arritm( &gui.model_icons.submeshs, mesh->submesh_start );
       }
    }
 
@@ -346,9 +346,9 @@ static void gui_init(void)
       gui_find_icon("icon_rift_run_medal_silver");
 
    vg_linear_clear( vg_mem.scratch );
-   if( !mdl_arrcount( &gui.model_icons.textures ) )
+   if( !af_arrcount( &gui.model_icons.textures ) )
       vg_fatal_error( "No texture in menu file" );
-   mdl_texture *tex0 = mdl_arritm( &gui.model_icons.textures, 0 );
+   mdl_texture *tex0 = af_arritm( &gui.model_icons.textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
    mdl_fread_pack_file( &gui.model_icons, &tex0->file, data );
    vg_tex2d_load_qoi_async( data, tex0->file.pack_size, 
index 1f2b9c8f542a622f5c4714f53570734a171158cc..556cc0d7f3249149d913a74848a58078da79688b 100644 (file)
@@ -295,15 +295,15 @@ static i32 menu_nav( i32 *p_row, int mv, i32 max )
 static void menu_try_find_cam( i32 id )
 {
    world_instance *world = &world_static.instances[0];
-   for( u32 i=0; i<mdl_arrcount(&world->ent_npc); i ++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_npc); i ++ )
    {
-      ent_npc *fnpc = mdl_arritm( &world->ent_npc, i );
+      ent_npc *fnpc = af_arritm( &world->ent_npc, i );
       if( (fnpc->id == 50) && (fnpc->context == id) )
       {
          if( mdl_entity_id_type(fnpc->camera) == k_ent_camera )
          {
             u32 index = mdl_entity_id_id( fnpc->camera );
-            menu.bg_cam = mdl_arritm( &world->ent_camera, index );
+            menu.bg_cam = af_arritm( &world->ent_camera, index );
             menu.bg_blur = 0;
          }
       }
@@ -734,7 +734,7 @@ void menu_gui( ui_context *ctx )
       if( world->status == k_world_status_loaded )
       {
          const char *world_name = 
-            mdl_pstr( &world->meta, world->info.pstr_name );
+            ps_get( &world->meta.strings, world->info.pstr_name );
 
          vg_strnull( &str, buf, sizeof(buf) );
          vg_strcat( &str, world_name );
@@ -781,14 +781,15 @@ void menu_gui( ui_context *ctx )
 
          ui_rect_pad( stat_panel, (ui_px[2]){8,0} );
 
-         for( u32 i=0; i<mdl_arrcount( &world->ent_region ); i ++ )
+         for( u32 i=0; i<af_arrcount( &world->ent_region ); i ++ )
          {
-            ent_region *region = mdl_arritm( &world->ent_region, i );
+            ent_region *region = af_arritm( &world->ent_region, i );
 
             if( !region->zone_volume )
                continue;
 
-            const char *title = mdl_pstr( &world->meta, region->pstr_title );
+            const char *title = ps_get( &world->meta.strings, 
+                                         region->pstr_title );
             ctx->font = &vgf_default_large;
 
             ui_rect title_box;
@@ -798,7 +799,7 @@ void menu_gui( ui_context *ctx )
             stat_panel[2] -= 16;
             ctx->font = &vgf_default_small;
 
-            ent_volume *volume = mdl_arritm(&world->ent_volume,
+            ent_volume *volume = af_arritm(&world->ent_volume,
                   mdl_entity_id_id(region->zone_volume));
 
             u32 combined = k_ent_route_flag_achieve_gold | 
@@ -807,9 +808,9 @@ void menu_gui( ui_context *ctx )
             char buf[128];
             vg_str str;
 
-            for( u32 j=0; j<mdl_arrcount(&world->ent_route); j ++ )
+            for( u32 j=0; j<af_arrcount(&world->ent_route); j ++ )
             {
-               ent_route *route = mdl_arritm(&world->ent_route, j );
+               ent_route *route = af_arritm(&world->ent_route, j );
 
                v3f local;
                m4x3_mulv( volume->to_local, route->board_transform[3], local );
@@ -824,7 +825,7 @@ void menu_gui( ui_context *ctx )
 
                vg_strnull( &str, buf, sizeof(buf) );
                vg_strcat( &str, "(Race) " );
-               vg_strcat( &str, mdl_pstr(&world->meta, route->pstr_name));
+               vg_strcat( &str, ps_get(&world->meta.strings, route->pstr_name));
 
                if( route->flags & k_ent_route_flag_achieve_silver )
                   vg_strcat( &str, " \xb3");
@@ -837,9 +838,9 @@ void menu_gui( ui_context *ctx )
                         medal_colour( ctx, route->flags ) );
             }
 
-            for( u32 j=0; j<mdl_arrcount(&world->ent_challenge); j ++ )
+            for( u32 j=0; j<af_arrcount(&world->ent_challenge); j ++ )
             {
-               ent_challenge *challenge = mdl_arritm( &world->ent_challenge, j );
+               ent_challenge *challenge = af_arritm( &world->ent_challenge, j );
 
                v3f local;
                m4x3_mulv( volume->to_local, challenge->transform.co, local );
@@ -851,7 +852,8 @@ void menu_gui( ui_context *ctx )
                }
 
                vg_strnull( &str, buf, sizeof(buf) );
-               vg_strcat( &str, mdl_pstr(&world->meta, challenge->pstr_alias));
+               vg_strcat( &str, ps_get(&world->meta.strings, 
+                           challenge->pstr_alias));
 
                u32 flags = 0x00;
                if( challenge->status )
diff --git a/src/metascene.c b/src/metascene.c
new file mode 100644 (file)
index 0000000..4bb0ca1
--- /dev/null
@@ -0,0 +1,45 @@
+#include "metascene.h"
+
+void metascene_load( ms_context *ms, const char *path, void *alloc )
+{
+   memset( ms, 0, sizeof( ms_context ) );
+   FILE *fp = fopen( path, "rb" );
+
+   if( !fp )
+   {
+      vg_fatal_condition();
+      vg_info( "metascene_load( '%s' ): %s\n", path, strerror(errno) );
+      vg_fatal_exit();
+   }
+
+   u64 l = fread( &ms->info, sizeof(ms_header), 1, fp );
+   if( l != 1 )
+   {
+      vg_fatal_condition();
+      vg_info( "Read corruption error" );
+      vg_fatal_exit();
+   }
+
+   if( ms->info.version < MS_VERSION_MIN )
+   {
+      vg_fatal_condition();
+      vg_info( "Legacy metascene version incompatable" );
+      vg_info( "For file: %s\n", path );
+      vg_info( " version: %u (min: %u, current: %u)\n", 
+               ms->info.version, MS_VERSION_MIN, MS_VERSION_NR );
+      vg_fatal_exit();
+   }
+
+   af_load_array_file( fp, &ms->index, &ms->info.index, alloc,
+                       sizeof(array_file_meta) );
+
+   af_load_array( fp, &ms->index, &ms->strings, "strings", alloc, 1 );
+   AF_LOAD_ARRAY_STRUCT( fp, &ms->index, &ms->instances, ms_instance, alloc );
+   AF_LOAD_ARRAY_STRUCT( fp, &ms->index, &ms->overrides, ms_override, alloc );
+   AF_LOAD_ARRAY_STRUCT( fp, &ms->index, &ms->strips, ms_strip, alloc );
+   AF_LOAD_ARRAY_STRUCT( fp, &ms->index, &ms->tracks, ms_track, alloc );
+   AF_LOAD_ARRAY_STRUCT( fp, &ms->index, &ms->keyframes, ms_keyframe, alloc );
+   af_load_array( fp, &ms->index, &ms->curves, "ms_curves", 
+                     alloc, sizeof(ms_curve_keyframe) );
+   fclose( fp );
+}
diff --git a/src/metascene.h b/src/metascene.h
new file mode 100644 (file)
index 0000000..6b7685d
--- /dev/null
@@ -0,0 +1,76 @@
+#pragma once
+#include "model.h"
+
+#define MS_VERSION_NR 1
+#define MS_VERSION_MIN 1
+
+typedef struct ms_context ms_context;
+typedef struct ms_header ms_header;
+typedef struct ms_instance ms_instance;
+typedef struct ms_override ms_override;
+typedef struct ms_strip ms_strip;
+typedef struct ms_track ms_track;
+typedef struct ms_curve_keyframe ms_curve_keyframe;
+typedef struct mdl_transform ms_keyframe;
+
+struct ms_header
+{
+   u32 version;
+   f32 framerate;
+   array_file_meta index;
+};
+
+struct ms_context
+{
+   ms_header info;
+   struct array_file_ptr index,
+                         strings,
+
+                         instances,
+                         overrides,
+                         strips,
+                         tracks,
+                         keyframes,
+                         curves;
+};
+
+struct ms_instance
+{
+   u32 pstr_name,
+       override_start,
+       override_count;
+};
+
+struct ms_override
+{
+   u32 pstr_name;
+   mdl_transform transform;
+};
+
+struct ms_strip
+{
+   u32 data_start,
+       data_count,
+       data_mode,
+       offset,
+       length,
+       pstr_name,
+       pstr_internal_name,
+       instance_id,
+       object_id;
+};
+
+struct ms_track
+{
+   u32 keyframe_start,
+       keyframe_count,
+       pstr_datapath,
+       semantic_type;
+};
+
+struct ms_curve_keyframe
+{
+   v2f co, l, r;
+};
+
+void metascene_load( ms_context *ms, const char *path, void *alloc );
index f3f7ab2aa5a25bc63cb6932a5a1b4b45cc1f6749..fc7e38749fed830b421359119afe4720421578f6 100644 (file)
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include "model.h"
 #include "shader_props.h"
+#include "array_file.h"
 
 static void mdl_load_fatal_corrupt( mdl_context *mdl )
 {
@@ -37,7 +38,7 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst )
    {
       vg_fatal_condition();
       vg_info( "Packed file is only a header; it is not packed" );
-      vg_info( "path: %s\n", mdl_pstr( mdl, info->pstr_path ) );
+      vg_info( "path: %s\n", ps_get( &mdl->strings, info->pstr_path ) );
       vg_fatal_exit();
    }
 
@@ -47,132 +48,31 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst )
    if( l != 1 ) mdl_load_fatal_corrupt( mdl );
 }
 
-/* TODO: Rename these */
-static void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, 
-                                        void *buffer, u32 stride )
+int mdl_load_array( mdl_context *mdl, array_file_ptr *ptr, const char *name,
+                    void *lin_alloc, u32 stride )
 {
-   if( arr->item_count )
-   {
-      fseek( mdl->file, arr->file_offset, SEEK_SET );
-
-      if( stride == arr->item_size )
-      {
-         u64 l = fread( buffer, arr->item_size*arr->item_count, 1, mdl->file );
-         if( l != 1 ) mdl_load_fatal_corrupt( mdl );
-      }
-      else 
-      {
-         vg_warn( "Applying alignment fixup to array @%p [%u -> %u] x %u\n", 
-                  buffer, arr->item_size, stride, arr->item_count );
-
-         if( stride > arr->item_size )
-            memset( buffer, 0, stride*arr->item_count );
-
-         u32 read_size = VG_MIN( stride, arr->item_size );
-
-         for( u32 i=0; i<arr->item_count; i++ )
-         {
-            u64 l = fread( buffer+i*stride, read_size, 1, mdl->file );
-            if( stride < arr->item_size )
-               fseek( mdl->file, arr->item_size-stride, SEEK_CUR );
-
-            if( l != 1 ) mdl_load_fatal_corrupt( mdl );
-         }
-      }
-   }
-}
-
-static void mdl_load_array_file( mdl_context *mdl, mdl_array_ptr *ptr, 
-                                 mdl_array *arr, void *lin_alloc, u32 stride )
-{
-   if( arr->item_count )
-   {
-      u32 size = stride*arr->item_count;
-      ptr->data = lin_alloc? vg_linear_alloc( lin_alloc, vg_align8(size) ):
-                             malloc( size );
-      mdl_load_array_file_buffer( mdl, arr, ptr->data, stride );
-   }
-   else
-   {
-      ptr->data = NULL;
-   }
-   
-   ptr->stride = stride;
-   ptr->count = arr->item_count;
-}
-
-void *mdl_arritm( mdl_array_ptr *arr, u32 index )
-{
-   return ((u8 *)arr->data) + index*arr->stride;
-}
-
-u32 mdl_arrcount( mdl_array_ptr *arr )
-{
-   return arr->count;
-}
-
-static mdl_array *mdl_find_array( mdl_context *mdl, const char *name )
-{
-   for( u32 i=0; i<mdl_arrcount(&mdl->index); i++ )
-   {
-      mdl_array *arr = mdl_arritm( &mdl->index, i );
-      
-      if( !strncmp(arr->name,name,16) )
-         return arr;
-   }
-
-   return NULL;
-}
-
-int _mdl_load_array( mdl_context *mdl, mdl_array_ptr *ptr,
-                     const char *name, void *lin_alloc, u32 stride )
-{
-   mdl_array *arr = mdl_find_array( mdl, name );
-
-   if( arr )
-   {
-      mdl_load_array_file( mdl, ptr, arr, lin_alloc, stride );
-      return 1;
-   }
-   else
-   {
-      ptr->data = NULL;
-      ptr->count = 0;
-      ptr->stride = 0;
-      return 0;
-   }
+   return af_load_array( mdl->file, &mdl->index, ptr, name, lin_alloc, stride );
 }
 
 int mdl_load_mesh_block( mdl_context *mdl, void *lin_alloc )
 {
-   int success = 1;
-
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->verts,    mdl_vert,   lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->indices,  mdl_indice, lin_alloc );
-
-   return success;
+   int s = 1;
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->verts,    mdl_vert,   lin_alloc );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->indices,  mdl_indice, lin_alloc );
+   return s;
 }
 
 int mdl_load_metadata_block( mdl_context *mdl, void *lin_alloc )
 {
-   int success = 1;
-
-   success &= _mdl_load_array( mdl, &mdl->strings, "strings", lin_alloc, 1 );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->meshs,     mdl_mesh,     lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->submeshs,  mdl_submesh,  lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->textures,  mdl_texture,  lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->armatures, mdl_armature, lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->bones,     mdl_bone,     lin_alloc );
-   success &= MDL_LOAD_ARRAY( mdl, &mdl->animations,mdl_animation,lin_alloc );
-
-   success &= mdl_load_materials( mdl, lin_alloc );
-
-   return success;
-}
-
-int mdl_load_animation_block( mdl_context *mdl, void *lin_alloc )
-{
-   return MDL_LOAD_ARRAY( mdl, &mdl->keyframes, mdl_keyframe, lin_alloc );
+   int s = 1;
+   s &= mdl_load_array       ( mdl, &mdl->strings, "strings", lin_alloc, 1 );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->meshs,     mdl_mesh,     lin_alloc );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->submeshs,  mdl_submesh,  lin_alloc );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->textures,  mdl_texture,  lin_alloc );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->armatures, mdl_armature, lin_alloc );
+   s &= MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->bones,     mdl_bone,     lin_alloc );
+   s &= mdl_load_materials( mdl, lin_alloc );
+   return s;
 }
 
 void *mdl_shader_standard( vg_msg *msg, void *alloc )
@@ -182,7 +82,6 @@ void *mdl_shader_standard( vg_msg *msg, void *alloc )
 
    vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse,
                      NULL );
-
    return props;
 }
 
@@ -247,7 +146,8 @@ void *mdl_shader_cubemapped( vg_msg *msg, void *alloc )
    return props;
 }
 
-bool _mdl_legacy_v105_properties( struct mdl_material_v105 *mat, vg_msg *dst )
+static bool mdl_legacy_v105_properties( struct mdl_material_v105 *mat, 
+                                        vg_msg *dst )
 {
    vg_msg_wkvnum( dst, "tex_diffuse", k_vg_msg_u32, 1, &mat->tex_diffuse );
 
@@ -276,27 +176,27 @@ bool _mdl_legacy_v105_properties( struct mdl_material_v105 *mat, vg_msg *dst )
 
 int mdl_load_materials( mdl_context *mdl, void *lin_alloc )
 {
-   MDL_LOAD_ARRAY( mdl, &mdl->materials, mdl_material, lin_alloc );
+   MDL_LOAD_ARRAY_STRUCT( mdl, &mdl->materials, mdl_material, lin_alloc );
 
 #if (MDL_VERSION_MIN <= 105)
    /* load legacy material data into scratch */
-   mdl_array_ptr legacy_materials;
+   array_file_ptr legacy_materials;
    if( mdl->info.version <= 105 )
    {
-      _mdl_load_array( mdl, &legacy_materials, "mdl_material", vg_mem.scratch,
-                       sizeof(struct mdl_material_v105) );
+      mdl_load_array( mdl, &legacy_materials, "mdl_material", vg_mem.scratch,
+                      sizeof(struct mdl_material_v105) );
    }
 #endif
 
-   mdl_array_ptr data;
-   _mdl_load_array( mdl, &data, "shader_data", vg_mem.scratch, 1 );
+   array_file_ptr data;
+   mdl_load_array( mdl, &data, "shader_data", vg_mem.scratch, 1 );
 
    if( !lin_alloc )
       return 1;
 
-   for( u32 i=0; i<mdl_arrcount(&mdl->materials); i ++ )
+   for( u32 i=0; i<af_arrcount(&mdl->materials); i ++ )
    {
-      mdl_material *mat = mdl_arritm( &mdl->materials, i );
+      mdl_material *mat = af_arritm( &mdl->materials, i );
       vg_msg msg;
 
 #if (MDL_VERSION_MIN <= 105)
@@ -304,7 +204,7 @@ int mdl_load_materials( mdl_context *mdl, void *lin_alloc )
       if( mdl->info.version <= 105 )
       {
          vg_msg_init( &msg, legacy_buf, sizeof(legacy_buf) );
-         _mdl_legacy_v105_properties( mdl_arritm( &legacy_materials,i ), &msg );
+         mdl_legacy_v105_properties( af_arritm( &legacy_materials,i ), &msg );
          vg_msg_init( &msg, legacy_buf, msg.cur.co );
       }
       else
@@ -373,10 +273,10 @@ void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc )
       vg_fatal_exit();
    }
 
-   mdl_load_array_file( mdl, &mdl->index, &mdl->info.index, lin_alloc,
-                        sizeof(mdl_array) );
+   af_load_array_file( mdl->file, &mdl->index, &mdl->info.index, lin_alloc,
+                       sizeof(array_file_meta) );
 
-   mdl_array *pack = mdl_find_array( mdl, "pack" );
+   array_file_meta *pack = af_find_array( &mdl->index, "pack" );
    if( pack ) mdl->pack_base_offset = pack->file_offset;
    else mdl->pack_base_offset = 0;
 }
@@ -401,22 +301,6 @@ void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx )
    v3_copy( transform->co, mtx[3] );
 }
 
-const char *mdl_pstr( mdl_context *mdl, u32 pstr )
-{
-   return ((char *)mdl_arritm( &mdl->strings, pstr )) + 4;
-}
-
-
-int mdl_pstreq( mdl_context *mdl, u32 pstr, const char *str, u32 djb2 )
-{
-   u32 hash = *((u32 *)mdl_arritm( &mdl->strings, pstr ));
-   if( hash == djb2 ){
-      if( !strcmp( str, mdl_pstr( mdl, pstr ))) return 1;
-      else return 0;
-   }
-   else return 0;
-}
-
 /*
  * Simple mesh interface for OpenGL
  * ----------------------------------------------------------------------------
@@ -510,13 +394,12 @@ void mdl_draw_submesh( mdl_submesh *sm )
 
 mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name )
 {
-   for( u32 i=0; i<mdl_arrcount( &mdl->meshs ); i++ )
+   u32 hash = vg_strdjb2( name );
+   for( u32 i=0; i<af_arrcount( &mdl->meshs ); i++ )
    {
-      mdl_mesh *mesh = mdl_arritm( &mdl->meshs, i );
-      if( !strcmp( name, mdl_pstr( mdl, mesh->pstr_name )))
-      {
+      mdl_mesh *mesh = af_arritm( &mdl->meshs, i );
+      if( ps_consteq( &mdl->strings, mesh->pstr_name, name, hash ) ) 
          return mesh;
-      }
    }
    return NULL;
 }
@@ -528,7 +411,7 @@ mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name )
    if( !mesh ) return NULL;
    if( !mesh->submesh_count ) return NULL;
 
-   return mdl_arritm( &mdl->submeshs, mesh->submesh_start );
+   return af_arritm( &mdl->submeshs, mesh->submesh_start );
 }
 
 #ifdef VG_3D
@@ -552,8 +435,8 @@ static void _sync_mdl_load_glmesh( void *payload, u32 size )
 
 void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table )
 {
-   mdl_array *arr_vertices = mdl_find_array( mdl, "mdl_vert" );
-   mdl_array *arr_indices = mdl_find_array( mdl, "mdl_indice" );
+   array_file_meta *arr_vertices = af_find_array( &mdl->index, "mdl_vert" );
+   array_file_meta *arr_indices = af_find_array( &mdl->index, "mdl_indice" );
 
    if( arr_vertices && arr_indices )
    {
@@ -573,9 +456,9 @@ void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table )
       job->vertex_count = arr_vertices->item_count;
       job->indice_count = arr_indices->item_count;
 
-      mdl_load_array_file_buffer( mdl, arr_vertices, 
+      af_load_array_file_buffer( mdl->file, arr_vertices, 
                                   job->verts, sizeof(mdl_vert) );
-      mdl_load_array_file_buffer( mdl, arr_indices, job->indices, 
+      af_load_array_file_buffer( mdl->file, arr_indices, job->indices, 
                                   sizeof(mdl_indice) );
 
       if( fixup_table )
@@ -596,14 +479,14 @@ void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table )
        * ---------------------------------------------------------
        */
 
-      if( mdl_arrcount( &mdl->submeshs ) )
+      if( af_arrcount( &mdl->submeshs ) )
       {
-         mdl_submesh *sm = mdl_arritm( &mdl->submeshs, 0 );
+         mdl_submesh *sm = af_arritm( &mdl->submeshs, 0 );
          u32 offset = sm->vertex_count;
 
-         for( u32 i=1; i<mdl_arrcount( &mdl->submeshs ); i++ )
+         for( u32 i=1; i<af_arrcount( &mdl->submeshs ); i++ )
          {
-            mdl_submesh *sm = mdl_arritm( &mdl->submeshs, i );
+            mdl_submesh *sm = af_arritm( &mdl->submeshs, i );
             u32 *indices    = job->indices + sm->indice_start;
 
             for( u32 j=0; j<sm->indice_count; j++ )
@@ -633,10 +516,10 @@ void mdl_async_full_load_std( mdl_context *mdl )
 {
    mdl_async_load_glmesh( mdl, &mdl->mesh, NULL );
    
-   for( u32 i=0; i<mdl_arrcount( &mdl->textures ); i ++ )
+   for( u32 i=0; i<af_arrcount( &mdl->textures ); i ++ )
    {
       vg_linear_clear( vg_mem.scratch );
-      mdl_texture *tex = mdl_arritm( &mdl->textures, i );
+      mdl_texture *tex = af_arritm( &mdl->textures, i );
 
       void *data = vg_linear_alloc( vg_mem.scratch, tex->file.pack_size );
       mdl_fread_pack_file( mdl, &tex->file, data );
index aade46aa21ddd00c341c552d71669bc20f1fbd00..b706482b6872db57f16be90084f046fc605e34c7 100644 (file)
@@ -5,7 +5,9 @@
 #pragma once
 
 #define MDL_VERSION_MIN 101
-#define MDL_VERSION_NR 106
+#define MDL_VERSION_NR 107
+
+#include "array_file.h"
 
 enum mdl_shader{
    k_shader_standard                = 0,
@@ -67,7 +69,6 @@ struct mdl_vert
 typedef u32 mdl_indice;
 
 typedef struct mdl_context mdl_context;
-typedef struct mdl_array_ptr mdl_array_ptr;
 typedef struct mdl_vert mdl_vert;
 typedef struct mdl_transform mdl_transform;
 typedef struct mdl_submesh mdl_submesh;
@@ -75,11 +76,9 @@ typedef struct mdl_material mdl_material;
 typedef struct mdl_bone mdl_bone;
 typedef struct mdl_armature mdl_armature;
 typedef struct mdl_animation mdl_animation;
-typedef struct mdl_transform mdl_keyframe;
 typedef struct mdl_mesh mdl_mesh;
 typedef struct mdl_file mdl_file;
 typedef struct mdl_texture mdl_texture;
-typedef struct mdl_array mdl_array;
 typedef struct mdl_header mdl_header;
 
 typedef struct glmesh glmesh;
@@ -202,18 +201,20 @@ struct mdl_armature
    mdl_transform transform;
    u32 bone_start,
        bone_count,
-       anim_start,
-       anim_count;
-};
+       anim_start_OBSOLETE_107, // obsolete 107+
+       anim_count_OBSOLETE_107, // .
 
-struct mdl_animation
-{
-   u32 pstr_name,
-       length;
-   float rate;
-   u32 offset;
+       pstr_name; // v107+
 };
 
+// struct mdl_animation
+// {
+//    u32 pstr_name,
+//        length;
+//    float rate;
+//    u32 offset;
+// };
+
 struct mdl_submesh
 {
    u32 indice_start,
@@ -247,19 +248,10 @@ struct mdl_texture
    u32 glname;
 };
 
-struct mdl_array
-{
-   u32 file_offset,
-       item_count,
-       item_size;
-
-   char name[16];
-};
-
 struct mdl_header
 {
    u32 version;
-   mdl_array index;
+   array_file_meta index;
 };
 
 struct mdl_context
@@ -267,12 +259,7 @@ struct mdl_context
    FILE *file;
    mdl_header info;
 
-   struct mdl_array_ptr
-   {
-      void *data;
-      u32 count, stride;
-   }
-   index,
+   struct array_file_ptr index,
 
    /* metadata */
    strings,
@@ -282,10 +269,6 @@ struct mdl_context
    textures,
    armatures,
    bones,
-   animations,
-
-   /* animation buffers */
-   keyframes,
 
    /* mesh buffers */
    verts,
@@ -305,21 +288,16 @@ void mesh_free( glmesh *mesh );
 void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc );
 void mdl_close( mdl_context *mdl );
 
-/* array loading */
-int _mdl_load_array( mdl_context *mdl, mdl_array_ptr *ptr,
-                     const char *name, void *lin_alloc, u32 stride );
-#define MDL_LOAD_ARRAY( MDL, PTR, STRUCT, ALLOCATOR ) \
-   _mdl_load_array( MDL, PTR, #STRUCT, ALLOCATOR, sizeof(STRUCT) )
+int mdl_load_array( mdl_context *mdl, array_file_ptr *ptr, const char *name,
+                    void *lin_alloc, u32 stride );
 
-/* array access */
-void *mdl_arritm( mdl_array_ptr *arr, u32 index );
-u32 mdl_arrcount( mdl_array_ptr *arr );
+#define MDL_LOAD_ARRAY_STRUCT( MDL, PTR, STRUCT, ALLOCATOR ) \
+   mdl_load_array( MDL, PTR, #STRUCT, ALLOCATOR, sizeof(STRUCT) )
 
 /* pack access */
 void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst );
 
 /* standard array groups */
-int mdl_load_animation_block( mdl_context *mdl, void *lin_alloc );
 int mdl_load_metadata_block( mdl_context *mdl, void *lin_alloc );
 int mdl_load_mesh_block( mdl_context *mdl, void *lin_alloc );
 int mdl_load_materials( mdl_context *mdl, void *lin_alloc );
@@ -335,11 +313,5 @@ void mdl_draw_submesh( mdl_submesh *sm );
 mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name );
 mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name );
 
-/* pstrs */
-const char *mdl_pstr( mdl_context *mdl, u32 pstr );
-int mdl_pstreq( mdl_context *mdl, u32 pstr, const char *str, u32 djb2 );
-#define MDL_CONST_PSTREQ( MDL, Q, CONSTSTR )\
-   mdl_pstreq( MDL, Q, CONSTSTR, vg_strdjb2( CONSTSTR ) )
-
 void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx );
 
index 551b39be0ee9305da0733b0a3ab02cd97b9c9209..2a57488d92e9e469e9e44311df52cb64d65a8c09 100644 (file)
@@ -180,7 +180,7 @@ void player__pass_gate( u32 id )
    localplayer.boundary_hash &= ~NETMSG_BOUNDARY_MASK;
    localplayer.boundary_hash |= index;
    
-   ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
+   ent_gate *gate = af_arritm( &world->ent_gate, mdl_entity_id_id(id) );
    world_routes_fracture( world, gate, localplayer.rb.co, localplayer.rb.v );
 
    localplayer.gate_waiting = gate;
index ff8c2e1ed653047b4c5828ebbebf740e4b04df49..47fabaebd601e09c40596c19916afeabb0516d05 100644 (file)
@@ -135,6 +135,7 @@ struct localplayer
     * Rendering
     */
    mdl_context skeleton_meta;
+   ms_context animations;
    struct skeleton skeleton;
 
    u8 id_hip,
@@ -187,6 +188,7 @@ void player__reset(void);
 void player__kill(void);
 void player__begin_holdout( v3f offset );
 
+void player_get_anim( skeleton_anim *out_anim, const char *name );
 int localplayer_cmd_respawn( int argc, const char *argv[] );
 void player_apply_transport_to_cam( m4x3f transport );
 
index f7f47852e4505b271bf23e7dfff3949ddd57fc2d..51b21b69de22bf41c6e710b97fe4f0b6d1e54d48 100644 (file)
@@ -1,5 +1,6 @@
 #pragma once
 #include "model.h"
+#include "metascene.h"
 
 typedef struct player_instance player_instance;
 typedef struct player_pose player_pose;
@@ -14,7 +15,7 @@ struct player_pose{
    v3f root_co;
    v4f root_q;
 
-   mdl_keyframe keyframes[32];
+   ms_keyframe keyframes[32];
 
    struct player_board_pose {
       f32 lean;
index 43b6211a659caef2f9e6c6025de16b2ea805d9e7..a5b588293e07cbdc112244ea6f1d8892f091980a 100644 (file)
@@ -201,5 +201,5 @@ void player__dead_animator_exchange( bitpack_ctx *ctx, void *data )
 void player__dead_bind(void)
 {
    struct skeleton *sk = &localplayer.skeleton;
-   player_dead.anim_bail = skeleton_get_anim( sk, "pose_bail_ball" );
+   player_get_anim( &player_dead.anim_bail, "pose_bail_ball" );
 }
index 93b0cc3d231bf77a6c91c8598fc8dcf364169cc2..b86c586493b6653531498f7ad9ea5a9521b9dbee 100644 (file)
@@ -15,7 +15,7 @@ struct player_dead
    }
    animator;
 
-   struct skeleton_anim *anim_bail;
+   skeleton_anim anim_bail;
 }
 extern player_dead;
 extern struct player_subsystem_interface player_subsystem_dead;
index 04620370f97a23641a22736d31d41445044b0298..e55a66883529b3ee0a4519fbf5ed6a747761f2ce 100644 (file)
@@ -46,7 +46,7 @@ void player__drive_pose( void *animator, player_pose *pose )
 {
    struct skeleton *sk = &localplayer.skeleton;
 
-   skeleton_sample_anim( sk, player_drive.anim_drive, 0.0f, pose->keyframes );
+   skeleton_sample_anim( sk, &player_drive.anim_drive, 0.0f, pose->keyframes );
    v3_copy( localplayer.rb.co, pose->root_co );
    v4_copy( localplayer.rb.q, pose->root_q );
 }
@@ -83,5 +83,5 @@ void player__drive_bind(void)
 {
    struct skeleton *sk = &localplayer.skeleton;
    player_drive.vehicle = &gzoomer;
-   player_drive.anim_drive = skeleton_get_anim( sk, "idle_cycle+y" );
+   player_get_anim( &player_drive.anim_drive, "idle_cycle+y" );
 }
index 9a5649d94409671d04565a9de60aa9ca03db8616..772a0d3b8092abdda8143538b567a135aa71eb79 100644 (file)
@@ -5,7 +5,7 @@
 struct player_drive 
 {
    drivable_vehicle *vehicle;
-   struct skeleton_anim *anim_drive;
+   skeleton_anim anim_drive;
 }
 extern player_drive;
 extern struct player_subsystem_interface player_subsystem_drive;
index d9977ce20ea829fef1cb877129da07a5fc5b3d8b..8eea9106f7b3db8b2451fb099a656652f64b777d 100644 (file)
@@ -307,7 +307,7 @@ void player_glide_pose( void *_animator, player_pose *pose )
    pose->type = k_player_pose_type_ik;
    pose->board.lean = 0.0f;
 
-   skeleton_sample_anim( sk, player_glide.anim_glide, 0.0f, pose->keyframes );
+   skeleton_sample_anim( sk, &player_glide.anim_glide, 0.0f, pose->keyframes );
 
    v3f temp;
    q_mulv( animator->root_q, (v3f){0,-0.5f,0}, temp );
@@ -449,7 +449,7 @@ void player_glide_bind(void)
 
    /* resources */
    struct skeleton *sk = &localplayer.skeleton;
-   player_glide.anim_glide = skeleton_get_anim( sk, "glide_pose" );
+   player_get_anim( &player_glide.anim_glide, "glide_pose" );
 
    void *alloc = vg_mem.rtmemory;
    mdl_context *mdl = &player_glide.glider;
@@ -459,13 +459,13 @@ void player_glide_bind(void)
    mdl_async_full_load_std( mdl );
 
    /* load trail positions */
-   mdl_array_ptr markers;
-   MDL_LOAD_ARRAY( mdl, &markers, ent_marker, vg_mem.scratch );
+   array_file_ptr markers;
+   MDL_LOAD_ARRAY_STRUCT( mdl, &markers, ent_marker, vg_mem.scratch );
    mdl_close( mdl );
 
-   for( u32 i=0; i<mdl_arrcount( &markers ); i ++ )
+   for( u32 i=0; i<af_arrcount( &markers ); i ++ )
    {
-      ent_marker *marker = mdl_arritm( &markers, i );
+      ent_marker *marker = af_arritm( &markers, i );
       v3_copy( marker->transform.co, 
                player_glide.trail_positions[ player_glide.trail_count ++ ] );
 
@@ -524,9 +524,9 @@ void render_glider_model( vg_camera *cam, world_instance *world,
    mdl_context *mdl = &player_glide.glider;
    mesh_bind( &player_glide.glider.mesh );
 
-   for( u32 i=0; i<mdl_arrcount(&mdl->meshs); i ++ )
+   for( u32 i=0; i<af_arrcount(&mdl->meshs); i ++ )
    {
-      mdl_mesh *mesh = mdl_arritm( &mdl->meshs, i );
+      mdl_mesh *mesh = af_arritm( &mdl->meshs, i );
 
       m4x3f mmmdl;
       mdl_transform_m4x3( &mesh->transform, mmmdl );
@@ -546,7 +546,7 @@ void render_glider_model( vg_camera *cam, world_instance *world,
 
       for( u32 j=0; j<mesh->submesh_count; j ++ )
       {
-         mdl_submesh *sm = mdl_arritm( &mdl->submeshs, mesh->submesh_start+j );
+         mdl_submesh *sm = af_arritm( &mdl->submeshs, mesh->submesh_start+j );
          if( !sm->material_id ) 
          {
             vg_error( "Invalid material ID 0\n" );
@@ -555,7 +555,7 @@ void render_glider_model( vg_camera *cam, world_instance *world,
 
          if( sm->material_id != current_mat )
          {
-            mdl_material *mat = mdl_arritm( &mdl->materials,sm->material_id-1 );
+            mdl_material *mat = af_arritm( &mdl->materials,sm->material_id-1 );
             GLuint tex = vg.tex_missing;
 
             if( mat->shader == k_shader_standard )
@@ -563,7 +563,7 @@ void render_glider_model( vg_camera *cam, world_instance *world,
                struct shader_props_standard *props = mat->props.compiled;
 
                u32 index = props->tex_diffuse-1;
-               mdl_texture *ptex = mdl_arritm( &mdl->textures, index );
+               mdl_texture *ptex = af_arritm( &mdl->textures, index );
                tex = ptex->glname;
             }
 
@@ -604,7 +604,7 @@ void player_glide_render( vg_camera *cam, world_instance *world,
 
    WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_board_view );
 
-   mdl_keyframe kf_res;
+   ms_keyframe kf_res;
    if( localplayer.glider_orphan ){
       rb_extrapolate( &player_glide.rb, kf_res.co, kf_res.q );
       v3_fill( kf_res.s, 1.0f );
@@ -622,7 +622,7 @@ void player_glide_render( vg_camera *cam, world_instance *world,
       if( skaterift.activity != k_skaterift_replay )
          vg_slewf( &player_glide.t, target, vg.time_frame_delta * 4.0f );
 
-      mdl_keyframe kf_backpack;
+      ms_keyframe kf_backpack;
 
       struct skeleton *sk = &localplayer.skeleton;
       m4x3_mulv( localplayer.final_mtx[localplayer.id_chest ],
index 03c8260f88f33d2c88d3f3a6df472d03feedf013..2a6676416d8b34e403a36c243e2ee7c99da17b12 100644 (file)
@@ -5,7 +5,7 @@
 
 struct player_glide 
 {
-   struct skeleton_anim *anim_glide;
+   struct skeleton_anim anim_glide;
 
    struct player_glide_animator 
    {
index 1527d106df934f3d5d6a17a0887b2015f125f6b3..4fa37cd318e0d85cd7e2fa3751048c7d91b9faec 100644 (file)
@@ -561,8 +561,8 @@ void player_ragdoll_iter( struct player_ragdoll *rd )
    if( run_sim && 
          (v3_length2(player_dead.v_lpf)>(k_ragdoll_active_threshold*
                                          k_ragdoll_active_threshold)) ){
-      mdl_keyframe anim[32];
-      skeleton_sample_anim( &localplayer.skeleton, player_dead.anim_bail,
+      ms_keyframe anim[32];
+      skeleton_sample_anim( &localplayer.skeleton, &player_dead.anim_bail,
                             0.0f, anim );
 
       for( u32 i=0; i<rd->cone_constraints_count; i ++ ){
@@ -583,7 +583,7 @@ void player_ragdoll_iter( struct player_ragdoll *rd )
          struct ragdoll_part *pa = &rd->parts[ id_a ],
                              *pp = &rd->parts[ id_p ];
 
-         mdl_keyframe *kf = &anim[ pa->bone_id-1 ];
+         ms_keyframe *kf = &anim[ pa->bone_id-1 ];
          m3x3_mulv( pa->collider_mtx, st->coneva, vap );
          q_mulv( kf->q, vap, vap );
 
index 15dec10523bb7b2a0bd528c29ed755a081dedba8..1531c34ffdf3dd3493be7aa52537f6f1bf5b8612 100644 (file)
 #include "network.h"
 #include "player_remote.h"
 #include "player_glide.h"
+#include "metascene.h"
+
+void player_load_animations( const char *path )
+{
+   metascene_load( &localplayer.animations, path, vg_mem.rtmemory );
+}
+
+void player_get_anim( skeleton_anim *out_anim, const char *name )
+{
+   ms_context *ms = &localplayer.animations;
+   u32 hash = vg_strdjb2( name );
+
+   for( u32 i=0; i<af_arrcount( &ms->strips ); i ++ )
+   {
+      ms_strip *strip = af_arritm( &ms->strips, i );
+      
+      if( ps_consteq( &ms->strings, strip->pstr_name, name, hash ) )
+      {
+         out_anim->strip = strip;
+         out_anim->framerate = localplayer.animations.info.framerate;
+         out_anim->keyframes_base = 
+            af_arritm( &localplayer.animations.keyframes, strip->data_start );
+         return;
+      }
+   }
+
+   vg_fatal_condition();
+   vg_info( "Failed to find animation '%s' in metascene.\n", name );
+   vg_fatal_exit();
+}
 
 void player_load_animation_reference( const char *path )
 {
    mdl_context *meta = &localplayer.skeleton_meta;
    mdl_open( meta, path, vg_mem.rtmemory );
    mdl_load_metadata_block( meta, vg_mem.rtmemory );
-   mdl_load_animation_block( meta, vg_mem.rtmemory );
    mdl_close( meta );
 
    struct skeleton *sk = &localplayer.skeleton;
@@ -35,8 +64,8 @@ void player_load_animation_reference( const char *path )
    localplayer.id_ik_elbow_l = skeleton_bone_id( sk, "elbow.L" );
    localplayer.id_ik_elbow_r = skeleton_bone_id( sk, "elbow.R" );
    localplayer.id_head       = skeleton_bone_id( sk, "head" );
-   localplayer.id_foot_l  = skeleton_bone_id( sk, "foot.L" );
-   localplayer.id_foot_r  = skeleton_bone_id( sk, "foot.R" );
+   localplayer.id_foot_l     = skeleton_bone_id( sk, "foot.L" );
+   localplayer.id_foot_r     = skeleton_bone_id( sk, "foot.R" );
    localplayer.id_ik_foot_l  = skeleton_bone_id( sk, "foot.IK.L" );
    localplayer.id_ik_foot_r  = skeleton_bone_id( sk, "foot.IK.R" );
    localplayer.id_board      = skeleton_bone_id( sk, "board" );
@@ -92,10 +121,10 @@ void dynamic_model_load( mdl_context *ctx,
                          struct dynamic_model_1texture *mdl, 
                          const char *path, u32 *fixup_table )
 {
-   if( !mdl_arrcount( &ctx->textures ) )
+   if( !af_arrcount( &ctx->textures ) )
       vg_fatal_error( "No texture in model" );
 
-   mdl_texture *tex0 = mdl_arritm( &ctx->textures, 0 );
+   mdl_texture *tex0 = af_arritm( &ctx->textures, 0 );
    void *data = vg_linear_alloc( vg_mem.scratch, tex0->file.pack_size );
    mdl_fread_pack_file( ctx, &tex0->file, data );
 
@@ -123,8 +152,8 @@ void player_board_load( struct player_board *board, const char *path )
 
    dynamic_model_load( &ctx, &board->mdl, path, NULL );
 
-   mdl_array_ptr markers;
-   MDL_LOAD_ARRAY( &ctx, &markers, ent_marker, vg_mem.scratch );
+   array_file_ptr markers;
+   MDL_LOAD_ARRAY_STRUCT( &ctx, &markers, ent_marker, vg_mem.scratch );
 
    /* TODO: you get put into a new section, the above is standard mdl loads. */
    for( int i=0; i<4; i++ )
@@ -133,18 +162,18 @@ void player_board_load( struct player_board *board, const char *path )
       board->trucks[i].indice_count = 0;
    board->board.indice_count = 0;
 
-   for( u32 i=0; i<mdl_arrcount(&ctx.meshs); i++ ){
-      mdl_mesh *mesh = mdl_arritm( &ctx.meshs, i );
+   for( u32 i=0; i<af_arrcount(&ctx.meshs); i++ ){
+      mdl_mesh *mesh = af_arritm( &ctx.meshs, i );
 
       if( mdl_entity_id_type( mesh->entity_id ) != k_ent_marker )
          continue;
 
       u32 index = mdl_entity_id_id( mesh->entity_id );
-      ent_marker *marker = mdl_arritm( &markers, index );
+      ent_marker *marker = af_arritm( &markers, index );
 
-      mdl_submesh *sm0 = mdl_arritm( &ctx.submeshs, mesh->submesh_start );
+      mdl_submesh *sm0 = af_arritm( &ctx.submeshs, mesh->submesh_start );
       
-      const char *alias = mdl_pstr( &ctx, marker->pstr_alias );
+      const char *alias = ps_get( &ctx.strings, marker->pstr_alias );
       u32 lr = marker->transform.co[0] > 0.0f? 1: 0,
           fb = marker->transform.co[2] > 0.0f? 0: 1;
 
@@ -182,20 +211,23 @@ void player_model_load( struct player_model *board, const char *path)
    if( !ctx.armatures.count )
       vg_fatal_error( "No armature in playermodel\n" );
 
-   mdl_armature *armature = mdl_arritm( &ctx.armatures, 0 );
+   mdl_armature *armature = af_arritm( &ctx.armatures, 0 );
 
    u32 fixup_table[ armature->bone_count+1 ];
    for( u32 i=0; i<armature->bone_count+1; i ++ )
       fixup_table[i] = 0;
 
-   for( u32 i=1; i<localplayer.skeleton.bone_count; i ++ ){
+   for( u32 i=1; i<localplayer.skeleton.bone_count; i ++ )
+   {
       struct skeleton_bone *sb = &localplayer.skeleton.bones[i];
       u32 hash = vg_strdjb2( sb->name );
 
-      for( u32 j=1; j<armature->bone_count; j ++ ){
-         mdl_bone *bone = mdl_arritm( &ctx.bones, armature->bone_start+j );
+      for( u32 j=1; j<armature->bone_count; j ++ )
+      {
+         mdl_bone *bone = af_arritm( &ctx.bones, armature->bone_start+j );
 
-         if( mdl_pstreq( &ctx, bone->pstr_name, sb->name, hash ) ){
+         if( ps_consteq( &ctx.strings, bone->pstr_name, sb->name, hash ) )
+         {
             fixup_table[j+1] = i;
             break;
          }
@@ -472,7 +504,7 @@ void render_board( vg_camera *cam, world_instance *world,
       m4x3f mlocal;
       m3x3_identity( mlocal );
 
-      mdl_keyframe kf;
+      ms_keyframe kf;
       v3_zero( kf.co );
       q_identity( kf.q );
       v3_zero( kf.s );
@@ -606,13 +638,13 @@ void player__render( vg_camera *cam )
    glDisable( GL_CULL_FACE );
 }
 
-void player_mirror_pose( mdl_keyframe pose[32], mdl_keyframe mirrored[32] )
+void player_mirror_pose( ms_keyframe pose[32], ms_keyframe mirrored[32] )
 {
-   mdl_keyframe temp[32];
+   ms_keyframe temp[32];
 
    struct skeleton *sk = &localplayer.skeleton;
    for( u32 i=1; i<sk->bone_count; i ++ ){
-      mdl_keyframe *dest = &temp[i-1];
+      ms_keyframe *dest = &temp[i-1];
       u8 mapping = localplayer.skeleton_mirror[i];
 
       if( mapping ) *dest = pose[mapping-1]; /* R */
index cfc48e78940cd5a67256911682bea13039d8327e..5a2a9cdb2e1d63f08c493056d8c75252fbe371ce 100644 (file)
@@ -72,9 +72,10 @@ void apply_full_skeleton_pose( struct skeleton *sk, player_pose *pose,
                                m4x3f *final_mtx );
 void lerp_player_pose( player_pose *pose0, player_pose *pose1, f32 t,
                        player_pose *posed );
-void player_mirror_pose( mdl_keyframe pose[32], 
-                         mdl_keyframe mirrored[32] );
+void player_mirror_pose( ms_keyframe pose[32], 
+                         ms_keyframe mirrored[32] );
 void player__observe_system( enum player_subsystem id );
+void player_load_animations( const char *path );
 void player_load_animation_reference( const char *path );
 void player__render( vg_camera *cam );
 void player__animate_from_replay( replay_buffer *replay );
index 387f1ec46d05e4d6a1ea428be5b66ea7e56f62db..9fc67aef18c52b5622dd2ac287c912b1b9f86a9e 100644 (file)
@@ -43,7 +43,7 @@ void player__skate_bind(void){
    struct skeleton *sk = &localplayer.skeleton;
    rb_update_matrices( &localplayer.rb );
 
-   struct { struct skeleton_anim **anim; const char *name; }
+   struct { struct skeleton_anim *anim; const char *name; }
    bindings[] = {
       { &player_skate.anim_grind,        "pose_grind" },
       { &player_skate.anim_grind_jump,   "pose_grind_jump" },
@@ -60,7 +60,7 @@ void player__skate_bind(void){
    };
 
    for( u32 i=0; i<VG_ARRAY_LEN(bindings); i++ )
-      *bindings[i].anim = skeleton_get_anim( sk, bindings[i].name );
+      player_get_anim( bindings[i].anim, bindings[i].name );
 }
 
 void player__skate_kill_audio(void){
@@ -1193,9 +1193,9 @@ void player__skate_pre_update(void){
 
    if( state->activity == k_skate_activity_handplant ){
       state->handplant_t += vg.time_delta;
-      mdl_keyframe hpose[32];
+      ms_keyframe hpose[32];
 
-      struct skeleton_anim *anim = player_skate.anim_handplant;
+      struct skeleton_anim *anim = &player_skate.anim_handplant;
 
       int end = !skeleton_sample_anim_clamped( 
                &localplayer.skeleton, anim,
@@ -1204,7 +1204,7 @@ void player__skate_pre_update(void){
       if( state->reverse < 0.0f )
          player_mirror_pose( hpose, hpose );
 
-      mdl_keyframe *kf_world = &hpose[ localplayer.id_world -1 ];
+      ms_keyframe *kf_world = &hpose[ localplayer.id_world -1 ];
       m4x3f world, mmdl, world_view;
       q_m3x3( kf_world->q, world );
       v3_copy( kf_world->co, world[3] );
@@ -2713,7 +2713,7 @@ begin_collision:;
    u32 id = world_intersect_gates( world, localplayer.rb.co, state->prev_pos );
 
    if( id ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
+      ent_gate *gate = af_arritm( &world->ent_gate, mdl_entity_id_id(id) );
 
       m4x3_mulv( gate->transport, localplayer.rb.co, localplayer.rb.co );
       m3x3_mulv( gate->transport, localplayer.rb.v,  localplayer.rb.v );
@@ -3152,8 +3152,8 @@ void player__skate_pose( void *_animator, player_pose *pose ){
    /* ANIMATIONS 
     * ---------------------------------------------------------------------- */
 
-   mdl_keyframe apose[32], bpose[32];
-   mdl_keyframe ground_pose[32];
+   ms_keyframe apose[32], bpose[32];
+   ms_keyframe ground_pose[32];
    {
       /* stand/crouch */
       f32 dir_frame   = animator->z * (15.0f/30.0f),
@@ -3163,55 +3163,55 @@ void player__skate_pose( void *_animator, player_pose *pose ){
 
       stand_blend = vg_clampf( 1.0f-animator->local_cog[1], 0, 1 );
 
-      skeleton_sample_anim( sk, player_skate.anim_stand, dir_frame, apose );
-      skeleton_sample_anim( sk, player_skate.anim_highg, dir_frame, bpose );
+      skeleton_sample_anim( sk, &player_skate.anim_stand, dir_frame, apose );
+      skeleton_sample_anim( sk, &player_skate.anim_highg, dir_frame, bpose );
       skeleton_lerp_pose( sk, apose, bpose, stand_blend, apose );
 
       /* sliding */
       f32 slide_frame = animator->x * 0.25f + 0.25f;
-      skeleton_sample_anim( sk, player_skate.anim_slide, slide_frame, bpose );
+      skeleton_sample_anim( sk, &player_skate.anim_slide, slide_frame, bpose );
 
-      mdl_keyframe mirrored[32];
+      ms_keyframe mirrored[32];
       player_mirror_pose( bpose, mirrored );
       skeleton_lerp_pose( sk, bpose, mirrored, animator->z, bpose );
       skeleton_lerp_pose( sk, apose, bpose, animator->slide, apose );
 
       if( animator->reverse > 0.0f ){
-         skeleton_sample_anim( sk, player_skate.anim_push, animator->push_time, 
+         skeleton_sample_anim( sk, &player_skate.anim_push, animator->push_time, 
                                bpose );
       }
       else{
-         skeleton_sample_anim( sk, player_skate.anim_push_reverse, 
+         skeleton_sample_anim( sk, &player_skate.anim_push_reverse, 
                                animator->push_time, bpose );
       }
       skeleton_lerp_pose( sk, apose, bpose, animator->push, apose );
 
       struct skeleton_anim *jump_anim = animator->jump_dir?
-                                        player_skate.anim_ollie:
-                                        player_skate.anim_ollie_reverse;
+                                        &player_skate.anim_ollie:
+                                        &player_skate.anim_ollie_reverse;
 
       f32 setup_blend = vg_minf( animator->jump, 1.0f );
       skeleton_sample_anim_clamped( sk, jump_anim, animator->jump_time, bpose );
       skeleton_lerp_pose( sk, apose, bpose, setup_blend, ground_pose );
    }
    
-   mdl_keyframe air_pose[32];
+   ms_keyframe air_pose[32];
    {
       float air_frame = (animator->airdir*0.5f+0.5f) * (15.0f/30.0f);
-      skeleton_sample_anim( sk, player_skate.anim_air, air_frame, apose );
+      skeleton_sample_anim( sk, &player_skate.anim_air, air_frame, apose );
 
       float ang = atan2f( animator->grab[0], animator->grab[1] ),
             ang_unit = (ang+VG_PIf) * (1.0f/VG_TAUf),
             grab_frame = ang_unit * (15.0f/30.0f);
 
-      skeleton_sample_anim( sk, player_skate.anim_grabs, grab_frame, bpose );
+      skeleton_sample_anim( sk, &player_skate.anim_grabs, grab_frame, bpose );
       skeleton_lerp_pose( sk, apose, bpose, animator->grabbing, air_pose );
    }
 
    skeleton_lerp_pose( sk, ground_pose, air_pose, animator->fly, 
                        pose->keyframes );
 
-   mdl_keyframe *kf_board    = &pose->keyframes[localplayer.id_board-1],
+   ms_keyframe *kf_board    = &pose->keyframes[localplayer.id_board-1],
                 *kf_foot_l   = &pose->keyframes[localplayer.id_ik_foot_l-1],
                 *kf_foot_r   = &pose->keyframes[localplayer.id_ik_foot_r-1],
                 *kf_knee_l   = &pose->keyframes[localplayer.id_ik_knee_l-1],
@@ -3221,12 +3221,12 @@ void player__skate_pose( void *_animator, player_pose *pose ){
                                  &pose->keyframes[localplayer.id_wheel_l-1] };
 
 
-   mdl_keyframe grind_pose[32];
+   ms_keyframe grind_pose[32];
    {
       f32 frame = animator->grind_balance * 0.5f;
 
-      skeleton_sample_anim( sk, player_skate.anim_grind, frame, apose );
-      skeleton_sample_anim( sk, player_skate.anim_grind_jump, frame, bpose );
+      skeleton_sample_anim( sk, &player_skate.anim_grind, frame, apose );
+      skeleton_sample_anim( sk, &player_skate.anim_grind_jump, frame, bpose );
       skeleton_lerp_pose( sk, apose, bpose, animator->jump, grind_pose );
    }
    skeleton_lerp_pose( sk, pose->keyframes, grind_pose, 
@@ -3257,22 +3257,23 @@ void player__skate_pose( void *_animator, player_pose *pose ){
    v3_add( sk->bones[localplayer.id_hip].co, kf_hip->co, origin );
 
    for( int i=0; i<VG_ARRAY_LEN(apply_to); i ++ ){
-      mdl_keyframe *kf = &pose->keyframes[apply_to[i]-1];
+      ms_keyframe *kf = &pose->keyframes[apply_to[i]-1];
       keyframe_rotate_around( kf, origin, sk->bones[apply_to[i]].co,
                               animator->qfixuptotal );
    }
 #endif
 
 
-   if( animator->activity == k_skate_activity_handplant ){
-      struct skeleton_anim *anim = player_skate.anim_handplant;
+   if( animator->activity == k_skate_activity_handplant )
+   {
+      struct skeleton_anim *anim = &player_skate.anim_handplant;
 
-      mdl_keyframe hpose[32];
+      ms_keyframe hpose[32];
       skeleton_sample_anim_clamped( sk, anim, animator->handplant_t, hpose );
       if( animator->reverse < 0.0f )
          player_mirror_pose( hpose, hpose );
 
-      mdl_keyframe *kf_world = &hpose[ localplayer.id_world -1 ];
+      ms_keyframe *kf_world = &hpose[ localplayer.id_world -1 ];
       m4x3f world, mmdl, world_view;
       q_m3x3( kf_world->q, world );
       v3_copy( kf_world->co, world[3] );
@@ -3294,9 +3295,9 @@ void player__skate_pose( void *_animator, player_pose *pose ){
       v3_copy( world_view[3], pose->root_co );
 
       f32 t        = animator->handplant_t,
-          frames   = anim->length-1,
+          frames   = anim->strip->length-1,
           length   = animator->activity == k_skate_activity_handplant?
-                        frames / anim->rate:
+                        frames / anim->framerate:
                         999999,
           end_dist = vg_minf( t, length - t )/k_anim_transition,
           blend    = vg_smoothstepf( vg_minf(1,end_dist) );
@@ -3368,7 +3369,7 @@ void player__skate_pose( void *_animator, player_pose *pose ){
  
 #if 1
    {
-      mdl_keyframe
+      ms_keyframe
          *kf_head    = &pose->keyframes[localplayer.id_head-1],
          *kf_elbow_l = &pose->keyframes[localplayer.id_ik_elbow_l-1],
          *kf_elbow_r = &pose->keyframes[localplayer.id_ik_elbow_r-1],
@@ -3438,7 +3439,7 @@ void player__skate_pose( void *_animator, player_pose *pose ){
       q_axis_angle( qskid, (v3f){0,1,0}, -animator->steer[1]*0.2f );
 
       for( u32 i=0; i<VG_ARRAY_LEN(skidders); i ++ ){
-         mdl_keyframe *kf = &pose->keyframes[ skidders[i]-1 ];
+         ms_keyframe *kf = &pose->keyframes[ skidders[i]-1 ];
          keyframe_rotate_around( kf, 
                (v3f){0,0,0.4f*(animator->z*2.0f-1.0f)*amt}, 
                                  sk->bones[skidders[i]].co, qskid );
index 3795c6e6112b095a878000587c44f918d3a021e3..c234bdc369340fb2083ca570da6c9ff9bf652bca 100644 (file)
@@ -151,12 +151,12 @@ struct player_skate{
 
    /* animation /audio
     * --------------------------------------------------------------*/
-   struct skeleton_anim *anim_stand, *anim_highg, *anim_slide,
-                        *anim_air, *anim_grind, *anim_grind_jump,
-                        *anim_push,  *anim_push_reverse,
-                        *anim_ollie, *anim_ollie_reverse,
-                        *anim_grabs, *anim_stop,
-                        *anim_handplant;
+   struct skeleton_anim anim_stand, anim_highg, anim_slide,
+                        anim_air,   anim_grind, anim_grind_jump,
+                        anim_push,  anim_push_reverse,
+                        anim_ollie, anim_ollie_reverse,
+                        anim_grabs, anim_stop,
+                        anim_handplant;
 
    /* vectors representing the direction of the axels in localspace */
    v3f truckv0[2];
index 1e15afcd0ed2eb68835904ebd008394d05413d71..cf0fa6d42af6bc22e2ef554cb2f888ec7cfdd679 100644 (file)
@@ -247,7 +247,7 @@ static int player_walk_scan_for_drop_in(void){
 
 static bool player__preupdate_anim( struct skeleton_anim *anim, f32 *t, 
                                     f32 speed ){
-   f32 length = (f32)(anim->length-1) / anim->rate;
+   f32 length = (f32)(anim->strip->length-1) / anim->framerate;
    *t += (vg.time_delta * speed) / length;
 
    if( *t >= 1.0f ) return 1;
@@ -325,16 +325,16 @@ static void player_walk_pre_air(void){
 
 static void player_walk_pre_drop_in(void){
    struct player_walk *w = &player_walk;
-   bool finished = player__preupdate_anim( w->anim_drop_in, 
-                                          &w->state.transition_t, 1.0f );
+   bool finished = player__preupdate_anim( &w->anim_drop_in, 
+                                           &w->state.transition_t, 1.0f );
    if( finished )
       player_walk_drop_in_to_skate();
 }
 
 static void player_walk_pre_caveman(void){
    struct player_walk *w = &player_walk;
-   bool finished = player__preupdate_anim( w->anim_jump_to_air,
-                                          &w->state.transition_t, 1.0f );
+   bool finished = player__preupdate_anim( &w->anim_jump_to_air,
+                                           &w->state.transition_t, 1.0f );
    if( finished ){
       player_walk_generic_to_skate( k_skate_activity_air, 
                                     player_walk.animator.board_yaw );
@@ -343,8 +343,8 @@ static void player_walk_pre_caveman(void){
 
 static void player_walk_pre_running_start(void){
    struct player_walk *w = &player_walk;
-   bool finished = player__preupdate_anim( w->anim_intro, 
-                                          &w->state.transition_t, 1.0f );
+   bool finished = player__preupdate_anim( &w->anim_intro, 
+                                           &w->state.transition_t, 1.0f );
    if( finished ){
       /* TODO: get the derivative of the last keyframes to calculate new
        * velocity for player */
@@ -355,8 +355,8 @@ static void player_walk_pre_running_start(void){
 
 static void player_walk_pre_popoff(void){
    struct player_walk *w = &player_walk;
-   bool finished = player__preupdate_anim( w->anim_popoff, 
-                                          &w->state.transition_t, 1.0f );
+   bool finished = player__preupdate_anim( &w->anim_popoff, 
+                                           &w->state.transition_t, 1.0f );
 
    if( finished ){
       w->state.activity = k_walk_activity_ground;
@@ -672,7 +672,7 @@ static void player_walk_update_generic(void){
 
    u32 id = world_intersect_gates(world, localplayer.rb.co, w->state.prev_pos);
    if( id ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, mdl_entity_id_id(id) );
+      ent_gate *gate = af_arritm( &world->ent_gate, mdl_entity_id_id(id) );
       m4x3_mulv( gate->transport, localplayer.rb.co, localplayer.rb.co );
       m3x3_mulv( gate->transport, localplayer.rb.v,  localplayer.rb.v );
 
@@ -784,12 +784,13 @@ void player__walk_update(void){
    }
 }
 
-static void player_walk_animate_drop_in(void){
+static void player_walk_animate_drop_in(void)
+{
    struct player_walk *w = &player_walk;
    struct player_walk_animator *animator = &w->animator;
-   struct skeleton_anim *anim = w->anim_drop_in;
+   struct skeleton_anim *anim = &w->anim_drop_in;
 
-   f32 length = (f32)(anim->length-1) / anim->rate,
+   f32 length = (f32)(anim->strip->length-1) / anim->framerate,
        time   = w->state.transition_t;
 
    f32 walk_yaw = vg_alerpf( w->state.drop_in_start_angle, 
@@ -873,8 +874,8 @@ void player__walk_animate(void){
    }
 
    if( animator->run > 0.025f ){
-      f32 walk_norm = 30.0f/(float)w->anim_walk->length,
-          run_norm  = 30.0f/(float)w->anim_run->length,
+      f32 walk_norm = 30.0f/(float)w->anim_walk.strip->length,
+          run_norm  = 30.0f/(float)w->anim_run.strip->length,
           l;
 
       if( animator->run <= k_walkspeed )
@@ -917,14 +918,14 @@ void player__walk_animate(void){
 static void player_walk_pose_sit( struct player_walk_animator *animator,
                                   player_pose *pose )
 {
-   mdl_keyframe bpose[32];
+   ms_keyframe bpose[32];
 
    struct player_walk *w = &player_walk;
    struct skeleton *sk = &localplayer.skeleton;
 
    f32 t  = animator->transition_t,
-       st = t * ((f32)(w->anim_sit->length-1)/30.0f);
-   skeleton_sample_anim( sk, w->anim_sit, st, bpose );
+       st = t * ((f32)(w->anim_sit.strip->length-1)/30.0f);
+   skeleton_sample_anim( sk, &w->anim_sit, st, bpose );
 
    v4f qy,qp;
    f32 *qh = bpose[localplayer.id_head-1].q;
@@ -952,14 +953,14 @@ enum walk_transition_type {
 static void player_walk_pose_transition( 
       struct player_walk_animator *animator, struct skeleton_anim *anim,
       enum walk_transition_type type,
-      mdl_keyframe apose[32], f32 *mask, player_pose *pose ){
+      ms_keyframe apose[32], f32 *mask, player_pose *pose ){
 
-   mdl_keyframe bpose[32];
+   ms_keyframe bpose[32];
 
    struct player_walk *w = &player_walk;
    struct skeleton *sk = &localplayer.skeleton;
    
-   f32 length   = (f32)(anim->length-1) / anim->rate,
+   f32 length   = (f32)(anim->strip->length-1) / anim->framerate,
        t        = animator->transition_t * length,
        blend    = 1.0f;
 
@@ -973,7 +974,7 @@ static void player_walk_pose_transition(
 
    skeleton_sample_anim_clamped( sk, anim, t, bpose );
 
-   mdl_keyframe *kf_board = &bpose[localplayer.id_board-1];
+   ms_keyframe *kf_board = &bpose[localplayer.id_board-1];
    f32 yaw = animator->board_yaw * VG_TAUf * 0.5f;
 
    v4f qyaw;
@@ -999,32 +1000,32 @@ void player__walk_pose( void *_animator, player_pose *pose ){
    pose->board.lean = 0.0f;
    pose->type = k_player_pose_type_ik;
 
-   float walk_norm = (float)w->anim_walk->length/30.0f,
-         run_norm  = (float)w->anim_run->length/30.0f,
+   float walk_norm = (float)w->anim_walk.strip->length/30.0f,
+         run_norm  = (float)w->anim_run.strip->length/30.0f,
          t = animator->walk_timer;
 
    /* walk/run */
-   mdl_keyframe apose[32], bpose[32];
+   ms_keyframe apose[32], bpose[32];
    if( animator->run <= k_walkspeed ){ 
       /* walk / idle */
       f32 l = vg_minf( 1, (animator->run/k_walkspeed)*6.0f );
-      skeleton_sample_anim( sk, w->anim_idle, vg.time*0.1f, apose );
-      skeleton_sample_anim( sk, w->anim_walk, t*walk_norm, bpose );
+      skeleton_sample_anim( sk, &w->anim_idle, vg.time*0.1f, apose );
+      skeleton_sample_anim( sk, &w->anim_walk, t*walk_norm, bpose );
       skeleton_lerp_pose( sk, apose, bpose, l, apose );
    }
    else { 
       /* walk / run */
       f32 l = (animator->run-k_walkspeed) / (k_runspeed-k_walkspeed);
-      skeleton_sample_anim( sk, w->anim_walk, t*walk_norm, apose );
-      skeleton_sample_anim( sk, w->anim_run, t*run_norm, bpose );
+      skeleton_sample_anim( sk, &w->anim_walk, t*walk_norm, apose );
+      skeleton_sample_anim( sk, &w->anim_run, t*run_norm, bpose );
       skeleton_lerp_pose( sk, apose, bpose, l, apose );
    }
 
    /* air */
-   skeleton_sample_anim( sk, w->anim_jump, vg.time*0.6f, bpose );
+   skeleton_sample_anim( sk, &w->anim_jump, vg.time*0.6f, bpose );
    skeleton_lerp_pose( sk, apose, bpose, animator->fly, apose );
 
-   mdl_keyframe *kf_board = &apose[localplayer.id_board-1];
+   ms_keyframe *kf_board = &apose[localplayer.id_board-1];
    f32 yaw = animator->board_yaw;
 
    if( animator->activity == k_walk_activity_ipopoff )
@@ -1045,17 +1046,17 @@ void player__walk_pose( void *_animator, player_pose *pose ){
    }
    else if( animator->activity == k_walk_activity_odrop_in ){
       player_walk_pose_transition( 
-            animator, w->anim_drop_in, k_walk_transition_out, apose, 
+            animator, &w->anim_drop_in, k_walk_transition_out, apose, 
             NULL, pose );
    }
    else if( animator->activity == k_walk_activity_oair ){
       player_walk_pose_transition(
-            animator, w->anim_jump_to_air, k_walk_transition_out, apose, 
+            animator, &w->anim_jump_to_air, k_walk_transition_out, apose, 
             NULL, pose );
    }
    else if( animator->activity == k_walk_activity_oregular ){
       player_walk_pose_transition( 
-            animator, w->anim_intro, k_walk_transition_out, apose, 
+            animator, &w->anim_intro, k_walk_transition_out, apose, 
             NULL, pose );
    }
    else if( animator->activity == k_walk_activity_ipopoff ){
@@ -1072,12 +1073,12 @@ void player__walk_pose( void *_animator, player_pose *pose ){
          mask[ localplayer.id_ik_knee_r-1 ] = t;
          mask[ localplayer.id_hip-1 ] = t;
          player_walk_pose_transition( 
-               animator, w->anim_popoff, k_walk_transition_in, apose,
+               animator, &w->anim_popoff, k_walk_transition_in, apose,
                mask, pose );
       }
       else{
          player_walk_pose_transition( 
-               animator, w->anim_popoff, k_walk_transition_in, apose,
+               animator, &w->anim_popoff, k_walk_transition_in, apose,
                NULL, pose );
       }
    }
@@ -1127,19 +1128,20 @@ void player__walk_im_gui( ui_context *ctx )
                                              [w->surface] );
 }
 
-void player__walk_bind(void){
+void player__walk_bind(void)
+{
    struct player_walk *w = &player_walk;
    struct skeleton *sk = &localplayer.skeleton;
 
-   w->anim_idle         = skeleton_get_anim( sk, "idle_cycle+y" );
-   w->anim_walk         = skeleton_get_anim( sk, "walk+y" );
-   w->anim_run          = skeleton_get_anim( sk, "run+y" );
-   w->anim_jump         = skeleton_get_anim( sk, "jump+y" );
-   w->anim_jump_to_air  = skeleton_get_anim( sk, "jump_to_air" );
-   w->anim_drop_in      = skeleton_get_anim( sk, "drop_in" );
-   w->anim_intro        = skeleton_get_anim( sk, "into_skate" );
-   w->anim_sit          = skeleton_get_anim( sk, "sit" );
-   w->anim_popoff       = skeleton_get_anim( sk, "pop_off_short" );
+   player_get_anim( &w->anim_idle,        "idle_cycle+y" );
+   player_get_anim( &w->anim_walk,        "walk+y" );
+   player_get_anim( &w->anim_run,         "run+y" );
+   player_get_anim( &w->anim_jump,        "jump+y" );
+   player_get_anim( &w->anim_jump_to_air, "jump_to_air" );
+   player_get_anim( &w->anim_drop_in,     "drop_in" );
+   player_get_anim( &w->anim_intro,       "into_skate" );
+   player_get_anim( &w->anim_sit,         "sit" );
+   player_get_anim( &w->anim_popoff,      "pop_off_short" );
 }
 
 void player__walk_transition( bool grounded, f32 board_yaw ){
index 5da03501d6ed8dfd5644822773d34e9c2e52a746..56b8914369725cd9d08c3023f83266d6bb6953bf 100644 (file)
@@ -49,9 +49,9 @@ struct player_walk
    f32 move_speed;
 
    enum mdl_surface_prop surface;
-   struct skeleton_anim *anim_walk, *anim_run, *anim_idle, *anim_jump,
-                        *anim_jump_to_air, *anim_drop_in, *anim_intro,
-                        *anim_sit, *anim_popoff;
+   struct skeleton_anim anim_walk, anim_run, anim_idle, anim_jump,
+                        anim_jump_to_air, anim_drop_in, anim_intro,
+                        anim_sit, anim_popoff;
 
    struct player_walk_animator {
       v3f root_co;
index a94fbcaf377a0ef60366d4636b8a092f280d6827..93cada9db8f3523a1fa352d6c3b2632f1758f9c8 100644 (file)
@@ -61,10 +61,10 @@ void scene_add_mdl_submesh( scene_context *ctx, mdl_context *mdl,
                         ctx->max_indices );
    }
 
-   mdl_vert   *src_verts = mdl_arritm( &mdl->verts, sm->vertex_start );
+   mdl_vert   *src_verts = af_arritm( &mdl->verts, sm->vertex_start );
    scene_vert *dst_verts = &ctx->arrvertices[ ctx->vertex_count ];
 
-   u32 *src_indices    =  mdl_arritm( &mdl->indices, sm->indice_start ),
+   u32 *src_indices    =  af_arritm( &mdl->indices, sm->indice_start ),
        *dst_indices    = &ctx->arrindices[ ctx->indice_count ];
    
    /* Transform and place vertices */
index 36e087f3a0be7f383d3826d25174c3fb7d953afa..b28ee453234b9dfdd2e20774342d9cc224beca68 100644 (file)
@@ -143,6 +143,7 @@ static void skaterift_load_player_content(void)
    particle_alloc( &particles_env, 200 );
 
    player_load_animation_reference( "models/ch_none.mdl" );
+   player_load_animations( "metascenes/skater.ms" );
    player_model_load( &localplayer.fallback_model, "models/ch_none.mdl" );
    player__bind();
    player_board_load( &localplayer.fallback_board, "models/board_none.mdl" );
@@ -674,6 +675,8 @@ void vg_gui( ui_context *ctx )
 #include "world_volumes.c"
 #include "world_water.c"
 #include "ent_npc.c"
+#include "array_file.c"
 #include "model.c"
+#include "metascene.c"
 #include "control_overlay.c"
 #include "ent_camera.c"
index 9729b64c04a95b7b052ba1daa3f280f444670a44..9a3be61639f11bf8eff84ed51f6ea7178909ecd3 100644 (file)
@@ -16,7 +16,7 @@ struct skeleton
       u32 flags;
       int defer;
 
-      mdl_keyframe kf;
+      ms_keyframe kf;
       mdl_bone *orig_bone;
 
       u32 collider;
@@ -26,21 +26,6 @@ struct skeleton
    *bones;
    u32 bone_count;
 
-   struct skeleton_anim
-   {
-      const char *name;
-      u32 length;
-
-      float rate;
-      mdl_keyframe *anim_data;
-   }
-   *anims;
-   u32 anim_count;
-
-#if 0
-   m4x3f *final_mtx;
-#endif
-
    struct skeleton_ik
    {
       u32 lower, upper, target, pole;
@@ -54,6 +39,14 @@ struct skeleton
        bindable_count;
 };
 
+typedef struct skeleton_anim skeleton_anim;
+struct skeleton_anim 
+{
+   ms_strip *strip;
+   ms_keyframe *keyframes_base;
+   f32 framerate;
+};
+
 static u32 skeleton_bone_id( struct skeleton *skele, const char *name )
 {
    for( u32 i=1; i<skele->bone_count; i++ ){
@@ -67,7 +60,7 @@ static u32 skeleton_bone_id( struct skeleton *skele, const char *name )
    return 0;
 }
 
-static void keyframe_copy_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, 
+static void keyframe_copy_pose( ms_keyframe *kfa, ms_keyframe *kfb, 
                                    int num )
 {
    for( int i=0; i<num; i++ )
@@ -76,7 +69,7 @@ static void keyframe_copy_pose( mdl_keyframe *kfa, mdl_keyframe *kfb,
 
 
 /* apply a rotation from the perspective of root */
-static void keyframe_rotate_around( mdl_keyframe *kf, 
+static void keyframe_rotate_around( ms_keyframe *kf, 
                                     v3f origin, v3f offset, v4f q )
 {
    v3f v0, co;
@@ -90,8 +83,8 @@ static void keyframe_rotate_around( mdl_keyframe *kf,
    q_normalize( kf->q );
 }
 
-static void keyframe_lerp( mdl_keyframe *kfa, mdl_keyframe *kfb, f32 t,
-                           mdl_keyframe *kfd ){
+static void keyframe_lerp( ms_keyframe *kfa, ms_keyframe *kfb, f32 t,
+                           ms_keyframe *kfd ){
    v3_lerp( kfa->co, kfb->co, t, kfd->co );
    q_nlerp( kfa->q,  kfb->q,  t, kfd->q );
    v3_lerp( kfa->s,  kfb->s,  t, kfd->s );
@@ -100,8 +93,8 @@ static void keyframe_lerp( mdl_keyframe *kfa, mdl_keyframe *kfb, f32 t,
 /*
  * Lerp between two sets of keyframes and store in dest. Rotations use Nlerp.
  */
-static void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb, 
-                                float t, mdl_keyframe *kfd, int count ){
+static void keyframe_lerp_pose( ms_keyframe *kfa, ms_keyframe *kfb, 
+                                float t, ms_keyframe *kfd, int count ){
    if( t <= 0.0001f ){
       keyframe_copy_pose( kfa, kfd, count );
       return;
@@ -117,14 +110,14 @@ static void keyframe_lerp_pose( mdl_keyframe *kfa, mdl_keyframe *kfb,
 
 static 
 void skeleton_lerp_pose( struct skeleton *skele,
-                         mdl_keyframe *kfa, mdl_keyframe *kfb, float t,
-                         mdl_keyframe *kfd )
+                         ms_keyframe *kfa, ms_keyframe *kfb, float t,
+                         ms_keyframe *kfd )
 {
    keyframe_lerp_pose( kfa, kfb, t, kfd, skele->bone_count-1 );
 }
 
 static void skeleton_copy_pose( struct skeleton *skele,
-                                   mdl_keyframe *kfa, mdl_keyframe *kfd )
+                                   ms_keyframe *kfa, ms_keyframe *kfd )
 {
    keyframe_copy_pose( kfa, kfd, skele->bone_count-1 );
 }
@@ -132,37 +125,40 @@ static void skeleton_copy_pose( struct skeleton *skele,
 /*
  * Sample animation between 2 closest frames using time value. Output is a
  * keyframe buffer that is allocated with an appropriate size
+ *
+ * Time is in SECONDS
  */
-static void skeleton_sample_anim( struct skeleton *skele,
-                                  struct skeleton_anim *anim,
-                                  float time,
-                                  mdl_keyframe *output )
+void skeleton_sample_anim( struct skeleton *skele,
+                           skeleton_anim *anim,
+                           float time,
+                           ms_keyframe *output )
 {
-   f32 animtime  = fmodf( time*anim->rate, anim->length ),
+   ms_strip *strip = anim->strip;
+   f32 animtime  = fmodf( time*anim->framerate, (f32)strip->length ),
        animframe = floorf( animtime ),
        t = animtime - animframe;
 
-   u32 frame = (u32)animframe % anim->length,
-       next  = (frame+1) % anim->length;
+   u32 frame = (u32)animframe % strip->length,
+       next  = (frame+1) % strip->length;
 
-   mdl_keyframe *base  = anim->anim_data + (skele->bone_count-1)*frame,
-                *nbase = anim->anim_data + (skele->bone_count-1)*next;
+   ms_keyframe *base  = anim->keyframes_base + strip->data_count*frame,
+               *nbase = anim->keyframes_base + strip->data_count*next;
 
    skeleton_lerp_pose( skele, base, nbase, t, output );
 }
 
-static int skeleton_sample_anim_clamped( struct skeleton *skele,
-                                         struct skeleton_anim *anim,
-                                         float time,
-                                         mdl_keyframe *output )
+/* time is in SECONDS */
+int skeleton_sample_anim_clamped( struct skeleton *skele,
+                                  skeleton_anim *anim,
+                                  float time,
+                                  ms_keyframe *output )
 {
-   float end = (float)(anim->length-1) / anim->rate;
+   ms_strip *strip = anim->strip;
+   f32 end = (strip->length-1)/anim->framerate;
    skeleton_sample_anim( skele, anim, vg_minf( end, time ), output );
 
-   if( time > end )
-      return 0;
-   else
-      return 1;
+   if( time > end ) return 0;
+   else             return 1;
 }
 
 typedef enum anim_apply
@@ -205,11 +201,14 @@ int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type )
 /*
  * Apply block of keyframes to skeletons final pose
  */
-static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose,
-                                 anim_apply passtype, m4x3f *final_mtx ){
-   if( passtype == k_anim_apply_absolute ){
-      for( u32 i=1; i<skele->bone_count; i++ ){
-         mdl_keyframe *kf = &pose[i-1];
+static void skeleton_apply_pose( struct skeleton *skele, ms_keyframe *pose,
+                                 anim_apply passtype, m4x3f *final_mtx )
+{
+   if( passtype == k_anim_apply_absolute )
+   {
+      for( u32 i=1; i<skele->bone_count; i++ )
+      {
+         ms_keyframe *kf = &pose[i-1];
 
          v3f *posemtx = final_mtx[i];
 
@@ -224,7 +223,8 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose,
    skele->bones[0].defer = 0;
    skele->bones[0].flags &= ~k_bone_flag_ik;
 
-   for( u32 i=1; i<skele->bone_count; i++ ){
+   for( u32 i=1; i<skele->bone_count; i++ )
+   {
       struct skeleton_bone *sb = &skele->bones[i],
                            *sp = &skele->bones[sb->parent];
       
@@ -240,7 +240,7 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose,
       v3_sub( skele->bones[i].co, skele->bones[sb->parent].co, temp_delta );
 
       /* pose matrix */
-      mdl_keyframe *kf = &pose[i-1];
+      ms_keyframe *kf = &pose[i-1];
       q_m3x3( kf->q, posemtx );
       m3x3_scale( posemtx, kf->s );
       v3_copy( kf->co, posemtx[3] );
@@ -255,11 +255,11 @@ static void skeleton_apply_pose( struct skeleton *skele, mdl_keyframe *pose,
  * Take the final matrices and decompose it into an absolute positioned anim
  */
 static void skeleton_decompose_mtx_absolute( struct skeleton *skele, 
-                                             mdl_keyframe *anim,
+                                             ms_keyframe *anim,
                                              m4x3f *final_mtx ){
    for( u32 i=1; i<skele->bone_count; i++ ){
       struct skeleton_bone *sb = &skele->bones[i];
-      mdl_keyframe *kf = &anim[i-1];
+      ms_keyframe *kf = &anim[i-1];
       m4x3_decompose( final_mtx[i], kf->co, kf->q, kf->s );
    }
 }
@@ -331,8 +331,10 @@ static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx ){
 /*
  * Apply all IK modifiers (2 bone ik reference from blender is supported)
  */
-static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ){
-   for( u32 i=0; i<skele->ik_count; i++ ){
+static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx )
+{
+   for( u32 i=0; i<skele->ik_count; i++ )
+   {
       struct skeleton_ik *ik = &skele->ik[i];
       
       v3f v0, /* base -> target */
@@ -409,8 +411,9 @@ static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ){
  * Applies the typical operations that you want for an IK rig: 
  *    Pose, IK, Pose(deferred), Inverses, Transform
  */
-static void skeleton_apply_standard( struct skeleton *skele, mdl_keyframe *pose,
-                                     m4x3f transform, m4x3f *final_mtx ){
+static void skeleton_apply_standard( struct skeleton *skele, ms_keyframe *pose,
+                                     m4x3f transform, m4x3f *final_mtx )
+{
    skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik, final_mtx );
    skeleton_apply_ik_pass( skele, final_mtx );
    skeleton_apply_pose( skele, pose, k_anim_apply_deffered_only, final_mtx );
@@ -418,35 +421,18 @@ static void skeleton_apply_standard( struct skeleton *skele, mdl_keyframe *pose,
    skeleton_apply_transform( skele, transform, final_mtx );
 }
 
-/*
- * Get an animation by name
- */
-static struct skeleton_anim *skeleton_get_anim( struct skeleton *skele,
-                                                   const char *name ){
-   for( u32 i=0; i<skele->anim_count; i++ ){
-      struct skeleton_anim *anim = &skele->anims[i];
-
-      if( !strcmp( anim->name, name ) )
-         return anim;
-   }
-
-   vg_error( "skeleton_get_anim( *, \"%s\" )\n", name );
-   vg_fatal_error( "Invalid animation name\n" );
-
-   return NULL;
-}
-
 static void skeleton_alloc_from( struct skeleton *skele,
                                     void *lin_alloc,
                                     mdl_context *mdl,
-                                    mdl_armature *armature ){
+                                    mdl_armature *armature )
+{
    skele->bone_count     = armature->bone_count+1;
-   skele->anim_count     = armature->anim_count;
    skele->ik_count       = 0;
    skele->collider_count = 0;
 
-   for( u32 i=0; i<armature->bone_count; i++ ){
-      mdl_bone *bone = mdl_arritm( &mdl->bones, armature->bone_start+i );
+   for( u32 i=0; i<armature->bone_count; i++ )
+   {
+      mdl_bone *bone = af_arritm( &mdl->bones, armature->bone_start+i );
 
       if( bone->flags & k_bone_flag_ik )
          skele->ik_count ++;
@@ -457,58 +443,54 @@ static void skeleton_alloc_from( struct skeleton *skele,
 
    u32 bone_size = sizeof(struct skeleton_bone) * skele->bone_count,
        ik_size   = sizeof(struct skeleton_ik)   * skele->ik_count,
-       mtx_size  = sizeof(m4x3f)                * skele->bone_count,
-       anim_size = sizeof(struct skeleton_anim) * skele->anim_count;
+       mtx_size  = sizeof(m4x3f)                * skele->bone_count;
 
    skele->bones      = vg_linear_alloc( lin_alloc, bone_size );
    skele->ik         = vg_linear_alloc( lin_alloc, ik_size );
-   //skele->final_mtx  = vg_linear_alloc( lin_alloc, mtx_size );
-   skele->anims      = vg_linear_alloc( lin_alloc, anim_size );
 
    memset( skele->bones, 0, bone_size );
    memset( skele->ik, 0, ik_size );
-   //memset( skele->final_mtx, 0, mtx_size );
-   memset( skele->anims, 0, anim_size );
 }
 
 static void skeleton_fatal_err(void){
    vg_fatal_error( "Skeleton setup failed" );
 }
 
-/* Setup an animated skeleton from model. mdl's metadata should stick around */
+/* Setup a skeleton from model. mdl's metadata should stick around */
 static void skeleton_setup( struct skeleton *skele,
                             void *lin_alloc, mdl_context *mdl ){
    u32 ik_count = 0, collider_count = 0;
    skele->bone_count = 0;
    skele->bones = NULL;
-   //skele->final_mtx = NULL;
-   skele->anims = NULL;
 
    if( !mdl->armatures.count ){
       vg_error( "No skeleton in model\n" );
       skeleton_fatal_err();
    }
 
-   mdl_armature *armature = mdl_arritm( &mdl->armatures, 0 );
+   mdl_armature *armature = af_arritm( &mdl->armatures, 0 );
    skeleton_alloc_from( skele, lin_alloc, mdl, armature );
 
-   for( u32 i=0; i<armature->bone_count; i++ ){
-      mdl_bone *bone = mdl_arritm( &mdl->bones, armature->bone_start+i );
+   for( u32 i=0; i<armature->bone_count; i++ )
+   {
+      mdl_bone *bone = af_arritm( &mdl->bones, armature->bone_start+i );
       struct skeleton_bone *sb = &skele->bones[i+1];
 
       v3_copy( bone->co, sb->co );
       v3_copy( bone->end, sb->end );
 
       sb->parent = bone->parent;
-      sb->name   = mdl_pstr( mdl, bone->pstr_name );
+      sb->name   = ps_get( &mdl->strings, bone->pstr_name );
       sb->flags  = bone->flags;
       sb->collider = bone->collider;
       sb->orig_bone = bone;
 
-      if( sb->flags & k_bone_flag_ik ){
+      if( sb->flags & k_bone_flag_ik )
+      {
          skele->bones[ sb->parent ].flags |= k_bone_flag_ik;
          
-         if( ik_count == skele->ik_count ){
+         if( ik_count == skele->ik_count )
+         {
             vg_error( "Too many ik bones, corrupt model file\n" );
             skeleton_fatal_err();
          }
@@ -540,20 +522,20 @@ static void skeleton_setup( struct skeleton *skele,
    skele->bones[0].name = "[root]";
    
    /* process animation quick refs */
-   for( u32 i=0; i<skele->anim_count; i++ ){
-      mdl_animation *anim = 
-         mdl_arritm( &mdl->animations, armature->anim_start+i );
-
-      skele->anims[i].rate       = anim->rate;
-      skele->anims[i].length     = anim->length;
-      skele->anims[i].name       = mdl_pstr(mdl, anim->pstr_name);
-      skele->anims[i].anim_data  = 
-         mdl_arritm( &mdl->keyframes, anim->offset );
-
-      vg_info( "animation[ %f, %u ] '%s'\n", anim->rate,
-                                             anim->length,
-                                             skele->anims[i].name );
-   }
+   // for( u32 i=0; i<skele->anim_count; i++ ){
+   //    mdl_animation *anim = 
+   //       af_arritm( &mdl->animations, armature->anim_start+i );
+
+   //    skele->anims[i].rate       = anim->rate;
+   //    skele->anims[i].length     = anim->length;
+   //    skele->anims[i].name       = mdl_pstr(mdl, anim->pstr_name);
+   //    skele->anims[i].anim_data  = 
+   //       af_arritm( &mdl->keyframes, anim->offset );
+
+   //    vg_info( "animation[ %f, %u ] '%s'\n", anim->rate,
+   //                                           anim->length,
+   //                                           skele->anims[i].name );
+   // }
 
    skeleton_create_inverses( skele );
    vg_success( "Loaded skeleton with %u bones\n", skele->bone_count );
index 7814b094988144e34fc1b78c1d8a0739b8dec27a..550110034d32fce6fd180c8a0c5d435d8266bd71 100644 (file)
@@ -550,9 +550,9 @@ static void workshop_op_load_model( ui_context *ctx )
 
    if( workshop_form.submission.type == k_addon_type_board )
    {
-      if( mdl_arrcount( &world->ent_swspreview ) )
+      if( af_arrcount( &world->ent_swspreview ) )
       {
-         workshop_form.ptr_ent = mdl_arritm( &world->ent_swspreview, 0 );
+         workshop_form.ptr_ent = af_arritm( &world->ent_swspreview, 0 );
       }
       else
       {
@@ -919,8 +919,9 @@ static void workshop_render_player_preview(void)
    player_pose res;
    res.type = k_player_pose_type_ik;
 
-   struct skeleton_anim *anim = skeleton_get_anim( sk, "idle_cycle+y" );
-   skeleton_sample_anim( sk, anim, vg.time*0.1f, res.keyframes );
+   skeleton_anim anim;
+   player_get_anim( &anim, "idle_cycle+y" );
+   skeleton_sample_anim( sk, &anim, vg.time*0.1f, res.keyframes );
    q_axis_angle( res.root_q, (v3f){0.0f,1.0f,0.0f}, VG_PIf );
    v3_zero( res.root_co );
    res.root_co[1] = 200.0f;
@@ -978,11 +979,11 @@ static void workshop_render_board_preview(void)
    ent_swspreview *swsprev = workshop_form.ptr_ent;
    world_instance *world = workshop_form.view_world;
 
-   ent_camera *ref = mdl_arritm( &world->ent_camera, 
+   ent_camera *ref = af_arritm( &world->ent_camera, 
                                  mdl_entity_id_id(swsprev->id_camera) );
-   ent_marker *display = mdl_arritm( &world->ent_marker,
+   ent_marker *display = af_arritm( &world->ent_marker,
                                  mdl_entity_id_id(swsprev->id_display) ),
-              *display1= mdl_arritm( &world->ent_marker,
+              *display1= af_arritm( &world->ent_marker,
                                  mdl_entity_id_id(swsprev->id_display1) );
 
    v3f baseco;
index 3a067db5ce24cdc4e47de1f121126096f0c47ff0..30d8d633aab327bc8dc1712c83a6a150129830fb 100644 (file)
@@ -163,7 +163,7 @@ struct world_instance {
    u32 surface_count;
 
    ent_worldinfo info;
-   mdl_array_ptr ent_spawn,
+   array_file_ptr ent_spawn,
                  ent_gate,
                  ent_light,
                  ent_route_node,
index b85e6fa65fdce99149de1ab6c80a42434e270a6f..d551d813770521a95343c248c29238c3886f1c4f 100644 (file)
@@ -89,7 +89,7 @@ void world_entity_focus_camera( world_instance *world, u32 uid )
    if( mdl_entity_id_type( uid ) == k_ent_camera )
    {
       u32 index = mdl_entity_id_id( uid );
-      ent_camera *cam = mdl_arritm( &world->ent_camera, index );
+      ent_camera *cam = af_arritm( &world->ent_camera, index );
       ent_camera_unpack( cam, &world_static.focus_cam );
    }
    else 
@@ -154,7 +154,7 @@ void world_entity_focus_render(void)
        index = mdl_entity_id_id( world_static.focused_entity );
 
    if( type == k_ent_skateshop ){
-      ent_skateshop *skateshop = mdl_arritm( &world->ent_skateshop, index );
+      ent_skateshop *skateshop = af_arritm( &world->ent_skateshop, index );
       skateshop_render( skateshop );
    }
    else if( type == k_ent_challenge ){}
@@ -169,8 +169,9 @@ void world_entity_focus_render(void)
 void world_gen_entities_init( world_instance *world )
 {
    /* lights */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_light); j ++ ){
-      ent_light *light = mdl_arritm( &world->ent_light, j );
+   for( u32 j=0; j<af_arrcount(&world->ent_light); j ++ )
+   {
+      ent_light *light = af_arritm( &world->ent_light, j );
 
       m4x3f to_world;
       q_m3x3( light->transform.q, to_world );
@@ -185,9 +186,11 @@ void world_gen_entities_init( world_instance *world )
    vg_async_stall();
 
    /* water */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_water); j++ ){
-      ent_water *water = mdl_arritm( &world->ent_water, j );
-      if( world->water.enabled ){
+   for( u32 j=0; j<af_arrcount(&world->ent_water); j++ )
+   {
+      ent_water *water = af_arritm( &world->ent_water, j );
+      if( world->water.enabled )
+      {
          vg_warn( "Multiple water surfaces in level!\n" );
          break;
       }
@@ -197,21 +200,25 @@ void world_gen_entities_init( world_instance *world )
    }
    
    /* volumes */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_volume); j++ ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, j );
+   for( u32 j=0; j<af_arrcount(&world->ent_volume); j++ )
+   {
+      ent_volume *volume = af_arritm( &world->ent_volume, j );
       mdl_transform_m4x3( &volume->transform, volume->to_world );
       m4x3_invert_full( volume->to_world, volume->to_local );
    }
 
    /* audio packs */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_audio); j++ ){
-      ent_audio *audio = mdl_arritm( &world->ent_audio, j );
+   for( u32 j=0; j<af_arrcount(&world->ent_audio); j++ )
+   {
+      ent_audio *audio = af_arritm( &world->ent_audio, j );
 
-      for( u32 k=0; k<audio->clip_count; k++ ){
-         ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip,  
+      for( u32 k=0; k<audio->clip_count; k++ )
+      {
+         ent_audio_clip *clip = af_arritm( &world->ent_audio_clip,  
                                              audio->clip_start+k );
 
-         if( clip->_.file.pack_size ){
+         if( clip->_.file.pack_size )
+         {
             u32 size = clip->_.file.pack_size,
                 offset = clip->_.file.pack_offset;
 
@@ -229,8 +236,10 @@ void world_gen_entities_init( world_instance *world )
             clip->_.clip.data = data;
             clip->_.clip.size = size;
          }
-         else{
-            clip->_.clip.path = mdl_pstr(&world->meta,clip->_.file.pstr_path);
+         else
+         {
+            clip->_.clip.path = ps_get( &world->meta.strings, 
+                                         clip->_.file.pstr_path );
             clip->_.clip.flags = audio->flags;
             clip->_.clip.data = NULL;
             clip->_.clip.size = 0;
@@ -244,7 +253,7 @@ void world_gen_entities_init( world_instance *world )
    u32 indexed_count = 0;
    struct {
       u32 type;
-      mdl_array_ptr *array;
+      array_file_ptr *array;
    }
    indexables[] = {
       { k_ent_gate, &world->ent_gate },
@@ -256,16 +265,17 @@ void world_gen_entities_init( world_instance *world )
    };
 
    for( u32 i=0; i<VG_ARRAY_LEN(indexables); i++ )
-      indexed_count += mdl_arrcount( indexables[i].array );
+      indexed_count += af_arrcount( indexables[i].array );
    vg_info( "indexing %u entities\n", indexed_count );
 
    world->entity_list = vg_linear_alloc( world->heap, 
                                          vg_align8(indexed_count*sizeof(u32)));
 
    u32 index=0;
-   for( u32 i=0; i<VG_ARRAY_LEN(indexables); i++ ){
+   for( u32 i=0; i<VG_ARRAY_LEN(indexables); i++ )
+   {
       u32 type  = indexables[i].type,
-          count = mdl_arrcount( indexables[i].array );
+          count = af_arrcount( indexables[i].array );
       
       for( u32 j=0; j<count; j ++ )
          world->entity_list[index ++] = mdl_entity_id( type, j );
@@ -277,13 +287,14 @@ void world_gen_entities_init( world_instance *world )
    world->tar_min = world->entity_bh->nodes[0].bbx[0][1];
    world->tar_max = world->entity_bh->nodes[0].bbx[1][1] + 20.0f;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_marker); i++ ){
-      ent_marker *marker = mdl_arritm( &world->ent_marker, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_marker); i++ )
+   {
+      ent_marker *marker = af_arritm( &world->ent_marker, i );
 
-      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tar_min" ) )
+      if( PS_EQ( &world->meta.strings, marker->pstr_alias, "tar_min" ) )
          world->tar_min = marker->transform.co[1];
 
-      if( MDL_CONST_PSTREQ( &world->meta, marker->pstr_alias, "tar_max" ) )
+      if( PS_EQ( &world->meta.strings, marker->pstr_alias, "tar_max" ) )
          world->tar_max = marker->transform.co[1];
    }
 }
@@ -293,8 +304,8 @@ ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
    ent_spawn *rp = NULL, *r;
    float min_dist = INFINITY;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
-      r = mdl_arritm( &world->ent_spawn, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_spawn); i++ ){
+      r = af_arritm( &world->ent_spawn, i );
       float d = v3_dist2( r->transform.co, position );
       
       if( d < min_dist ){
@@ -304,9 +315,9 @@ ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
    }
 
    if( !rp ){
-      if( mdl_arrcount(&world->ent_spawn) ){
+      if( af_arrcount(&world->ent_spawn) ){
          vg_warn( "Invalid distances to spawns.. defaulting to first one.\n" );
-         return mdl_arritm( &world->ent_spawn, 0 );
+         return af_arritm( &world->ent_spawn, 0 );
       }
       else{
          vg_error( "There are no spawns in the level!\n" );
@@ -319,9 +330,14 @@ ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
 ent_spawn *world_find_spawn_by_name( world_instance *world, const char *name )
 {
    ent_spawn *rp = NULL, *r;
-   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
-      r = mdl_arritm( &world->ent_spawn, i );
-      if( !strcmp( mdl_pstr(&world->meta, r->pstr_name), name ) ){
+   u32 hash = vg_strdjb2( name );
+
+   for( u32 i=0; i<af_arrcount(&world->ent_spawn); i++ )
+   {
+      r = af_arritm( &world->ent_spawn, i );
+
+      if( ps_consteq( &world->meta.strings, r->pstr_name, name, hash ) )
+      {
          rp = r;
          break;
       }
@@ -349,7 +365,7 @@ void world_default_spawn_pos( world_instance *world, v3f pos )
 entity_call_result ent_volume_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+   ent_volume *volume = af_arritm( &world->ent_volume, index );
 
    if( !volume->target ) 
       return k_entity_call_result_OK;
@@ -408,7 +424,7 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call )
 
    u8 world_id = (world - world_static.instances) + 1;
    u32 index = mdl_entity_id_id( call->id );
-   ent_audio *audio = mdl_arritm( &world->ent_audio, index );
+   ent_audio *audio = af_arritm( &world->ent_audio, index );
 
    v3f sound_co;
 
@@ -427,7 +443,7 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call )
          bar = 0.0f;
 
    for( u32 i=0; i<audio->clip_count; i++ ){
-      ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip, 
+      ent_audio_clip *clip = af_arritm( &world->ent_audio_clip, 
                                           audio->clip_start+i );
 
       float mod = world->probabilities[ audio->probability_curve ],
@@ -507,8 +523,9 @@ entity_call_result ent_ccmd_call( world_instance *world, ent_call *call )
    if( call->function == k_ent_function_trigger )
    {
       u32 index = mdl_entity_id_id( call->id );
-      ent_ccmd *ccmd = mdl_arritm( &world->ent_ccmd, index );
-      vg_execute_console_input( mdl_pstr(&world->meta, ccmd->pstr_command), 0 );
+      ent_ccmd *ccmd = af_arritm( &world->ent_ccmd, index );
+      vg_execute_console_input( ps_get(&world->meta.strings, 
+                                        ccmd->pstr_command), 0 );
       return k_entity_call_result_OK;
    }
    else
@@ -529,14 +546,14 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
        index = mdl_entity_id_id( id );
 
    if( type == k_ent_gate ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+      ent_gate *gate = af_arritm( &world->ent_gate, index );
       boxf box = {{ -gate->dimensions[0], -gate->dimensions[1], -0.1f },
                   {  gate->dimensions[0],  gate->dimensions[1],  0.1f }};
 
       m4x3_expand_aabb_aabb( gate->to_world, bound, box );
    }
    else if( type == k_ent_objective ){
-      ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+      ent_objective *objective = af_arritm( &world->ent_objective, index );
       
       /* TODO: This might be more work than necessary. could maybe just get
        *       away with representing them as points */
@@ -545,7 +562,7 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
       box_init_inf( box );
 
       for( u32 i=0; i<objective->submesh_count; i++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs,
                                        objective->submesh_start+i );
          box_concat( box, sm->bbx );
       }
@@ -555,12 +572,12 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
       m4x3_expand_aabb_aabb( transform, bound, box );
    }
    else if( type == k_ent_volume ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      ent_volume *volume = af_arritm( &world->ent_volume, index );
       m4x3_expand_aabb_aabb( volume->to_world, bound,
                               (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}} );
    }
    else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
       boxf box = {{-1.2f*0.5f,-0.72f*0.5f,-0.01f*0.5f},
                   { 1.2f*0.5f, 0.72f*0.5f, 0.01f*0.5f}};
@@ -569,7 +586,7 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
       m4x3_expand_aabb_aabb( transform, bound, box );
    }
    else if( type == k_ent_glider ){
-      ent_glider *glider = mdl_arritm( &world->ent_glider, index );
+      ent_glider *glider = af_arritm( &world->ent_glider, index );
       m4x3f transform;
       mdl_transform_m4x3( &glider->transform, transform );
       m4x3_expand_aabb_aabb( transform, bound,
@@ -577,7 +594,7 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index )
    }
    else if( type == k_ent_npc )
    {
-      ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+      ent_npc *npc = af_arritm( &world->ent_npc, index );
       box_addpt( bound, npc->transform.co );
    }
    else{
@@ -594,30 +611,30 @@ float entity_bh_centroid( void *user, u32 item_index, int axis )
        index = mdl_entity_id_id( id );
 
    if( type == k_ent_gate ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+      ent_gate *gate = af_arritm( &world->ent_gate, index );
       return gate->to_world[3][axis];
    }
    else if( type == k_ent_objective ){
-      ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+      ent_objective *objective = af_arritm( &world->ent_objective, index );
       return objective->transform.co[axis];
    }
    else if( type == k_ent_volume ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      ent_volume *volume = af_arritm( &world->ent_volume, index );
       return volume->transform.co[axis];
    }
    else if( type == k_ent_challenge )
    {
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
       return challenge->transform.co[axis];
    }
    else if( type == k_ent_glider )
    {
-      ent_glider *glider = mdl_arritm( &world->ent_glider, index );
+      ent_glider *glider = af_arritm( &world->ent_glider, index );
       return glider->transform.co[axis];
    }
    else if( type == k_ent_npc )
    {
-      ent_npc *npc = mdl_arritm( &world->ent_npc, index );
+      ent_npc *npc = af_arritm( &world->ent_npc, index );
       return npc->transform.co[axis];
    }
    else 
@@ -646,18 +663,18 @@ void entity_bh_debug( void *user, u32 item_index ){
        index = mdl_entity_id_id( id );
 
    if( type == k_ent_gate ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+      ent_gate *gate = af_arritm( &world->ent_gate, index );
       boxf box = {{ -gate->dimensions[0], -gate->dimensions[1], -0.1f },
                   {  gate->dimensions[0],  gate->dimensions[1],  0.1f }};
       vg_line_boxf_transformed( gate->to_world, box, 0xf000ff00 );
    }
    else if( type == k_ent_objective ){
-      ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+      ent_objective *objective = af_arritm( &world->ent_objective, index );
       boxf box;
       box_init_inf( box );
 
       for( u32 i=0; i<objective->submesh_count; i++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs,
                                        objective->submesh_start+i );
          box_concat( box, sm->bbx );
       }
@@ -667,13 +684,13 @@ void entity_bh_debug( void *user, u32 item_index ){
       vg_line_boxf_transformed( transform, box, 0xf000ff00 );
    }
    else if( type == k_ent_volume ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      ent_volume *volume = af_arritm( &world->ent_volume, index );
       vg_line_boxf_transformed( volume->to_world,
                                 (boxf){{-1.0f,-1.0f,-1.0f},{ 1.0f, 1.0f, 1.0f}},
                                 0xf000ff00 );
    }
    else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
 
       boxf box = {{-1.2f*0.5f,-0.72f*0.5f,-0.01f*0.5f},
                   { 1.2f*0.5f, 0.72f*0.5f, 0.01f*0.5f}};
@@ -691,19 +708,24 @@ void update_ach_models(void)
    world_instance *hub = &world_static.instances[k_world_purpose_hub];
    if( hub->status != k_world_status_loaded ) return;
 
-   for( u32 i=0; i<mdl_arrcount( &hub->ent_prop ); i ++ ){
-      ent_prop *prop = mdl_arritm( &hub->ent_prop, i );
-      if( prop->flags & 0x2 ){
-         if( MDL_CONST_PSTREQ( &hub->meta, prop->pstr_alias, "MARC" ) )
+   for( u32 i=0; i<af_arrcount( &hub->ent_prop ); i ++ )
+   {
+      ent_prop *prop = af_arritm( &hub->ent_prop, i );
+      if( prop->flags & 0x2 )
+      {
+         if( PS_EQ( &hub->meta.strings, prop->pstr_alias, "MARC" ) )
             if( skaterift.achievements & 0x1 )
                prop->flags &= ~0x1;
-         if( MDL_CONST_PSTREQ( &hub->meta, prop->pstr_alias, "ALBERT" ) )
+
+         if( PS_EQ( &hub->meta.strings, prop->pstr_alias, "ALBERT" ) )
             if( skaterift.achievements & 0x2 )
                prop->flags &= ~0x1;
-         if( MDL_CONST_PSTREQ( &hub->meta, prop->pstr_alias, "JANET" ) )
+
+         if( PS_EQ( &hub->meta.strings, prop->pstr_alias, "JANET" ) )
             if( skaterift.achievements & 0x4 )
                prop->flags &= ~0x1;
-         if( MDL_CONST_PSTREQ( &hub->meta, prop->pstr_alias, "BERNADETTA" ) )
+
+         if( PS_EQ( &hub->meta.strings, prop->pstr_alias, "BERNADETTA" ) )
             if( skaterift.achievements & 0x8 )
                prop->flags &= ~0x1;
       }
@@ -719,19 +741,19 @@ void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest )
        index = mdl_entity_id_id( id );
 
    if( type == k_ent_gate ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+      ent_gate *gate = af_arritm( &world->ent_gate, index );
       v3_copy( gate->to_world[3], closest );
    }
    else if( type == k_ent_objective ){
-      ent_objective *challenge = mdl_arritm( &world->ent_objective, index );
+      ent_objective *challenge = af_arritm( &world->ent_objective, index );
       v3_copy( challenge->transform.co, closest );
    }
    else if( type == k_ent_volume ){
-      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      ent_volume *volume = af_arritm( &world->ent_volume, index );
       v3_copy( volume->to_world[3], closest );
    }
    else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
       v3_copy( challenge->transform.co, closest );
    }
    else{
@@ -744,9 +766,9 @@ void world_entity_start( world_instance *world, vg_msg *sav )
    vg_info( "Start instance %p\n", world );
 
    world->probabilities[ k_probability_curve_constant ] = 1.0f;
-   for( u32 i=0; i<mdl_arrcount(&world->ent_audio); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_audio); i++ )
    {
-      ent_audio *audio = mdl_arritm(&world->ent_audio,i);
+      ent_audio *audio = af_arritm(&world->ent_audio,i);
       if( audio->flags & AUDIO_FLAG_AUTO_START )
       {
          ent_call call;
@@ -760,9 +782,9 @@ void world_entity_start( world_instance *world, vg_msg *sav )
    /* read savedata 
     * ----------------------------------------------------------------------- */
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
-      const char *alias = mdl_pstr( &world->meta, challenge->pstr_alias );
+   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ ){
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
+      const char *alias = ps_get( &world->meta.strings, challenge->pstr_alias );
 
       u32 result;
       vg_msg_getkvintg( sav, alias, k_vg_msg_u32, &result, NULL );
@@ -778,12 +800,13 @@ void world_entity_start( world_instance *world, vg_msg *sav )
 
    vg_msg routes_block = *sav;
    if( vg_msg_seekframe( &routes_block, "routes" ) ){
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+         ent_route *route = af_arritm( &world->ent_route, i );
 
          vg_msg route_info = routes_block;
          if( vg_msg_seekframe( &route_info, 
-                               mdl_pstr(&world->meta,route->pstr_name) ) ){
+                               ps_get(&world->meta.strings,route->pstr_name) ) )
+         {
 
             u32 flags;
             vg_msg_getkvintg( &route_info, "flags", k_vg_msg_u32,    
@@ -806,7 +829,7 @@ void world_entity_start( world_instance *world, vg_msg *sav )
             }
 
             for( u32 j=0; j<route->checkpoints_count; j ++ ){
-               ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint,
+               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint,
                      route->checkpoints_start + j );
 
                cp->best_time = sections[j];
@@ -817,7 +840,8 @@ void world_entity_start( world_instance *world, vg_msg *sav )
                for( u32 j=0; j<VG_ARRAY_LEN(track_infos); j ++ ){
                   struct track_info *inf = &track_infos[j];
                   if( !strcmp(inf->name,
-                              mdl_pstr(&world->meta,route->pstr_name))){
+                              ps_get(&world->meta.strings,route->pstr_name)))
+                  {
                      
                      steamapi_bool set = 0;
                      if( SteamAPI_ISteamUserStats_GetAchievement( 
@@ -839,19 +863,19 @@ void world_entity_start( world_instance *world, vg_msg *sav )
 
 void world_entity_serialize( world_instance *world, vg_msg *sav )
 {
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
-      ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
+   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ ){
+      ent_challenge *challenge = af_arritm(&world->ent_challenge,i);
 
-      const char *alias = mdl_pstr(&world->meta,challenge->pstr_alias);
+      const char *alias = ps_get( &world->meta.strings, challenge->pstr_alias );
       vg_msg_wkvnum( sav, alias, k_vg_msg_u32, 1, &challenge->status );
    }
    
-   if( mdl_arrcount(&world->ent_route) ){
+   if( af_arrcount(&world->ent_route) ){
       vg_msg_frame( sav, "routes" );
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+         ent_route *route = af_arritm( &world->ent_route, i );
          
-         vg_msg_frame( sav, mdl_pstr( &world->meta, route->pstr_name ) );
+         vg_msg_frame( sav, ps_get( &world->meta.strings, route->pstr_name ) );
          {
             vg_msg_wkvnum( sav, "flags", k_vg_msg_u32, 1, &route->flags );
             vg_msg_wkvnum( sav, "best_laptime", 
@@ -860,7 +884,7 @@ void world_entity_serialize( world_instance *world, vg_msg *sav )
             f32 sections[ route->checkpoints_count ];
 
             for( u32 j=0; j<route->checkpoints_count; j ++ ){
-               ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint,
+               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint,
                      route->checkpoints_start + j );
 
                sections[j] = cp->best_time;
index 3e6fdbb0a9009266bbb8f408bb7631da7b5b5de4..ad8c73850ca8b1bdc0edce34ff666519ba130840 100644 (file)
@@ -56,7 +56,7 @@ void world_gates_init(void)
    mdl_load_metadata_block( &mgate, vg_mem.scratch );
 
    mdl_mesh *surface = mdl_find_mesh( &mgate, "rs_gate" );
-   mdl_submesh *sm = mdl_arritm(&mgate.submeshs,surface->submesh_start);
+   mdl_submesh *sm = af_arritm(&mgate.submeshs,surface->submesh_start);
    world_gates.sm_surface = *sm;
 
    const char *names[] = { "rs_gate_marker", "rs_gate_marker.001", 
@@ -64,7 +64,7 @@ void world_gates_init(void)
 
    for( int i=0; i<4; i++ ){
       mdl_mesh *marker = mdl_find_mesh( &mgate, names[i] );
-      sm = mdl_arritm( &mgate.submeshs, marker->submesh_start );
+      sm = af_arritm( &mgate.submeshs, marker->submesh_start );
       world_gates.sm_marker[i] = *sm;
    }
 
@@ -87,7 +87,7 @@ static void render_gate_mesh( world_instance *world, ent_gate *gate )
    if( gate->flags & k_ent_gate_custom_mesh ){
       mesh_bind( &world->mesh_no_collide );
       for( u32 i=0; i<gate->submesh_count; i++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        gate->submesh_start+i );
          mdl_draw_submesh( sm );
       }
@@ -276,8 +276,8 @@ int gate_intersect( ent_gate *gate, v3f pos, v3f last )
  */
 u32 world_intersect_gates( world_instance *world, v3f pos, v3f last )
 {
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
 
       if( !(gate->flags & k_ent_gate_linked) ) continue;
       if( gate->flags & k_ent_gate_locked ) continue;
@@ -298,7 +298,7 @@ u32 world_intersect_gates( world_instance *world, v3f pos, v3f last )
 entity_call_result ent_gate_call( world_instance *world, ent_call *call )
 {
    u32 index = mdl_entity_id_id( call->id );
-   ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+   ent_gate *gate = af_arritm( &world->ent_gate, index );
 
    if( call->function == 0 ) /* unlock() */
    { 
@@ -317,9 +317,9 @@ entity_call_result ent_gate_call( world_instance *world, ent_call *call )
  */
 void world_unlink_nonlocal( world_instance *world )
 {
-   for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ )
+   for( u32 j=0; j<af_arrcount(&world->ent_gate); j ++ )
    {
-      ent_gate *gate = mdl_arritm( &world->ent_gate, j );
+      ent_gate *gate = af_arritm( &world->ent_gate, j );
 
       if( gate->flags & k_ent_gate_nonlocal )
       {
@@ -339,9 +339,9 @@ void world_link_gates_async( void *payload, u32 size )
    world_instance *world = payload;
    u32 world_id = world - world_static.instances;
 
-   for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ )
+   for( u32 j=0; j<af_arrcount(&world->ent_gate); j ++ )
    {
-      ent_gate *gate = mdl_arritm( &world->ent_gate, j );
+      ent_gate *gate = af_arritm( &world->ent_gate, j );
       gate_transform_update( gate );
 
       if( skaterift.demo_mode )
@@ -351,7 +351,7 @@ void world_link_gates_async( void *payload, u32 size )
       if( !(gate->flags & k_ent_gate_nonlocal) ) continue;
       if( gate->flags & k_ent_gate_linked ) continue;
 
-      const char *key = mdl_pstr( &world->meta, gate->key );
+      const char *key = ps_get( &world->meta.strings, gate->key );
       vg_info( "key: %s\n", key );
 
       for( u32 i=0; i<VG_ARRAY_LEN(world_static.instances); i++ ){
@@ -360,13 +360,13 @@ void world_link_gates_async( void *payload, u32 size )
          if( other->status != k_world_status_loaded ) continue;
          vg_info( "Checking world %u for key matches\n", i );
 
-         for( u32 k=0; k<mdl_arrcount( &other->ent_gate ); k++ ){
-            ent_gate *gate2 = mdl_arritm( &other->ent_gate, k );
+         for( u32 k=0; k<af_arrcount( &other->ent_gate ); k++ ){
+            ent_gate *gate2 = af_arritm( &other->ent_gate, k );
 
             if( !(gate2->flags & k_ent_gate_nonlocal) ) continue;
             if( gate2->flags & k_ent_gate_linked ) continue;
 
-            const char *key2 = mdl_pstr( &other->meta, gate2->key );
+            const char *key2 = ps_get( &other->meta.strings, gate2->key );
             vg_info( " key2: %s\n", key2 );
 
             if( strcmp( key, key2 ) ) continue;
index e51836d757574d9e7ee1e2bfd2c8b17afa0cf332..0f329a4b56a2dae0aa72cd85d4e9afa77b2afcc3 100644 (file)
 static void world_add_all_if_material( m4x3f transform, scene_context *scene, 
                                           mdl_context *mdl, u32 id )
 {
-   for( u32 i=0; i<mdl_arrcount(&mdl->meshs); i++ ){
-      mdl_mesh *mesh = mdl_arritm( &mdl->meshs, i );
+   for( u32 i=0; i<af_arrcount(&mdl->meshs); i++ ){
+      mdl_mesh *mesh = af_arritm( &mdl->meshs, i );
 
       for( u32 j=0; j<mesh->submesh_count; j++ ){
-         mdl_submesh *sm = mdl_arritm( &mdl->submeshs, mesh->submesh_start+j );
+         mdl_submesh *sm = af_arritm( &mdl->submeshs, mesh->submesh_start+j );
          if( sm->material_id == id ){
             m4x3f transform2;
             mdl_transform_m4x3( &mesh->transform, transform2 );
@@ -298,11 +298,11 @@ void world_gen_generate_meshes( world_instance *world )
     * models. we only have 2 types at the moment which need dynamic models but
     * would make sense to do this when/if we have more.
     */
-   for( u32 i=0; i<mdl_arrcount( &world->ent_traffic ); i++ ){
-      ent_traffic *vehc = mdl_arritm( &world->ent_traffic, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_traffic ); i++ ){
+      ent_traffic *vehc = af_arritm( &world->ent_traffic, i );
 
       for( u32 j=0; j<vehc->submesh_count; j++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        vehc->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
          world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_TRAFFIC;
@@ -310,46 +310,46 @@ void world_gen_generate_meshes( world_instance *world )
    }
 
    /* unpack challenge models */
-   for( u32 i=0; i<mdl_arrcount( &world->ent_objective ); i++ ){
-      ent_objective *objective = mdl_arritm( &world->ent_objective, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_objective ); i++ ){
+      ent_objective *objective = af_arritm( &world->ent_objective, i );
 
       for( u32 j=0; j<objective->submesh_count; j ++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        objective->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
       }
    }
 
    /* unpack region models */
-   for( u32 i=0; i<mdl_arrcount( &world->ent_region ); i++ ){
-      ent_region *region = mdl_arritm( &world->ent_region, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_region ); i++ ){
+      ent_region *region = af_arritm( &world->ent_region, i );
 
       for( u32 j=0; j<region->submesh_count; j ++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        region->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
       }
    }
 
    /* unpack gate models */
-   for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_gate ); i++ ){
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
 
       if( !(gate->flags & k_ent_gate_custom_mesh) ) continue;
 
       for( u32 j=0; j<gate->submesh_count; j ++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        gate->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
       }
    }
 
    /* unpack prop models */
-   for( u32 i=0; i<mdl_arrcount( &world->ent_prop ); i++ ){
-      ent_prop *prop = mdl_arritm( &world->ent_prop, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_prop ); i++ ){
+      ent_prop *prop = af_arritm( &world->ent_prop, i );
 
       for( u32 j=0; j<prop->submesh_count; j ++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        prop->submesh_start+j );
          world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_PROPS;
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
@@ -487,8 +487,8 @@ void world_gen_compute_light_indices( world_instance *world )
             float influences[6] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
             const int N = VG_ARRAY_LEN( influences );
 
-            for( u32 j=0; j<mdl_arrcount(&world->ent_light); j ++ ){
-               ent_light *light = mdl_arritm( &world->ent_light, j );
+            for( u32 j=0; j<af_arrcount(&world->ent_light); j ++ ){
+               ent_light *light = af_arritm( &world->ent_light, j );
                v3f closest;
                closest_point_aabb( light->transform.co, bbx, closest );
 
@@ -563,7 +563,7 @@ void async_world_postprocess( void *payload, u32 _size )
    /* create scene lighting buffer */
    world_instance *world = payload;
 
-   u32 size = VG_MAX(mdl_arrcount(&world->ent_light),1) * sizeof(float)*12;
+   u32 size = VG_MAX(af_arrcount(&world->ent_light),1) * sizeof(float)*12;
    vg_info( "Upload %ubytes (lighting)\n", size );
 
    glGenBuffers( 1, &world->tbo_light_entities );
@@ -579,8 +579,8 @@ void async_world_postprocess( void *payload, u32 _size )
     */
 
    v4f *light_dst = glMapBuffer( GL_TEXTURE_BUFFER, GL_WRITE_ONLY );
-   for( u32 i=0; i<mdl_arrcount(&world->ent_light); i++ ){
-      ent_light *light = mdl_arritm( &world->ent_light, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_light); i++ ){
+      ent_light *light = af_arritm( &world->ent_light, i );
 
       /* colour  + night */
       v3_muls( light->colour, light->colour[3] * 2.0f, light_dst[i*3+0] );
@@ -672,8 +672,8 @@ void async_world_postprocess( void *payload, u32 _size )
    /*
     * Allocate cubemaps
     */
-   for( u32 i=0; i<mdl_arrcount(&world->ent_cubemap); i++ ){
-      ent_cubemap *cm = mdl_arritm(&world->ent_cubemap,i);
+   for( u32 i=0; i<af_arrcount(&world->ent_cubemap); i++ ){
+      ent_cubemap *cm = af_arritm(&world->ent_cubemap,i);
 
       glGenTextures( 1, &cm->texture_id );
       glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id );
@@ -723,9 +723,9 @@ void world_gen_load_surfaces( world_instance *world )
                               vg_align8(sizeof(GLuint)*world->texture_count) );
    world->textures[0] = vg.tex_missing;
 
-   for( u32 i=0; i<mdl_arrcount(&world->meta.textures); i++ )
+   for( u32 i=0; i<af_arrcount(&world->meta.textures); i++ )
    {
-      mdl_texture *tex = mdl_arritm( &world->meta.textures, i );
+      mdl_texture *tex = af_arritm( &world->meta.textures, i );
 
       if( !tex->file.pack_size )
       {
@@ -752,10 +752,10 @@ void world_gen_load_surfaces( world_instance *world )
    struct world_surface *errmat = &world->surfaces[0];
    memset( errmat, 0, sizeof(struct world_surface) );
                        
-   for( u32 i=0; i<mdl_arrcount(&world->meta.materials); i++ )
+   for( u32 i=0; i<af_arrcount(&world->meta.materials); i++ )
    {
       struct world_surface *surf = &world->surfaces[i+1];
-      surf->info = *(mdl_material *)mdl_arritm( &world->meta.materials, i );
+      surf->info = *(mdl_material *)af_arritm( &world->meta.materials, i );
       surf->flags = 0;
 
       if( surf->info.shader == k_shader_water )
index 30c2b2cce14573855069ddf5621632c35d8a5714..cb473d8edccaf400c040b61da93652c2cb1d2943 100644 (file)
@@ -40,49 +40,48 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
 
    mdl_open( meta, path, world->heap );
    mdl_load_metadata_block( meta, world->heap );
-   mdl_load_animation_block( meta, world->heap );
    mdl_load_mesh_block( meta, world->heap );
 
    vg_info( "%u\n", sizeof(ent_cubemap) );
 
-   MDL_LOAD_ARRAY( meta, &world->ent_gate,      ent_gate,       heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_camera,    ent_camera,     heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_spawn,     ent_spawn,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_light,     ent_light,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_route_node,ent_route_node, heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_path_index,ent_path_index, heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_checkpoint,ent_checkpoint, heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_route,     ent_route,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_water,     ent_water,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_audio_clip,ent_audio_clip, heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_audio,     ent_audio,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_volume,    ent_volume,     heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_traffic,   ent_traffic,    heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_marker,    ent_marker,     heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_skateshop, ent_skateshop,  heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_swspreview,ent_swspreview, heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_ccmd,      ent_ccmd,       heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_objective, ent_objective,  heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_challenge, ent_challenge,  heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_relay,     ent_relay,      heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_cubemap,   ent_cubemap,    heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_miniworld, ent_miniworld,  heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_prop,      ent_prop,       heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_region,    ent_region,     heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_glider,    ent_glider,     heap );
-   MDL_LOAD_ARRAY( meta, &world->ent_npc,       ent_npc,        heap );
-
-   mdl_array_ptr infos;
-   MDL_LOAD_ARRAY( meta, &infos, ent_worldinfo, vg_mem.scratch );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_gate,      ent_gate,       heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_camera,    ent_camera,     heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_spawn,     ent_spawn,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_light,     ent_light,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_route_node,ent_route_node, heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_path_index,ent_path_index, heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_checkpoint,ent_checkpoint, heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_route,     ent_route,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_water,     ent_water,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_audio_clip,ent_audio_clip, heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_audio,     ent_audio,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_volume,    ent_volume,     heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_traffic,   ent_traffic,    heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_marker,    ent_marker,     heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_skateshop, ent_skateshop,  heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_swspreview,ent_swspreview, heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_ccmd,      ent_ccmd,       heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_objective, ent_objective,  heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_challenge, ent_challenge,  heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_relay,     ent_relay,      heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_cubemap,   ent_cubemap,    heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_miniworld, ent_miniworld,  heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_prop,      ent_prop,       heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_region,    ent_region,     heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_glider,    ent_glider,     heap );
+   MDL_LOAD_ARRAY_STRUCT( meta, &world->ent_npc,       ent_npc,        heap );
+
+   array_file_ptr infos;
+   MDL_LOAD_ARRAY_STRUCT( meta, &infos, ent_worldinfo, vg_mem.scratch );
 
    world->skybox = k_skybox_default;
-   if( mdl_arrcount(&infos) )
+   if( af_arrcount(&infos) )
    {
-      world->info = *((ent_worldinfo *)mdl_arritm(&infos,0));
+      world->info = *((ent_worldinfo *)af_arritm(&infos,0));
 
       if( world->meta.info.version >= 104 )
       {
-         if( MDL_CONST_PSTREQ( &world->meta, world->info.pstr_skybox,"space"))
+         if( PS_EQ( &world->meta.strings, world->info.pstr_skybox, "space" ))
          {
             world->skybox = k_skybox_space;
          }
@@ -140,10 +139,10 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    world_default_spawn_pos( world, world->player_co );
 
    /* allocate leaderboard buffers */
-   u32 bs = mdl_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache);
+   u32 bs = af_arrcount(&world->ent_route)*sizeof(struct leaderboard_cache);
    world->leaderboard_cache = vg_linear_alloc( heap, bs );
 
-   for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i ++ )
+   for( u32 i=0; i<af_arrcount( &world->ent_route ); i ++ )
    {
       struct leaderboard_cache *board = &world->leaderboard_cache[i];
       board->data = vg_linear_alloc( heap, NETWORK_REQUEST_MAX );
@@ -153,7 +152,7 @@ static void world_instance_load_mdl( u32 instance_id, const char *path ){
    }
 
    world->routes_ui = vg_linear_alloc( heap, 
-         sizeof(struct route_ui)*mdl_arrcount(&world->ent_route) );
+         sizeof(struct route_ui)*af_arrcount(&world->ent_route) );
 
    vg_async_call( async_world_postprocess, world, 0 );
    vg_async_stall();
@@ -488,8 +487,8 @@ void world_free( world_instance *world )
                      vg_linear_header(world->heap) );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_cubemap); i++ ){
-      ent_cubemap *cm = mdl_arritm(&world->ent_cubemap,i);
+   for( u32 i=0; i<af_arrcount(&world->ent_cubemap); i++ ){
+      ent_cubemap *cm = af_arritm(&world->ent_cubemap,i);
       glDeleteTextures( 1, &cm->texture_id );
       glDeleteFramebuffers( 1, &cm->framebuffer_id );
       glDeleteRenderbuffers( 1, &cm->renderbuffer_id );
index 279942874459ebda7604cbaf8cb3ba12bc7c6ce5..5287affb3358f64f4936cc2e0f88e2eeff29941b 100644 (file)
@@ -187,9 +187,9 @@ void world_map_pre_update(void)
    f32 closest2 = INFINITY;
    v2f centroid = { 0, 0 };
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_spawn); i++ )
    {
-      ent_spawn *spawn = mdl_arritm(&world->ent_spawn,i);
+      ent_spawn *spawn = af_arritm(&world->ent_spawn,i);
 
       v4f v;
       v3_copy( spawn->transform.co, v );
@@ -239,9 +239,9 @@ void world_map_pre_update(void)
 
    /* icons
     * ---------------------*/
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ )
    {
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
 
       enum gui_icon icon = k_gui_icon_exclaim_2d;
       if( challenge->status )
@@ -250,9 +250,9 @@ void world_map_pre_update(void)
       respawn_map_draw_icon( cam, icon, challenge->transform.co, 1.0f );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i ++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_spawn); i ++ )
    {
-      ent_spawn *spawn = mdl_arritm( &world->ent_spawn, i );
+      ent_spawn *spawn = af_arritm( &world->ent_spawn, i );
 
       if( spawn->transform.s[0] > 0.3f )
          continue;
@@ -264,9 +264,9 @@ void world_map_pre_update(void)
             spawn->transform.co, s );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_skateshop); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_skateshop); i++ )
    {
-      ent_skateshop *shop = mdl_arritm( &world->ent_skateshop, i );
+      ent_skateshop *shop = af_arritm( &world->ent_skateshop, i );
       if( shop->type == k_skateshop_type_boardshop )
       {
          respawn_map_draw_icon( cam, k_gui_icon_board, shop->transform.co, 1 );
@@ -277,18 +277,18 @@ void world_map_pre_update(void)
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ )
    {
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
       if( gate->flags & k_ent_gate_nonlocal )
       {
          respawn_map_draw_icon( cam, k_gui_icon_rift, gate->co[0], 1 );
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
    {
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+      ent_route *route = af_arritm( &world->ent_route, i );
 
       v4f colour;
       v4_copy( route->colour, colour );
@@ -298,9 +298,9 @@ void world_map_pre_update(void)
                              route->board_transform[3], 1 );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_glider); i ++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_glider); i ++ )
    {
-      ent_glider *glider = mdl_arritm( &world->ent_glider, i );
+      ent_glider *glider = af_arritm( &world->ent_glider, i );
 
       v4f colour = { 1,1,1,1 };
 
index 3eb07a1270c55e5ea50cee1bbcccd7fc21be72be..b7a673216b869559bd6ed90df14aa660b6fa6e29 100644 (file)
@@ -169,7 +169,7 @@ static void world_render_submeshes( world_instance *world,
 {
    for( u32 k=0; k<count; k++ )
    {
-      mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, start+k );
+      mdl_submesh *sm = af_arritm( &world->meta.submeshs, start+k );
       if( sm->material_id != material_id ) 
          continue;
 
@@ -198,8 +198,8 @@ static void world_render_props( world_instance *world, u32 material_id,
 
    pass->fn_bind( world, mat );
 
-   for( u32 j=0; j<mdl_arrcount( &world->ent_prop ); j++ ){
-      ent_prop *prop = mdl_arritm( &world->ent_prop, j );
+   for( u32 j=0; j<af_arrcount( &world->ent_prop ); j++ ){
+      ent_prop *prop = af_arritm( &world->ent_prop, j );
       if( prop->flags & 0x1 ) continue;
 
       world_render_submeshes( world, pass, &prop->transform, 
@@ -218,8 +218,8 @@ static void world_render_traffic( world_instance *world, u32 material_id,
 
    pass->fn_bind( world, mat );
 
-   for( u32 j=0; j<mdl_arrcount( &world->ent_traffic ); j++ ){
-      ent_traffic *traffic = mdl_arritm( &world->ent_traffic, j );
+   for( u32 j=0; j<af_arrcount( &world->ent_traffic ); j++ ){
+      ent_traffic *traffic = af_arritm( &world->ent_traffic, j );
 
       world_render_submeshes( world, pass, &traffic->transform,
                               traffic->submesh_start, traffic->submesh_count,
@@ -375,7 +375,7 @@ static void bindpoint_world_cubemapped( world_instance *world,
       cubemap_index = mdl_entity_id_id( cubemap_id );
    }
 
-   ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, cubemap_index );
+   ent_cubemap *cm = af_arritm( &world->ent_cubemap, cubemap_index );
    glActiveTexture( GL_TEXTURE10 );
    glBindTexture( GL_TEXTURE_CUBE_MAP, cm->texture_id );
 
@@ -395,7 +395,7 @@ static void bindpoint_world_cubemapped_disabled( world_instance *world,
 static void render_world_cubemapped( world_instance *world, vg_camera *cam,
                                      int enabled )
 {
-   if( !mdl_arrcount( &world->ent_cubemap ) )
+   if( !af_arrcount( &world->ent_cubemap ) )
       return;
 
    if( !enabled )
@@ -520,7 +520,7 @@ static void world_render_challenges( world_instance *world,
             !world_static.challenge_target) ){
          world_instance *challenge_world = world_current_instance();
          u32 index = mdl_entity_id_id( world_static.focused_entity );
-         active_challenge = mdl_arritm(&challenge_world->ent_challenge, index);
+         active_challenge = af_arritm(&challenge_world->ent_challenge, index);
       }
    }
 
@@ -533,7 +533,7 @@ static void world_render_challenges( world_instance *world,
          u32 index = mdl_entity_id_id( next );
          objective_list[ objective_count ++ ] = index;
 
-         ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+         ent_objective *objective = af_arritm( &world->ent_objective, index );
          next = objective->id_next;
       }
 
@@ -567,7 +567,7 @@ static void world_render_challenges( world_instance *world,
    for( u32 i=0; i<objective_count; i++ )
    {
       u32 index = objective_list[ i ];
-      ent_objective *objective = mdl_arritm( &world->ent_objective, index );
+      ent_objective *objective = af_arritm( &world->ent_objective, index );
       if( (objective->flags & k_ent_objective_hidden) &&
           !active_challenge ) continue;
 
@@ -599,7 +599,7 @@ static void world_render_challenges( world_instance *world,
 
       for( u32 j=0; j<objective->submesh_count; j++ )
       {
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+         mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                        objective->submesh_start + j );
 
          if( sm->material_id != last_material )
@@ -616,9 +616,9 @@ static void world_render_challenges( world_instance *world,
 
    u32 count = 0;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ )
    {
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
       if( challenge->status ) count ++;
    }
 
@@ -627,7 +627,7 @@ static void world_render_challenges( world_instance *world,
    vg_strnull( &str, buf, sizeof(buf) );
    vg_strcati32( &str, count );
    vg_strcatch( &str, '/' );
-   vg_strcati32( &str, mdl_arrcount(&world->ent_challenge) );
+   vg_strcati32( &str, af_arrcount(&world->ent_challenge) );
 
    f32 w = font3d_string_width( 1, buf );
    m4x3f mlocal;
@@ -639,7 +639,7 @@ static void world_render_challenges( world_instance *world,
    for( u32 i=0; i<challenge_count; i++ )
    {
       u32 index = challenge_list[ i ];
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+      ent_challenge *challenge = af_arritm( &world->ent_challenge, index );
       m4x3f mmdl;
       mdl_transform_m4x3( &challenge->transform, mmdl );
       m4x3_mul( mmdl, mlocal, mmdl );
@@ -698,9 +698,9 @@ static void render_world_fxglow( world_instance *host_world,
       mesh_bind( &world->mesh_no_collide );
 
       u32 last_material = 0;
-      for( u32 i=0; i<mdl_arrcount(&world->ent_region); i ++ ){
+      for( u32 i=0; i<af_arrcount(&world->ent_region); i ++ ){
          shader_scene_fxglow_uUvOffset( (v2f){ 0.0f, 0.0f } );
-         ent_region *region = mdl_arritm( &world->ent_region, i );
+         ent_region *region = af_arritm( &world->ent_region, i );
 
          f32 offset = 0.0f;
          if( region->flags & k_ent_route_flag_achieve_gold )
@@ -717,7 +717,7 @@ static void render_world_fxglow( world_instance *host_world,
 
          for( u32 j=0; j<region->submesh_count; j++ )
          {
-            mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+            mdl_submesh *sm = af_arritm( &world->meta.submeshs, 
                                           region->submesh_start + j );
 
             if( sm->material_id != last_material )
@@ -863,8 +863,8 @@ void render_world_gates( world_instance *world, vg_camera *cam )
    float closest = INFINITY;
    struct ent_gate *gate = NULL;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gi = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gi = af_arritm( &world->ent_gate, i );
 
       if( !(gi->flags & k_ent_gate_nonlocal) )
          if( !(gi->flags & k_ent_gate_linked) )
@@ -906,7 +906,7 @@ void render_world_gates( world_instance *world, vg_camera *cam )
 
 void world_prerender( world_instance *world )
 {
-   if( mdl_arrcount( &world->ent_light ) ){
+   if( af_arrcount( &world->ent_light ) ){
       f32 rate = vg_maxf(0.1f, fabsf(k_day_length)) * vg_signf(k_day_length);
       world->time += vg.time_frame_delta * (1.0/(rate*60.0));
    }
@@ -996,7 +996,7 @@ static void render_other_entities( world_instance *world, vg_camera *cam )
 
    for( u32 j=0; j<glider_count; j ++ )
    {
-      ent_glider *glider = mdl_arritm( &world->ent_glider, glider_list[j] );
+      ent_glider *glider = af_arritm( &world->ent_glider, glider_list[j] );
 
       if( !(glider->flags & 0x1) )
          continue;
@@ -1014,7 +1014,7 @@ static void render_other_entities( world_instance *world, vg_camera *cam )
    for( u32 j=0; j<npc_count; j ++ )
    {
       u32 index = npc_list[j];
-      ent_npc *npc = mdl_arritm( &world->ent_npc, npc_list[j] );
+      ent_npc *npc = af_arritm( &world->ent_npc, npc_list[j] );
       npc_update( npc );
       npc_render( npc, world, cam );
    }
@@ -1057,9 +1057,9 @@ void render_world( world_instance *world, vg_camera *cam,
       u32 closest = 0;
       float min_dist = INFINITY;
 
-      if( mdl_arrcount( &world->ent_route ) ){
-         for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
-            ent_route *route = mdl_arritm( &world->ent_route, i );
+      if( af_arrcount( &world->ent_route ) ){
+         for( u32 i=0; i<af_arrcount( &world->ent_route ); i++ ){
+            ent_route *route = af_arritm( &world->ent_route, i );
             float dist = v3_dist2( route->board_transform[3], cam->pos );
 
             if( dist < min_dist ){
@@ -1068,7 +1068,7 @@ void render_world( world_instance *world, vg_camera *cam,
             }
          }
 
-         ent_route *route = mdl_arritm( &world->ent_route, closest );
+         ent_route *route = af_arritm( &world->ent_route, closest );
          sfd_render( world, cam, route->board_transform );
       }
    }
@@ -1280,8 +1280,8 @@ void render_world_cubemaps( world_instance *world )
       world->cubemap_cooldown = 60;
 
       glViewport( 0, 0, WORLD_CUBEMAP_RES, WORLD_CUBEMAP_RES );
-      for( u32 i=0; i<mdl_arrcount( &world->ent_cubemap ); i++ ){
-         ent_cubemap *cm = mdl_arritm( &world->ent_cubemap, i );
+      for( u32 i=0; i<af_arrcount( &world->ent_cubemap ); i++ ){
+         ent_cubemap *cm = af_arritm( &world->ent_cubemap, i );
          glBindFramebuffer( GL_FRAMEBUFFER, cm->framebuffer_id );
 
          world->cubemap_side ++;
index e4fd80e99e2aa790df90b18716f4b2e283e5bdcd..c8d506866c87b878767fd600a9754d5b51592712 100644 (file)
 
 void world_routes_clear( world_instance *world )
 {
-   for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_route ); i++ ){
+      ent_route *route = af_arritm( &world->ent_route, i );
       route->active_checkpoint = 0xffff;
    }
 
-   for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
-      ent_gate *rg = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount( &world->ent_gate ); i++ ){
+      ent_gate *rg = af_arritm( &world->ent_gate, i );
       rg->timing_version = 0;
       rg->timing_time = 0.0;
    }
@@ -43,7 +43,7 @@ void world_routes_clear( world_instance *world )
 
 static void world_routes_time_lap( world_instance *world, ent_route *route ){
    vg_info( "------- time lap %s -------\n", 
-            mdl_pstr(&world->meta,route->pstr_name) );
+            ps_get(&world->meta.strings,route->pstr_name) );
 
    double start_time = 0.0;
    u32 last_version=0;
@@ -57,9 +57,9 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){
       u32 cpid  = (i+route->active_checkpoint) % route->checkpoints_count;
           cpid += route->checkpoints_start;
 
-      ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, cpid );
-      ent_gate *rg = mdl_arritm( &world->ent_gate, cp->gate_index );
-                rg = mdl_arritm( &world->ent_gate, rg->target );
+      ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, cpid );
+      ent_gate *rg = af_arritm( &world->ent_gate, cp->gate_index );
+                rg = af_arritm( &world->ent_gate, rg->target );
 
       if( i == 1 ){
          route->timing_base = rg->timing_time;
@@ -128,7 +128,7 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){
       char mod_uid[ ADDON_UID_MAX ];
       addon_alias_uid( alias, mod_uid );
       network_publish_laptime( mod_uid, 
-                               mdl_pstr( &world->meta, route->pstr_name ),
+                               ps_get( &world->meta.strings, route->pstr_name ),
                                lap_time );
    }
 
@@ -147,10 +147,10 @@ static void world_routes_time_lap( world_instance *world, ent_route *route ){
 void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
 {
    world_static.last_use = world_static.time;
-   ent_gate *dest = mdl_arritm( &world->ent_gate, rg->target );
+   ent_gate *dest = af_arritm( &world->ent_gate, rg->target );
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      ent_route *route = af_arritm( &world->ent_route, i );
 
       u32 active_prev = route->active_checkpoint;
       route->active_checkpoint = 0xffff;
@@ -158,11 +158,11 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
       for( u32 j=0; j<4; j++ ){
          if( dest->routes[j] == i ){
             for( u32 k=0; k<route->checkpoints_count; k++ ){
-               ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, 
+               ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, 
                                                  route->checkpoints_start+k );
 
-               ent_gate *gk = mdl_arritm( &world->ent_gate, cp->gate_index );
-                         gk = mdl_arritm( &world->ent_gate, gk->target );
+               ent_gate *gk = af_arritm( &world->ent_gate, cp->gate_index );
+                         gk = af_arritm( &world->ent_gate, gk->target );
                if( gk == dest ){
                   route->active_checkpoint = k;
                   world_routes_time_lap( world, route );
@@ -190,13 +190,13 @@ void world_routes_activate_entry_gate( world_instance *world, ent_gate *rg )
 /* draw lines along the paths */
 static void world_routes_debug( world_instance *world )
 {
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route_node); i++ ){
-      ent_route_node *rn = mdl_arritm(&world->ent_route_node,i);
+   for( u32 i=0; i<af_arrcount(&world->ent_route_node); i++ ){
+      ent_route_node *rn = af_arritm(&world->ent_route_node,i);
       vg_line_point( rn->co, 0.25f, VG__WHITE );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm(&world->ent_route, i);
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      ent_route *route = af_arritm(&world->ent_route, i);
 
       u32 colours[] = { 0xfff58142, 0xff42cbf5, 0xff42f56c, 0xfff542b3,
                         0xff5442f5 };
@@ -210,20 +210,20 @@ static void world_routes_debug( world_instance *world )
          int i0 = route->checkpoints_start+i,
              i1 = route->checkpoints_start+((i+1)%route->checkpoints_count);
 
-         ent_checkpoint *c0 = mdl_arritm(&world->ent_checkpoint, i0),
-                        *c1 = mdl_arritm(&world->ent_checkpoint, i1);
+         ent_checkpoint *c0 = af_arritm(&world->ent_checkpoint, i0),
+                        *c1 = af_arritm(&world->ent_checkpoint, i1);
 
-         ent_gate *start_gate = mdl_arritm( &world->ent_gate, c0->gate_index );
-         ent_gate *end_gate = mdl_arritm( &world->ent_gate, c1->gate_index );
+         ent_gate *start_gate = af_arritm( &world->ent_gate, c0->gate_index );
+         ent_gate *end_gate = af_arritm( &world->ent_gate, c1->gate_index );
 
          v3f p0, p1;
          v3_copy( start_gate->co[1], p0 );
 
          for( int j=0; j<c0->path_count; j ++ ){
-            ent_path_index *index = mdl_arritm( &world->ent_path_index, 
+            ent_path_index *index = af_arritm( &world->ent_path_index, 
                                                 c0->path_start+j );
 
-            ent_route_node *rn = mdl_arritm( &world->ent_route_node,
+            ent_route_node *rn = af_arritm( &world->ent_route_node,
                                              index->index );
 
             v3_copy( rn->co, p1 );
@@ -357,7 +357,7 @@ void world_routes_place_curve( world_instance *world, ent_route *route,
 static void world_routes_gen_meshes( world_instance *world, u32 route_id, 
                                         scene_context *sc )
 {
-   ent_route *route = mdl_arritm( &world->ent_route, route_id );
+   ent_route *route = af_arritm( &world->ent_route, route_id );
    u8 colour[4];
    colour[0] = route->colour[0] * 255.0f;
    colour[1] = route->colour[1] * 255.0f;
@@ -370,14 +370,14 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id,
       int i0 = route->checkpoints_start+i,
           i1 = route->checkpoints_start+((i+1)%route->checkpoints_count);
 
-      ent_checkpoint *c0 = mdl_arritm(&world->ent_checkpoint, i0),
-                     *c1 = mdl_arritm(&world->ent_checkpoint, i1);
+      ent_checkpoint *c0 = af_arritm(&world->ent_checkpoint, i0),
+                     *c1 = af_arritm(&world->ent_checkpoint, i1);
 
-      ent_gate *start_gate = mdl_arritm( &world->ent_gate, c0->gate_index );
-      start_gate = mdl_arritm( &world->ent_gate, start_gate->target );
+      ent_gate *start_gate = af_arritm( &world->ent_gate, c0->gate_index );
+      start_gate = af_arritm( &world->ent_gate, start_gate->target );
 
-      ent_gate *end_gate = mdl_arritm( &world->ent_gate, c1->gate_index ),
-               *collector = mdl_arritm( &world->ent_gate, end_gate->target );
+      ent_gate *end_gate = af_arritm( &world->ent_gate, c1->gate_index ),
+               *collector = af_arritm( &world->ent_gate, end_gate->target );
 
       v4f p[3];
 
@@ -396,8 +396,8 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id,
       for( int j=0; j<2; j++ ){
          int pi = c0->path_start + ((j==1)? c0->path_count-1: 0);
 
-         ent_path_index *index = mdl_arritm( &world->ent_path_index, pi );
-         ent_route_node *rn = mdl_arritm( &world->ent_route_node,
+         ent_path_index *index = af_arritm( &world->ent_path_index, pi );
+         ent_route_node *rn = af_arritm( &world->ent_route_node,
                                           index->index );
          v3f v0;
          v3_sub( rn->co, both[j]->co[0], v0 );
@@ -410,9 +410,9 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id,
 
 
       for( int j=0; j<c0->path_count; j ++ ){
-         ent_path_index *index = mdl_arritm( &world->ent_path_index, 
+         ent_path_index *index = af_arritm( &world->ent_path_index, 
                                              c0->path_start+j );
-         ent_route_node *rn = mdl_arritm( &world->ent_route_node,
+         ent_route_node *rn = af_arritm( &world->ent_route_node,
                                           index->index );
          if( j==0 || j==c0->path_count-1 )
             if( j == 0 )
@@ -427,9 +427,9 @@ static void world_routes_gen_meshes( world_instance *world, u32 route_id,
          rn->ref_count ++;
 
          if( j+1 < c0->path_count ){
-            index = mdl_arritm( &world->ent_path_index, 
+            index = af_arritm( &world->ent_path_index, 
                                 c0->path_start+j+1 );
-            rn = mdl_arritm( &world->ent_route_node, index->index );
+            rn = af_arritm( &world->ent_route_node, index->index );
 
             if( j+1 == c0->path_count-1 )
                v3_lerp( p[1], temp_alignments[1], 0.5f, p[2] );
@@ -492,46 +492,46 @@ void world_gen_routes_generate( u32 instance_id )
                                                   &world->mesh_route_lines,
                                                   200000, 300000 );
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
       gate->ref_count = 0;
       gate->route_count = 0;
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route_node); i++ ){
-      ent_route_node *rn = mdl_arritm( &world->ent_route_node, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_route_node); i++ ){
+      ent_route_node *rn = af_arritm( &world->ent_route_node, i );
       rn->ref_count = 0;
       rn->ref_total = 0;
    }
 
-   for( u32 k=0; k<mdl_arrcount(&world->ent_route); k++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, k );
+   for( u32 k=0; k<af_arrcount(&world->ent_route); k++ ){
+      ent_route *route = af_arritm( &world->ent_route, k );
 
       for( int i=0; i<route->checkpoints_count; i++ ){
          int i0 = route->checkpoints_start+i,
              i1 = route->checkpoints_start+((i+1)%route->checkpoints_count);
 
-         ent_checkpoint *c0 = mdl_arritm(&world->ent_checkpoint, i0),
-                        *c1 = mdl_arritm(&world->ent_checkpoint, i1);
+         ent_checkpoint *c0 = af_arritm(&world->ent_checkpoint, i0),
+                        *c1 = af_arritm(&world->ent_checkpoint, i1);
 
-         ent_gate *start_gate = mdl_arritm( &world->ent_gate, c0->gate_index );
-         start_gate = mdl_arritm( &world->ent_gate, start_gate->target );
+         ent_gate *start_gate = af_arritm( &world->ent_gate, c0->gate_index );
+         start_gate = af_arritm( &world->ent_gate, start_gate->target );
          start_gate->route_count ++;
 
          if( !c0->path_count )
             continue;
 
          for( int j=0; j<c0->path_count; j ++ ){
-            ent_path_index *index = mdl_arritm( &world->ent_path_index, 
+            ent_path_index *index = af_arritm( &world->ent_path_index, 
                                                 c0->path_start+j );
-            ent_route_node *rn = mdl_arritm( &world->ent_route_node,
+            ent_route_node *rn = af_arritm( &world->ent_route_node,
                                              index->index );
             rn->ref_total ++;
          }
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
       world_routes_gen_meshes( world, i, &world->scene_lines );
    }
 
@@ -544,15 +544,16 @@ void world_gen_routes_ent_init( world_instance *world )
 {
    vg_info( "Initializing routes\n" );
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
       for( u32 j=0; j<4; j++ ){
          gate->routes[j] = 0xffff;
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm(&world->ent_route,i);
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
+   {
+      ent_route *route = af_arritm(&world->ent_route,i);
       mdl_transform_m4x3( &route->anon.transform, route->board_transform );
 
       route->flags = 0x00;
@@ -560,22 +561,24 @@ void world_gen_routes_ent_init( world_instance *world )
       route->ui_stopper = 0.0f;
       route->ui_residual = 0.0f;
       
-      if( mdl_arrcount(&world->ent_region) )
+      if( af_arrcount(&world->ent_region) )
          route->flags |= k_ent_route_flag_out_of_zone;
 
       route->anon.official_track_id = 0xffffffff;
-      for( u32 j=0; j<VG_ARRAY_LEN(track_infos); j ++ ){
+      for( u32 j=0; j<VG_ARRAY_LEN(track_infos); j ++ )
+      {
          if( !strcmp(track_infos[j].name, 
-                     mdl_pstr(&world->meta,route->pstr_name))){
+                     ps_get( &world->meta.strings ,route->pstr_name )))
+         {
             route->anon.official_track_id = j;
          }
       }
 
       for( u32 j=0; j<route->checkpoints_count; j++ ){
          u32 id = route->checkpoints_start + j;
-         ent_checkpoint *cp = mdl_arritm(&world->ent_checkpoint,id);
+         ent_checkpoint *cp = af_arritm(&world->ent_checkpoint,id);
          
-         ent_gate *gate = mdl_arritm( &world->ent_gate, cp->gate_index );
+         ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index );
 
          for( u32 k=0; k<4; k++ ){
             if( gate->routes[k] == 0xffff ){
@@ -586,7 +589,7 @@ void world_gen_routes_ent_init( world_instance *world )
 
          if( (gate->flags & k_ent_gate_linked) &
             !(gate->flags & k_ent_gate_nonlocal) ){
-            gate = mdl_arritm(&world->ent_gate, gate->target );
+            gate = af_arritm(&world->ent_gate, gate->target );
 
             for( u32 k=0; k<4; k++ ){
                if( gate->routes[k] == i ){
@@ -602,12 +605,12 @@ void world_gen_routes_ent_init( world_instance *world )
       }
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_gate); i++ ){
+      ent_gate *gate = af_arritm( &world->ent_gate, i );
    }
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_checkpoint); i++ ){
-      ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_checkpoint); i++ ){
+      ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, i );
       cp->best_time = 0.0;
    }
 
@@ -618,7 +621,7 @@ void world_routes_recv_scoreboard( world_instance *world,
                                    vg_msg *body, u32 route_id,
                                    enum request_status status )
 {
-   if( route_id >= mdl_arrcount( &world->ent_route ) ){
+   if( route_id >= af_arrcount( &world->ent_route ) ){
       vg_error( "Scoreboard route_id out of range (%u)\n", route_id );
       return;
    }
@@ -658,8 +661,8 @@ void world_routes_update( world_instance *world )
 {
    world_static.time += vg.time_delta;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      ent_route *route = af_arritm( &world->ent_route, i );
       
       int target = route->active_checkpoint == 0xffff? 0: 1;
       route->factive = vg_lerpf( route->factive, target, 
@@ -734,17 +737,17 @@ void world_routes_update_timer_texts( world_instance *world )
 {
    world_render.timer_text_count = 0;
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      ent_route *route = af_arritm( &world->ent_route, i );
 
       if( route->active_checkpoint != 0xffff ){
          u32 next = route->active_checkpoint+1;
              next = next % route->checkpoints_count;
              next += route->checkpoints_start;
 
-         ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, next );
-         ent_gate *gate = mdl_arritm( &world->ent_gate, cp->gate_index );
-         ent_gate *dest = mdl_arritm( &world->ent_gate, gate->target );
+         ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, next );
+         ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index );
+         ent_gate *dest = af_arritm( &world->ent_gate, gate->target );
          
          u32 j=0;
          for( ; j<4; j++ ){
@@ -972,8 +975,8 @@ void render_world_routes( world_instance *world,
 
    mesh_bind( &world->mesh_route_lines );
 
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-      ent_route *route = mdl_arritm( &world->ent_route, i );
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+      ent_route *route = af_arritm( &world->ent_route, i );
 
       f32 t = viewing_from_hub? 1.0f: route->factive;
 
@@ -1046,8 +1049,8 @@ void render_world_routes( world_instance *world,
    glDisable( GL_CULL_FACE );
 
    if( viewing_from_hub ){
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+         ent_route *route = af_arritm( &world->ent_route, i );
 
          v4f colour;
          v3_muls( route->colour, 1.6666f, colour );
@@ -1055,16 +1058,16 @@ void render_world_routes( world_instance *world,
 
          shader_model_gate_uColour( colour );
 
-         for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
-            ent_gate *gate = mdl_arritm( &world->ent_gate, j );
+         for( u32 j=0; j<af_arrcount(&world->ent_gate); j ++ ){
+            ent_gate *gate = af_arritm( &world->ent_gate, j );
             if( !(gate->flags & k_ent_gate_nonlocal) )
                render_gate_markers( mmdl, i, gate );
          }
       }
    }
    else{
-      for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+      for( u32 i=0; i<af_arrcount(&world->ent_route); i++ ){
+         ent_route *route = af_arritm( &world->ent_route, i );
 
          if( route->active_checkpoint != 0xffff ){
             v4f colour;
@@ -1078,8 +1081,8 @@ void render_world_routes( world_instance *world,
                 next = next % route->checkpoints_count;
                 next += route->checkpoints_start;
 
-            ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, next );
-            ent_gate *gate = mdl_arritm( &world->ent_gate, cp->gate_index );
+            ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, next );
+            ent_gate *gate = af_arritm( &world->ent_gate, cp->gate_index );
             render_gate_markers( mmdl, i, gate );
          }
       }
index 0afbeae9abd8154a1b405afe17f32dce9bc01519..a85ca624fd383ac803b49f2875b3312e55128a2e 100644 (file)
@@ -35,9 +35,9 @@ static void ent_route_imgui( ui_context *ctx,
           cpid %= route->checkpoints_count;
           cpid += route->checkpoints_start;
 
-      ent_checkpoint *cp = mdl_arritm( &world->ent_checkpoint, cpid );
-      ent_gate *rg = mdl_arritm( &world->ent_gate, cp->gate_index );
-                rg = mdl_arritm( &world->ent_gate, rg->target );
+      ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, cpid );
+      ent_gate *rg = af_arritm( &world->ent_gate, cp->gate_index );
+                rg = af_arritm( &world->ent_gate, rg->target );
 
       if( last_version+1 == rg->timing_version ) {
          struct time_block *block = &blocks[ valid_sections ++ ];
@@ -161,8 +161,8 @@ void world_routes_imgui( ui_context *ctx, world_instance *world )
    if( skaterift.activity == k_skaterift_menu ) return;
 
    ui_point cursor = { 4, 4 };
-   for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ )
+   for( u32 i=0; i<af_arrcount(&world->ent_route); i++ )
    {
-      ent_route_imgui( ctx, world, mdl_arritm( &world->ent_route, i ), cursor );
+      ent_route_imgui( ctx, world, af_arritm( &world->ent_route, i ), cursor );
    }
 }
index 6473d63b3404b24f3699a789d9d9ffcd171afbf7..6d406770050b929eee1942054004a45e3a108d9e 100644 (file)
@@ -180,11 +180,11 @@ void world_sfd_compile_active_scores(void)
    struct leaderboard_cache *board = NULL;
    const char *name = "Out of range";
 
-   if( world_sfd.active_route_board < mdl_arrcount( &world->ent_route ) ){
+   if( world_sfd.active_route_board < af_arrcount( &world->ent_route ) ){
       board = &world->leaderboard_cache[ world_sfd.active_route_board ];
-      ent_route *route = mdl_arritm( &world->ent_route, 
+      ent_route *route = af_arritm( &world->ent_route, 
                                      world_sfd.active_route_board );
-      name = mdl_pstr( &world->meta, route->pstr_name );
+      name = ps_get( &world->meta.strings, route->pstr_name );
    }
          
    world_sfd_compile_scores( board, name );
@@ -192,12 +192,12 @@ void world_sfd_compile_active_scores(void)
 
 void world_sfd_update( world_instance *world, v3f pos )
 {
-   if( mdl_arrcount( &world->ent_route ) ){
+   if( af_arrcount( &world->ent_route ) ){
       u32 closest = 0;
       float min_dist = INFINITY;
 
-      for( u32 i=0; i<mdl_arrcount( &world->ent_route ); i++ ){
-         ent_route *route = mdl_arritm( &world->ent_route, i );
+      for( u32 i=0; i<af_arrcount( &world->ent_route ); i++ ){
+         ent_route *route = af_arritm( &world->ent_route, i );
          float dist = v3_dist2( route->board_transform[3], pos );
 
          if( dist < min_dist ){
@@ -213,7 +213,7 @@ void world_sfd_update( world_instance *world, v3f pos )
          f64 delta = vg.time_real - board->cache_time;
          if( (delta > 45.0) || (board->cache_time == 0.0) ){
             board->cache_time = vg.time_real;
-            ent_route *route = mdl_arritm( &world->ent_route, closest );
+            ent_route *route = af_arritm( &world->ent_route, closest );
             addon_reg *world_reg = 
                world_static.instance_addons[ world - world_static.instances ];
 
@@ -222,7 +222,7 @@ void world_sfd_update( world_instance *world, v3f pos )
 
             network_request_scoreboard( 
                   mod_uid, 
-                  mdl_pstr( &world->meta, route->pstr_name ),
+                  ps_get( &world->meta.strings, route->pstr_name ),
                   NETWORK_LEADERBOARD_ALLTIME_AND_CURRENT_WEEK, closest );
          }
       }
@@ -321,8 +321,8 @@ void world_sfd_init(void)
             *m_card   = mdl_find_mesh( &mscoreboard, "score_card" );
 
    mdl_submesh 
-      *sm_backer = mdl_arritm( &mscoreboard.submeshs, m_backer->submesh_start ),
-      *sm_card   = mdl_arritm( &mscoreboard.submeshs, m_card->submesh_start );
+      *sm_backer = af_arritm( &mscoreboard.submeshs, m_backer->submesh_start ),
+      *sm_card   = af_arritm( &mscoreboard.submeshs, m_card->submesh_start );
    world_sfd.sm_base = *sm_backer;
 
    m4x3f identity;
index b74e4932daa2c0e295e62f63c3a91a6d999f49d2..ceb154182e9129485ae6b706e6a67fb51141ff6b 100644 (file)
@@ -6,7 +6,7 @@ void world_volumes_update( world_instance *world, v3f pos )
    u32 j=0;
    for( u32 i=0; i<world_static.active_trigger_volume_count; i++ ){
       i32 idx = world_static.active_trigger_volumes[i];
-      ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
+      ent_volume *volume = af_arritm( &world->ent_volume, idx );
 
       v3f local;
       m4x3_mulv( volume->to_local, pos, local );
@@ -57,7 +57,7 @@ void world_volumes_update( world_instance *world, v3f pos )
 
       if( type != k_ent_volume ) continue;
 
-      ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+      ent_volume *volume = af_arritm( &world->ent_volume, index );
       boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
       
       if( volume->flags & k_ent_volume_flag_particles ){