fuckin hell
[carveJwlIkooP6JGAAIwe30JlM.git] / world_gen.h
index 89fea39c9f5068227257a806da896f1aad23db4a..f5e7599c7fe260f17439259f3ea1e0e49ac16e85 100644 (file)
@@ -182,6 +182,11 @@ VG_STATIC void world_ents_allocate(void)
          k_classtype_logic_achievement,
          (void*)&world.logic_achievements,
          sizeof(struct logic_achievement)
+      },
+      {
+         k_classtype_point_light,
+         (void*)&world.lights,
+         sizeof(struct world_light)
       }
    };
 
@@ -325,6 +330,16 @@ VG_STATIC void world_pct_achievement( mdl_node *pnode )
    world.achievement_count ++;
 }
 
+VG_STATIC void world_pct_point_light( 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(void)
 {
@@ -340,7 +355,8 @@ VG_STATIC void world_entities_process(void)
       { 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_logic_achievement, world_pct_achievement },
+      { k_classtype_point_light, world_pct_point_light }
    };
 
    for( int i=0; i<world.meta->info.node_count; i++ )
@@ -360,6 +376,42 @@ VG_STATIC void world_entities_process(void)
    }
 }
 
+VG_STATIC void world_scene_compute_light_clusters( 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;
+         }
+      }
+   }
+}
+
 VG_STATIC void world_generate(void)
 {
    /* 
@@ -387,10 +439,8 @@ VG_STATIC void world_generate(void)
 
       scene_copy_slice( world.scene_geo, &mat->sm_geo );
    }
+   world_scene_compute_light_clusters( world.scene_geo );
 
-
-
-   
    /* compress that bad boy */
    world.scene_geo = scene_fix( world.dynamic_vgl, world.scene_geo );
 
@@ -434,6 +484,7 @@ VG_STATIC void world_generate(void)
 
       scene_copy_slice( world.scene_no_collide, &mat->sm_no_collide );
    }
+   world_scene_compute_light_clusters( world.scene_no_collide );
 
    /* upload and free that */
    vg_acquire_thread_sync();
@@ -531,6 +582,17 @@ VG_STATIC void world_post_process(void)
       v4_copy( info_vec, winfo->g_depth_bounds );
 
       winfo->g_water_fog = 0.04f;
+
+      for( int i=0; i<world.light_count; i++ )
+      {
+         struct world_light *light = &world.lights[i];
+
+         v3_muls( light->colour, light->colour[3] * 2.0f,
+                  gpipeline.ub_world_lighting.g_point_light_colours[i] );
+         v3_copy( light->co, 
+                  gpipeline.ub_world_lighting.g_point_light_positions[i] );
+      }
+
       render_update_lighting_ub();
    }
 
@@ -664,6 +726,9 @@ VG_STATIC void world_unload(void)
    world.triggers = NULL;
    world.trigger_count = 0;
 
+   world.lights = NULL;
+   world.light_count = 0;
+
    world.logic_relays = NULL;
    world.relay_count = 0;