"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.
_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),
("path_count",c_uint16)]
#}
-class ent_route(Structure):
+class ent_route(Structure):
#{
_fields_ = [("transform",mdl_transform),
("pstr_name",c_uint32),
("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'
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
#}
#}
#}
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 )
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 ''}")
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)
+ #}
#}
#}
#{
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):
#{
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):
@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
#}
#}
+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)
#}
#}
+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",
('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
)
#}
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]
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) )
+ #}
#}
#}
\
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 \
ent_path_index,
ent_checkpoint,
ent_route,
- ent_water;
+ ent_water,
+
+ ent_audio_clip,
+ ent_audio,
+ ent_volume;
ent_gate *rendering_gate;
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; i<audio->clip_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!!!!!! */
}
sfd_update();
-#if 0
- /* TODO: Bvh */
+
static float random_accum = 0.0f;
random_accum += vg.time_delta;
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; j<random_ticks; j++ )
+ boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
+
+ if( volume->type == 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; j<random_ticks; j++ ){
+ 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 );
-#endif
+ entity_call( world, &basecall );
}
-
- vg_line_boxf_transformed( zone->transform, (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 )
}
}
- world_global.in_volume = in_volume;
#endif
#if 0
#include "world.h"
-#if 0
/*
* BVH implementation
* ----------------------------------------------------------------------------
{
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;
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 =
.item_debug = volume_vg_debug,
.cast_ray = NULL
};
-#endif
#endif /* WORLD_VOLUMES_H */