loader stuff
authorhgn <hgodden00@gmail.com>
Mon, 22 May 2023 05:02:15 +0000 (06:02 +0100)
committerhgn <hgodden00@gmail.com>
Mon, 22 May 2023 05:02:15 +0000 (06:02 +0100)
22 files changed:
blender_export.py
bvh.h
ent_skateshop.c
ent_skateshop.h
maps_src/mp_arizona.mdl [deleted file]
maps_src/mp_gridmap.mdl [deleted file]
maps_src/mp_home.mdl [deleted file]
maps_src/mp_mtzero.mdl [deleted file]
maps_src/mp_mtzero/main.mdl [new file with mode: 0644]
maps_src/mp_mtzero/main.mdl.meta [new file with mode: 0644]
maps_src/mp_spawn.mdl [deleted file]
maps_src/mp_spawn/main.mdl [new file with mode: 0644]
player_skate.c
pointcloud.h
rigidbody.h
shaders/cloud.vs
shaders/point_map.h
skaterift.c
skaterift.h
workshop.h
world.h
world_routes.h

index 8c1eaace97da36bdd8f3831d403f8521a9c86e8c..293b87cd89e81385131e586cd25a939446ff929f 100644 (file)
@@ -1922,6 +1922,7 @@ def sr_compile( collection ):
    path = F"{folder}{collection.name}.mdl"
    print( path )
 
+   os.makedirs(os.path.dirname(path),exist_ok=True)
    fp = open( path, "wb" )
    header = mdl_header()
    header.version = 101
diff --git a/bvh.h b/bvh.h
index ddc81ca7c1ad5793d45d72ca579aeccab7e85657..21bfb39c3b162ceca22d22a207b3021f6931747a 100644 (file)
--- a/bvh.h
+++ b/bvh.h
@@ -228,9 +228,7 @@ VG_STATIC int bh_ray( bh_tree *bh, v3f co, v3f dir, ray_hit *hit )
    stack[2] = bh->nodes[0].ir;
 
    v3f dir_inv;
-   dir_inv[0] = 1.0f/dir[0];
-   dir_inv[1] = 1.0f/dir[1];
-   dir_inv[2] = 1.0f/dir[2];
+   v3_div( (v3f){1.0f,1.0f,1.0f}, dir, dir_inv );
    
    while(depth){
       bh_node *inode = &bh->nodes[ stack[depth] ];
@@ -269,30 +267,73 @@ VG_STATIC int bh_ray( bh_tree *bh, v3f co, v3f dir, ray_hit *hit )
 typedef struct bh_iter bh_iter;
 struct bh_iter
 {
-   struct 
-   {
-      int id, depth;
+   struct {
+      i32 id, depth;
    }
    stack[64];
 
-   int depth, i;
+   enum bh_query_type{
+      k_bh_query_box,
+      k_bh_query_ray
+   }
+   query;
+
+   union{
+      struct{
+         boxf box;
+      }
+      box;
+
+      struct{
+         v3f co, inv_dir;
+         f32 max_dist;
+      }
+      ray;
+   };
+
+   i32 depth, i;
 };
 
-VG_STATIC void bh_iter_init( int root, bh_iter *it )
+VG_STATIC void bh_iter_init_box( i32 root, bh_iter *it, boxf box )
 {
+   it->query = k_bh_query_box;
    it->stack[0].id = root;
    it->stack[0].depth = 0;
    it->depth = 0;
    it->i = 0;
+
+   box_copy( box, it->box.box );
 }
 
-VG_STATIC int bh_next( bh_tree *bh, bh_iter *it, boxf box, int *em )
+VG_STATIC void bh_iter_init_ray( i32 root, bh_iter *it, v3f co, 
+                                 v3f dir, f32 max_dist )
+{
+   it->query = k_bh_query_ray;
+   it->stack[0].id = root;
+   it->stack[0].depth = 0;
+   it->depth = 0;
+   it->i = 0;
+   
+   v3_div( (v3f){1.0f,1.0f,1.0f}, dir, it->ray.inv_dir );
+   v3_copy( co, it->ray.co );
+   it->ray.max_dist = max_dist;
+}
+
+VG_STATIC i32 bh_next( bh_tree *bh, bh_iter *it, i32 *em )
 {
    while( it->depth >= 0 ){
       bh_node *inode = &bh->nodes[ it->stack[it->depth].id ];
       
       /* Only process overlapping nodes */
-      if( !box_overlap( inode->bbx, box ) ){
+      i32 q = 0;
+
+      if( it->query == k_bh_query_box )
+         q = box_overlap( inode->bbx, it->box.box );
+      else
+         q = ray_aabb1( inode->bbx, it->ray.co, 
+                        it->ray.inv_dir, it->ray.max_dist );
+
+      if( !q ){
          it->depth --;
          continue;
       }
index 40362219b37b9d8ae1c6479c7ebad3b6077cd469..a3e12dca52986e6b39c14c12b97e75f759321348 100644 (file)
@@ -353,6 +353,147 @@ VG_STATIC void workshop_op_item_scan(void)
    vg_loader_start( workshop_scan_thread, NULL );
 }
 
+/*
+ * op: k_async_op_world_scan
+ * -----------------------------------------------------------------------------
+ */
+
+/*
+ * Reciever for scan completion. copies the registry_count back into t0
+ */
+VG_STATIC void workshop_async_world_reg_update( void *data, u32 size )
+{
+   vg_info( "World registry update notify\n" );
+   global_skateshop.world_registry_count = 
+      global_skateshop.t1_world_registry_count;
+   skaterift_end_op();
+}
+
+/*
+ * Add a local world folder to the registry, it will verify existing ones are 
+ * still there too.
+ */
+VG_STATIC void world_scan_register_local( const char *folder_name )
+{
+   u32 hash = vg_strdjb2( folder_name );
+   for( u32 i=0; i<global_skateshop.t1_world_registry_count; i++ ){
+      struct registry_world *reg = 
+         &global_skateshop.world_registry[i];
+
+      if( const_str_eq( hash, folder_name, reg->foldername ) ){
+         reg->state = k_registry_board_state_indexed;
+         return;
+      }
+   }
+
+   if( global_skateshop.t1_world_registry_count == SKATESHOP_WORLDS_MAX ){
+      vg_error( "You have too many worlds installed!\n" );
+      return;
+   }
+
+   vg_info( "new listing!: %s\n", folder_name );
+
+   struct registry_world *reg = &global_skateshop.world_registry[
+      global_skateshop.t1_world_registry_count ++ ];
+
+   vg_strncpy( folder_name, reg->foldername, 64, k_strncpy_overflow_fatal );
+   reg->foldername_hash = hash;
+   reg->state = k_registry_board_state_indexed;
+   reg->meta_present = 0;
+}
+
+/*
+ * Async thread which scans local files for boards, as well as scheduling 
+ * synchronous calls to the workshop
+ */
+VG_STATIC void world_scan_thread( void *_args )
+{
+   vg_linear_clear( vg_mem.scratch );
+
+   for( u32 i=0; i<global_skateshop.t1_world_registry_count; i++ ){
+      struct registry_world *reg = &global_skateshop.world_registry[i];
+      reg->state = k_registry_board_state_indexed_absent;
+   }
+
+   /*
+    * Local disk scan
+    */
+   vg_info( "Scanning maps/*.mdl\n" );
+
+   char path_buf[4096];
+   vg_str path;
+   vg_strnull( &path, path_buf, 4096 );
+   vg_strcat( &path, "maps/" );
+
+   DIR *dir = opendir( path.buffer );
+   if( !dir ){
+      vg_error( "opendir('maps') failed\n" );
+      vg_async_call( workshop_async_any_complete, NULL, 0 );
+      return;
+   }
+
+   struct dirent *entry;
+   while( (entry = readdir(dir)) ){
+      if( entry->d_type == DT_DIR ){
+         if( entry->d_name[0] == '.' ) continue;
+
+         vg_str folder = path;
+         char *folder_name = folder.buffer+folder.i;
+
+         if( strlen( entry->d_name ) >
+               vg_list_size(global_skateshop.world_registry[0].foldername)){
+            vg_warn( "Map folder too long: %s\n", entry->d_name );
+            continue;
+         }
+
+         vg_strcat( &folder, entry->d_name );
+         if( !vg_strgood( &folder ) ) break;
+
+         DIR *subdir = opendir( folder.buffer );
+         while( (entry = readdir(subdir)) ){
+            if( entry->d_type == DT_REG ){
+               if( entry->d_name[0] == '.' ) continue;
+
+               vg_str file = folder;
+               vg_strcat( &file, "/" );
+               vg_strcat( &file, entry->d_name );
+               if( !vg_strgood( &file ) ) break;
+
+               char *ext = vg_strch( &file, '.' );
+               if( !ext ) continue;
+               if( strcmp(ext,".mdl") ) continue;
+               
+               vg_strcat( &folder, "" );
+               world_scan_register_local( folder_name );
+            }
+         }
+         closedir(subdir);
+      }
+   }
+   closedir(dir);
+
+   vg_async_call( workshop_async_world_reg_update, NULL, 0 );
+
+#if 0
+   tinydir_close(&dir);
+
+   if( steam_ready ) workshop_steam_scan();
+   
+   vg_async_call( workshop_async_reg_update, NULL, 0 );
+   vg_async_stall();
+   workshop_visibile_load_loop_thread(NULL);
+#endif
+}
+
+/*
+ * Asynchronous scan of local disk for worlds
+ */
+VG_STATIC void skateshop_op_world_scan(void)
+{
+   skaterift_begin_op( k_async_op_world_scan );
+   vg_loader_start( world_scan_thread, NULL );
+}
+
 /*
  * Regular stuff
  * -----------------------------------------------------------------------------
@@ -408,10 +549,12 @@ VG_STATIC void callback_persona_statechange( CallbackMsg_t *msg )
 VG_STATIC void skateshop_init(void)
 {
    u32 reg_size   = sizeof(struct registry_board)*SKATESHOP_REGISTRY_MAX,
+       wreg_size  = sizeof(struct registry_world)*SKATESHOP_WORLDS_MAX,
        cache_size = sizeof(struct cache_board)*SKATESHOP_BOARD_CACHE_MAX;
    
    global_skateshop.registry = vg_linear_alloc( vg_mem.rtmemory, reg_size );
-   global_skateshop.registry_count = 0;
+   global_skateshop.world_registry = 
+      vg_linear_alloc( vg_mem.rtmemory, wreg_size );
    global_skateshop.cache = vg_linear_alloc( vg_mem.rtmemory, cache_size );
 
    memset( global_skateshop.cache, 0, cache_size );
@@ -573,23 +716,36 @@ VG_STATIC void global_skateshop_preupdate(void)
       }
    }
    else if( shop->type == k_skateshop_type_worldshop ){
-      gui_helper_action( axis_display_string( k_sraxis_mbrowse_h ), "browse" );
-
-      v2f input;
-      joystick_state( k_srjoystick_steer, input );
-      pointcloud.control[0] += input[0] * vg.time_delta;
-      pointcloud.control[2] += input[1] * vg.time_delta;
+      if( global_skateshop.world_registry_count ){
+         gui_helper_action( axis_display_string(k_sraxis_mbrowse_h), "browse" );
+      }
+      
+      int change = 0;
+      if( button_down( k_srbind_mleft ) ){
+         if( global_skateshop.selected_world_id > 0 ){
+            global_skateshop.selected_world_id --;
+            change = 1;
+         }
+      }
 
-      pointcloud.control[0] = vg_clampf( pointcloud.control[0], -10.0f, 10.0f );
-      pointcloud.control[2] = vg_clampf( pointcloud.control[2], -10.0f, 10.0f );
+      if( button_down( k_srbind_mright ) ){
+         if( global_skateshop.selected_world_id+1 < 
+                  global_skateshop.world_registry_count ){
+            global_skateshop.selected_world_id ++;
+            change = 1;
+         }
+      }
+      
+      if( change && (pointcloud.anim == k_pointcloud_anim_idle) ){
+         pointcloud.anim = k_pointcloud_anim_hiding;
+         pointcloud.anim_start = vg.time;
+      }
 
-      if( button_press( k_srbind_trick1 ) ){
-         pointcloud.control[3] += vg.time_delta*0.2f;
+      if( button_down( k_srbind_maccept ) ){
+         vg_info( "Select world (%u)\n", global_skateshop.selected_world_id );
+         global_skateshop_exit();
+         return;
       }
-      if( button_press( k_srbind_trick0 ) ){
-         pointcloud.control[3] -= vg.time_delta*0.2f;
-}
-      pointcloud.control[3] = vg_clampf( pointcloud.control[3], 0.001f, 10.0f );
    }
    else{
       vg_fatal_error( "Unknown store (%u)\n", shop->type );
@@ -718,6 +874,7 @@ fade_out:;
    mlocal[3][0] = -font3d_string_width( &world_global.font, 0, info->title );
    mlocal[3][0] *= scale*0.5f;
    mlocal[3][1] = 0.1f;
+   mlocal[3][2] = 0.0f;
    m4x3_mul( mtext, mlocal, mmdl );
    font3d_simple_draw( &world_global.font, 0, info->title, &main_camera, mmdl );
 
@@ -729,6 +886,7 @@ fade_out:;
                                         info->author_name );
    mlocal[3][0] *= scale*0.5f;
    mlocal[3][1] = 0.0f;
+   mlocal[3][2] = 0.0f;
    m4x3_mul( mtext, mlocal, mmdl );
    font3d_simple_draw( &world_global.font, 0, 
                        info->author_name, &main_camera, mmdl );
@@ -742,50 +900,74 @@ VG_STATIC void skateshop_render_worldshop(void)
 {
    world_instance *world = get_active_world();
 
-   m4x3f mmdl;
    ent_skateshop *shop = global_skateshop.ptr_ent;
    ent_marker *mark_display = mdl_arritm( &world->ent_marker,
-                                  mdl_entity_id_id(shop->worlds.id_display));
-   mdl_transform_m4x3( &mark_display->transform, mmdl );
-
-   /* TODO? ... */
-#if 0
-   v3f vol;
-   v3_sub( world->scene_geo.bbx[1], world->scene_geo.bbx[0], vol );
-
-   v2f rect = { 1.0f, 1.0f },
-       map  = { vol[0], vol[2] },
-       result;
-
-   f32 rp = rect[0] * map[1],
-       rc = rect[1] * map[0];
+                                  mdl_entity_id_id(shop->worlds.id_display)),
+              *mark_info = mdl_arritm( &world->ent_marker, 
+                                  mdl_entity_id_id(shop->boards.id_info));
+
+   /* Text */
+   char buftext[128], bufsubtext[128];
+   vg_str info, subtext;
+   vg_strnull( &info, buftext, 128 );
+   vg_strnull( &subtext, bufsubtext, 128 );
    
-   u32 axis, other;
-   if( rc > rp ) axis = 0;
-   else          axis = 1;
-   other = axis ^ 0x1;
-
-   result[axis] = rect[axis];
-   result[other] = (rect[axis] * map[other]) / map[axis];
+   if( global_skateshop.world_registry_count ){
+      struct registry_world *rw = &global_skateshop.world_registry[
+         global_skateshop.selected_world_id ];
+
+      info.i+=highscore_intl( info.buffer+info.i, 
+                              global_skateshop.selected_world_id+1, 3 );
+      info.buffer[info.i++] = '/';
+      info.i+=highscore_intl( info.buffer+info.i, 
+                              global_skateshop.world_registry_count, 3 );
+      info.buffer[info.i++] = ' ';
+      info.buffer[info.i] = '\0';
+
+      if( rw->meta_present ){
+         vg_fatal_error("");
+      }
+      else{
+         vg_strcat( &info, rw->foldername );
+         vg_strcat( &subtext, "No information" );
+      }
+   }
+   else{
+      vg_strcat( &info, "No worlds installed" );
+   }
 
-   m4x3f mlocal, mx;
-   m4x3_identity( mlocal );
+   m4x3f mtext,mlocal,mtextmdl;
+   mdl_transform_m4x3( &mark_info->transform, mtext );
 
-   mlocal[0][0] = result[0];
-   mlocal[2][2] = result[1];
-   mlocal[1][1] = (vol[1]/vol[0]) * mlocal[0][0];
-   mlocal[3][0] = (rect[0]-result[0])*0.5f - rect[0]*0.5f;  /* sea level? */
-   mlocal[3][2] = (rect[1]-result[1])*0.5f - rect[1]*0.5f;
-   m4x3_mul( mmdl, mlocal, mx );
-#endif
+   font3d_bind( &world_global.font, &main_camera );
+   shader_model_font_uColour( (v4f){1.0f,1.0f,1.0f,1.0f} );
 
+   float scale = 0.2f, thickness = 0.015f, scale1 = 0.08f;
+   m3x3_zero( mlocal );
+   m3x3_setdiagonalv3( mlocal, (v3f){ scale, scale, thickness } );
+   mlocal[3][0] = -font3d_string_width( &world_global.font, 0, buftext );
+   mlocal[3][0] *= scale*0.5f;
+   mlocal[3][1] = 0.1f;
+   mlocal[3][2] = 0.0f;
+   m4x3_mul( mtext, mlocal, mtextmdl );
+   font3d_simple_draw( &world_global.font, 0, buftext, &main_camera, mtextmdl );
+
+   m3x3_setdiagonalv3( mlocal, (v3f){ scale1, scale1, thickness } );
+   mlocal[3][0] = -font3d_string_width( &world_global.font, 0, bufsubtext );
+   mlocal[3][0] *= scale1*0.5f;
+   mlocal[3][1] = -scale1*0.3f;
+   m4x3_mul( mtext, mlocal, mtextmdl );
+   font3d_simple_draw( &world_global.font, 0, bufsubtext, 
+                       &main_camera, mtextmdl );
+
+   /* pointcloud */
+   m4x3f mmdl;
+   mdl_transform_m4x3( &mark_display->transform, mmdl );
    m4x3_rotate_y( mmdl, vg.time * 0.2 );
 
-#if 1
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDisable(GL_DEPTH_TEST);
-#endif
    pointcloud_render( world, &main_camera, mmdl );
    glDisable(GL_BLEND);
    glEnable(GL_DEPTH_TEST);
@@ -846,6 +1028,11 @@ VG_STATIC void ent_skateshop_call( world_instance *world, ent_call *call )
          skateshop_update_viewpage();
          workshop_op_item_scan();
       }
+      else if( shop->type == k_skateshop_type_worldshop ){
+         pointcloud.anim = k_pointcloud_anim_opening;
+         pointcloud.anim_start = vg.time;
+         skateshop_op_world_scan();
+      }
    }
 }
 
index 2cc5d5a15ad41b8cd0640988fdae391d0ff2a987..f73b875d069004144d3123fd18a01fd97a3b9426 100644 (file)
@@ -8,6 +8,7 @@
 
 #define SKATESHOP_REGISTRY_MAX     64
 #define SKATESHOP_BOARD_CACHE_MAX  10
+#define SKATESHOP_WORLDS_MAX       32
 #define SKATESHOP_VIEW_SLOT_MAX    6
 #define SKATESHOP_REGISTRYID_NONE  0xffffffff
 
@@ -63,6 +64,20 @@ struct{
           registry_count;
 
    u32 selected_registry_id;
+
+   /* worlds */
+   struct registry_world{
+      enum registry_board_state state;
+      char foldername[64];
+      u32 foldername_hash;
+      
+      int meta_present;
+      ent_worldinfo info;
+   }
+   *world_registry;
+   u32 t1_world_registry_count,
+          world_registry_count,
+       selected_world_id;
 }
 static global_skateshop;
 
diff --git a/maps_src/mp_arizona.mdl b/maps_src/mp_arizona.mdl
deleted file mode 100644 (file)
index 01ea7eb..0000000
Binary files a/maps_src/mp_arizona.mdl and /dev/null differ
diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl
deleted file mode 100644 (file)
index c4763cc..0000000
Binary files a/maps_src/mp_gridmap.mdl and /dev/null differ
diff --git a/maps_src/mp_home.mdl b/maps_src/mp_home.mdl
deleted file mode 100644 (file)
index 265f909..0000000
Binary files a/maps_src/mp_home.mdl and /dev/null differ
diff --git a/maps_src/mp_mtzero.mdl b/maps_src/mp_mtzero.mdl
deleted file mode 100644 (file)
index ddd7d6d..0000000
Binary files a/maps_src/mp_mtzero.mdl and /dev/null differ
diff --git a/maps_src/mp_mtzero/main.mdl b/maps_src/mp_mtzero/main.mdl
new file mode 100644 (file)
index 0000000..ddd7d6d
Binary files /dev/null and b/maps_src/mp_mtzero/main.mdl differ
diff --git a/maps_src/mp_mtzero/main.mdl.meta b/maps_src/mp_mtzero/main.mdl.meta
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/maps_src/mp_spawn.mdl b/maps_src/mp_spawn.mdl
deleted file mode 100644 (file)
index 2c01527..0000000
Binary files a/maps_src/mp_spawn.mdl and /dev/null differ
diff --git a/maps_src/mp_spawn/main.mdl b/maps_src/mp_spawn/main.mdl
new file mode 100644 (file)
index 0000000..8978cf2
Binary files /dev/null and b/maps_src/mp_spawn/main.mdl differ
index f38f6d4302a38c8914ac4b60c4de46ebd470b56d..e208a49b6cf99aef08e6518060e3842e5e6a5b72 100644 (file)
@@ -102,10 +102,6 @@ VG_STATIC int skate_grind_scansq( player_instance *player,
    boxf box;
    v3_add( pos, (v3f){ r, r, r }, box[1] );
    v3_sub( pos, (v3f){ r, r, r }, box[0] );
-   
-   bh_iter it;
-   bh_iter_init( 0, &it );
-   int idx;
 
    struct grind_sample
    {
@@ -124,7 +120,11 @@ VG_STATIC int skate_grind_scansq( player_instance *player,
    v3_cross( plane, player->basis[1], support_axis );
    v3_normalize( support_axis );
    
-   while( bh_next( world->geo_bh, &it, box, &idx ) ){
+   bh_iter it;
+   bh_iter_init_box( 0, &it, box );
+   i32 idx;
+   
+   while( bh_next( world->geo_bh, &it, &idx ) ){
       u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
       v3f tri[3];
 
index 454d9a46b8df9e318801c3a570fffda1852caec9..f29197f6e491bb13e8f1c4caac8446733be3aa1b 100644 (file)
 struct pointcloud{
    GLuint vao, vbo;
    u32 count;
-   v4f control;
+
+   f64 anim_start;
+   f32 visibility;
+   enum pointcloud_anim{
+      k_pointcloud_anim_opening = 0,
+      k_pointcloud_anim_hiding  = 1,
+      k_pointcloud_anim_idle    = 2
+   }
+   anim;
 }
-static pointcloud = { .control = {0.0f,0.0f,0.0f,1.0f} };
+static pointcloud;
 
 #pragma pack(push,1)
 struct pointcloud_vert{
@@ -96,6 +104,28 @@ static void pointcloud_init(void)
 
 static void pointcloud_render( world_instance *world, camera *cam, m4x3f model )
 {
+   if( pointcloud.anim != k_pointcloud_anim_idle ){
+      f32 const k_transition = 1.0f;
+      f32 t = (vg.time - pointcloud.anim_start) / k_transition;
+
+      if( pointcloud.anim == k_pointcloud_anim_hiding ){
+         if( t > 1.0f ){
+            pointcloud.visibility = 0.0f;
+            pointcloud.anim = k_pointcloud_anim_idle;
+         }
+         else pointcloud.visibility = 1.0f-t;
+      }
+      else if( pointcloud.anim == k_pointcloud_anim_opening ){
+         if( t > 1.0f ){
+            pointcloud.visibility = 1.0f;
+            pointcloud.anim = k_pointcloud_anim_idle;
+         }
+         else pointcloud.visibility = t;
+      }
+   }
+
+   if( pointcloud.visibility == 0.0f ) return;
+
    m4x4f upvmprev;
    m4x3_expand( model, upvmprev );
    m4x4_mul( cam->mtx_prev.pv, upvmprev, upvmprev );
@@ -105,8 +135,8 @@ static void pointcloud_render( world_instance *world, camera *cam, m4x3f model )
    shader_point_map_uPvmPrev( upvmprev );
    shader_point_map_uMdl( model );
    shader_point_map_uCamera( cam->pos );
-   shader_point_map_uTime( (v2f){ vg.time, sinf(vg.time) } );
-   shader_point_map_uTransform( pointcloud.control );
+   shader_point_map_uAnim( (v4f){ 32, 1.0f-pointcloud.visibility, 
+                                  0.0f, vg.time } );
 
    glBindVertexArray( pointcloud.vao );
    glEnable( GL_PROGRAM_POINT_SIZE );
index efce416487fc164d2a2772d8c4a44d499fc2d989..b3bd4425cb6d493e5a89c7465325891b133eaac5 100644 (file)
@@ -1233,18 +1233,18 @@ VG_STATIC int rb_sphere__scene( m4x3f mtxA, rb_sphere *b,
 {
    scene_context *sc = s->bh_scene->user;
 
-   bh_iter it;
-   bh_iter_init( 0, &it );
-   int idx;
-
    int count = 0;
 
    float r = b->radius + 0.1f;
    boxf box;
    v3_sub( mtxA[3], (v3f){ r,r,r }, box[0] );
    v3_add( mtxA[3], (v3f){ r,r,r }, box[1] );
+
+   bh_iter it;
+   i32 idx;
+   bh_iter_init_box( 0, &it, box );
    
-   while( bh_next( s->bh_scene, &it, box, &idx ) ){
+   while( bh_next( s->bh_scene, &it, &idx ) ){
       u32 *ptri = &sc->arrindices[ idx*3 ];
       v3f tri[3];
 
@@ -1294,13 +1294,13 @@ VG_STATIC int rb_box__scene( m4x3f mtxA, boxf bbx,
    m4x3_invert_affine( mtxA, to_local );
 
    bh_iter it;
-   bh_iter_init( 0, &it );
+   bh_iter_init_box( 0, &it, world_bbx );
    int idx;
    int count = 0;
 
    vg_line_boxf( world_bbx, VG__RED );
    
-   while( bh_next( s->bh_scene, &it, world_bbx, &idx ) ){
+   while( bh_next( s->bh_scene, &it, &idx ) ){
       u32 *ptri = &sc->arrindices[ idx*3 ];
 
       for( int j=0; j<3; j++ )
@@ -1517,9 +1517,6 @@ VG_STATIC int rb_capsule__scene( m4x3f mtxA, rb_capsule *c,
                                  m4x3f mtxB, rb_scene *s, 
                                  rb_ct *buf )
 {
-   bh_iter it;
-   bh_iter_init( 0, &it );
-   int idx;
    int count = 0;
 
    boxf bbx;
@@ -1528,7 +1525,10 @@ VG_STATIC int rb_capsule__scene( m4x3f mtxA, rb_capsule *c,
    
    scene_context *sc = s->bh_scene->user;
    
-   while( bh_next( s->bh_scene, &it, bbx, &idx ) ){
+   bh_iter it;
+   bh_iter_init_box( 0, &it, bbx );
+   i32 idx;
+   while( bh_next( s->bh_scene, &it, &idx ) ){
       u32 *ptri = &sc->arrindices[ idx*3 ];
       v3f tri[3];
 
index 431afd05c28f3163ad0c42c9b373231d21b59758..88b0d4dd721dd438cacd726c1e3dac09eac0bcd9 100644 (file)
@@ -7,8 +7,7 @@ uniform mat4x3 uMdl;
 uniform mat3 uNormMtx;
 uniform mat4 uPv;
 uniform mat4 uPvmPrev;
-uniform vec2 uTime;
-uniform vec4 uTransform;
+uniform vec4 uAnim;
 
 out vec4 aColour;
 out vec3 aWorldCo;
@@ -21,37 +20,34 @@ vec2 rand_hash22( vec2 p )
    return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
 }
 
-vec3 mapP( vec3 p )
+vec3 gridify( vec3 p, float s, float t )
 {
-   return p;
-   float t = max(0.0,uTime.y);
+   vec3 co = p*s;
+   vec2 r2 = rand_hash22(p.xz);
+   vec3 grid = vec3(floor(co.x),co.y,floor(co.z)) * (1.0/s);
 
-   vec3 lco = p * 20.0;
-   vec3 grid = vec3(floor(lco.x),lco.y,floor(lco.z));//fract(p);
+   float t1 = 1.0-t;
+         t1 = 1.0-t1*t1;
+   float t2 = t*t;
 
-   return mix(p,grid * (1.0/20.0), t)*vec3(1.0+t,1.0-t,1.0+t);
+   return mix( p, grid, t1 ) + t2*vec3(0.0,r2.y*r2.y*0.2,0.0);
 }
 
 void main()
 {
-   vec3 mco = a_co.xyz * uTransform.w + uTransform.xyz;
+   vec3 co = gridify( a_co.xyz, uAnim.x, uAnim.y );
 
-
-   vec3 center = vec3(0.5);
-   vec3 lco = mapP(mco);
-
-   vec3 world_pos0 = uMdl     * vec4( mco, 1.0 );
+   vec3 world_pos0 = uMdl     * vec4( co, 1.0 );
    vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );
-   vec4 vproj1     = uPvmPrev * vec4( mco, 1.0 );
+   vec4 vproj1     = uPvmPrev * vec4( co, 1.0 );
 
-   float t = max(0.0,uTime.y);
-   float scaler = smoothstep(0.6,0.58,length(lco.xz));
+   float scaler = smoothstep(0.6,0.58,length(co.xz));
 
    vs_motion_out( vproj0, vproj1 );
 
    gl_Position = vproj0;
-   gl_PointSize = (9.0*uTransform.w*scaler) / (gl_Position.z + 0.01);
+   gl_PointSize = (9.0*scaler) / (gl_Position.z + 0.01);
    aWorldCo = world_pos0;
-   aColour = a_colour*scaler;
-   aCo = mco;
+   aColour = a_colour*scaler*(1.0-uAnim.y*uAnim.y);
+   aCo = co;
 }
index 931d512595edad6ddadd5c1a0e7e32db449fd6c1..5330dec1d3e496bba8330c5414c822deba31ee12 100644 (file)
@@ -36,8 +36,7 @@ static struct vg_shader _shader_point_map = {
 "uniform mat3 uNormMtx;\n"
 "uniform mat4 uPv;\n"
 "uniform mat4 uPvmPrev;\n"
-"uniform vec2 uTime;\n"
-"uniform vec4 uTransform;\n"
+"uniform vec4 uAnim;\n"
 "\n"
 "out vec4 aColour;\n"
 "out vec3 aWorldCo;\n"
@@ -50,39 +49,36 @@ static struct vg_shader _shader_point_map = {
 "   return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));\n"
 "}\n"
 "\n"
-"vec3 mapP( vec3 p )\n"
+"vec3 gridify( vec3 p, float s, float t )\n"
 "{\n"
-"   return p;\n"
-"   float t = max(0.0,uTime.y);\n"
+"   vec3 co = p*s;\n"
+"   vec2 r2 = rand_hash22(p.xz);\n"
+"   vec3 grid = vec3(floor(co.x),co.y,floor(co.z)) * (1.0/s);\n"
 "\n"
-"   vec3 lco = p * 20.0;\n"
-"   vec3 grid = vec3(floor(lco.x),lco.y,floor(lco.z));//fract(p);\n"
+"   float t1 = 1.0-t;\n"
+"         t1 = 1.0-t1*t1;\n"
+"   float t2 = t*t;\n"
 "\n"
-"   return mix(p,grid * (1.0/20.0), t)*vec3(1.0+t,1.0-t,1.0+t);\n"
+"   return mix( p, grid, t1 ) + t2*vec3(0.0,r2.y*r2.y*0.2,0.0);\n"
 "}\n"
 "\n"
 "void main()\n"
 "{\n"
-"   vec3 mco = a_co.xyz * uTransform.w + uTransform.xyz;\n"
+"   vec3 co = gridify( a_co.xyz, uAnim.x, uAnim.y );\n"
 "\n"
-"\n"
-"   vec3 center = vec3(0.5);\n"
-"   vec3 lco = mapP(mco);\n"
-"\n"
-"   vec3 world_pos0 = uMdl     * vec4( mco, 1.0 );\n"
+"   vec3 world_pos0 = uMdl     * vec4( co, 1.0 );\n"
 "   vec4 vproj0     = uPv      * vec4( world_pos0, 1.0 );\n"
-"   vec4 vproj1     = uPvmPrev * vec4( mco, 1.0 );\n"
+"   vec4 vproj1     = uPvmPrev * vec4( co, 1.0 );\n"
 "\n"
-"   float t = max(0.0,uTime.y);\n"
-"   float scaler = smoothstep(0.6,0.58,length(lco.xz));\n"
+"   float scaler = smoothstep(0.6,0.58,length(co.xz));\n"
 "\n"
 "   vs_motion_out( vproj0, vproj1 );\n"
 "\n"
 "   gl_Position = vproj0;\n"
-"   gl_PointSize = (9.0*uTransform.w*scaler) / (gl_Position.z + 0.01);\n"
+"   gl_PointSize = (9.0*scaler) / (gl_Position.z + 0.01);\n"
 "   aWorldCo = world_pos0;\n"
-"   aColour = a_colour*scaler;\n"
-"   aCo = mco;\n"
+"   aColour = a_colour*scaler*(1.0-uAnim.y*uAnim.y);\n"
+"   aCo = co;\n"
 "}\n"
 ""},
    .fs = 
@@ -137,8 +133,7 @@ static GLuint _uniform_point_map_uMdl;
 static GLuint _uniform_point_map_uNormMtx;
 static GLuint _uniform_point_map_uPv;
 static GLuint _uniform_point_map_uPvmPrev;
-static GLuint _uniform_point_map_uTime;
-static GLuint _uniform_point_map_uTransform;
+static GLuint _uniform_point_map_uAnim;
 static GLuint _uniform_point_map_uCamera;
 static void shader_point_map_uMdl(m4x3f m){
    glUniformMatrix4x3fv(_uniform_point_map_uMdl,1,GL_FALSE,(float*)m);
@@ -152,11 +147,8 @@ static void shader_point_map_uPv(m4x4f m){
 static void shader_point_map_uPvmPrev(m4x4f m){
    glUniformMatrix4fv(_uniform_point_map_uPvmPrev,1,GL_FALSE,(float*)m);
 }
-static void shader_point_map_uTime(v2f v){
-   glUniform2fv(_uniform_point_map_uTime,1,v);
-}
-static void shader_point_map_uTransform(v4f v){
-   glUniform4fv(_uniform_point_map_uTransform,1,v);
+static void shader_point_map_uAnim(v4f v){
+   glUniform4fv(_uniform_point_map_uAnim,1,v);
 }
 static void shader_point_map_uCamera(v3f v){
    glUniform3fv(_uniform_point_map_uCamera,1,v);
@@ -170,8 +162,7 @@ static void shader_point_map_link(void){
    _uniform_point_map_uNormMtx = glGetUniformLocation( _shader_point_map.id, "uNormMtx" );
    _uniform_point_map_uPv = glGetUniformLocation( _shader_point_map.id, "uPv" );
    _uniform_point_map_uPvmPrev = glGetUniformLocation( _shader_point_map.id, "uPvmPrev" );
-   _uniform_point_map_uTime = glGetUniformLocation( _shader_point_map.id, "uTime" );
-   _uniform_point_map_uTransform = glGetUniformLocation( _shader_point_map.id, "uTransform" );
+   _uniform_point_map_uAnim = glGetUniformLocation( _shader_point_map.id, "uAnim" );
    _uniform_point_map_uCamera = glGetUniformLocation( _shader_point_map.id, "uCamera" );
 }
 #endif /* SHADER_point_map_H */
index daac040234cbfd89f99c2c063f26a6b159680ba6..6f0364a9db7970728743a4ab2f1e68274eeca3cc 100644 (file)
@@ -136,7 +136,7 @@ VG_STATIC void vg_load(void)
 
    /* 'systems' are completely loaded now */
    /* load home/permanent world */
-   world_load( 0, "maps/mp_spawn.mdl" );
+   world_load( 0, "maps/mp_spawn/main.mdl" );
 
    vg_console_load_autos();
    menu_link();
index b76fd1dc69d52b8c085d6ab837223cec1bbf10ae..5d250a1fe7e0978afcdd278bde4f436823065d95 100644 (file)
@@ -9,7 +9,7 @@ struct{
       k_async_op_clientloading,
       k_async_op_world_preloading,
       k_async_op_world_loading,
-      k_async_op_cloud_loading,
+      k_async_op_world_scan,
       k_workshop_form_op_loading_model,
       k_workshop_form_op_downloading_submission,
       k_workshop_form_op_publishing_update,
index 6418339d4851dd7811b5a89977f62a1a4f558c83..9029ed09d12d0bfddff000aae8edc869dcb6a67f 100644 (file)
@@ -5,6 +5,7 @@
 #include "vg/vg.h"
 #include "vg/vg_steam_remote_storage.h"
 #include "skaterift.h"
+#include "pointcloud.h"
 
 struct workshop_file_info{
    u64 author;
@@ -12,6 +13,14 @@ struct workshop_file_info{
    char title[64];
 };
 
+struct world_file_info{
+   char title[64];      /* extracted from ent_worldinfo */
+   char location[64];
+
+   u32 pointcloud_count;
+   pointcloud_vert pointcloud[];
+};
+
 struct async_workshop_filepath_info{
    PublishedFileId_t id;
    char *buf;
diff --git a/world.h b/world.h
index 66b3b28f2c0b14a961cf7ea04ef4b27321332cc7..98d7efbe611fdab0930a5e880f5bbf2a40b4accd 100644 (file)
--- a/world.h
+++ b/world.h
@@ -681,12 +681,12 @@ VG_STATIC void world_update( world_instance *world, v3f pos )
    v3_sub( pos, (v3f){ radius, radius, radius }, volume_proximity[0] );
 
    bh_iter it;
-   bh_iter_init( 0, &it );
-   int idx;
+   bh_iter_init_box( 0, &it, volume_proximity );
+   i32 idx;
 
    int in_volume = 0;
 
-   while( bh_next( world->volume_bh, &it, volume_proximity, &idx ) ){
+   while( bh_next( world->volume_bh, &it, &idx ) ){
       ent_volume *volume = mdl_arritm( &world->ent_volume, idx );
 
       boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
@@ -776,9 +776,6 @@ VG_STATIC int ray_world( world_instance *world,
 VG_STATIC int spherecast_world( world_instance *world,
                                 v3f pa, v3f pb, float r, float *t, v3f n )
 {
-   bh_iter it;
-   bh_iter_init( 0, &it );
-
    boxf region;
    box_init_inf( region );
    box_addpt( region, pa );
@@ -798,8 +795,10 @@ VG_STATIC int spherecast_world( world_instance *world,
    int hit = -1;
    float min_t = 1.0f;
 
-   int idx;
-   while( bh_next( world->geo_bh, &it, region, &idx ) ){
+   bh_iter it;
+   bh_iter_init_box( 0, &it, region );
+   i32 idx;
+   while( bh_next( world->geo_bh, &it, &idx ) ){
       u32 *ptri = &world->scene_geo.arrindices[ idx*3 ];
       v3f tri[3];
 
index bb344ed4383db7416dfcfdde84660ba821e1f6a0..b0151b4eecda1f288f0853b8219e437fea71de13 100644 (file)
@@ -649,13 +649,14 @@ VG_STATIC f64 world_routes_scatter_surface_points( world_instance *world,
 VG_STATIC void world_routes_surface_grid( world_instance *world,
                                           pointcloud_buffer *pcbuf )
 {
-   i32 const k_gridlines = 63,
+   i32 const k_gridlines = 32,
              k_gridres   = 255;
 
    v3f inv_ext;
    v3_sub( pcbuf->boundary[1], pcbuf->boundary[0], inv_ext );
    v3_div( (v3f){1.0f,1.0f,1.0f}, inv_ext, inv_ext );
    v4f colour = {0.2f,0.2f,0.2f,1.0f};
+   v3f dir = {0.0f,-1.0f,0.0f};
 
    for( u32 k=0; k<2; k++ ){
       u32 a = k*2,
@@ -669,35 +670,51 @@ VG_STATIC void world_routes_surface_grid( world_instance *world,
             f32 tz = (float)z / (float)k_gridres,
                 pz = vg_lerpf(pcbuf->boundary[0][b],pcbuf->boundary[1][b], tz);
 
-            v3f ro;
+            v3f ro, hit;
             ro[a] = px;
             ro[1] = 1000.0f;
             ro[b] = pz;
 
-            ray_hit hit;
-            hit.dist = INFINITY;
+            bh_iter it;
+            bh_iter_init_ray( 0, &it, ro, dir, INFINITY );
+            i32 idx;
 
-            if( ray_world( world, ro, (v3f){0.0f,-1.0f,0.0f}, &hit )){
-               struct world_surface *m1 = ray_hit_surface( world, &hit );
+            while( bh_next( world->geo_bh, &it, &idx ) ){
+               u32 *tri = &world->scene_geo.arrindices[ idx*3 ];
+               v3f vs[3];
 
-               if( world->water.enabled )
-                  if( hit.pos[1] < world->water.height )
+               for( u32 i=0; i<3; i++ ){
+                  v3_copy( world->scene_geo.arrvertices[tri[i]].co, vs[i] );
+               }
+               
+               f32 t;
+               if( ray_tri( vs, ro, dir, &t ) ){
+                  v3_muladds( ro, dir, t, hit );
+                  struct world_surface *m1 = 
+                     world_tri_index_surface( world, tri[0] );
+
+                  if( !(m1->info.flags & k_material_flag_preview_visibile) )
                      continue;
 
-               if( pcbuf->count >= pcbuf->max ) return;
+                  if( world->water.enabled )
+                     if( hit[1] < world->water.height )
+                        continue;
 
-               pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
+                  if( pcbuf->count >= pcbuf->max ) return;
 
-               v3f co;
-               v3_sub( hit.pos, pcbuf->boundary[0], co );
-               v3_mul( co, inv_ext, co );
+                  pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ];
 
-               for( u32 i=0; i<3; i++ ){
-                  vert->pos[i] = (co[i]-0.5f) * 32767.0f;
-               }
+                  v3f co;
+                  v3_sub( hit, pcbuf->boundary[0], co );
+                  v3_mul( co, inv_ext, co );
+
+                  for( u32 i=0; i<3; i++ ){
+                     vert->pos[i] = (co[i]-0.5f) * 32767.0f;
+                  }
 
-               for( u32 i=0; i<4; i++ ){
-                  vert->colour[i] = colour[i] * 255.0f;
+                  for( u32 i=0; i<4; i++ ){
+                     vert->colour[i] = colour[i] * 255.0f;
+                  }
                }
             }
          }