From: hgn Date: Mon, 22 May 2023 05:02:15 +0000 (+0100) Subject: loader stuff X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=63b5ac44f74599b21c4b9b18398c29b797337bea;p=carveJwlIkooP6JGAAIwe30JlM.git loader stuff --- diff --git a/blender_export.py b/blender_export.py index 8c1eaac..293b87c 100644 --- a/blender_export.py +++ b/blender_export.py @@ -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 ddc81ca..21bfb39 100644 --- 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; } diff --git a/ent_skateshop.c b/ent_skateshop.c index 4036221..a3e12dc 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -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; ifoldername ) ){ + 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; istate = 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(); + } } } diff --git a/ent_skateshop.h b/ent_skateshop.h index 2cc5d5a..f73b875 100644 --- a/ent_skateshop.h +++ b/ent_skateshop.h @@ -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 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 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 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 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 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 index 0000000..e69de29 diff --git a/maps_src/mp_spawn.mdl b/maps_src/mp_spawn.mdl deleted file mode 100644 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 index 0000000..8978cf2 Binary files /dev/null and b/maps_src/mp_spawn/main.mdl differ diff --git a/player_skate.c b/player_skate.c index f38f6d4..e208a49 100644 --- a/player_skate.c +++ b/player_skate.c @@ -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]; diff --git a/pointcloud.h b/pointcloud.h index 454d9a4..f29197f 100644 --- a/pointcloud.h +++ b/pointcloud.h @@ -10,9 +10,17 @@ 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 ); diff --git a/rigidbody.h b/rigidbody.h index efce416..b3bd442 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -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]; diff --git a/shaders/cloud.vs b/shaders/cloud.vs index 431afd0..88b0d4d 100644 --- a/shaders/cloud.vs +++ b/shaders/cloud.vs @@ -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; } diff --git a/shaders/point_map.h b/shaders/point_map.h index 931d512..5330dec 100644 --- a/shaders/point_map.h +++ b/shaders/point_map.h @@ -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 */ diff --git a/skaterift.c b/skaterift.c index daac040..6f0364a 100644 --- a/skaterift.c +++ b/skaterift.c @@ -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(); diff --git a/skaterift.h b/skaterift.h index b76fd1d..5d250a1 100644 --- a/skaterift.h +++ b/skaterift.h @@ -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, diff --git a/workshop.h b/workshop.h index 6418339..9029ed0 100644 --- a/workshop.h +++ b/workshop.h @@ -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 66b3b28..98d7efb 100644 --- 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]; diff --git a/world_routes.h b/world_routes.h index bb344ed..b0151b4 100644 --- a/world_routes.h +++ b/world_routes.h @@ -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; + } } } }