-VG_STATIC void world_ents_allocate( world_instance *world )
-{
- vg_info( "Allocating entities\n" );
-
- /* count entites to allocate buffers for them.
- * maybe in the future we just store these numbers in the model file...
- *
- * TODO: use this in world_routes too */
-
- struct countable
- {
- enum classtype ct;
- void **to_allocate;
- u32 item_size;
- int count;
- }
- entity_counts[] =
- {
- {
- k_classtype_spawn,
- (void*)&world->spawns,
- sizeof(struct respawn_point)
- },
- {
- k_classtype_audio,
- (void*)&world->audio_things,
- sizeof(struct world_audio_thing)
- },
- {
- k_classtype_trigger,
- (void*)&world->triggers,
- sizeof(struct trigger_zone)
- },
- {
- k_classtype_logic_relay,
- (void*)&world->logic_relays,
- sizeof(struct logic_relay)
- },
- {
- k_classtype_logic_achievement,
- (void*)&world->logic_achievements,
- sizeof(struct logic_achievement)
- },
- {
- k_classtype_point_light,
- (void*)&world->lights,
- sizeof(struct world_light)
- }
- };
-
- for( int i=0; i<vg_list_size(entity_counts); i++ )
- entity_counts[i].count = 0;
-
- for( int i=0; i<world->meta->info.node_count; i++ )
- {
- mdl_node *pnode = mdl_node_from_id( world->meta, i );
-
- for( int j=0; j<vg_list_size(entity_counts); j ++ )
- {
- if( pnode->classtype == entity_counts[j].ct )
- {
- pnode->sub_uid = entity_counts[j].count;
- entity_counts[j].count ++;
- break;
- }
- }
- }
-
- for( int i=0; i<vg_list_size(entity_counts); i++ )
- {
- struct countable *counter = &entity_counts[i];
-
- u32 bufsize = counter->item_size*counter->count;
- *counter->to_allocate = vg_linear_alloc( world_global.generic_heap,
- bufsize );
- }
-}
-
-VG_STATIC void world_pct_spawn( world_instance *world, mdl_node *pnode )
-{
- struct respawn_point *rp = &world->spawns[ world->spawn_count ++ ];
-
- v3_copy( pnode->co, rp->co );
- v4_copy( pnode->q, rp->q );
- rp->name = mdl_pstr( world->meta, pnode->pstr_name );
-}
-
-VG_STATIC void world_pct_water( world_instance *world, mdl_node *pnode )
-{
- if( world->water.enabled )
- {
- vg_warn( "Multiple water surfaces in level! ('%s')\n",
- mdl_pstr( world->meta, pnode->pstr_name ));
- return;
- }
-
- world->water.enabled = 1;
- water_set_surface( world, pnode->co[1] );
-}
-
-VG_STATIC void world_pct_audio( world_instance *world, mdl_node *pnode )
-{
- struct world_audio_thing *thing = &world->audio_things[
- world->audio_things_count ];
-
- memset( thing, 0, sizeof(struct world_audio_thing) );
- struct classtype_audio *aud = mdl_get_entdata( world->meta, pnode );
-
- v3_copy( pnode->co, thing->pos );
-
- if( aud->flags & AUDIO_FLAG_SPACIAL_3D )
- thing->volume = aud->volume * pnode->s[0];
- else
- thing->volume = aud->volume;
-
- thing->flags = aud->flags;
- thing->temp_embedded_clip.path = mdl_pstr( world->meta, aud->pstr_file );
- thing->temp_embedded_clip.source_mode = k_audio_source_mono;
-
- audio_clip_load( &thing->temp_embedded_clip, world_global.audio_heap );
- thing->player.name = mdl_pstr( world->meta, pnode->pstr_name );
- thing->player.enqued = 0;
-
- pnode->sub_uid = world->audio_things_count;
- world->audio_things_count ++;
-}
-
-VG_STATIC void world_pct_trigger( world_instance *world, mdl_node *pnode )
-{
- struct trigger_zone *trigger = &world->triggers[ world->trigger_count ];
- struct classtype_trigger *inf = mdl_get_entdata( world->meta, pnode );
-
- if( inf->target )
- {
- mdl_node *target_node = mdl_node_from_id( world->meta, inf->target );
-
- trigger->target.sub_id = target_node->sub_uid;
- trigger->target.classtype = target_node->classtype;
- }
- else
- {
- vg_warn( "Trigger with no target...\n" );
- return;
- }
-
- mdl_node_transform( pnode, trigger->transform );
- m4x3_invert_full( trigger->transform, trigger->inv_transform );
-
- world->trigger_count ++;
-}
-
-
-VG_STATIC void world_pct_relay( world_instance *world, mdl_node *pnode )
-{
- struct logic_relay *relay = &world->logic_relays[ world->relay_count ];
- struct classtype_logic_relay *inf = mdl_get_entdata( world->meta, pnode );
-
- relay->target_count = 0;
-
- for( int i=0; i<vg_list_size(relay->targets); i++ )
- {
- if( inf->targets[i] )
- {
- struct relay_target *target = &relay->targets[relay->target_count ++];
- mdl_node *other = mdl_node_from_id( world->meta, inf->targets[i] );
-
- target->classtype = other->classtype;
- target->sub_id = other->sub_uid;
- }
- }
-
- v3_copy( pnode->co, relay->pos );
- world->relay_count ++;
-}
-
-
-VG_STATIC void world_pct_achievement( world_instance *world, mdl_node *pnode )
-{
- struct logic_achievement *ach =
- &world->logic_achievements[ world->achievement_count ];
- struct classtype_logic_achievement *inf =
- mdl_get_entdata( world->meta, pnode );
-
- v3_copy( pnode->co, ach->pos );
- ach->achievement_id = mdl_pstr( world->meta, inf->pstr_name );
- ach->achieved = 0;
-
- world->achievement_count ++;
-}
-
-VG_STATIC void world_pct_point_light( world_instance *world, mdl_node *pnode )
-{
- struct world_light *light = &world->lights[ world->light_count ];
- v3_copy( pnode->co, light->co );
-
- struct classtype_point_light *inf = mdl_get_entdata( world->meta, pnode );
- v4_copy( inf->colour, light->colour );
-
- world->light_count ++;
-}
-
-VG_STATIC void world_entities_process( world_instance *world )
-{
- struct entity_instruction
- {
- enum classtype ct;
- void (*process)( world_instance *world, mdl_node *pnode );
- }
- entity_instructions[] =
- {
- { k_classtype_spawn, world_pct_spawn },
- { k_classtype_water, world_pct_water },
- { k_classtype_audio, world_pct_audio },
- { k_classtype_trigger, world_pct_trigger },
- { k_classtype_logic_relay, world_pct_relay },
- { k_classtype_logic_achievement, world_pct_achievement },
- { k_classtype_point_light, world_pct_point_light }
- };
-
- for( int i=0; i<world->meta->info.node_count; i++ )
- {
- mdl_node *pnode = mdl_node_from_id( world->meta, i );
-
- for( int j=0; j<vg_list_size(entity_instructions); j++ )
- {
- struct entity_instruction *instr = &entity_instructions[j];
-
- if( pnode->classtype == instr->ct )
- {
- instr->process( world, pnode );
- break;
- }
- }
- }
-}
-
-VG_STATIC void world_scene_compute_light_clusters( world_instance *world,
- scene *sc )
-{
- for( int i=0; i<sc->vertex_count; i++ )
- {
- scene_vert *vert = &sc->arrvertices[i];
- vert->lights[0] = 255;
- vert->lights[1] = 255;
- vert->lights[2] = 255;
- vert->lights[3] = 255;
-
- float distances[4] = { INFINITY, INFINITY, INFINITY, INFINITY };
-
- for( int j=0; j<world->light_count; j ++ )
- {
- float dist = v3_dist2( world->lights[j].co, vert->co );
-
- int best_pos = 4;
- for( int k=best_pos-1; k>=0; k -- )
- if( dist < distances[k] )
- best_pos = k;
-
- if( best_pos < 4 )
- {
- for( int k=3; k>best_pos; k -- )
- {
- distances[k] = distances[k-1];
- vert->lights[k] = vert->lights[k-1];
- }
-
- distances[best_pos] = dist;
- vert->lights[best_pos] = j;
- }
- }
- }
-}
-