_fields_ = [("transform",mdl_transform),
("submesh_start",c_uint32), ("submesh_count",c_uint32),
("id_next",c_uint32),
- ("filter",c_uint32)]
+ ("filter",c_uint32),
+ ("time_limit",c_float)]
+
+ sr_functions = { 0: 'trigger',
+ 1: 'start_challenge' }
#}
def obj_ent_type( obj ):
if obj_data.target:#{
volume.target = sr_entity_id( obj_data.target )
+ volume._anon.trigger.event = obj_data.event
#}
sr_ent_push(volume)
challenge = ent_challenge()
obj_data = obj.SR_data.ent_challenge[0]
challenge.id_next = sr_entity_id( obj_data.proxima )
+ challenge.filter = 0
+ challenge.time_limit = obj_data.time_limit
compile_obj_transform( obj, challenge.transform )
challenge.submesh_start, challenge.submesh_count, _ = \
#}
#}
-class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):
-#{
+class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{
subtype: bpy.props.EnumProperty(
name="Subtype",
items=[('0','Trigger',''),
target: bpy.props.PointerProperty( \
type=bpy.types.Object, name="Target", \
poll=lambda self,obj: sr_filter_ent_type(obj,\
- ['ent_audio','ent_skateshop','ent_ccmd']))
+ ['ent_audio','ent_skateshop','ent_ccmd',\
+ 'ent_challenge']))
+
+ event: bpy.props.IntProperty( name="Event/Method" )
@staticmethod
- def sr_inspector( layout, data ):
- #{
- data = data[0]
- layout.prop( data, 'subtype' )
- layout.prop( data, 'target' )
+ def sr_inspector( layout, data ):#{
+ layout.prop( data[0], 'subtype' )
+ layout.prop( data[0], 'target' )
+
+ row = layout.row()
+ row.prop( data[0], 'event' )
+
+ if data[0].target:#{
+ tipo = data[0].target.SR_data.ent_type
+ cls = globals()[ tipo ]
+
+ table = getattr( cls, 'sr_functions', None )
+ if table:#{
+ if data[0].event in table:#{
+ row.label( text=table[data[0].event] )
+ #}
+ else:#{
+ row.label( text="undefined function" )
+ #}
+ #}
+ #}
#}
#}
type=bpy.types.Object, name="Target", \
poll=lambda self,obj: sr_filter_ent_type(obj,\
['ent_audio','ent_ccmd']))
+ event: bpy.props.IntProperty( name="Event/Method" )
+ time_limit: bpy.props.FloatProperty( name="Time Limit", default=1.0 )
#}
class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup):
cv_draw_ucube( obj.matrix_world, (0,1,0) )
if data.target:#{
- cv_draw_line( obj.location, data.target.location, (0,1,0) )
+ cv_draw_arrow( 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) )
+ cv_draw_arrow( obj.location, data.target.location, (1,1,0) )
#}
#}
#}
elif ent_type == 'ent_volume':#{
cv_ent_volume( obj )
#}
+ elif ent_type == 'ent_challenge':#{
+ data = obj.SR_data.ent_challenge[0]
+ if data.proxima:#{
+ cv_draw_arrow( obj.location, data.proxima.location, (0,0.2,1.0) )
+ #}
+ #}
elif ent_type == 'ent_audio':#{
if obj.SR_data.ent_audio[0].flag_3d:
cv_draw_sphere( obj.location, obj.scale[0], (1,1,0) )
--- /dev/null
+#ifndef ENT_CHALLENGE_C
+#define ENT_CHALLENGE_C
+
+#include "world.h"
+#include "world_load.h"
+#include "entity.h"
+
+VG_STATIC void ent_challenge_pass( world_instance *world,
+ ent_challenge *challenge ){
+ if( challenge->id_next ){
+ world->challenge_timer += challenge->filter;
+
+ u32 index = mdl_entity_id_id( challenge->id_next );
+ ent_challenge *next = mdl_arritm( &world->ent_challenge, index );
+ world->challenge_target = next;
+
+ vg_info( "pass challenge point\n" );
+ }
+ else {
+ vg_success( "NYU Film school graduate SUCKAH\n" );
+ world->challenge_target = NULL;
+ world->challenge_timer = 0.0f;
+ }
+}
+
+VG_STATIC void 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 );
+
+ if( call->function == 0 ){
+ if( world->challenge_target ){
+ if( world->challenge_target == challenge ){
+ ent_challenge_pass( world, challenge );
+ }
+ else {
+ vg_error( "womp womp\n" );
+ world->challenge_target = NULL;
+ world->challenge_timer = 0.0f;
+ }
+ }
+ }
+ else if( call->function == 1 ){
+ vg_info( "begin the challenge\n" );
+ world->challenge_timer = 0.0f;
+ ent_challenge_pass( world, challenge );
+ }
+ else {
+ vg_print_backtrace();
+ vg_error( "Unhandled function id: %u\n", call->function );
+ }
+}
+
+#endif /* ENT_CHALLENGE_C */
#include "world_entity.h"
#include "ent_skateshop.c"
+#include "ent_challenge.c"
-VG_STATIC void entity_call( world_instance *world, ent_call *call )
-{
+typedef void (*fn_entity_call_handler)( world_instance *, ent_call *);
+
+VG_STATIC void entity_call( world_instance *world, ent_call *call ){
u32 type = mdl_entity_id_type( call->id );
- if( type == k_ent_volume ){
- ent_volume_call( world, call );
- } else if( type == k_ent_audio ){
- ent_audio_call( world, call );
- } else if( type == k_ent_skateshop ){
- ent_skateshop_call( world, call );
- } else if( type == k_ent_ccmd ){
- ent_ccmd_call( world, call );
+ fn_entity_call_handler table[] = {
+ [k_ent_volume] = ent_volume_call,
+ [k_ent_audio] = ent_audio_call,
+ [k_ent_skateshop] = ent_skateshop_call,
+ [k_ent_challenge] = ent_challenge_call,
+ [k_ent_ccmd] = ent_ccmd_call
+ };
+
+ if( type > vg_list_size(table) ){
+ vg_error( "call to entity type: %u is out of range\n", type );
+ return;
+ }
+
+ fn_entity_call_handler fn = table[ type ];
+
+ if( !fn ){
+ vg_error( "call to entity type: %u is undefined\n", type );
+ return;
}
+
+ fn( world, call );
}
#endif /* ENTITY_C */
k_ent_menuitem = 15,
k_ent_worldinfo = 16,
k_ent_ccmd = 17,
- k_ent_challenge = 18
+ k_ent_challenge = 18,
+ k_ent_relay = 19
};
static u32 mdl_entity_id_type( u32 entity_id ){
union{
mdl_file file;
audio_clip clip;
- };
+ }_;
float probability;
};
u32 event, blank;
};
-enum volume_subtype{
- k_volume_subtype_trigger,
- k_volume_subtype_particle
+enum ent_volume_flag {
+ k_ent_volume_flag_particles = 0x1,
+ k_ent_volume_flag_disabled = 0x2
};
struct ent_volume{
mdl_transform transform;
m4x3f to_world, to_local;
- u32 type;
+ u32 flags;
u32 target;
-
union{
volume_trigger trigger;
volume_particles particles;
submesh_count,
id_next,
filter;
+ f32 time_limit;
};
typedef struct ent_call ent_call;
if( gate->type == k_gate_type_nonlocel )
world_static.active_world = gate->target;
- world_volumes.inside = 0;
-
audio_lock();
audio_oneshot( &audio_gate_pass, 1.0f, 0.0f );
audio_unlock();
/*
* Update world space bounding box based on local one
*/
-VG_STATIC void rb_update_bounds( rigidbody *rb )
-{
- box_copy( rb->bbx, rb->bbx_world );
- m4x3_transform_aabb( rb->to_world, rb->bbx_world );
+VG_STATIC void rb_update_bounds( rigidbody *rb ){
+ box_init_inf( rb->bbx_world );
+ m4x3_expand_aabb_aabb( rb->to_world, rb->bbx_world, rb->bbx );
}
/*
/* Transform and place vertices */
boxf bbxnew;
- box_copy( sm->bbx, bbxnew );
- m4x3_transform_aabb( transform, bbxnew );
+ box_init_inf( bbxnew );
+ m4x3_expand_aabb_aabb( transform, bbxnew, sm->bbx );
box_concat( ctx->bbx, bbxnew );
m3x3f normal_matrix;
it up with the oblique rendering inside the
portals */
- world_render_challenges( localplayer.viewable_world );
+ //world_render_challenges( localplayer.viewable_world );
/* continue with variable rate */
render_scene_gate_subview();
scene_lines;
/* spacial mappings */
- bh_tree *audio_bh,
- *volume_bh,
- *geo_bh;
+ bh_tree *geo_bh,
+ *entity_bh;
+ u32 *entity_list;
/* graphics */
glmesh mesh_route_lines;
mesh_water;
rb_object rb_geo;
+
+ ent_challenge *challenge_target;
+ f32 challenge_timer;
};
struct world_static {
#ifndef WORLD_ENTITY_C
#define WORLD_ENTITY_C
+#include "model.h"
+#include "entity.h"
#include "world.h"
#include "world_load.h"
-#include "entity.h"
-VG_STATIC void world_gen_entities_init(void)
-{
+VG_STATIC void world_gen_entities_init(void){
world_instance *world = world_loading_instance();
/* lights */
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;
+ if( clip->_.file.pack_size ){
+ u32 size = clip->_.file.pack_size,
+ offset = clip->_.file.pack_offset;
/* embedded files are fine to clear the scratch buffer, only
* external audio uses it */
vg_linear_clear( vg_mem.scratch );
void *data = vg_linear_alloc( vg_mem.scratch,
- clip->file.pack_size );
+ clip->_.file.pack_size );
- mdl_fread_pack_file( &world->meta, &clip->file, data );
+ mdl_fread_pack_file( &world->meta, &clip->_.file, data );
- clip->clip.path = NULL;
- clip->clip.flags = audio->flags;
- clip->clip.data = data;
- clip->clip.size = size;
+ 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;
+ 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->heap );
+ audio_clip_load( &clip->_.clip, world->heap );
}
}
+
+ /* create generic entity hierachy for those who need it */
+ u32 indexed_count = 0;
+ struct {
+ u32 type;
+ mdl_array_ptr *array;
+ }
+ indexables[] = {
+ { k_ent_gate, &world->ent_gate },
+ { k_ent_challenge, &world->ent_challenge },
+ { k_ent_volume, &world->ent_volume }
+ };
+
+ for( u32 i=0; i<vg_list_size(indexables); i++ )
+ indexed_count += mdl_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_list_size(indexables); i++ ){
+ u32 type = indexables[i].type,
+ count = mdl_arrcount( indexables[i].array );
+
+ for( u32 j=0; j<count; j ++ )
+ world->entity_list[index ++] = mdl_entity_id( type, j );
+ }
+
+ world->entity_bh = bh_create( world->heap, &bh_system_entity_list, world,
+ indexed_count, 2 );
}
VG_STATIC
if( call->function == k_ent_function_trigger ){
call->id = volume->target;
- if( volume->type == k_volume_subtype_particle ){
+ if( volume->flags & k_ent_volume_flag_particles ){
float *co = alloca( sizeof(float)*3 );
co[0] = vg_randf64()*2.0f-1.0f;
co[1] = vg_randf64()*2.0f-1.0f;
entity_call( world, call );
}
else{
+ call->function = volume->trigger.event;
entity_call( world, call );
}
}
audio_lock();
if( audio->behaviour == k_channel_behaviour_unlimited ){
- audio_oneshot_3d( &clip->clip, sound_co,
+ audio_oneshot_3d( &clip->_.clip, sound_co,
audio->transform.s[0],
audio->volume );
}
audio->max_channels );
if( ch ){
- audio_channel_init( ch, &clip->clip, audio->flags );
+ audio_channel_init( ch, &clip->_.clip, audio->flags );
audio_channel_group( ch, audio->group );
audio_channel_world( ch, world_id );
audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] );
audio_get_group_first_active_channel( audio->group );
if( existing ){
- if( existing->source == &clip->clip ){
+ if( existing->source == &clip->_.clip ){
audio_unlock();
return;
}
}
if( ch ){
- audio_channel_init( ch, &clip->clip, audio->flags );
+ audio_channel_init( ch, &clip->_.clip, audio->flags );
audio_channel_group( ch, audio->group );
audio_channel_world( ch, world_id );
audio_channel_fadein( ch, audio->crossfade );
}
}
+/*
+ * BVH implementation
+ * ----------------------------------------------------------------------------
+ */
+
+VG_STATIC void
+entity_bh_expand_bound( void *user, boxf bound, u32 item_index ){
+ world_instance *world = user;
+
+ u32 id = world->entity_list[ item_index ],
+ type = mdl_entity_id_type( id ),
+ index = mdl_entity_id_id( id );
+
+ if( type == k_ent_gate ){
+ ent_gate *gate = mdl_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_challenge ){
+ ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+
+ /* TODO: This might be more work than necessary. could maybe just get
+ * away with representing them as points */
+
+ boxf box;
+ box_init_inf( box );
+
+ for( u32 i=0; i<challenge->submesh_count; i++ ){
+ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+ challenge->submesh_start+i );
+ box_concat( box, sm->bbx );
+ }
+
+ m4x3f transform;
+ mdl_transform_m4x3( &challenge->transform, transform );
+ m4x3_expand_aabb_aabb( transform, bound, box );
+ }
+ else if( type == k_ent_volume ){
+ ent_volume *volume = mdl_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}} );
+ }
+}
+
+VG_STATIC float entity_bh_centroid( void *user, u32 item_index, int axis ){
+ world_instance *world = user;
+
+ u32 id = world->entity_list[ item_index ],
+ type = mdl_entity_id_type( id ),
+ index = mdl_entity_id_id( id );
+
+ if( type == k_ent_gate ){
+ ent_gate *gate = mdl_arritm( &world->ent_gate, index );
+ return gate->to_world[3][axis];
+ }
+ else if( type == k_ent_challenge ){
+ ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+ return challenge->transform.co[axis];
+ }
+ else if( type == k_ent_volume ){
+ ent_volume *volume = mdl_arritm( &world->ent_volume, index );
+ return volume->transform.co[axis];
+ }
+ else {
+ vg_fatal_error( "Programming error\n" );
+ return INFINITY;
+ }
+}
+
+VG_STATIC void entity_bh_swap( void *user, u32 ia, u32 ib ){
+ world_instance *world = user;
+
+ u32 a = world->entity_list[ ia ],
+ b = world->entity_list[ ib ];
+
+ world->entity_list[ ia ] = b;
+ world->entity_list[ ib ] = a;
+}
+
+VG_STATIC void entity_bh_debug( void *user, u32 item_index ){
+ world_instance *world = user;
+
+ u32 id = world->entity_list[ item_index ],
+ type = mdl_entity_id_type( id ),
+ index = mdl_entity_id_id( id );
+
+ if( type == k_ent_gate ){
+ ent_gate *gate = mdl_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_challenge ){
+ ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
+ boxf box;
+ box_init_inf( box );
+
+ for( u32 i=0; i<challenge->submesh_count; i++ ){
+ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+ challenge->submesh_start+i );
+ box_concat( box, sm->bbx );
+ }
+
+ m4x3f transform;
+ mdl_transform_m4x3( &challenge->transform, transform );
+ vg_line_boxf_transformed( transform, box, 0xf000ff00 );
+ }
+ else if( type == k_ent_volume ){
+ ent_volume *volume = mdl_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{
+ vg_fatal_error( "Programming error\n" );
+ }
+}
+
#endif /* WORLD_ENTITY_C */
#include "world.h"
#include "entity.h"
+#include "bvh.h"
VG_STATIC void world_gen_entities_init(void);
VG_STATIC ent_spawn *world_find_spawn_by_name( world_instance *world,
VG_STATIC void ent_audio_call( world_instance *world, ent_call *call );
VG_STATIC void ent_ccmd_call( world_instance *world, ent_call *call );
+VG_STATIC void entity_bh_expand_bound( void *user, boxf bound, u32 item_index );
+VG_STATIC float entity_bh_centroid( void *user, u32 item_index, int axis );
+VG_STATIC void entity_bh_swap( void *user, u32 ia, u32 ib );
+VG_STATIC void entity_bh_debug( void *user, u32 item_index );
+
+static bh_system bh_system_entity_list = {
+ .expand_bound = entity_bh_expand_bound,
+ .item_centroid = entity_bh_centroid,
+ .item_closest = NULL,
+ .item_swap = entity_bh_swap,
+ .item_debug = entity_bh_debug,
+ .cast_ray = NULL
+};
+
#endif /* WORLD_ENTITY_H */
vg_info( "%d foliage models added\n", count );
}
+VG_STATIC
+void world_unpack_submesh_dynamic( world_instance *world,
+ scene_context *scene, mdl_submesh *sm ){
+ if( sm->flags & k_submesh_flag_consumed ) return;
+
+ m4x3f identity;
+ m4x3_identity( identity );
+ scene_add_mdl_submesh( scene, &world->meta, sm, identity );
+
+ scene_copy_slice( scene, sm );
+ sm->flags |= k_submesh_flag_consumed;
+}
+
/*
* Create the main meshes for the world
*/
scene_copy_slice( &world->scene_no_collide, &surf->sm_no_collide );
}
+ /* unpack traffic models.. TODO: should we just put all these submeshes in a
+ * dynamic models list? and then the actual entitities point to the
+ * 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 j=0; j<vehc->submesh_count; j++ ){
mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
vehc->submesh_start+j );
+ world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+ }
+ }
- if( sm->flags & k_submesh_flag_consumed ){
- continue;
- }
-
- m4x3f identity;
- m4x3_identity( identity );
- scene_add_mdl_submesh( &world->scene_no_collide,
- &world->meta, sm, identity );
+ /* unpack challenge models */
+ for( u32 i=0; i<mdl_arrcount( &world->ent_challenge ); i++ ){
+ ent_challenge *challenge = mdl_arritm( &world->ent_challenge, i );
- scene_copy_slice( &world->scene_no_collide, sm );
- sm->flags |= k_submesh_flag_consumed;
+ for( u32 j=0; j<challenge->submesh_count; j ++ ){
+ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+ challenge->submesh_start+j );
+ world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
}
}
world_gen_load_surfaces();
world_gen_routes_ent_init();
world_gen_entities_init();
- world->volume_bh = bh_create( heap, &bh_system_volumes, world,
- mdl_arrcount( &world->ent_volume ), 1 );
/* main bulk */
world_gen_generate_meshes();
world->surface_count = 0;
world->geo_bh = NULL;
- world->volume_bh = NULL;
- world->audio_bh = NULL;
+ world->entity_bh = NULL;
+ world->entity_list = NULL;
world->rendering_gate = NULL;
world->water.enabled = 0;
}
}
-VG_STATIC
-void world_render_challenges( world_instance *world ){
- if( !world ) return;
-
- shader_scene_fxglow_use();
- for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
- ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
-
- m4x3f mmdl;
- mdl_transform_m4x3( &challenge->transform, mmdl );
- shader_scene_fxglow_uMdl( mmdl );
- }
-}
-
VG_STATIC
void world_render_both_stages( world_instance *world, struct world_pass *pass )
{
glEnable(GL_CULL_FACE);
}
+VG_STATIC
+void world_render_challenges( world_instance *world, struct world_pass *pass ){
+ if( !world ) return;
+
+ glDisable( GL_CULL_FACE );
+ mesh_bind( &world->mesh_no_collide );
+
+ u32 last_material = 0;
+
+ for( u32 i=0; i<mdl_arrcount(&world->ent_challenge); i++ ){
+ ent_challenge *challenge = mdl_arritm(&world->ent_challenge,i);
+
+ m4x3f mmdl;
+ mdl_transform_m4x3( &challenge->transform, mmdl );
+ shader_scene_fxglow_uMdl( mmdl );
+
+ for( u32 j=0; j<challenge->submesh_count; j++ ){
+ mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
+ challenge->submesh_start + j );
+
+ if( sm->material_id != last_material ){
+ last_material = sm->material_id;
+
+ pass->fn_bind_textures( world, &world->surfaces[sm->material_id] );
+ }
+
+ mdl_draw_submesh( sm );
+ }
+ }
+}
+
VG_STATIC void render_world_fxglow( world_instance *world, camera *cam ){
//glDrawBuffers( 1, (GLenum[]){ GL_COLOR_ATTACHMENT0 } );
};
world_render_both_stages( world, &pass );
+ world_render_challenges( world, &pass );
glEnable(GL_CULL_FACE);
//glDrawBuffers( 2, (GLenum[]){ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 } );
bh_iter_init_box( 0, &it, volume_proximity );
i32 idx;
- while( bh_next( world->volume_bh, &it, &idx ) ){
- ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
+ while( bh_next( world->entity_bh, &it, &idx ) ){
+ u32 id = world->entity_list[ idx ],
+ type = mdl_entity_id_type( id ),
+ index = mdl_entity_id_id( id );
+
+ if( type != k_ent_volume ) continue;
+ ent_volume *volume = mdl_arritm( &world->ent_volume, index );
boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
- if( volume->type == k_volume_subtype_trigger ){
+ if( volume->flags & k_ent_volume_flag_particles ){
+ vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
+
+ for( int j=0; j<random_ticks; j++ ){
+ ent_call basecall;
+ basecall.id = id;
+ basecall.data = NULL;
+ basecall.function = 0;
+
+ entity_call( world, &basecall );
+ }
+ }
+ else{
for( u32 i=0; i<world_static.active_trigger_volume_count; i++ )
- if( world_static.active_trigger_volumes[i] == idx )
+ if( world_static.active_trigger_volumes[i] == index )
goto next_volume;
if( world_static.active_trigger_volume_count >
if( (fabsf(local[0]) <= 1.0f) &&
(fabsf(local[1]) <= 1.0f) &&
- (fabsf(local[2]) <= 1.0f) )
- {
+ (fabsf(local[2]) <= 1.0f) ){
ent_call basecall;
- basecall.function = k_ent_function_trigger;
- basecall.id = mdl_entity_id( k_ent_volume, idx );
+ basecall.function = 0;
+ basecall.id = id;
basecall.data = NULL;
entity_call( world, &basecall );
world_static.active_trigger_volumes[
- world_static.active_trigger_volume_count ++ ] = idx;
+ world_static.active_trigger_volume_count ++ ] = index;
}
else
vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );
}
- else if( volume->type == k_volume_subtype_particle ){
- vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
-
- for( int j=0; j<random_ticks; j++ ){
- ent_call basecall;
- basecall.id = mdl_entity_id( k_ent_volume, idx );
- basecall.data = NULL;
-
- entity_call( world, &basecall );
- }
- }
next_volume:;
}
}
-/*
- * BVH implementation
- * ----------------------------------------------------------------------------
- */
-
-VG_STATIC void volume_vg_expand_bound( void *user, boxf bound, u32 item_index )
-{
- world_instance *world = user;
-
- ent_volume *volume = mdl_arritm( &world->ent_volume, item_index );
-
- 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 = 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 *a = mdl_arritm( &world->ent_volume, ia ),
- *b = mdl_arritm( &world->ent_volume, ib ),
- temp;
-
- temp = *a;
- *a = *b;
- *b = temp;
-}
-
-VG_STATIC void volume_vg_debug( void *user, u32 item_index )
-{
- world_instance *world = user;
- 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 );
-}
-
#endif /* WORLD_VOLUMES_H */
#include "world.h"
#include "bvh.h"
-struct {
- int inside;
-}
-static world_volumes;
-
-VG_STATIC void volume_vg_expand_bound( void *user, boxf bound, u32 item_index );
-VG_STATIC float volume_vg_centroid( void *user, u32 item_index, int axis );
-VG_STATIC void volume_vg_swap( void *user, u32 ia, u32 ib );
-VG_STATIC void volume_vg_debug( void *user, u32 item_index );
-
-static bh_system bh_system_volumes =
-{
- .expand_bound = volume_vg_expand_bound,
- .item_centroid = volume_vg_centroid,
- .item_closest = NULL,
- .item_swap = volume_vg_swap,
- .item_debug = volume_vg_debug,
- .cast_ray = NULL
-};
-
#endif /* WORLD_VOLUMES_H */