From: hgn Date: Sat, 1 Apr 2023 02:51:55 +0000 (+0100) Subject: entities zones X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=4b8aac300ee193cfa12011dfe0238cfe7d7ffce7;hp=0a33f65eecb5e75cddaefa08d3a5eb1a301d0479;p=carveJwlIkooP6JGAAIwe30JlM.git entities zones --- diff --git a/blender_export.py b/blender_export.py index 07179e7..a367cc1 100644 --- a/blender_export.py +++ b/blender_export.py @@ -16,6 +16,16 @@ bl_info = { "category":"Import/Export", } +sr_entity_alias = { + 'ent_gate': 1, + 'ent_spawn': 2, + 'ent_route_node': 3, + 'ent_route': 4, + 'ent_water': 5, + 'ent_volume': 6, + 'ent_audio': 7 +} + class mdl_vert(Structure): # 48 bytes. Quite large. Could compress #{ # the normals and uvs to i16s. Not an _pack_ = 1 # real issue, yet. @@ -175,6 +185,26 @@ class ent_path_index(Structure): _fields_ = [("index",c_uint16)] #} +class vg_audio_clip(Structure): +#{ + _fields_ = [("path",c_uint64), + ("flags",c_uint32), + ("size",c_uint32), + ("data",c_uint64)] +#} + +class union_file_audio_clip(Union): +#{ + _fields_ = [("file",mdl_file), + ("reserved",vg_audio_clip)] +#} + +class ent_audio_clip(Structure): +#{ + _fields_ = [("_anon",union_file_audio_clip), + ("probability",c_float)] +#} + class ent_checkpoint(Structure): #{ _fields_ = [("gate_index",c_uint16), @@ -182,7 +212,7 @@ class ent_checkpoint(Structure): ("path_count",c_uint16)] #} -class ent_route(Structure): +class ent_route(Structure): #{ _fields_ = [("transform",mdl_transform), ("pstr_name",c_uint32), @@ -204,6 +234,54 @@ class ent_water(Structure): ("reserved1",c_uint32)] #} +class volume_trigger(Structure): +#{ + _fields_ = [("event",c_uint32), + ("blank",c_uint32)] +#} + +class volume_particles(Structure): +#{ + _fields_ = [("blank",c_uint32), + ("blank2",c_uint32)] +#} + +class volume_union(Union): +#{ + _fields_ = [("trigger",volume_trigger), + ("particles",volume_particles)] +#} + +class ent_index(Structure): +#{ + _fields_ = [("type",c_uint32), + ("index",c_uint32)] +#} + +class ent_volume(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("to_world",(c_float*3)*4), + ("to_local",(c_float*3)*4), + ("type",c_uint32), + ("target",ent_index), + ("_anon",volume_union)] +#} + +class ent_audio(Structure): +#{ + _fields_ = [("transform",mdl_transform), + ("flags",c_uint32), + ("clip_start",c_uint32), + ("clip_count",c_uint32), + ("volume",c_float), + ("crossfade",c_float), + ("channel_behaviour",c_uint32), + ("group",c_uint32), + ("probability_curve",c_uint32), + ("max_channels",c_uint32)] +#} + def obj_ent_type( obj ): #{ if obj.type == 'ARMATURE': return 'mdl_armature' @@ -211,14 +289,14 @@ def obj_ent_type( obj ): else: return obj.SR_data.ent_type #} -def sr_filter_ent_type( obj, ent_type ): +def sr_filter_ent_type( obj, ent_types ): #{ if obj == bpy.context.active_object: return False for c0 in obj.users_collection:#{ for c1 in bpy.context.active_object.users_collection:#{ if c0 == c1:#{ - return ent_type == obj_ent_type( obj ) + return obj_ent_type( obj ) in ent_types #} #} #} @@ -393,6 +471,17 @@ def material_info(mat): return info #} +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 ) @@ -1010,6 +1099,7 @@ def sr_compile( collection ): checkpoint_count = 0 pathindice_count = 0 + audio_clip_count = 0 for ent_type, arr in sr_compile.entities.items():#{ print(F"[SR] Compiling {len(arr)} {ent_type}{'s' if len(arr)>1 else ''}") @@ -1153,6 +1243,58 @@ def sr_compile( collection ): water.max_dist = 0.0 sr_ent_push( water ) #} + elif ent_type == 'ent_audio':#{ + obj_data = obj.SR_data.ent_audio[0] + audio = ent_audio() + compile_obj_transform( obj, audio.transform ) + audio.clip_start = audio_clip_count + audio.clip_count = len(obj_data.files) + audio.max_channels = obj_data.max_channels + audio.volume = obj_data.volume + + # TODO flags: + # - allow/disable doppler + # - channel group tags with random colours + # - transition properties + + if obj_data.flag_loop: audio.flags |= 0x1 + if obj_data.flag_nodoppler: audio.flags |= 0x2 + if obj_data.flag_3d: audio.flags |= 0x4 + if obj_data.flag_auto: audio.flags |= 0x8 + if obj_data.formato == '0': audio.flags |= 0x000 + elif obj_data.formato == '1': audio.flags |= 0x400 + elif obj_data.formato == '2': audio.flags |= 0x1000 + + for ci in range(audio.clip_count):#{ + entry = obj_data.files[ci] + clip = ent_audio_clip() + clip.probability = entry.probability + if obj_data.formato == '2':#{ + sr_pack_file( clip._anon.file, '', vg_str_bin(entry.path) ) + #} + else:#{ + clip._anon.file.path = sr_compile_string( entry.path ) + clip._anon.file.pack_offset = 0 + clip._anon.file.pack_size = 0 + #} + sr_ent_push( clip ) + #} + sr_ent_push( audio ) + #} + elif ent_type == 'ent_volume':#{ + obj_data = obj.SR_data.ent_volume[0] + volume = ent_volume() + volume.type = int(obj_data.subtype) + compile_obj_transform( obj, volume.transform ) + + if obj_data.target:#{ + target = obj_data.target + volume.target.type = sr_entity_alias[obj_ent_type(target)] + volume.target.index = sr_compile.entity_ids[ target.name ] + #} + + sr_ent_push(volume) + #} #} #} @@ -1567,7 +1709,7 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup): #{ target: bpy.props.PointerProperty( \ type=bpy.types.Object, name="destination", \ - poll=lambda self,obj: sr_filter_ent_type(obj,'ent_gate')) + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_gate'])) #} class SR_MESH_ENT_GATE(bpy.types.PropertyGroup): @@ -1579,7 +1721,7 @@ class SR_OBJECT_ENT_ROUTE_ENTRY(bpy.types.PropertyGroup): #{ target: bpy.props.PointerProperty( \ type=bpy.types.Object, name='target', \ - poll=lambda self,obj: sr_filter_ent_type(obj,'ent_gate')) + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_gate'])) #} class SR_UL_ROUTE_NODE_LIST(bpy.types.UIList): @@ -1612,7 +1754,7 @@ class SR_OT_ROUTE_LIST_DEL_ITEM(bpy.types.Operator): @classmethod def poll(cls, context):#{ active_object = context.active_object - if obj_ent_type == 'ent_gate':#{ + if obj_ent_type(active_object) == 'ent_gate':#{ return active_object.SR_data.ent_route[0].gates #} else: return False @@ -1629,6 +1771,64 @@ class SR_OT_ROUTE_LIST_DEL_ITEM(bpy.types.Operator): #} #} +class SR_OT_AUDIO_LIST_NEW_ITEM(bpy.types.Operator): +#{ + bl_idname = "skaterift.al_new_entry" + bl_label = "Add file" + + def execute(self, context):#{ + active_object = context.active_object + active_object.SR_data.ent_audio[0].files.add() + return{'FINISHED'} + #} +#} + +class SR_OT_AUDIO_LIST_DEL_ITEM(bpy.types.Operator): +#{ + bl_idname = "skaterift.al_del_entry" + bl_label = "Remove file" + + @classmethod + def poll(cls, context):#{ + active_object = context.active_object + if obj_ent_type(active_object) == 'ent_audio':#{ + return active_object.SR_data.ent_audio[0].files + #} + else: return False + #} + + def execute(self, context):#{ + active_object = context.active_object + lista = active_object.SR_data.ent_audio[0].files + index = active_object.SR_data.ent_audio[0].file_index + lista.remove(index) + active_object.SR_data.ent_audio[0].file_index = \ + min(max(0, index-1), len(lista) - 1) + return{'FINISHED'} + #} +#} + +class SR_OBJECT_ENT_AUDIO_FILE_ENTRY(bpy.types.PropertyGroup): +#{ + path: bpy.props.StringProperty( name="Path" ) + probability: bpy.props.FloatProperty( name="Probability",default=100.0 ) +#} + +class SR_UL_AUDIO_LIST(bpy.types.UIList): +#{ + bl_idname = 'SR_UL_AUDIO_LIST' + + def draw_item(_,context,layout,data,item,icon,active_data,active_propname): + #{ + split = layout.split(factor=0.7) + c = split.column() + c.prop( item, 'path', text='', emboss=False ) + c = split.column() + c.prop( item, 'probability', text='%', emboss=True ) + #} +#} + + class SR_OBJECT_ENT_ROUTE(bpy.types.PropertyGroup): #{ gates: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_ROUTE_ENTRY) @@ -1662,11 +1862,107 @@ class SR_OBJECT_ENT_ROUTE(bpy.types.PropertyGroup): #} #} +class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup): +#{ + subtype: bpy.props.EnumProperty( + name="Subtype", + items=[('0','Trigger',''), + ('1','Particles (0.1s)','')] + ) + + target: bpy.props.PointerProperty( \ + type=bpy.types.Object, name="Target", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_audio'])) + + @staticmethod + def sr_inspector( layout, data ): + #{ + data = data[0] + layout.prop( data, 'subtype' ) + layout.prop( data, 'target' ) + #} +#} + +class SR_OBJECT_ENT_AUDIO(bpy.types.PropertyGroup): +#{ + files: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_AUDIO_FILE_ENTRY) + file_index: bpy.props.IntProperty() + + flag_3d: bpy.props.BoolProperty( name="3D audio",default=True ) + flag_loop: bpy.props.BoolProperty( name="Loop",default=False ) + flag_auto: bpy.props.BoolProperty( name="Play at start",default=False ) + flag_nodoppler: bpy.props.BoolProperty( name="No Doppler",default=False ) + formato: bpy.props.EnumProperty( + name="Format", + items=[('0','Uncompressed Mono',''), + ('1','Compressed Vorbis',''), + ('2','[vg] Bird Synthesis','')] + ) + probability_curve: bpy.props.EnumProperty( + name="Probability Curve", + items=[('0','Constant',''), + ('1','Wildlife Daytime',''), + ('2','Wildlife Nighttime','')]) + channel_behaviour: bpy.props.EnumProperty( + name="Channel Behaviour", + items=[('0','Unlimited',''), + ('1','Discard if group full', ''), + ('2','Crossfade if group full','')]) + + transition_duration: bpy.props.FloatProperty(name="Transition Time",\ + default=0.2) + + max_channels: bpy.props.IntProperty( name="Max Channels", default=1 ) + volume: bpy.props.FloatProperty( name="Volume",default=1.0 ) + + @staticmethod + def sr_inspector( layout, data ): + #{ + layout.prop( data[0], 'formato' ) + layout.prop( data[0], 'volume' ) + + box = layout.box() + box.label( text='Channels' ) + split = box.split(factor=0.3) + c = split.column() + c.prop( data[0], 'max_channels' ) + c = split.column() + c.prop( data[0], 'channel_behaviour', text='Behaviour' ) + if data[0].channel_behaviour == '2': + box.prop( data[0], 'transition_duration' ) + + box = layout.box() + box.label( text='Flags' ) + box.prop( data[0], 'flag_3d' ) + if data[0].flag_3d: box.prop( data[0], 'flag_nodoppler' ) + + box.prop( data[0], 'flag_loop' ) + box.prop( data[0], 'flag_auto' ) + + split = layout.split(factor=0.7) + c = split.column() + c.label( text='Filepath' ) + c = split.column() + c.label( text='Chance (0.1s)' ) + + layout.prop( data[0], 'probability_curve' ) + + layout.template_list('SR_UL_AUDIO_LIST', 'Files', \ + data[0], 'files', data[0], 'file_index', rows=5) + + row = layout.row() + row.operator( 'skaterift.al_new_entry', text='Add' ) + row.operator( 'skaterift.al_del_entry', text='Remove' ) + #} +#} + class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): #{ ent_gate: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GATE) ent_spawn: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_SPAWN) ent_route: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_ROUTE) + ent_volume: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_VOLUME) + ent_audio: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_AUDIO) ent_type: bpy.props.EnumProperty( name="Type", @@ -1675,7 +1971,9 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ('ent_spawn','Spawn','', 2), ('ent_route_node', 'Route Node', '', 3 ), ('ent_route', 'Route', '', 4), - ('ent_water', 'Water Surface', '', 5)], + ('ent_water', 'Water Surface', '', 5), + ('ent_volume', 'Volume', '', 6 ), + ('ent_audio', 'Audio Files', '', 7)], update=sr_on_type_change ) #} @@ -2295,6 +2593,28 @@ def cv_ent_gate( obj ): cv_draw_arrow( obj.location, data.target.location, sw ) #} +def cv_ent_volume( obj ): +#{ + global cv_view_verts, cv_view_colours + + data = obj.SR_data.ent_volume[0] + + if data.subtype == '0':#{ + cv_draw_ucube( obj.matrix_world, (0,1,0) ) + + if data.target:#{ + cv_draw_line( obj.location, data.target.location, (0,1,0) ) + #} + #} + elif data.subtype == '1':#{ + cv_draw_ucube( obj.matrix_world, (1,1,0) ) + + if data.target:#{ + cv_draw_line( obj.location, data.target.location, (1,1,0) ) + #} + #} +#} + def dijkstra( graph, start_node, target_node ): #{ unvisited = [_ for _ in graph] @@ -2464,6 +2784,12 @@ def cv_draw(): route_nodes += [obj] elif ent_type == 'ent_route': routes += [obj] + elif ent_type == 'ent_volume':#{ + cv_ent_volume( obj ) + #} + elif ent_type == 'ent_audio':#{ + cv_draw_sphere( obj.location, obj.scale[0], (1,1,0) ) + #} #} #} @@ -2482,8 +2808,12 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ \ SR_OBJECT_ENT_GATE, SR_MESH_ENT_GATE, SR_OBJECT_ENT_SPAWN, \ SR_OBJECT_ENT_ROUTE_ENTRY, SR_UL_ROUTE_NODE_LIST, \ - SR_OBJECT_ENT_ROUTE, SR_OT_ROUTE_LIST_NEW_ITEM, + SR_OBJECT_ENT_ROUTE, SR_OT_ROUTE_LIST_NEW_ITEM,\ + SR_OT_AUDIO_LIST_NEW_ITEM,SR_OT_AUDIO_LIST_DEL_ITEM,\ + SR_OBJECT_ENT_VOLUME, + SR_UL_AUDIO_LIST, SR_OBJECT_ENT_AUDIO_FILE_ENTRY,\ SR_OT_ROUTE_LIST_DEL_ITEM,\ + SR_OBJECT_ENT_AUDIO,\ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \ diff --git a/entity.h b/entity.h index 2c70b82..490737d 100644 --- a/entity.h +++ b/entity.h @@ -11,6 +11,32 @@ typedef struct ent_path_index ent_path_index; typedef struct ent_checkpoint ent_checkpoint; typedef struct ent_route ent_route; typedef struct ent_water ent_water; +typedef struct ent_audio_clip ent_audio_clip; +typedef struct volume_particles volume_particles; +typedef struct volume_trigger volume_trigger; +typedef struct ent_volume ent_volume; +typedef struct ent_audio ent_audio; +typedef struct ent_index ent_index; + +enum entity_alias{ + k_ent_gate = 1, + k_ent_spawn = 2, + k_ent_route_node = 3, + k_ent_route = 4, + k_ent_water = 5, + k_ent_volume = 6, + k_ent_audio = 7 +}; + +struct ent_index{ + u32 type, + index; +}; + +enum entity_function{ + k_ent_function_trigger, + k_ent_function_particle_spawn +}; struct ent_spawn{ mdl_transform transform; @@ -109,4 +135,51 @@ struct ent_water{ u32 reserved0, reserved1; }; +struct ent_audio_clip{ + union{ + mdl_file file; + audio_clip clip; + }; + + float probability; +}; + +struct volume_particles{ + u32 blank, blank2; +}; + +struct volume_trigger{ + u32 event, blank; +}; + +enum volume_subtype{ + k_volume_subtype_trigger, + k_volume_subtype_particle +}; + +struct ent_volume{ + mdl_transform transform; + m4x3f to_world, to_local; + u32 type; + + ent_index target; + + union{ + volume_trigger trigger; + volume_particles particles; + }; +}; + +struct ent_audio{ + mdl_transform transform; + u32 flags, + clip_start, + clip_count; + float volume, crossfade; + u32 channel_behaviour, + group, + probability_curve, + max_channels; +}; + #endif /* ENTITY_H */ diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index 726aaa8..ceb3721 100644 Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ diff --git a/player_skate.c b/player_skate.c index bfccb61..0362386 100644 --- a/player_skate.c +++ b/player_skate.c @@ -1198,11 +1198,17 @@ VG_STATIC void player__skate_post_update( player_instance *player ) const u32 flags = AUDIO_FLAG_SPACIAL_3D|AUDIO_FLAG_LOOP; - if( !s->aud_air ) - s->aud_air = audio_request_channel( &audio_board[1], flags ); + if( !s->aud_air ){ + s->aud_air = audio_get_first_idle_channel(); + if( s->aud_air ) + audio_channel_init( s->aud_air, &audio_board[1], flags ); + } - if( !s->aud_slide ) - s->aud_slide = audio_request_channel( &audio_board[2], flags ); + if( !s->aud_slide ){ + s->aud_slide = audio_get_first_idle_channel(); + if( s->aud_slide ) + audio_channel_init( s->aud_slide, &audio_board[2], flags ); + } /* brrrrrrrrrrrt sound for tiles and stuff diff --git a/world.h b/world.h index 80bf3b6..08d3ca0 100644 --- a/world.h +++ b/world.h @@ -155,7 +155,11 @@ struct world_instance ent_path_index, ent_checkpoint, ent_route, - ent_water; + ent_water, + + ent_audio_clip, + ent_audio, + ent_volume; ent_gate *rendering_gate; @@ -466,6 +470,78 @@ VG_STATIC void world_init(void) VG_MEMORY_SYSTEM ); } +typedef struct ent_call ent_call; +struct ent_call{ + ent_index ent; + u32 function; + void *data; +}; + +VG_STATIC void entity_call( world_instance *world, ent_call *call ); + +VG_STATIC void ent_volume_call( world_instance *world, ent_call *call ) +{ + ent_volume *volume = mdl_arritm( &world->ent_volume, call->ent.index ); + if( !volume->target.type ) return; + + if( call->function == k_ent_function_trigger ){ + call->ent = volume->target; + + if( volume->type == k_volume_subtype_particle ){ + v3f co; + co[0] = vg_randf()*2.0f-1.0f; + co[1] = vg_randf()*2.0f-1.0f; + co[2] = vg_randf()*2.0f-1.0f; + m4x3_mulv( volume->to_world, co, co ); + + call->function = k_ent_function_particle_spawn; + call->data = co; + + entity_call( world, call ); + } + else if( volume->type == k_volume_subtype_trigger ){ + /* TODO */ + } + } +} + +VG_STATIC void ent_audio_call( world_instance *world, ent_call *call ) +{ + ent_audio *audio = mdl_arritm( &world->ent_audio, call->ent.index ); + + if( call->function == k_ent_function_particle_spawn ){ + float chance = vg_randf()*100.0f, + bar = 0.0f; + + for( u32 i=0; iclip_count; i++ ){ + ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip, + audio->clip_start+i ); + + bar += clip->probability; + + if( chance < bar ){ + float *pos = call->data; + + audio_lock(); + audio_oneshot_3d( &clip->clip, pos, + audio->transform.s[0], + audio->volume ); + audio_unlock(); + break; + } + } + } +} + +VG_STATIC void entity_call( world_instance *world, ent_call *call ) +{ + if( call->ent.type == k_ent_volume ){ + ent_volume_call( world, call ); + } else if( call->ent.type == k_ent_audio ){ + ent_audio_call( world, call ); + } +} + VG_STATIC void world_update( world_instance *world, v3f pos ) { /* TEMP!!!!!! */ @@ -549,8 +625,7 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) } sfd_update(); -#if 0 - /* TODO: Bvh */ + static float random_accum = 0.0f; random_accum += vg.time_delta; @@ -573,69 +648,48 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) int in_volume = 0; - while( bh_next( world->volume_bh, &it, volume_proximity, &idx ) ) - { - struct world_volume *zone = &world->volumes[idx]; + while( bh_next( world->volume_bh, &it, volume_proximity, &idx ) ){ + ent_volume *volume = mdl_arritm( &world->ent_volume, idx ); - if( zone->node->classtype == k_classtype_volume_audio ) - { - vg_line_boxf_transformed( zone->transform, (boxf){{-1.0f,-1.0f,-1.0f}, - { 1.0f, 1.0f, 1.0f}}, - 0xff00c0ff ); -#if 0 - for( int j=0; jtype == k_volume_subtype_trigger ){ + v3f local; + m4x3_mulv( volume->to_local, pos, local ); + vg_line_boxf_transformed( volume->to_world, cube, 0xff00ff00 ); + + if( (fabsf(local[0]) <= 1.0f) && + (fabsf(local[1]) <= 1.0f) && + (fabsf(local[2]) <= 1.0f) ) { - logic_packet packet; - packet.location = zone->target_logic_brick; - packet.function = 0; + in_volume = 1; - packet.type = k_mdl_128bit_datatype_vec3; - packet.data._v4f[0] = vg_randf()*2.0f-1.0f; - packet.data._v4f[1] = vg_randf()*2.0f-1.0f; - packet.data._v4f[2] = vg_randf()*2.0f-1.0f; - m4x3_mulv( zone->transform, packet.data._v4f, packet.data._v4f ); + if( !world_global.in_volume ){ + ent_call basecall; + basecall.ent.index = idx; + basecall.ent.type = k_ent_volume; + basecall.function = k_ent_function_trigger; + basecall.data = NULL; - logic_bricks_send_packet( world, &packet ); + entity_call( world, &basecall ); + } } -#endif - continue; } + else if( volume->type == k_volume_subtype_particle ){ + vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff ); - v3f local; - m4x3_mulv( zone->inv_transform, pos, local ); - - if( (fabsf(local[0]) <= 1.0f) && - (fabsf(local[1]) <= 1.0f) && - (fabsf(local[2]) <= 1.0f) ) - { - in_volume = 1; - - if( !world_global.in_volume ) - { -#if 0 - logic_packet packet; - packet.location = zone->target_logic_brick; - packet.function = 0; - - packet.type = k_mdl_128bit_datatype_vec3; - v3_copy( pos, packet.data._v4f ); + for( int j=0; jtransform, (boxf){{-1.0f,-1.0f,-1.0f}, - { 1.0f, 1.0f, 1.0f}}, - 0xff00ff00 ); - } - else - { - vg_line_boxf_transformed( zone->transform, (boxf){{-1.0f,-1.0f,-1.0f}, - { 1.0f, 1.0f, 1.0f}}, - 0xff0000ff ); } } -#endif + world_global.in_volume = in_volume; #if 0 if( k_debug_light_indices ) @@ -657,7 +711,6 @@ VG_STATIC void world_update( world_instance *world, v3f pos ) } } - world_global.in_volume = in_volume; #endif #if 0 diff --git a/world_gen.h b/world_gen.h index 63cb1ef..fac1fe7 100644 --- a/world_gen.h +++ b/world_gen.h @@ -791,6 +791,44 @@ VG_STATIC void world_entities_init( world_instance *world ) world->water.enabled = 1; water_set_surface( world, water->transform.co[1] ); } + + /* volumes */ + for( u32 j=0; jent_volume); j++ ){ + ent_volume *volume = mdl_arritm( &world->ent_volume, j ); + mdl_transform_m4x3( &volume->transform, volume->to_world ); + m4x3_invert_affine( volume->to_world, volume->to_local ); + } + + /* audio packs */ + for( u32 j=0; jent_audio); j++ ){ + ent_audio *audio = mdl_arritm( &world->ent_audio, j ); + + for( u32 k=0; kclip_count; k++ ){ + ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip, + audio->clip_start+k ); + + if( clip->file.pack_size ){ + u32 size = clip->file.pack_size, + offset = clip->file.pack_offset; + + /* FIXME: Ditchable asset! */ + void *data = mdl_arritm(&world->meta.pack, clip->file.pack_offset); + + clip->clip.path = NULL; + clip->clip.flags = audio->flags; + clip->clip.data = data; + clip->clip.size = size; + } + else{ + clip->clip.path = mdl_pstr( &world->meta, clip->file.pstr_path ); + clip->clip.flags = audio->flags; + clip->clip.data = NULL; + clip->clip.size = 0; + } + + audio_clip_load( &clip->clip, world_global.generic_heap ); + } + } } VG_STATIC void world_load( world_instance *world, const char *path ) @@ -804,6 +842,8 @@ VG_STATIC void world_load( world_instance *world, const char *path ) mdl_load_metadata_block( &world->meta, world_global.generic_heap ); mdl_load_animation_block( &world->meta, world_global.generic_heap ); mdl_load_mesh_block( &world->meta, world_global.generic_heap ); + + /* TODO: This should get a seperate memory area */ mdl_load_pack_block( &world->meta, world_global.generic_heap ); mdl_load_array( &world->meta, &world->ent_gate, @@ -823,6 +863,12 @@ VG_STATIC void world_load( world_instance *world, const char *path ) "ent_route", world_global.generic_heap ); mdl_load_array( &world->meta, &world->ent_water, "ent_water", world_global.generic_heap ); + mdl_load_array( &world->meta, &world->ent_audio_clip, + "ent_audio_clip", world_global.generic_heap ); + mdl_load_array( &world->meta, &world->ent_audio, + "ent_audio", world_global.generic_heap ); + mdl_load_array( &world->meta, &world->ent_volume, + "ent_volume", world_global.generic_heap ); mdl_close( &world->meta ); @@ -838,6 +884,11 @@ VG_STATIC void world_load( world_instance *world, const char *path ) #endif world_routes_ent_init( world ); world_entities_init( world ); + world->volume_bh = bh_create( world_global.generic_heap, + &bh_system_volumes, + world, + mdl_arrcount( &world->ent_volume ), + 1 ); /* main bulk */ world_generate( world ); diff --git a/world_volumes.h b/world_volumes.h index f333626..da39d26 100644 --- a/world_volumes.h +++ b/world_volumes.h @@ -3,7 +3,6 @@ #include "world.h" -#if 0 /* * BVH implementation * ---------------------------------------------------------------------------- @@ -13,35 +12,30 @@ VG_STATIC void volume_vg_expand_bound( void *user, boxf bound, u32 item_index ) { world_instance *world = user; - ent_volume *volume_array = world_ent_array( world, k_ent_volume ), - *volume = volume_array + item_index; + ent_volume *volume = mdl_arritm( &world->ent_volume, item_index ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){ 1.0f, 1.0f, 1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){ 1.0f, 1.0f,-1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){ 1.0f,-1.0f, 1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){ 1.0f,-1.0f,-1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){-1.0f, 1.0f, 1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){-1.0f, 1.0f,-1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){-1.0f,-1.0f, 1.0f} ); - m4x3_expand_aabb_point( volume->transform, bound, (v3f){-1.0f,-1.0f,-1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f, 1.0f, 1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f, 1.0f,-1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f,-1.0f, 1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){ 1.0f,-1.0f,-1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f, 1.0f, 1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f, 1.0f,-1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f,-1.0f, 1.0f} ); + m4x3_expand_aabb_point( volume->to_world, bound, (v3f){-1.0f,-1.0f,-1.0f} ); } VG_STATIC float volume_vg_centroid( void *user, u32 item_index, int axis ) { world_instance *world = user; - - ent_volume *volume_array = world_ent_array( world, k_ent_volume ), - *volume = volume_array + item_index; - - return volume->transform[3][axis]; + ent_volume *volume = mdl_arritm( &world->ent_volume, item_index ); + return volume->to_world[3][axis]; } VG_STATIC void volume_vg_swap( void *user, u32 ia, u32 ib ) { world_instance *world = user; - ent_volume *volume_array = world_ent_array( world, k_ent_volume ), - *a = volume_array + ia, - *b = volume_array + ib, + ent_volume *a = mdl_arritm( &world->ent_volume, ia ), + *b = mdl_arritm( &world->ent_volume, ib ), temp; temp = *a; @@ -52,12 +46,10 @@ VG_STATIC void volume_vg_swap( void *user, u32 ia, u32 ib ) VG_STATIC void volume_vg_debug( void *user, u32 item_index ) { world_instance *world = user; - ent_volume *volume_array = world_ent_array( world, k_ent_volume ), - *volume = volume_array + item_index; - - vg_line_boxf_transformed( volume->transform, (boxf){{-1.0f,-1.0f,-1.0f}, - { 1.0f, 1.0f, 1.0f}}, - 0xff00ff00 ); + ent_volume *volume = mdl_arritm( &world->ent_volume, item_index ); + vg_line_boxf_transformed( volume->to_world, (boxf){{-1.0f,-1.0f,-1.0f}, + { 1.0f, 1.0f, 1.0f}}, + 0xff00ff00 ); } VG_STATIC bh_system bh_system_volumes = @@ -69,6 +61,5 @@ VG_STATIC bh_system bh_system_volumes = .item_debug = volume_vg_debug, .cast_ray = NULL }; -#endif #endif /* WORLD_VOLUMES_H */