From 6ab4435fb19beb6af6c52691793d5ca17a120f69 Mon Sep 17 00:00:00 2001 From: hgn Date: Fri, 21 Jul 2023 02:35:50 +0100 Subject: [PATCH] some gate improvements --- blender_export.py | 41 ++++++++-- entity.h | 17 ++++- maps_src/mp_spawn/main.mdl | Bin 8418152 -> 8422784 bytes model.h | 9 ++- player.c | 2 +- player_skate.c | 2 +- shaders/model_gate.h | 3 - shaders/model_gate.vs | 3 - world_entity.c | 2 +- world_gate.c | 149 +++++++++++++++++++++++-------------- world_gate.h | 2 +- world_gen.c | 13 ++++ world_render.c | 19 ++--- world_routes.c | 5 +- 14 files changed, 174 insertions(+), 93 deletions(-) diff --git a/blender_export.py b/blender_export.py index 820c49a..8eb39a3 100644 --- a/blender_export.py +++ b/blender_export.py @@ -39,6 +39,8 @@ sr_entity_list = [ ('ent_challenge', 'Challenge', '', 18 ) ] +MDL_VERSION_NR = 102 + def get_entity_enum_id( alias ): #{ for et in sr_entity_list:#{ @@ -186,7 +188,7 @@ class version_refcount_union(Union): class ent_gate(Structure): #{ - _fields_ = [("type",c_uint32), + _fields_ = [("flags",c_uint32), ("target", c_uint32), ("key",c_uint32), ("dimensions", c_float*3), @@ -197,7 +199,10 @@ class ent_gate(Structure): ("_anonymous_union",version_refcount_union), ("timing_time",c_double), ("routes",c_uint16*4), - ("route_count",c_uint8)] + ("route_count",c_uint8), + ("submesh_start",c_uint32), # v102+ + ("submesh_count",c_uint32), # v102+ (can be 0) + ] #} class ent_route_node(Structure): @@ -1572,6 +1577,12 @@ def sr_compile( collection ): if ent_type == 'ent_font_variant': continue if ent_type == 'ent_menuitem': continue if ent_type == 'ent_challenge': continue + + #TODO: This is messy. + if ent_type == 'ent_gate':#{ + obj_data = obj.SR_data.ent_gate[0] + if obj_data.custom: continue + #} #-------------------------- print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' ) @@ -1619,18 +1630,27 @@ def sr_compile( collection ): obj_data = obj.SR_data.ent_gate[0] mesh_data = obj.data.SR_data.ent_gate[0] + flags = 0x0000 + if obj_data.tipo == 'default':#{ if obj_data.target:#{ gate.target = sr_compile.entity_ids[obj_data.target.name] - gate.type = 1 + flags |= 0x0001 #} #} elif obj_data.tipo == 'nonlocal':#{ gate.target = 0 gate.key = sr_compile_string(obj_data.key) - gate.type = 2 + flags |= 0x0002 + #} + + if obj_data.flip: flags |= 0x0004 + if obj_data.custom:#{ + flags |= 0x0008 + gate.submesh_start, gate.submesh_count, _ = \ + sr_compile_mesh_internal( obj ) #} - else: gate.type = 0 + gate.flags = flags gate.dimensions[0] = mesh_data.dimensions[0] gate.dimensions[1] = mesh_data.dimensions[1] @@ -1996,7 +2016,7 @@ def sr_compile( collection ): os.makedirs(os.path.dirname(path),exist_ok=True) fp = open( path, "wb" ) header = mdl_header() - header.version = 101 + header.version = MDL_VERSION_NR sr_array_title( header.arrays, \ 'index', len(file_array_instructions), \ sizeof(mdl_array), header_size ) @@ -2380,7 +2400,10 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup): key: bpy.props.StringProperty() tipo: bpy.props.EnumProperty(items=(('default', 'Default', ""), - ('nonlocal', 'Non-Local', ""),)) + ('nonlocal', 'Non-Local', ""))) + + flip: bpy.props.BoolProperty( name="Flip exit", default=False ) + custom: bpy.props.BoolProperty( name="Mesh is surface", default=False ) @staticmethod def sr_inspector( layout, data ): @@ -2390,6 +2413,10 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup): if data[0].tipo == 'default': box.prop( data[0], 'target' ) elif data[0].tipo == 'nonlocal': box.prop( data[0], 'key' ) + + flags = box.box() + flags.prop( data[0], 'flip' ) + flags.prop( data[0], 'custom' ) #} #} diff --git a/entity.h b/entity.h index 05294f3..da2341e 100644 --- a/entity.h +++ b/entity.h @@ -91,15 +91,27 @@ struct ent_light{ v2f angle_sin_cos; }; +/* v101 */ +#if 0 enum gate_type{ k_gate_type_unlinked = 0, k_gate_type_teleport = 1, k_gate_type_nonlocal_unlinked = 2, k_gate_type_nonlocel = 3 }; +#endif + +/* v102+ */ +enum ent_gate_flag{ + k_ent_gate_linked = 0x1, /* this is a working portal */ + k_ent_gate_nonlocal = 0x2, /* use the key string to link this portal. + NOTE: if set, it adds the flip flag. */ + k_ent_gate_flip = 0x4, /* flip direction 180* for exiting portal */ + k_ent_gate_custom_mesh = 0x8, /* use a custom submesh instead of default */ +}; struct ent_gate{ - u32 type, + u32 flags, target, key; @@ -122,6 +134,9 @@ struct ent_gate{ double timing_time; u16 routes[4]; /* routes that pass through this gate */ u8 route_count; + + /* v102+ */ + u32 submesh_start, submesh_count; }; struct ent_route_node{ diff --git a/maps_src/mp_spawn/main.mdl b/maps_src/mp_spawn/main.mdl index 5df1a39b3706c460754163a903c43bcb8e51874b..4467e7b18e3e9baa1dfc01a7350a1cafcce6296b 100644 GIT binary patch delta 7639 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 diff --git a/model.h b/model.h index 6ff0a85..f9ec815 100644 --- a/model.h +++ b/model.h @@ -7,7 +7,8 @@ #include "skaterift.h" -#define MDL_VERSION_NR 101 +#define MDL_VERSION_MIN 101 +#define MDL_VERSION_NR 102 enum mdl_shader { @@ -414,10 +415,10 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc ) if( l != 1 ) mdl_load_fatal_corrupt( mdl ); - if( mdl->info.version < MDL_VERSION_NR ){ + if( mdl->info.version < MDL_VERSION_MIN ){ vg_warn( "For model: %s\n", path ); - vg_warn( " version: %u (current: %u)\n", mdl->info.version, - MDL_VERSION_NR ); + vg_warn( " version: %u (min: %u, current: %u)\n", + mdl->info.version, MDL_VERSION_MIN, MDL_VERSION_NR ); vg_fatal_error( "Legacy model version incompatable" ); } diff --git a/player.c b/player.c index b67e050..ab39319 100644 --- a/player.c +++ b/player.c @@ -164,7 +164,7 @@ void player__pass_gate( player_instance *player, ent_gate *gate ) m4x3_mulv( gate->transport, player->cam.pos, player->cam.pos ); - if( gate->type == k_gate_type_nonlocel ) + if( gate->flags & k_ent_gate_nonlocal ) world_static.active_world = gate->target; audio_lock(); diff --git a/player_skate.c b/player_skate.c index ac14239..baa1ce7 100644 --- a/player_skate.c +++ b/player_skate.c @@ -499,7 +499,7 @@ void player__approximate_best_trajectory( player_instance *player ) m4x3_mulv( gate->transport, launch_co, launch_co ); m3x3_mul( gate->transport, basis, basis ); - if( gate->type == k_gate_type_nonlocel ){ + if( gate->flags & k_ent_gate_nonlocal ){ trace_world = &world_static.worlds[ gate->target ]; } } diff --git a/shaders/model_gate.h b/shaders/model_gate.h index fc9c1ea..cd2c29b 100644 --- a/shaders/model_gate.h +++ b/shaders/model_gate.h @@ -12,9 +12,6 @@ static struct vg_shader _shader_model_gate = { "layout (location=0) in vec3 a_co;\n" "layout (location=1) in vec3 a_norm;\n" "layout (location=2) in vec2 a_uv;\n" -"layout (location=3) in vec4 a_colour;\n" -"layout (location=4) in vec4 a_weights;\n" -"layout (location=5) in ivec4 a_groups;\n" "\n" "uniform mat4 uPv;\n" "uniform mat4x3 uMdl;\n" diff --git a/shaders/model_gate.vs b/shaders/model_gate.vs index edea94d..ce70d52 100644 --- a/shaders/model_gate.vs +++ b/shaders/model_gate.vs @@ -1,9 +1,6 @@ layout (location=0) in vec3 a_co; layout (location=1) in vec3 a_norm; layout (location=2) in vec2 a_uv; -layout (location=3) in vec4 a_colour; -layout (location=4) in vec4 a_weights; -layout (location=5) in ivec4 a_groups; uniform mat4 uPv; uniform mat4x3 uMdl; diff --git a/world_entity.c b/world_entity.c index db1d244..7e285d4 100644 --- a/world_entity.c +++ b/world_entity.c @@ -26,7 +26,7 @@ VG_STATIC void world_gen_entities_init(void){ for( u32 j=0; jent_gate); j ++ ){ ent_gate *gate = mdl_arritm( &world->ent_gate, j ); - if( gate->type == k_gate_type_teleport ){ + if( !(gate->flags & k_ent_gate_nonlocal) ) { gate_transform_update( gate ); } } diff --git a/world_gate.c b/world_gate.c index a61bc16..a4cf8fd 100644 --- a/world_gate.c +++ b/world_gate.c @@ -20,8 +20,13 @@ /* * Update the transform matrices for gate */ -VG_STATIC void gate_transform_update( ent_gate *gate ) -{ +VG_STATIC void gate_transform_update( ent_gate *gate ){ + if( gate->flags & k_ent_gate_flip ){ + v4f qflip; + q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); + q_mul( gate->q[1], qflip, gate->q[1] ); + } + m4x3f to_local, recv_to_world; q_m3x3( gate->q[0], gate->to_world ); @@ -32,9 +37,6 @@ VG_STATIC void gate_transform_update( ent_gate *gate ) q_m3x3( gate->q[1], recv_to_world ); v3_copy( gate->co[1], recv_to_world[3] ); m4x3_mul( recv_to_world, to_local, gate->transport ); - - m3x3_scale( gate->to_world, (v3f){ gate->dimensions[0], - gate->dimensions[1], 1.0f } ); } VG_STATIC void world_gates_init(void) @@ -69,7 +71,7 @@ VG_STATIC void world_gates_init(void) /* * Render the view through a gate */ -VG_STATIC int render_gate( world_instance *world_inside, +VG_STATIC int render_gate( world_instance *world, world_instance *world_inside, ent_gate *gate, camera *cam, int layer_depth ) { v3f viewdir, gatedir; @@ -89,19 +91,20 @@ VG_STATIC int render_gate( world_instance *world_inside, return 0; { - v3f a,b,c,d; + f32 w = gate->dimensions[0], + h = gate->dimensions[1]; - m4x3_mulv( gate->to_world, (v3f){-1.0f,-1.0f,0.0f}, a ); - m4x3_mulv( gate->to_world, (v3f){ 1.0f,-1.0f,0.0f}, b ); - m4x3_mulv( gate->to_world, (v3f){ 1.0f, 1.0f,0.0f}, c ); - m4x3_mulv( gate->to_world, (v3f){-1.0f, 1.0f,0.0f}, d ); + v3f a,b,c,d; + m4x3_mulv( gate->to_world, (v3f){-w,-h,0.0f}, a ); + m4x3_mulv( gate->to_world, (v3f){ w,-h,0.0f}, b ); + m4x3_mulv( gate->to_world, (v3f){ w, h,0.0f}, c ); + m4x3_mulv( gate->to_world, (v3f){-w, h,0.0f}, d ); vg_line( a,b, 0xffffa000 ); vg_line( b,c, 0xffffa000 ); vg_line( c,d, 0xffffa000 ); vg_line( d,a, 0xffffa000 ); - - vg_line2( gate->co[0], gate->co[1], 0xff0000ff, 0x00000000 ); + vg_line( gate->co[0], gate->co[1], 0xff0000ff ); } /* update gate camera */ @@ -131,7 +134,6 @@ VG_STATIC int render_gate( world_instance *world_inside, { shader_model_gate_use(); shader_model_gate_uPv( cam->mtx.pv ); - shader_model_gate_uMdl( gate->to_world ); shader_model_gate_uCam( cam->pos ); shader_model_gate_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} ); shader_model_gate_uTime( vg.time*0.25f ); @@ -143,13 +145,33 @@ VG_STATIC int render_gate( world_instance *world_inside, glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE ); glStencilFunc( GL_ALWAYS, 1, 0xFF ); glStencilMask( 0xFF ); + glDisable( GL_CULL_FACE ); + + m4x3f mmdl; + m4x3_copy( gate->to_world, mmdl ); + + if( gate->flags & k_ent_gate_custom_mesh ){ + mesh_bind( &world->mesh_no_collide ); + for( u32 i=0; isubmesh_count; i++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + gate->submesh_start+i ); + mdl_draw_submesh( sm ); + } + } + else { + m3x3_scale( mmdl, (v3f){ gate->dimensions[0], + gate->dimensions[1], 1.0f } ); + + mesh_bind( &world_gates.mesh ); + mdl_draw_submesh( &world_gates.sm_surface ); + } - mesh_bind( &world_gates.mesh ); - mdl_draw_submesh( &world_gates.sm_surface ); + shader_model_gate_uMdl( mmdl ); glClear( GL_DEPTH_BUFFER_BIT ); glStencilFunc( GL_EQUAL, 1, 0xFF ); glStencilMask( 0x00 ); + glEnable( GL_CULL_FACE ); } render_world( world_inside, &world_gates.cam, layer_depth ); @@ -225,7 +247,8 @@ VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last ) v2f xy; if( gate_intersect_plane( gate, pos, last, xy ) ){ - if( fabsf(xy[0]) <= 1.0f && fabsf(xy[1]) <= 1.0f ){ + if( (fabsf(xy[0]) <= gate->dimensions[0]) && + (fabsf(xy[1]) <= gate->dimensions[1]) ){ return 1; } } @@ -237,15 +260,13 @@ VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last ) * Intersect all gates in the world */ VG_STATIC ent_gate *world_intersect_gates( world_instance *world, - v3f pos, v3f last ) -{ + v3f pos, v3f last ){ for( u32 i=0; ient_gate); i++ ){ ent_gate *gate = mdl_arritm( &world->ent_gate, i ); - if( gate->type == k_gate_type_unlinked || - gate->type == k_gate_type_nonlocal_unlinked ) - continue; - if( gate->type == k_gate_type_nonlocel ){ + if( !(gate->flags & k_ent_gate_linked) ) continue; + + if( gate->flags & k_ent_gate_nonlocal ){ if( world_loader.state != k_world_loader_none ){ continue; } @@ -262,13 +283,12 @@ VG_STATIC ent_gate *world_intersect_gates( world_instance *world, /* * detatches any nonlocal gates */ -VG_STATIC void world_unlink_nonlocal( world_instance *world ) -{ +VG_STATIC void world_unlink_nonlocal( world_instance *world ){ for( u32 j=0; jent_gate); j ++ ){ ent_gate *gate = mdl_arritm( &world->ent_gate, j ); - if( gate->type == k_gate_type_nonlocel ){ - gate->type = k_gate_type_nonlocal_unlinked; + if( gate->flags & k_ent_gate_nonlocal ){ + gate->flags &= ~k_ent_gate_linked; } } } @@ -284,51 +304,66 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ) for( u32 j=0; jent_gate); j ++ ){ ent_gate *gate = mdl_arritm( &world->ent_gate, j ); - if( gate->type == k_gate_type_nonlocal_unlinked ){ - const char *key = mdl_pstr( &world->meta, gate->key ); - vg_info( "key: %s\n", key ); + if( !(gate->flags & k_ent_gate_nonlocal) ) continue; + if( gate->flags & k_ent_gate_linked ) continue; + + const char *key = mdl_pstr( &world->meta, gate->key ); + vg_info( "key: %s\n", key ); + + for( u32 i=0; istatus != k_world_status_loaded ) continue; + vg_info( "Checking world %u for key matches\n", i ); + + for( u32 j=0; jent_gate ); j++ ){ + ent_gate *gate2 = mdl_arritm( &other->ent_gate, j ); - for( u32 i=0; istatus != k_world_status_loaded ) continue; - vg_info( "Checking world %u for key matches\n", i ); + if( !(gate2->flags & k_ent_gate_nonlocal) ) continue; + if( gate2->flags & k_ent_gate_linked ) continue; - for( u32 j=0; jent_gate ); j++ ){ - ent_gate *gate2 = mdl_arritm( &other->ent_gate, j ); - if( gate2->type != k_gate_type_nonlocal_unlinked ) continue; + const char *key2 = mdl_pstr( &other->meta, gate2->key ); + vg_info( " key2: %s\n", key2 ); - const char *key2 = mdl_pstr( &other->meta, gate2->key ); - vg_info( " key2: %s\n", key2 ); + if( strcmp( key, key2 ) ) continue; - if( strcmp( key, key2 ) ) continue; + vg_success( "Non-local matching pair '%s' found. (%u:%u)\n", + key, world_id, i ); - vg_success( "Non-local matching pair '%s' found. (%u:%u)\n", - key, world_id, i ); - - gate->type = k_gate_type_nonlocel; - gate2->type = k_gate_type_nonlocel; - gate->target = i; - gate2->target = world_id; + gate->flags |= k_ent_gate_linked; + gate2->flags |= k_ent_gate_linked; + gate->target = i; + gate2->target = world_id; - v3_copy( gate->co[0], gate2->co[1] ); - v3_copy( gate2->co[0], gate->co[1] ); - v4_copy( gate->q[0], gate2->q[1] ); - v4_copy( gate2->q[0], gate->q[1] ); + v3_copy( gate->co[0], gate2->co[1] ); + v3_copy( gate2->co[0], gate->co[1] ); + v4_copy( gate->q[0], gate2->q[1] ); + v4_copy( gate2->q[0], gate->q[1] ); + if( other->meta.info.version >= 102 ){ + gate->flags |= k_ent_gate_flip; + gate2->flags |= k_ent_gate_flip; + } + else { + /* LEGACY BEHAVIOUR: v101 + * this would flip both the client worlds portal's entrance and + * exit. effectively the clients portal would be the opposite + * to the hub worlds one. new behaviour is to just flip the + * destinations so the rules are consistent in each world. + */ v4f qflip; q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); q_mul( gate->q[0], qflip, gate->q[0] ); q_mul( gate->q[1], qflip, gate->q[1] ); + } - gate_transform_update( gate ); - gate_transform_update( gate2 ); + gate_transform_update( gate ); + gate_transform_update( gate2 ); - goto matched; - } + goto matched; } -matched:; } +matched:; } } diff --git a/world_gate.h b/world_gate.h index b45c70d..4b3299a 100644 --- a/world_gate.h +++ b/world_gate.h @@ -20,7 +20,7 @@ VG_STATIC void world_gates_init(void); VG_STATIC void gate_transform_update( ent_gate *gate ); VG_STATIC void world_link_nonlocal_async( void *payload, u32 size ); VG_STATIC void world_unlink_nonlocal( world_instance *world ); -VG_STATIC int render_gate( world_instance *world_inside, +VG_STATIC int render_gate( world_instance *world, world_instance *world_inside, ent_gate *gate, camera *cam, int layer_depth ); VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last ); diff --git a/world_gen.c b/world_gen.c index c31c2c2..5f7b9a3 100644 --- a/world_gen.c +++ b/world_gen.c @@ -282,6 +282,19 @@ VG_STATIC void world_gen_generate_meshes(void) } } + /* unpack gate models */ + for( u32 i=0; ient_gate ); i++ ){ + ent_gate *gate = mdl_arritm( &world->ent_gate, i ); + + if( !(gate->flags & k_ent_gate_custom_mesh) ) continue; + + for( u32 j=0; jsubmesh_count; j ++ ){ + mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, + gate->submesh_start+j ); + world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm ); + } + } + vg_async_dispatch( call, async_scene_upload ); } diff --git a/world_render.c b/world_render.c index a33d774..a7ff25c 100644 --- a/world_render.c +++ b/world_render.c @@ -520,7 +520,7 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam, for( u32 i=0; ient_gate); i++ ){ ent_gate *gi = mdl_arritm( &world->ent_gate, i ); - if( gi->type == k_gate_type_unlinked ) + if( !(gi->flags & k_ent_gate_linked) ) continue; float dist = v3_dist2( gi->co[0], cam->transform[3] ); @@ -533,25 +533,20 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam, } } + world->rendering_gate = gate; if( gate ){ - /* should really be set in fixed update since its used in the physics - * of most systems. too bad! */ - world->rendering_gate = gate; - - if( gate->type == k_gate_type_teleport ){ - render_gate( world, gate, cam, layer_depth ); - } - else if( gate->type == k_gate_type_nonlocel ){ + if( gate->flags & k_ent_gate_nonlocal ){ if( world_loader.state != k_world_loader_none ){ world->rendering_gate = NULL; return; } world_instance *dest_world = &world_static.worlds[ gate->target ]; - render_gate( dest_world, gate, cam, layer_depth ); + render_gate( world, dest_world, gate, cam, layer_depth ); + } + else{ + render_gate( world, world, gate, cam, layer_depth ); } - else - world->rendering_gate = NULL; } } diff --git a/world_routes.c b/world_routes.c index d2816d1..44d055b 100644 --- a/world_routes.c +++ b/world_routes.c @@ -133,7 +133,7 @@ VG_STATIC void world_routes_activate_entry_gate( world_instance *world, world_static.last_use = world_static.time; /* disable all routes and leave the world */ - if( rg->type == k_gate_type_nonlocel ){ + if( rg->flags & k_ent_gate_nonlocal ){ for( u32 i=0; ient_route); i++ ){ ent_route *route = mdl_arritm( &world->ent_route, i ); route->active_checkpoint = 0xffff; @@ -912,7 +912,8 @@ VG_STATIC void world_gen_routes_ent_init(void) } } - if( gate->type == k_gate_type_teleport ){ + if( (gate->flags & k_ent_gate_linked) & + !(gate->flags & k_ent_gate_nonlocal) ){ gate = mdl_arritm(&world->ent_gate, gate->target ); for( u32 k=0; k<4; k++ ){ -- 2.25.1