refactor model api
[carveJwlIkooP6JGAAIwe30JlM.git] / world_entity.c
diff --git a/world_entity.c b/world_entity.c
deleted file mode 100644 (file)
index 1466836..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-#ifndef WORLD_ENTITY_C
-#define WORLD_ENTITY_C
-
-#include "model.h"
-#include "entity.h"
-#include "world.h"
-#include "world_load.h"
-#include "save.h"
-#include "vg/vg_msg.h"
-#include "menu.h"
-#include "ent_challenge.h"
-#include "ent_skateshop.h"
-#include "ent_route.h"
-
-static void world_entity_focus( u32 entity_id ){
-   localplayer.immobile = 1;
-   menu.disable_open = 1;
-
-   v3_zero( localplayer.rb.v );
-   v3_zero( localplayer.rb.w );
-   player_walk.move_speed = 0.0f;
-   world_static.focused_entity = entity_id;
-   skaterift.activity = k_skaterift_ent_focus;
-}
-
-static void world_entity_unfocus(void){
-   localplayer.immobile = 0;
-   skaterift.activity = k_skaterift_default;
-   menu.disable_open = 0;
-   srinput.state = k_input_state_resume;
-}
-
-static void world_entity_focus_camera( world_instance *world, u32 uid ){
-   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 );
-
-      v3f dir = {0.0f,-1.0f,0.0f};
-      mdl_transform_vector( &cam->transform, dir, dir );
-      v3_angles( dir, world_static.focus_cam.angles );
-      v3_copy( cam->transform.co, world_static.focus_cam.pos );
-      world_static.focus_cam.fov = cam->fov;
-   }
-   else {
-      camera_copy( &localplayer.cam, &world_static.focus_cam );
-
-      /* TODO ? */
-      world_static.focus_cam.nearz = localplayer.cam.nearz;
-      world_static.focus_cam.farz = localplayer.cam.farz;
-   }
-}
-
-/* logic preupdate */
-static void world_entity_focus_preupdate(void){
-   f32 rate = vg_minf( 1.0f, vg.time_frame_delta * 2.0f );
-   int active = 0;
-   if( skaterift.activity == k_skaterift_ent_focus )
-      active = 1;
-
-   vg_slewf( &world_static.focus_strength, active, 
-             vg.time_frame_delta * (1.0f/0.5f) );
-
-   u32 type = mdl_entity_id_type( world_static.focused_entity ),
-       index = mdl_entity_id_id( world_static.focused_entity );
-   world_instance *world = world_current_instance();
-
-   /* TODO: Table. */
-   if( type == k_ent_skateshop ){
-      ent_skateshop *skateshop = mdl_arritm( &world->ent_skateshop, index );
-      ent_skateshop_preupdate( skateshop, active );
-   }
-   else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
-      ent_challenge_preupdate( challenge, active );
-   }
-   else if( type == k_ent_route ){
-      ent_route *route = mdl_arritm( &world->ent_route, index );
-      ent_route_preupdate( route, active );
-   }
-}
-
-/* additional renderings like text etc.. */
-static void world_entity_focus_render(void){
-   if( skaterift.activity != k_skaterift_ent_focus )
-      return;
-
-   u32 type = mdl_entity_id_type( world_static.focused_entity ),
-       index = mdl_entity_id_id( world_static.focused_entity );
-   world_instance *world = world_current_instance();
-
-   if( type == k_ent_skateshop ){
-      ent_skateshop *skateshop = mdl_arritm( &world->ent_skateshop, index );
-      skateshop_render( skateshop );
-   }
-   else if( type == k_ent_challenge ){}
-   else if( type == k_ent_route ){}
-   else if( type == k_ent_miniworld ){}
-   else {
-      vg_fatal_error( "Programming error\n" );
-   }
-}
-
-static 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 );
-
-      m4x3f to_world;
-      q_m3x3( light->transform.q, to_world );
-      v3_copy( light->transform.co, to_world[3] );
-      m4x3_invert_affine( to_world, light->inverse_world );
-
-      light->angle_sin_cos[0] = sinf( light->angle * 0.5f );
-      light->angle_sin_cos[1] = cosf( light->angle * 0.5f );
-   }
-
-   /* gates */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
-      ent_gate *gate = mdl_arritm( &world->ent_gate, j );
-
-      if( !(gate->flags & k_ent_gate_nonlocal) ) {
-         gate_transform_update( gate );
-      }
-   }
-      
-   vg_async_call( world_link_nonlocal_async, world, 0 );
-
-   /* 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 ){
-         vg_warn( "Multiple water surfaces in level!\n" );
-         break;
-      }
-
-      world->water.enabled = 1;
-      water_set_surface( world, water->transform.co[1] );
-   }
-   
-   /* volumes */
-   for( u32 j=0; j<mdl_arrcount(&world->ent_volume); j++ ){
-      ent_volume *volume = mdl_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 k=0; k<audio->clip_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;
-
-            /* 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 );
-
-            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;
-         }
-         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->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_objective, &world->ent_objective },
-      { k_ent_volume, &world->ent_volume },
-      { k_ent_challenge, &world->ent_challenge }
-   };
-
-   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 );
-}
-
-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;
-}
-
-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;
-}
-
-static void 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 );
-   if( !volume->target ) return;
-
-   if( call->function == k_ent_function_trigger ){
-      call->id = volume->target;
-
-      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;
-         co[2] = vg_randf64()*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{
-         call->function = volume->trigger.event;
-         entity_call( world, call );
-      }
-   }
-   else if( call->function == k_ent_function_trigger_leave ){
-      call->id = volume->target;
-
-      if( volume->flags & k_ent_volume_flag_particles ){
-         assert(0);
-      }
-      else{
-         call->function = volume->trigger.event_leave;
-         entity_call( world, call );
-      }
-   }
-}
-
-static void ent_audio_call( world_instance *world, ent_call *call ){
-   if( world->status == k_world_status_unloading ){
-      vg_warn( "cannot modify audio while unloading world\n" );
-      return;
-   }
-
-   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 );
-
-   v3f sound_co;
-
-   if( call->function == k_ent_function_particle_spawn ){
-      v3_copy( call->data, sound_co );
-   }
-   else if( call->function == k_ent_function_trigger ){
-      v3_copy( audio->transform.co, sound_co );
-   }
-   else
-      return;
-
-   float chance = vg_randf64()*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 );
-
-      float mod = world->probabilities[ audio->probability_curve ],
-            p   = clip->probability * mod;
-
-      bar += p;
-      if( chance < bar ){
-         audio_lock();
-
-         if( audio->behaviour == k_channel_behaviour_unlimited ){
-            audio_oneshot_3d( &clip->_.clip, sound_co,
-                              audio->transform.s[0],
-                              audio->volume );
-         }
-         else if( audio->behaviour == k_channel_behaviour_discard_if_full ){
-            audio_channel *ch = 
-               audio_get_group_idle_channel( audio->group, 
-                                             audio->max_channels );
-
-            if( ch ){
-               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_channel_edit_volume( ch, audio->volume, 1 );
-               ch = audio_relinquish_channel( ch );
-            }
-         }
-         else if( audio->behaviour == k_channel_behaviour_crossfade_if_full){
-            audio_channel *ch =
-               audio_get_group_idle_channel( audio->group,
-                                             audio->max_channels );
-
-            /* group is full */
-            if( !ch ){
-               audio_channel *existing = 
-                  audio_get_group_first_active_channel( audio->group );
-
-               if( existing ){
-                  if( existing->source == &clip->_.clip ){
-                     audio_unlock();
-                     return;
-                  }
-                 
-                  existing->group = 0;
-                  existing = audio_channel_fadeout(existing, audio->crossfade);
-               }
-
-               ch = audio_get_first_idle_channel();
-            }
-
-            if( ch ){
-               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 );
-               ch = audio_relinquish_channel( ch );
-            }
-         }
-
-         audio_unlock();
-         return;
-      }
-   }
-}
-
-
-static void ent_ccmd_call( world_instance *world, ent_call *call ){
-   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) );
-   }
-}
-
-/*
- * BVH implementation
- * ----------------------------------------------------------------------------
- */
-
-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_objective ){
-      ent_objective *objective = mdl_arritm( &world->ent_objective, 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<objective->submesh_count; i++ ){
-         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs,
-                                       objective->submesh_start+i );
-         box_concat( box, sm->bbx );
-      }
-
-      m4x3f transform;
-      mdl_transform_m4x3( &objective->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}} );
-   }
-   else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_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}};
-      m4x3f transform;
-      mdl_transform_m4x3( &challenge->transform, transform );
-      m4x3_expand_aabb_aabb( transform, bound, box );
-   }
-   else{
-      vg_fatal_error( "Programming error\n" );
-   }
-}
-
-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_objective ){
-      ent_objective *objective = mdl_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 );
-      return volume->transform.co[axis];
-   }
-   else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
-      return challenge->transform.co[axis];
-   }
-   else {
-      vg_fatal_error( "Programming error\n" );
-      return INFINITY;
-   }
-}
-
-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;
-}
-
-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_objective ){
-      ent_objective *objective = mdl_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,
-                                       objective->submesh_start+i );
-         box_concat( box, sm->bbx );
-      }
-
-      m4x3f transform;
-      mdl_transform_m4x3( &objective->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 if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_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}};
-      m4x3f transform;
-      mdl_transform_m4x3( &challenge->transform, transform );
-      vg_line_boxf_transformed( transform, box, 0xf0ff0000 );
-   }
-   else{
-      vg_fatal_error( "Programming error\n" );
-   }
-}
-
-static void entity_bh_closest( void *user, u32 item_index, v3f point,
-                                  v3f closest ){
-   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 );
-      v3_copy( gate->to_world[3], closest );
-   }
-   else if( type == k_ent_objective ){
-      ent_objective *challenge = mdl_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 );
-      v3_copy( volume->to_world[3], closest );
-   }
-   else if( type == k_ent_challenge ){
-      ent_challenge *challenge = mdl_arritm( &world->ent_challenge, index );
-      v3_copy( challenge->transform.co, closest );
-   }
-   else{
-      vg_fatal_error( "Programming error\n" );
-   }
-}
-
-static void world_entity_start( world_instance *world, vg_msg *sav ){
-   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++ ){
-      ent_audio *audio = mdl_arritm(&world->ent_audio,i);
-      if( audio->flags & AUDIO_FLAG_AUTO_START ){
-         ent_call call;
-         call.data = NULL;
-         call.function = k_ent_function_trigger;
-         call.id = mdl_entity_id( k_ent_audio, i );
-         entity_call( world, &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 );
-
-      if( vg_msg_getkvu32( sav, alias, 0 ) ){
-         ent_call call;
-         call.data = NULL;
-         call.function = 0;
-         call.id = mdl_entity_id( k_ent_challenge, i );
-         entity_call( world, &call );
-      }
-   }
-}
-
-static 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);
-
-      const char *alias = mdl_pstr(&world->meta,challenge->pstr_alias);
-      vg_msg_wkvu32( sav, alias, challenge->status );
-   }
-}
-
-#endif /* WORLD_ENTITY_C */