#include "vg/vg_m.h"
#include "src/model.h"
#include "src/model.c"
+#include "src/array_file.c"
/*
* Addon metadata utilities
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 );
--- /dev/null
+**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>
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()
--- /dev/null
+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()
+#}
('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',\
_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):
("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):
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
#}
# 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
#
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 )
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
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 )
#}
#}
# Add submesh to encoder
#
- sr_compile.submesh_data.extend( bytearray(sm) )
+ sr_compile.submeshes.append( sm )
submesh_count += 1
#}
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 ):
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]
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]
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 )
#}
#}
#}
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]
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]
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)
#}
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):
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)" )
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
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 )
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
#}
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' )
#}
#{
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),
],
)
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'}
#}
#}
#}
+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"
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
+ #}
#}
#}
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: #{
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" )
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, \
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()
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
#}
--- /dev/null
+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
+#}
--- /dev/null
+#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;
+ }
+}
--- /dev/null
+#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 ) )
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 );
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)
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
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;
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 )
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 );
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();
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 );
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 )
{
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 );
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;
}
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;
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 )
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,
}
}
- 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 );
#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;
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 );
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 );
void npc_init(void)
{
+#if 0
npc_load_model( &npc_gumpa, "models/gumpa.mdl" );
gumpa_idle = skeleton_get_anim( &npc_gumpa.skeleton, "gumpa_idle" );
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 )
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 )
{
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 )
{
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 );
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);
}
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;
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 )
{
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 );
}
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;
}
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;
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 );
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 );
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 )
{
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() */
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;
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};
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 );
}
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 );
}
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;
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? */
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 );
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 );
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){
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;
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 )
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) ||
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 );
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;
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 );
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,
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] );
}
}
-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;
}
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{
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;
}
}
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,
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 );
}
}
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,
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;
}
}
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 );
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;
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 |
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 );
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");
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 );
}
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 )
--- /dev/null
+#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 );
+}
--- /dev/null
+#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 );
#include <errno.h>
#include "model.h"
#include "shader_props.h"
+#include "array_file.h"
static void mdl_load_fatal_corrupt( mdl_context *mdl )
{
{
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();
}
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 )
vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse,
NULL );
-
return props;
}
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 );
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)
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
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;
}
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
* ----------------------------------------------------------------------------
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;
}
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
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 )
{
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 )
* ---------------------------------------------------------
*/
- 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++ )
{
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 );
#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,
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;
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;
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,
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
FILE *file;
mdl_header info;
- struct mdl_array_ptr
- {
- void *data;
- u32 count, stride;
- }
- index,
+ struct array_file_ptr index,
/* metadata */
strings,
textures,
armatures,
bones,
- animations,
-
- /* animation buffers */
- keyframes,
/* mesh buffers */
verts,
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 );
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 );
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;
* Rendering
*/
mdl_context skeleton_meta;
+ ms_context animations;
struct skeleton skeleton;
u8 id_hip,
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 );
#pragma once
#include "model.h"
+#include "metascene.h"
typedef struct player_instance player_instance;
typedef struct player_pose player_pose;
v3f root_co;
v4f root_q;
- mdl_keyframe keyframes[32];
+ ms_keyframe keyframes[32];
struct player_board_pose {
f32 lean;
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" );
}
}
animator;
- struct skeleton_anim *anim_bail;
+ skeleton_anim anim_bail;
}
extern player_dead;
extern struct player_subsystem_interface player_subsystem_dead;
{
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 );
}
{
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" );
}
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;
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 );
/* 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;
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 ++ ] );
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 );
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" );
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 )
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;
}
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 );
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 ],
struct player_glide
{
- struct skeleton_anim *anim_glide;
+ struct skeleton_anim anim_glide;
struct player_glide_animator
{
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 ++ ){
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 );
#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;
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" );
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 );
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++ )
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;
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;
}
m4x3f mlocal;
m3x3_identity( mlocal );
- mdl_keyframe kf;
+ ms_keyframe kf;
v3_zero( kf.co );
q_identity( kf.q );
v3_zero( kf.s );
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 */
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 );
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" },
};
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){
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,
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] );
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 );
/* 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),
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],
&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,
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] );
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) );
#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],
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 );
/* 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];
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;
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 );
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 */
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;
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 );
}
}
-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,
}
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 )
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;
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;
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;
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 )
}
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 ){
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 );
}
}
[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 ){
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;
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 */
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" );
#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"
u32 flags;
int defer;
- mdl_keyframe kf;
+ ms_keyframe kf;
mdl_bone *orig_bone;
u32 collider;
*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;
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++ ){
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++ )
/* 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;
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 );
/*
* 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;
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 );
}
/*
* 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
/*
* 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];
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];
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] );
* 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 );
}
}
/*
* 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 */
* 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 );
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 ++;
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();
}
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 );
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
{
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;
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;
u32 surface_count;
ent_worldinfo info;
- mdl_array_ptr ent_spawn,
+ array_file_ptr ent_spawn,
ent_gate,
ent_light,
ent_route_node,
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
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 ){}
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 );
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;
}
}
/* 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;
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;
u32 indexed_count = 0;
struct {
u32 type;
- mdl_array_ptr *array;
+ array_file_ptr *array;
}
indexables[] = {
{ k_ent_gate, &world->ent_gate },
};
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 );
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];
}
}
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 ){
}
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" );
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;
}
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;
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;
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 ],
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
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 */
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 );
}
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}};
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,
}
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{
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
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 );
}
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}};
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;
}
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{
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;
/* 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 );
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,
}
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];
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(
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",
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;
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",
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;
}
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 );
}
*/
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;
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() */
{
*/
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 )
{
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 )
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++ ){
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;
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 );
* 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;
}
/* 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 );
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 );
/* 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 );
*/
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] );
/*
* 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 );
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 )
{
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 )
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;
}
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 );
}
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();
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 );
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 );
/* 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 )
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;
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 );
}
}
- 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 );
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 };
{
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;
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,
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,
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 );
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 )
!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);
}
}
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;
}
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;
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 )
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 ++;
}
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;
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 );
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 )
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 )
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) )
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));
}
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;
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 );
}
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 ){
}
}
- 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 );
}
}
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 ++;
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;
}
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;
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;
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 );
}
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;
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 );
/* 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 };
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 );
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;
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];
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 );
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 )
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] );
&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 );
}
{
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;
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 ){
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 ){
}
}
- 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;
}
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;
}
{
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,
{
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++ ){
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;
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 );
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;
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 );
}
}
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 ++ ];
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 );
}
}
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 );
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 ){
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 ];
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 );
}
}
*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;
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 );
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 ){