* -------------------------------------------------------
*/
+ void *heap;
char world_name[ 64 ];
struct{
rb_object rb_geo;
};
-VG_STATIC struct world_global{
+struct world_global{
/*
* Allocated as system memory
* --------------------------------------------------------------------------
*/
- void *generic_heap;
+ void *heap;
/* rendering */
glmesh skydome;
}
text_particles[6*4];
u32 text_particle_count;
-
}
-world_global;
+static world_global;
VG_STATIC world_instance *get_active_world( void )
{
VG_STATIC
int ray_world( world_instance *world, v3f pos, v3f dir, ray_hit *hit );
+VG_STATIC
+ent_spawn *world_find_closest_spawn( world_instance *world, v3f position )
+{
+ ent_spawn *rp = NULL, *r;
+ float min_dist = INFINITY;
+
+ for( u32 i=0; i<mdl_arrcount(&world->ent_spawn); i++ ){
+ r = mdl_arritm( &world->ent_spawn, i );
+ float d = v3_dist2( r->transform.co, position );
+
+ if( d < min_dist ){
+ min_dist = d;
+ rp = r;
+ }
+ }
+
+ if( !rp ){
+ if( mdl_arrcount(&world->ent_spawn) ){
+ vg_warn( "Invalid distances to spawns.. defaulting to first one.\n" );
+ return mdl_arritm( &world->ent_spawn, 0 );
+ }
+ else{
+ vg_error( "There are no spawns in the level!\n" );
+ }
+ }
+
+ return rp;
+}
+
+VG_STATIC
+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 ) ){
+ rp = r;
+ break;
+ }
+ }
+
+ if( !rp )
+ vg_warn( "No spawn named '%s'\n", name );
+
+ return rp;
+}
+
/*
* Submodules
*/
/* Allocate dynamic world memory arena */
u32 max_size = 76*1024*1024;
- world_global.generic_heap = vg_create_linear_allocator( vg_mem.rtmemory,
- max_size,
- VG_MEMORY_SYSTEM );
+ world_global.heap = vg_create_linear_allocator( vg_mem.rtmemory, max_size,
+ VG_MEMORY_SYSTEM );
}
typedef struct ent_call ent_call;
}
#endif
-
-#if 0
-
- /* process soundscape transactions */
- audio_lock();
- for( int i=0; i<world->soundscape_count; i++ )
- {
- struct soundscape *s = &world->soundscapes[i];
- s->usage_count = 0;
-
- for( int j=0; j<s->max_instances; j++ )
- {
- if( s->channels[j] )
- {
- if( audio_channel_finished(s->channels[j]) )
- s->channels[j] = audio_relinquish_channel( s->channels[j] );
- else
- s->usage_count ++;
- }
- }
- }
- audio_unlock();
-#endif
}
/*
return world_tri_index_surface( world, hit->tri[0] );
}
+/*
+ * -----------------------------------------------------------------------------
+ * Audio sampling
+ * -----------------------------------------------------------------------------
+ */
+
+VG_STATIC
+enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output);
+VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value );
+
+#include "audio.h"
+
+/*
+ * Trace out a random point, near the player to try and determine water areas
+ */
+VG_STATIC
+enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
+{
+ v3f chance = { (vg_randf()-0.5f) * 30.0f,
+ 8.0f,
+ (vg_randf()-0.5f) * 30.0f };
+
+ v3f pos;
+ v3_add( chance, origin, pos );
+
+ ray_hit contact;
+ contact.dist = vg_minf( 16.0f, pos[1] );
+
+ world_instance *world = get_active_world();
+
+ if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &contact ) ){
+ struct world_surface *mat = ray_hit_surface( world, &contact );
+
+ if( mat->info.surface_prop == k_surface_prop_grass){
+ v3_copy( contact.pos, output );
+ return k_audio_sprite_type_grass;
+ }
+ else{
+ return k_audio_sprite_type_none;
+ }
+ }
+
+ output[0] = pos[0];
+ output[1] = 0.0f;
+ output[2] = pos[2];
+
+ float dist = fabsf(output[1] - origin[1]);
+
+ if( world->water.enabled && dist<=40.0f )
+ return k_audio_sprite_type_water;
+ else
+ return k_audio_sprite_type_none;
+}
+
+VG_STATIC void world_audio_sample_distances( v3f co, int *index, float *value )
+{
+ float inr3 = 0.57735027,
+ inr2 = 0.70710678118;
+
+ v3f sample_directions[] = {
+ { -1.0f, 0.0f, 0.0f },
+ { 1.0f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 1.0f },
+ { 0.0f, 0.0f, -1.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { 0.0f, -1.0f, 0.0f },
+ { -inr3, inr3, inr3 },
+ { inr3, inr3, inr3 },
+ { -inr3, inr3, -inr3 },
+ { inr3, inr3, -inr3 },
+ { -inr2, 0.0f, inr2 },
+ { inr2, 0.0f, inr2 },
+ { -inr2, 0.0f, -inr2 },
+ { inr2, 0.0f, -inr2 },
+ };
+
+ static int si = 0;
+ static float distances[16];
+
+ ray_hit ray;
+ ray.dist = 5.0f;
+
+ v3f rc, rd, ro;
+ v3_copy( sample_directions[ si ], rd );
+ v3_add( co, (v3f){0.0f,1.5f,0.0f}, ro );
+ v3_copy( ro, rc );
+
+ float dist = 200.0f;
+
+ for( int i=0; i<10; i++ ){
+ if( ray_world( get_active_world(), rc, rd, &ray ) ){
+ dist = (float)i*5.0f + ray.dist;
+ break;
+ }
+ else{
+ v3_muladds( rc, rd, ray.dist, rc );
+ }
+ }
+
+ distances[si] = dist;
+
+ if( vg_lines.draw ){
+ for( int i=0; i<14; i++ ){
+ if( distances[i] != 200.0f ){
+ u32 colours[] = { VG__RED, VG__BLUE, VG__GREEN,
+ VG__CYAN, VG__YELOW, VG__PINK,
+ VG__WHITE };
+
+ u32 colour = colours[i%7];
+
+ v3f p1;
+ v3_muladds( ro, sample_directions[i], distances[i], p1 );
+ vg_line( ro, p1, colour );
+ vg_line_pt3( p1, 0.1f, colour );
+ }
+ }
+ }
+
+ *index = si;
+ *value = dist;
+
+ si ++;
+ if( si >= 14 )
+ si = 0;
+}
+
#endif /* WORLD_H */