TODO about preupdate call style
[carveJwlIkooP6JGAAIwe30JlM.git] / world.h
diff --git a/world.h b/world.h
index cdf2f16f0c85a901293dbc1cc9dc691c77b235a4..49d1aaea690849f6fb32bfb3e645901940d9d33d 100644 (file)
--- a/world.h
+++ b/world.h
-#ifndef WORLD_H
-#define WORLD_H
+/*
+ * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ */
 
-#define VG_3D
-#include "vg/vg.h"
-
-#include "scene.h"
-#include "terrain.h"
+#pragma once
 #include "render.h"
-#include "water.h"
-
-#include "shaders/standard.h"
-
-static struct gworld
-{
-   scene geo, foliage;
-   submodel sm_road, sm_terrain;
-   glmesh skybox;
-
-   v3f tutorial;
-}
-world;
-
-static void render_world( m4x4f projection, m4x3f camera )
-{
-   render_sky( camera );
-
-   m4x3f identity_matrix;
-   m4x3_identity( identity_matrix );
-
-   render_terrain( projection );
-   scene_bind( &world.geo );
-   scene_draw( &world.geo );
-
-   glDisable(GL_CULL_FACE);
-   scene_bind( &world.foliage );
-   scene_draw( &world.foliage );
-   glEnable(GL_CULL_FACE);
-}
-
-static int ray_world( v3f pos, v3f dir, ray_hit *hit )
-{
-   return bvh_raycast( &world.geo, pos, dir, hit );
-}
-
-static int ray_hit_is_ramp( ray_hit *hit )
-{
-   return hit->tri[0] < world.sm_road.vertex_count;
-}
-
-static void world_init_default(void)
-{
-   /* Setup scene */
-   scene_init( &world.geo );
-   model *mworld = vg_asset_read( "models/mp_dev.mdl" );
-
-   scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ),
-         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
-   scene_copy_slice( &world.geo, &world.sm_road );
-
-   scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ),
-         (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f );
-   scene_copy_slice( &world.geo, &world.sm_terrain );
-
-   v3_copy( model_marker_get( mworld, "mp_dev_tutorial" )->co, world.tutorial );
-
-
-   /* GATE DEV */
-#if 0
-   {
-      model_marker *ga = model_marker_get(mworld,"gate_a"),
-                   *gb = model_marker_get(mworld,"gate_a_recv");
+#include "network_msg.h"
+#include "addon.h"
+#include "scene.h"
 
-      v3_copy( ga->co, gate_a.co );
-      v3_copy( gb->co, gate_b.co );
-      v4_copy( ga->q, gate_a.q );
-      v4_copy( gb->q, gate_b.q );
-      v2_copy( ga->s, gate_a.dims );
-      v2_copy( gb->s, gate_b.dims );
+/* types
+ */
+
+enum world_geo_type{
+   k_world_geo_type_solid = 0,
+   k_world_geo_type_nonsolid = 1,
+   k_world_geo_type_water = 2
+};
+
+enum world_purpose{
+   k_world_purpose_invalid = -1,
+   k_world_purpose_hub = 0,
+   k_world_purpose_client = 1,
+   k_world_max
+};
+
+struct leaderboard_cache {
+   enum request_status status;
+   f64 cache_time;
+   u8 *data;
+   u32 data_len;
+};
+
+typedef struct world_instance world_instance;
+
+void skaterift_world_get_save_path( enum world_purpose which, char buf[128] );
+
+/* submodule headers */
+#include "world_entity.h"
+#include "world_gate.h"
+#include "world_gen.h"
+#include "world_info.h"
+#include "world_physics.h"
+#include "world_render.h"
+#include "world_sfd.h"
+#include "world_volumes.h"
+#include "world_water.h"
+#include "world_audio.h"
+#include "world_routes.h"
+#include "world_routes_ui.h"
+
+/* console variables */
+
+static f32   k_day_length            = 30.0f; /* minutes */
+static i32   k_debug_light_indices   = 0,
+             k_debug_light_complexity= 0,
+             k_light_preview         = 0,
+             k_light_editor          = 0;
+
+#define WORLD_SURFACE_HAS_TRAFFIC 0x1
+#define WORLD_SURFACE_HAS_PROPS   0x2
+
+struct world_instance {
+   /* Fixed items
+    * -------------------------------------------------------
+    */
+
+   v4f player_co;
+
+   void *heap;
+   enum world_status{
+      k_world_status_unloaded = 0,
+      k_world_status_loading = 1,
+      k_world_status_loaded = 2,
+      k_world_status_unloading = 3  /* dont spawn sounds and stuff */
+   }
+   status;
 
-      gate_a.other = &gate_b;
-      gate_b.other = &gate_a;
+   struct{
+      boxf depthbounds;
+      int depth_computed;
 
-      gate_transform_update( &gate_a );
-      gate_transform_update( &gate_b );
+      float height;
+      int enabled;
+      v4f plane;
    }
-#endif
-
-   /* WATER DEV */
-   {
-      glmesh surf;
-      submodel *sm = submodel_get(mworld,"mp_dev_water");
-      model_unpack_submodel( mworld, &surf, sm );
-            
-      water_init();
-      water_set_surface( &surf, sm->pivot[1] );
+   water;
+
+   f64 time;
+   f32 tar_min, tar_max;
+
+   /* STD140 */
+   struct ub_world_lighting{
+      v4f g_cube_min,
+          g_cube_inv_range;
+
+      v4f g_water_plane,
+          g_depth_bounds;
+
+      v4f g_daysky_colour;
+      v4f g_nightsky_colour;
+      v4f g_sunset_colour;
+      v4f g_ambient_colour;
+      v4f g_sunset_ambient;
+      v4f g_sun_colour;
+      v4f g_sun_dir;
+      v4f g_board_0;
+      v4f g_board_1;
+
+      float g_water_fog;
+      float g_time;
+      float g_realtime;
+      float g_shadow_length;
+      float g_shadow_spread;
+
+      float g_time_of_day;
+      float g_day_phase;
+      float g_sunset_phase;
+
+      int g_light_preview;
+      int g_shadow_samples;
+
+      int g_debug_indices;
+      int g_debug_complexity;
    }
-
-   free( mworld );
-   scene_upload( &world.geo );
-   bvh_create( &world.geo );
-
-
-
-   scene_init( &world.foliage );
-   model *mfoliage = vg_asset_read("models/rs_foliage.mdl");
-
-   v3f volume;
-   v3_sub( world.geo.bbx[1], world.geo.bbx[0], volume );
-   volume[1] = 1.0f;
-
-   m4x3f transform;
-
-   for( int i=0;i<100000;i++ )
-   {
-      v3f pos;
-      v3_mul( volume, (v3f){ vg_randf(), 1000.0f, vg_randf() }, pos );
-      v3_add( pos, world.geo.bbx[0], pos );
-      
-      ray_hit hit;
-      hit.dist = INFINITY;
-
-      if( ray_world( pos, (v3f){0.0f,-1.0f,0.0f}, &hit ))
-      {
-         if( hit.normal[1] > 0.8f && !ray_hit_is_ramp(&hit) )
-         {
-            v4f qsurface, qrandom;
-            v3f axis;
-
-            v3_cross( (v3f){0.0f,1.0f,0.0f}, hit.normal, axis );
-
-            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_randf()*VG_TAUf );
-            q_mul( qsurface, qrandom, qsurface );
-            q_m3x3( qsurface, transform );
-
-            v3_copy( hit.pos, transform[3] );
-
-            scene_add_foliage( &world.foliage, mfoliage,
-                  model_get_submodel( mfoliage, 0 ), transform );
-         }
-      }
+   ub_lighting;
+   GLuint ubo_lighting;
+   int    ubo_bind_point;
+
+   GLuint tbo_light_entities,
+          tex_light_entities,
+          tex_light_cubes;
+
+   float probabilities[3];
+
+   v3i light_cubes;
+   struct framebuffer heightmap;
+
+   /*
+    * Dynamically allocated when world_load is called.
+    *
+    *                  the following arrays index somewhere into this linear 
+    *                  allocator
+    * --------------------------------------------------------------------------
+    */
+
+   /*
+    * Main world .mdl 
+    */
+   mdl_context meta;
+
+   GLuint *textures;
+   u32 texture_count;
+
+   struct world_surface{
+      mdl_material info;
+      mdl_submesh sm_geo,
+                  sm_no_collide;
+      u32 flags;
    }
+   * surfaces;
+   u32 surface_count;
+
+   ent_worldinfo info;
+   mdl_array_ptr ent_spawn,
+                 ent_gate,
+                 ent_light,
+                 ent_route_node,
+                 ent_path_index,
+                 ent_checkpoint,
+                 ent_route,
+                 ent_water,
+
+                 ent_audio_clip,
+                 ent_audio,
+                 ent_volume,
+                 ent_traffic,
+                 ent_skateshop,
+                 ent_marker,
+                 ent_camera,
+                 ent_swspreview,
+                 ent_ccmd,
+                 ent_objective,
+                 ent_challenge,
+                 ent_relay,
+                 ent_cubemap,
+                 ent_miniworld,
+                 ent_prop,
+                 ent_region,
+                 ent_glider,
+                 ent_npc;
+
+   enum skybox {
+      k_skybox_default,
+      k_skybox_space
+   } skybox;
+
+   ent_gate *rendering_gate;
+
+   /* logic 
+    * ----------------------------------------------------
+    */
+
+   /* world geometry */
+   scene_context scene_geo,
+                 scene_no_collide,
+                 scene_lines;
+
+   /* spacial mappings */
+   bh_tree *geo_bh,
+           *entity_bh;
+   u32 *entity_list;
+
+   /* graphics */
+   glmesh mesh_route_lines;
+   glmesh mesh_geo, 
+          mesh_no_collide,
+          mesh_water;
+   u32 cubemap_cooldown, cubemap_side;
+
+   /* leaderboards */
+   struct leaderboard_cache *leaderboard_cache;
+
+   /* ui */
+   struct route_ui *routes_ui;
+};
+
+struct world_static {
+   /*
+    * Allocated as system memory
+    * --------------------------------------------------------------------------
+    */
+   void *heap;
+
+   u32 current_run_version;
+   double time, rewind_from, rewind_to, last_use;
+
+   u32 active_trigger_volumes[8];
+   u32 active_trigger_volume_count;
+
+   addon_reg *instance_addons[ k_world_max ];
+   world_instance instances[ k_world_max ];
+
+   enum world_purpose active_instance;
+   u32            focused_entity; /* like skateshop, challenge.. */
+   f32            focus_strength;
+   vg_camera      focus_cam;
+
+   /* challenges */
+   ent_objective *challenge_target;
+   f32 challenge_timer;
+
+   enum world_loader_state{
+      k_world_loader_none,
+      k_world_loader_preload,
+      k_world_loader_load
+   }
+   load_state;
 
-   free( mfoliage );
-   scene_upload( &world.foliage );
+   bool clear_async_op_when_done;
 }
+extern world_static;
 
-#endif /* WORLD_H */
+struct world_load_args 
+{
+   enum world_purpose purpose;
+   addon_reg *reg;
+};
+
+void world_init(void);
+world_instance *world_current_instance(void);
+void world_switch_instance( u32 index );
+void skaterift_world_load_thread( void *_args );
+void world_update( world_instance *world, v3f pos );