From 5d5d5f394cbe2212769bc58a70fa622b4ed46205 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 23 May 2023 06:55:37 +0100 Subject: [PATCH] mission is possible 2 --- .gitignore | 1 + ent_skateshop.c | 156 +++++++++++++++++++++++++++++++++++--------- ent_skateshop.h | 7 +- pointcloud.h | 28 ++++++-- shaders/cloud.vs | 2 +- shaders/point_map.h | 2 +- skaterift.h | 1 + world_load.c | 1 + world_load.h | 3 - world_physics.h | 1 + world_routes.c | 79 +++++++++++++++++++++- world_water.h | 2 +- 12 files changed, 236 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index 2a91391..ae6d327 100755 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.dll *.log *.old +*.bin # soft links steamworks_sdk diff --git a/ent_skateshop.c b/ent_skateshop.c index 19b868f..a667599 100644 --- a/ent_skateshop.c +++ b/ent_skateshop.c @@ -394,7 +394,8 @@ VG_STATIC void world_scan_register_local( const char *folder_name ) 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; + //reg->meta_present = 0; + reg->type = k_world_load_type_local; } /* @@ -587,6 +588,69 @@ VG_STATIC struct cache_board *skateshop_selected_cache_if_loaded(void) return NULL; } +VG_STATIC void pointcloud_async_end(void *_, u32 __) +{ + pointcloud_animate( k_pointcloud_anim_opening ); + skaterift_end_op(); +} + +VG_STATIC void pointcloud_clear_async(void *_, u32 __) +{ + pointcloud.count = 0; + pointcloud_animate( k_pointcloud_anim_opening ); + skaterift_end_op(); +} + +VG_STATIC void skateshop_preview_loader_thread( void *_data ) +{ + struct registry_world *reg = _data; + + if( reg->type == k_world_load_type_local ){ + char path_buf[4096]; + vg_str path; + vg_strnull( &path, path_buf, 4096 ); + vg_strcat( &path, "maps/" ); + vg_strcat( &path, reg->foldername ); + vg_strcat( &path, "/preview.bin" ); + + vg_linear_clear(vg_mem.scratch); + u32 size; + + void *data = vg_file_read( vg_mem.scratch, path_buf, &size ); + if( data ){ + if( size < sizeof(pointcloud_buffer) ){ + vg_async_call( pointcloud_clear_async, NULL, 0 ); + return; + } + + vg_async_item *call = vg_async_alloc(size); + pointcloud_buffer *pcbuf = call->payload; + memcpy( pcbuf, data, size ); + + u32 point_count = (size-sizeof(pointcloud_buffer)) / + sizeof(struct pointcloud_vert); + pcbuf->max = point_count; + pcbuf->count = point_count; + pcbuf->op = k_pointcloud_op_clear; + + vg_async_dispatch( call, async_pointcloud_sub ); + vg_async_call( pointcloud_async_end, NULL, 0 ); + } + else{ + vg_async_call( pointcloud_clear_async, NULL, 0 ); + } + } + else{ + vg_async_call( pointcloud_clear_async, NULL, 0 ); + } +} + +VG_STATIC void skateshop_load_world_preview( struct registry_world *reg ) +{ + skaterift_begin_op( k_async_op_world_load_preview ); + vg_loader_start( skateshop_preview_loader_thread, reg ); +} + /* * VG event preupdate */ @@ -600,7 +664,6 @@ VG_STATIC void global_skateshop_preupdate(void) if( !global_skateshop.active ) return; world_instance *world = world_current_instance(); - ent_skateshop *shop = global_skateshop.ptr_ent; /* camera positioning */ @@ -711,45 +774,78 @@ VG_STATIC void global_skateshop_preupdate(void) } } else if( shop->type == k_skateshop_type_worldshop ){ - if( global_skateshop.world_registry_count ){ + int browseable = 0, + loadable = 0; + + if( global_skateshop.world_registry_count && + ((skaterift.async_op == k_async_op_none)|| + (skaterift.async_op == k_async_op_world_load_preview))){ gui_helper_action( axis_display_string(k_sraxis_mbrowse_h), "browse" ); + browseable = 1; } if( skaterift.async_op == k_async_op_none ){ gui_helper_action( button_display_string(k_srbind_maccept), "load" ); + loadable = 1; } int change = 0; - if( button_down( k_srbind_mleft ) ){ - if( global_skateshop.selected_world_id > 0 ){ - global_skateshop.selected_world_id --; - change = 1; + + if( browseable ){ + if( button_down( k_srbind_mleft ) ){ + if( global_skateshop.selected_world_id > 0 ) + { + global_skateshop.selected_world_id --; + change = 1; + } } - } - 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( 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.visibility == 1.0f ){ - pointcloud.anim = k_pointcloud_anim_hiding; - pointcloud.anim_start = vg.time; + if( change && pointcloud_idle() ){ + pointcloud_animate( k_pointcloud_anim_hiding ); } - if( (skaterift.async_op == k_async_op_none ) && - button_down( k_srbind_maccept ) ) - { + if( skaterift.async_op == k_async_op_none ){ struct registry_world *rw = &global_skateshop.world_registry[ global_skateshop.selected_world_id ]; - vg_info( "Select world (%u)\n", global_skateshop.selected_world_id ); - skaterift_change_world( rw->foldername ); - return; + /* automatically load in clouds */ + if( loadable && button_down( k_srbind_maccept ) ){ + vg_info( "Select world (%u)\n", + global_skateshop.selected_world_id ); + skaterift_change_world( rw->foldername ); + return; + } + else{ + if( pointcloud.anim == k_pointcloud_anim_idle_closed ){ + if( global_skateshop.pointcloud_world_id != + global_skateshop.selected_world_id ) + { + global_skateshop.pointcloud_world_id = + global_skateshop.selected_world_id; + skateshop_load_world_preview( rw ); + } + else{ + pointcloud_animate( k_pointcloud_anim_opening ); + } + } + else if( pointcloud.anim == k_pointcloud_anim_idle_open ){ + if( global_skateshop.pointcloud_world_id != + global_skateshop.selected_world_id ) + { + pointcloud_animate( k_pointcloud_anim_hiding ); + } + } + } } } else{ @@ -927,11 +1023,12 @@ VG_STATIC void skateshop_render_worldshop(void) info.buffer[info.i++] = ' '; info.buffer[info.i] = '\0'; - if( rw->meta_present ){ - vg_fatal_error(""); + vg_strcat( &info, rw->foldername ); + if( skaterift.async_op == k_async_op_world_loading || + skaterift.async_op == k_async_op_world_preloading ){ + vg_strcat( &subtext, "Loading..." ); } else{ - vg_strcat( &info, rw->foldername ); vg_strcat( &subtext, "No information" ); } } @@ -939,10 +1036,6 @@ VG_STATIC void skateshop_render_worldshop(void) vg_strcat( &info, "No worlds installed" ); } - if( skaterift.async_op == k_async_op_world_loading || - skaterift.async_op == k_async_op_world_preloading ){ - vg_strcat( &info, "Loading..." ); - } m4x3f mtext,mlocal,mtextmdl; mdl_transform_m4x3( &mark_info->transform, mtext ); @@ -1036,8 +1129,7 @@ VG_STATIC void ent_skateshop_call( world_instance *world, ent_call *call ) workshop_op_item_scan(); } else if( shop->type == k_skateshop_type_worldshop ){ - pointcloud.anim = k_pointcloud_anim_opening; - pointcloud.anim_start = vg.time; + pointcloud_animate( k_pointcloud_anim_opening ); skateshop_op_world_scan(); } } diff --git a/ent_skateshop.h b/ent_skateshop.h index 93ebbec..c368c8d 100644 --- a/ent_skateshop.h +++ b/ent_skateshop.h @@ -2,6 +2,7 @@ #define ENT_SKATESHOP_H #include "world.h" +#include "world_load.h" #include "player.h" #include "vg/vg_steam_remote_storage.h" #include "workshop.h" @@ -70,14 +71,18 @@ struct{ enum registry_board_state state; char foldername[64]; u32 foldername_hash; + enum world_load_type type; +#if 0 int meta_present; ent_worldinfo info; +#endif } *world_registry; u32 t1_world_registry_count, world_registry_count, - selected_world_id; + selected_world_id, + pointcloud_world_id; } static global_skateshop; diff --git a/pointcloud.h b/pointcloud.h index f29197f..4775dd7 100644 --- a/pointcloud.h +++ b/pointcloud.h @@ -14,9 +14,11 @@ struct pointcloud{ f64 anim_start; f32 visibility; enum pointcloud_anim{ - k_pointcloud_anim_opening = 0, - k_pointcloud_anim_hiding = 1, - k_pointcloud_anim_idle = 2 + k_pointcloud_anim_opening, + k_pointcloud_anim_hiding, + k_pointcloud_anim_idle_any, + k_pointcloud_anim_idle_open, + k_pointcloud_anim_idle_closed, } anim; } @@ -102,23 +104,35 @@ static void pointcloud_init(void) shader_point_map_register(); } +static void pointcloud_animate( enum pointcloud_anim anim ) +{ + pointcloud.anim = anim; + pointcloud.anim_start = vg.time; +} + +static int pointcloud_idle(void) +{ + if( pointcloud.anim >= k_pointcloud_anim_idle_any ) return 1; + else return 0; +} + static void pointcloud_render( world_instance *world, camera *cam, m4x3f model ) { - if( pointcloud.anim != k_pointcloud_anim_idle ){ - f32 const k_transition = 1.0f; + if( pointcloud.anim < k_pointcloud_anim_idle_any ){ + f32 const k_transition = 0.6f; 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; + pointcloud.anim = k_pointcloud_anim_idle_closed; } 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; + pointcloud.anim = k_pointcloud_anim_idle_open; } else pointcloud.visibility = t; } diff --git a/shaders/cloud.vs b/shaders/cloud.vs index 88b0d4d..66a2bdf 100644 --- a/shaders/cloud.vs +++ b/shaders/cloud.vs @@ -24,7 +24,7 @@ vec3 gridify( vec3 p, float s, float t ) { 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 grid = (vec3(floor(co.x),co.y,floor(co.z))+vec3(0.5,0.0,0.5)) * (1.0/s); float t1 = 1.0-t; t1 = 1.0-t1*t1; diff --git a/shaders/point_map.h b/shaders/point_map.h index 5330dec..5c674cd 100644 --- a/shaders/point_map.h +++ b/shaders/point_map.h @@ -53,7 +53,7 @@ static struct vg_shader _shader_point_map = { "{\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" +" vec3 grid = (vec3(floor(co.x),co.y,floor(co.z))+vec3(0.5,0.0,0.5)) * (1.0/s);\n" "\n" " float t1 = 1.0-t;\n" " t1 = 1.0-t1*t1;\n" diff --git a/skaterift.h b/skaterift.h index ca31f23..b729bf7 100644 --- a/skaterift.h +++ b/skaterift.h @@ -11,6 +11,7 @@ struct{ k_async_op_world_preloading, k_async_op_world_loading, k_async_op_world_scan, + k_async_op_world_load_preview, k_workshop_form_op_loading_model, k_workshop_form_op_downloading_submission, k_workshop_form_op_publishing_update, diff --git a/world_load.c b/world_load.c index 493b89d..d62029d 100644 --- a/world_load.c +++ b/world_load.c @@ -4,6 +4,7 @@ #include "world_load.h" #include "world_routes.h" #include "world_gate.h" +#include "ent_skateshop.h" /* * load the .mdl file located in path (relative to exe), it will load into the diff --git a/world_load.h b/world_load.h index 74b5911..0b8a912 100644 --- a/world_load.h +++ b/world_load.h @@ -9,9 +9,6 @@ #include "world_entity.h" #include "world_volumes.h" -#include "ent_skateshop.h" -#include "workshop.h" - struct{ char name[64]; diff --git a/world_physics.h b/world_physics.h index 3e7e595..3a5561d 100644 --- a/world_physics.h +++ b/world_physics.h @@ -2,6 +2,7 @@ #define WORLD_PHYSICS_H #include "world.h" +#include "rigidbody.h" VG_STATIC void ray_world_get_tri( world_instance *world, ray_hit *hit, v3f tri[3] ); diff --git a/world_routes.c b/world_routes.c index a66f93f..529fdef 100644 --- a/world_routes.c +++ b/world_routes.c @@ -268,6 +268,57 @@ void world_routes_pointcloud_spot( world_instance *world, } } +/* + * ' + * . + * | + * | + * /#\ + * -'###`- + */ +VG_STATIC +void world_routes_pointcloud_tower( world_instance *world, + pointcloud_buffer *pcbuf, + v3f co, f32 radius, f32 height, + u32 samples, v4f colour ) +{ + 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 ); + + for( u32 j=0; jcount >= pcbuf->max ) + return; + + pointcloud_vert *vert = &pcbuf->buf[ pcbuf->count ++ ]; + + v3f point; + point[0] = vg_randf64()*2.0f-1.0f; + point[1] = 0.0f; + point[2] = vg_randf64()*2.0f-1.0f; + v3_normalize( point ); + v3_muls( point, sqrtf(vg_randf64()), point ); + + f32 h = vg_randf64(); + point[1] = h*h*h*height; + point[0] *= radius; + point[2] *= radius; + + v3_add( point, co, point ); + v3_sub( point, pcbuf->boundary[0], point ); + v3_mul( point, inv_ext, point ); + + /* TODO....... */ + for( u32 i=0; i<3; i++ ){ + vert->pos[i] = (point[i]-0.5f) * 32767.0f; + } + + for( u32 i=0; i<4; i++ ){ + vert->colour[i] = colour[i] * 255.0f; + } + } +} + VG_STATIC void world_routes_place_curve( world_instance *world, ent_route *route, v4f h[3], v3f n0, v3f n2, scene_context *scene, @@ -804,13 +855,39 @@ VG_STATIC void world_gen_routes_generate(void) f64 area = 0.0; area = world_routes_scatter_surface_points( world, pcbuf, 16.0f ); world_routes_surface_grid( world, pcbuf ); + + for( u32 i=0; ient_gate ); i++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, i ); + + world_routes_pointcloud_tower( world, pcbuf, gate->co[0], + 2.0f, 50.0f, 128, + (v4f){0.2f,0.2f,0.2f,1.0f} ); + } + vg_info( "Distrubuted %u points over %fkm^2!\n", pcbuf->count, area/1e6f ); + + if( world_loader.location == k_world_load_type_local ){ + char path_buf[4096]; + vg_str path; + vg_strnull( &path, path_buf, 4096 ); + vg_strcat( &path, "maps/" ); + vg_strcat( &path, world_loader.name ); + vg_strcat( &path, "/preview.bin" ); + + if( !vg_strgood( &path ) ) vg_fatal_error( "Path too long\n" ); + FILE *fp = fopen( path_buf, "wb" ); + if( !fp ) vg_fatal_error( "Cannot open '%s' for writing\n", path_buf ); + + fwrite( pcbuf, sizeof(pcbuf) + + sizeof(struct pointcloud_vert)*pcbuf->count, 1, fp ); + fclose( fp ); + } + vg_async_dispatch( call_pointcloud, async_pointcloud_sub ); } vg_async_dispatch( call_scene, async_scene_upload ); - world_routes_clear( world ); } diff --git a/world_water.h b/world_water.h index ad446d6..ae7a696 100644 --- a/world_water.h +++ b/world_water.h @@ -8,7 +8,7 @@ #include "world.h" struct world_water{ - VG_STATIC GLuint tex_water_surf; + GLuint tex_water_surf; } static world_water; VG_STATIC void world_water_init(void); -- 2.25.1