npcs and tutorial stuff
[carveJwlIkooP6JGAAIwe30JlM.git] / world_gen.c
index 0b0c3442e3105773cf81f127405cb9bed86e6dd3..bc9b2222dc7dda30952b9fca25eb60e6fbccf0cf 100644 (file)
@@ -4,10 +4,6 @@
  * World generation/population. Different to regular loading, since it needs to
  * create geometry, apply procedural stuff and save that image to files etc.
  */
-
-#ifndef WORLD_GEN_C
-#define WORLD_GEN_C
-
 #include "world.h"
 #include "world_gen.h"
 #include "world_load.h"
@@ -46,7 +42,7 @@ static void world_add_all_if_material( m4x3f transform, scene_context *scene,
  * |        |
  * |________|
  */
-static void world_gen_add_blob( world_instance *world,
+static void world_gen_add_blob( vg_rand *rand, world_instance *world,
                                    scene_context *scene, ray_hit *hit )
 {
    m4x3f transform;
@@ -57,7 +53,7 @@ static void world_gen_add_blob( world_instance *world,
 
    float angle = v3_dot(hit->normal,(v3f){0.0f,1.0f,0.0f});
    q_axis_angle( qsurface, axis, angle );
-   q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64()*VG_TAUf );
+   q_axis_angle( qrandom, (v3f){0.0f,1.0f,0.0f}, vg_randf64(rand)*VG_TAUf );
    q_mul( qsurface, qrandom, qsurface );
    q_m3x3( qsurface, transform );
    v3_copy( hit->pos, transform[3] );
@@ -85,13 +81,12 @@ static void world_gen_add_blob( world_instance *world,
 
    scene_vert *ref       = &world->scene_geo.arrvertices[ hit->tri[0] ];
 
-   for( u32 i=0; i<vg_list_size(verts); i++ )
-   {
+   for( u32 i=0; i<vg_list_size(verts); i++ ){
       scene_vert *pvert = &dst_verts[ i ],
                  *src   = &verts[ i ];
 
       m4x3_mulv( transform, src->co, pvert->co );
-      scene_vert_pack_norm( pvert, transform[1] );
+      scene_vert_pack_norm( pvert, transform[1], 0.0f );
 
       v2_copy( ref->uv, pvert->uv );
    }
@@ -110,7 +105,8 @@ static void world_apply_procedural_foliage( world_instance *world,
                                                scene_context *scene,
                                                struct world_surface *mat )
 {
-   if( vg.quality_profile == k_quality_profile_low )
+   if( (vg.quality_profile == k_quality_profile_low) ||
+       (vg.quality_profile == k_quality_profile_min) )
       return;
 
    vg_info( "Applying foliage (%u)\n", mat->info.pstr_name );
@@ -124,9 +120,10 @@ static void world_apply_procedural_foliage( world_instance *world,
    float area = volume[0]*volume[2];
    u32 particles = 0.08f * area;
 
-   /* TODO: Quasirandom? */
    vg_info( "Map area: %f. Max particles: %u\n", area, particles );
 
+   u64 t0 = SDL_GetPerformanceCounter();
+#if 0
    for( u32 i=0; i<particles; i++ ){
       v3f pos;
       v3_mul( volume, (v3f){ vg_randf64(), 1000.0f, vg_randf64() }, pos );
@@ -145,8 +142,52 @@ static void world_apply_procedural_foliage( world_instance *world,
          }
       }
    }
+#else
+
+   vg_rand rand;
+   vg_rand_seed( &rand, 3030 );
+   
+   const f32 tile_scale = 16.0f;
+   v2i tiles = { volume[0]/tile_scale, volume[2]/tile_scale };
+
+   u32 per_tile = particles/(tiles[0]*tiles[1]);
+
+   for( i32 x=0; x<tiles[0]; x ++ ){
+      for( i32 z=0; z<tiles[1]; z ++ ){
+         for( u32 i=0; i<per_tile; i ++ ){
+            v3f co = { (f32)x+vg_randf64(&rand), 0, (f32)z+vg_randf64(&rand) };
+            v3_muls( co, tile_scale, co );
+            co[1] = 1000.0f;
+            v3_add( co, world->scene_geo.bbx[0], co );
+
+            ray_hit hit;
+            hit.dist = INFINITY;
+
+            if( ray_world( world, co, (v3f){0.0f,-1.0f,0.0f}, &hit, 
+                           k_material_flag_ghosts )){
+               struct world_surface *m1 = ray_hit_surface( world, &hit );
+               if((hit.normal[1] > 0.8f) && (m1 == mat) &&
+                  (hit.pos[1] > 0.0f+10.0f)){
+                  world_gen_add_blob( &rand, world, scene, &hit );
+                  count ++;
+               }
+            }
 
-   vg_info( "%d foliage models added\n", count );
+         }
+      }
+   }
+
+#endif
+
+
+
+   u64 t1 = SDL_GetPerformanceCounter(),
+       utime_blobs = t1-t0,
+       ufreq = SDL_GetPerformanceFrequency();
+   f64 ftime_blobs = ((f64)utime_blobs / (f64)ufreq)*1000.0;
+
+   vg_info( "%d foliage models added. %f%% (%fms)\n", count, 
+            100.0*((f64)count/(f64)particles), ftime_blobs);
 }
 
 static 
@@ -165,7 +206,8 @@ void world_unpack_submesh_dynamic( world_instance *world,
 /*
  * Create the main meshes for the world
  */
-static void world_gen_generate_meshes( world_instance *world ){
+void world_gen_generate_meshes( world_instance *world )
+{
    /* 
     * Compile meshes into the world scenes
     */
@@ -222,19 +264,8 @@ static void world_gen_generate_meshes( world_instance *world ){
    /* need send off the memory to the gpu before we can create the bvh. */
    vg_async_stall();
    vg_info( "creating bvh\n" );
-
-   /* setup spacial mapping and rigidbody */
    world->geo_bh = scene_bh_create( world->heap, &world->scene_geo );
 
-   v3_zero( world->rb_geo.rb.co );
-   v3_zero( world->rb_geo.rb.v );
-   q_identity( world->rb_geo.rb.q );
-   v3_zero( world->rb_geo.rb.w );
-
-   world->rb_geo.type = k_rb_shape_scene;
-   world->rb_geo.inf.scene.bh_scene = world->geo_bh;
-   rb_init_object( &world->rb_geo );
-
    /*
     * Generate scene: non-collidable geometry
     * ----------------------------------------------------------------
@@ -273,6 +304,7 @@ static void world_gen_generate_meshes( world_instance *world ){
          mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
                                        vehc->submesh_start+j );
          world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+         world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_TRAFFIC;
       }
    }
 
@@ -287,6 +319,17 @@ static void world_gen_generate_meshes( world_instance *world ){
       }
    }
 
+   /* unpack region models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_region ); i++ ){
+      ent_region *region = mdl_arritm( &world->ent_region, i );
+
+      for( u32 j=0; j<region->submesh_count; j ++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       region->submesh_start+j );
+         world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+      }
+   }
+
    /* unpack gate models */
    for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, i );
@@ -300,6 +343,18 @@ static void world_gen_generate_meshes( world_instance *world ){
       }
    }
 
+   /* unpack prop models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_prop ); i++ ){
+      ent_prop *prop = mdl_arritm( &world->ent_prop, i );
+
+      for( u32 j=0; j<prop->submesh_count; j ++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       prop->submesh_start+j );
+         world->surfaces[ sm->material_id ].flags |= WORLD_SURFACE_HAS_PROPS;
+         world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+      }
+   }
+
    vg_async_dispatch( call, async_scene_upload );
 }
 
@@ -341,7 +396,8 @@ static void async_upload_light_indices( void *payload, u32 size ){
 /*
  * Computes light indices for world
  */
-static void world_gen_compute_light_indices( world_instance *world ){
+void world_gen_compute_light_indices( world_instance *world )
+{
    /* light cubes */
    v3f cubes_min, cubes_max;
    v3_muls( world->scene_geo.bbx[0], 1.0f/k_world_light_cube_size, cubes_min );
@@ -501,7 +557,8 @@ static void world_gen_compute_light_indices( world_instance *world ){
 /*
  * Rendering pass needed to complete the world
  */
-static void async_world_postprocess( void *payload, u32 _size ){
+void async_world_postprocess( void *payload, u32 _size )
+{
    /* create scene lighting buffer */
    world_instance *world = payload;
 
@@ -567,7 +624,7 @@ static void async_world_postprocess( void *payload, u32 _size ){
    /* 
     * Rendering the depth map
     */
-   camera ortho;
+   vg_camera ortho;
 
    v3f extent;
    v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], extent );
@@ -586,8 +643,8 @@ static void async_world_postprocess( void *payload, u32 _size ){
    ortho.mtx.p[3][1] = (ft + fb) * -tb;
    ortho.mtx.p[3][3] = 1.0f;
    m4x3_identity( ortho.transform );
-   camera_update_view( &ortho );
-   camera_finalize( &ortho );
+   vg_camera_update_view( &ortho );
+   vg_camera_finalize( &ortho );
 
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);
@@ -652,19 +709,18 @@ static void async_world_postprocess( void *payload, u32 _size ){
    }
 
    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
-   world->status = k_world_status_loaded;
 }
 
 /* Loads textures from the pack file */
-static void world_gen_load_surfaces( world_instance *world ){
+void world_gen_load_surfaces( world_instance *world )
+{
    vg_info( "Loading textures\n" );
    world->texture_count = 0;
 
    world->texture_count = world->meta.textures.count+1;
    world->textures = vg_linear_alloc( world->heap,
                               vg_align8(sizeof(GLuint)*world->texture_count) );
-
-   vg_tex2d_replace_with_error( &world->textures[0] );
+   world->textures[0] = vg.tex_missing;
 
    for( u32 i=0; i<mdl_arrcount(&world->meta.textures); i++ ){
       mdl_texture *tex = mdl_arritm( &world->meta.textures, i );
@@ -694,9 +750,8 @@ static void world_gen_load_surfaces( world_instance *world ){
    memset( errmat, 0, sizeof(struct world_surface) );
                        
    for( u32 i=0; i<mdl_arrcount(&world->meta.materials); i++ ){
-      world->surfaces[i+1].info = 
-         *(mdl_material *)mdl_arritm( &world->meta.materials, i );
+      struct world_surface *surf = &world->surfaces[i+1];
+      surf->info = *(mdl_material *)mdl_arritm( &world->meta.materials, i );
+      surf->flags = 0;
    }
 }
-
-#endif /* WORLD_GEN_C */