From: hgn Date: Fri, 24 Feb 2023 02:29:39 +0000 (+0000) Subject: longjump gates X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;ds=sidebyside;h=34a8df54eb962f3ad2e036355041f5bc5cabe5a0;p=carveJwlIkooP6JGAAIwe30JlM.git longjump gates --- diff --git a/blender_export.py b/blender_export.py index d6da9c2..ccad7bf 100644 --- a/blender_export.py +++ b/blender_export.py @@ -255,6 +255,40 @@ class classtype_gate(Structure): #} #} +class classtype_nonlocal_gate(classtype_gate): +#{ + def encode_obj(_,node,node_def): + #{ + node.classtype = 300 + + obj = node_def['obj'] + _.target = encoder_process_pstr( node_def['obj'].cv_data.strp ) + + if obj.type == 'MESH': + #{ + _.dims[0] = obj.data.cv_data.v0[0] + _.dims[1] = obj.data.cv_data.v0[1] + _.dims[2] = obj.data.cv_data.v0[2] + #} + else: + #{ + _.dims[0] = obj.cv_data.v0[0] + _.dims[1] = obj.cv_data.v0[1] + _.dims[2] = obj.cv_data.v0[2] + #} + #} + + @staticmethod + def editor_interface( layout, obj ): + #{ + layout.prop( obj.cv_data, "strp", text="Nonlocal ID" ) + + mesh = obj.data + layout.label( text=F"(i) Data is stored in {mesh.name}" ) + layout.prop( mesh.cv_data, "v0", text="Gate dimensions" ) + #} +#} + # Classtype 3 # # Purpose: player can reset here, its a safe place @@ -2633,6 +2667,7 @@ class CV_OBJ_SETTINGS(bpy.types.PropertyGroup): ('classtype_logic_achievement',"classtype_logic_achievement","",101), ('classtype_logic_relay',"classtype_logic_relay","",102), ('classtype_spawn_link',"classtype_spawn_link","",150), + ('classtype_nonlocal_gate', "classtype_nonlocal_gate", "", 300) ]) #} diff --git a/camera.h b/camera.h index 77fc089..405f055 100644 --- a/camera.h +++ b/camera.h @@ -25,7 +25,7 @@ struct camera mtx, mtx_prev; } -VG_STATIC main_camera; +VG_STATIC main_camera, gate_camera; VG_STATIC void camera_lerp_angles( v3f a, v3f b, float t, v3f d ) { diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index cb5211b..ca0c37a 100644 Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ diff --git a/maps_src/mp_home.mdl b/maps_src/mp_home.mdl index 761e527..a09afb0 100644 Binary files a/maps_src/mp_home.mdl and b/maps_src/mp_home.mdl differ diff --git a/maps_src/mp_mtzero.mdl b/maps_src/mp_mtzero.mdl index 96165c9..9213d01 100644 Binary files a/maps_src/mp_mtzero.mdl and b/maps_src/mp_mtzero.mdl differ diff --git a/model.h b/model.h index 5498723..95d6676 100644 --- a/model.h +++ b/model.h @@ -42,7 +42,8 @@ enum classtype k_classtype_trigger = 100, k_classtype_logic_achievement = 101, k_classtype_logic_relay = 102, - k_classtype_point_light = 200 + k_classtype_point_light = 200, + k_classtype_nonlocal_gate = 300 }; enum mdl_shader diff --git a/player.c b/player.c index b705d7f..115ecf2 100644 --- a/player.c +++ b/player.c @@ -176,6 +176,11 @@ VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) m4x3_expand( transport_i, transport_4 ); m4x4_mul( main_camera.mtx.pv, transport_4, main_camera.mtx.pv ); m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); + + /* we want the regular transform here no the inversion */ + m4x3_expand( transport, transport_4 ); + m4x4_mul( gate_camera.mtx.pv, transport_4, gate_camera.mtx.pv ); + m4x4_mul( gate_camera.mtx.v, transport_4, gate_camera.mtx.v ); } __attribute__ ((deprecated)) @@ -197,22 +202,25 @@ VG_STATIC void gate_rotate_angles( teleport_gate *gate, v3f angles, v3f d ) * Applies gate transport to a player_interface */ PLAYER_API -void player__pass_gate( player_instance *player, teleport_gate *gate ) +void player__pass_gate( player_instance *player, struct gate_hit *hit ) { - player->gate_waiting = gate; + player->gate_waiting = hit->gate; - m4x3_mulv( gate->transport, player->tpv_lpf, player->tpv_lpf ); - m3x3_mulv( gate->transport, player->cam_velocity_smooth, - player->cam_velocity_smooth ); + m4x3_mulv( hit->gate->transport, player->tpv_lpf, player->tpv_lpf ); + m3x3_mulv( hit->gate->transport, player->cam_velocity_smooth, + player->cam_velocity_smooth ); m3x3_copy( player->basis, player->basis_gate ); v4f q; - m3x3_q( gate->transport, q ); + m3x3_q( hit->gate->transport, q ); q_mul( q, player->qbasis, player->qbasis ); q_normalize( player->qbasis ); q_m3x3( player->qbasis, player->basis ); m3x3_transpose( player->basis, player->invbasis ); + + if( hit->nonlocal ) + world_global.active_world = hit->nonlocal->target_map_index; } VG_STATIC void player__pre_render( player_instance *player ) @@ -316,6 +324,7 @@ PLAYER_API void player__spawn( player_instance *player, m3x3_identity( player->invbasis ); player->subsystem = k_player_subsystem_walk; + player->viewable_world = get_active_world(); if( _player_reset[ player->subsystem ] ) _player_reset[ player->subsystem ]( player, rp ); diff --git a/player.h b/player.h index 8ecce40..8923cf9 100644 --- a/player.h +++ b/player.h @@ -16,6 +16,7 @@ struct player_instance v4f qbasis; m3x3f basis, invbasis, basis_gate; + world_instance *viewable_world; /* * Camera management diff --git a/player_api.h b/player_api.h index 75c3873..8819772 100644 --- a/player_api.h +++ b/player_api.h @@ -62,7 +62,7 @@ PLAYER_API void player__spawn ( player_instance *player, struct respawn_point *rp ); PLAYER_API void player__kill ( player_instance *player ); PLAYER_API void player__pass_gate ( player_instance *player, - teleport_gate *gate ); + struct gate_hit *hit ); /* * Utiltiy diff --git a/player_common.c b/player_common.c index 43112f9..0e0c8a9 100644 --- a/player_common.c +++ b/player_common.c @@ -42,6 +42,7 @@ VG_STATIC void player_camera_portal_correction( player_instance *player ) vg_success( "Plane cleared\n" ); player_apply_transport_to_cam( player->gate_waiting->transport ); player->gate_waiting = NULL; + player->viewable_world = get_active_world(); } else { diff --git a/player_skate.c b/player_skate.c index 098ce8a..847f7f5 100644 --- a/player_skate.c +++ b/player_skate.c @@ -2219,11 +2219,12 @@ begin_collision:; } skate_integrate( player ); - vg_line_pt3( s->state.cog, 0.02f, VG__WHITE ); + vg_line_pt3( s->state.cog, 0.02f, VG__WHITE ); - teleport_gate *gate; - if( (gate = world_intersect_gates(world, player->rb.co, s->state.prev_pos)) ) + struct gate_hit hit; + if( world_intersect_gates(world, player->rb.co, s->state.prev_pos, &hit) ) { + teleport_gate *gate = hit.gate; m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); m4x3_mulv( gate->transport, s->state.cog, s->state.cog ); @@ -2239,7 +2240,7 @@ begin_collision:; rb_update_transform( &player->rb ); s->state_gate_storage = s->state; - player__pass_gate( player, gate ); + player__pass_gate( player, &hit ); } } diff --git a/player_walk.c b/player_walk.c index 00ee7fb..fbae15d 100644 --- a/player_walk.c +++ b/player_walk.c @@ -580,9 +580,10 @@ VG_STATIC void player__walk_update( player_instance *player ) } } - teleport_gate *gate; - if( (gate = world_intersect_gates(world, player->rb.co, w->state.prev_pos)) ) + struct gate_hit hit; + if( world_intersect_gates(world, player->rb.co, w->state.prev_pos, &hit) ) { + teleport_gate *gate = hit.gate; m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); @@ -593,7 +594,7 @@ VG_STATIC void player__walk_update( player_instance *player ) rb_update_transform( &player->rb ); w->state_gate_storage = w->state; - player__pass_gate( player, gate ); + player__pass_gate( player, &hit ); } } diff --git a/scene.h b/scene.h index 7a9460b..bf69a63 100644 --- a/scene.h +++ b/scene.h @@ -182,7 +182,6 @@ __attribute__((warn_unused_result)) VG_STATIC scene *scene_fix( void *lin_alloc, scene *pscene ) { /* FIXME: Why is this disabled? */ - return pscene; u32 vertex_count = pscene->vertex_count, indice_count = pscene->indice_count, @@ -191,7 +190,7 @@ VG_STATIC scene *scene_fix( void *lin_alloc, scene *pscene ) tot_size = sizeof(scene) + vertex_length + index_length; /* copy down index data */ - void *dst_indices = pscene->arrvertices + vertex_length; + void *dst_indices = pscene->arrvertices + vertex_count; memmove( dst_indices, pscene->arrindices, index_length ); /* realloc */ diff --git a/skaterift.c b/skaterift.c index 9e162b2..6ca61ee 100644 --- a/skaterift.c +++ b/skaterift.c @@ -264,6 +264,9 @@ VG_STATIC void vg_load(void) /* load home world */ world_load( &world_global.worlds[0], "maps/mp_home.mdl" ); + world_load( &world_global.worlds[1], "maps/mp_gridmap.mdl" ); + world_link_nonlocal_gates( 0, 1 ); + vg_console_load_autos(); } @@ -411,8 +414,8 @@ VG_STATIC void render_scene(void) /* Draw world */ glEnable( GL_DEPTH_TEST ); - world_instance *world = get_active_world(); - render_world( world, &main_camera ); + world_instance *view_world = localplayer.viewable_world; + render_world( view_world, &main_camera ); int player_transparent = 1, player_draw = 1; @@ -427,10 +430,10 @@ VG_STATIC void render_scene(void) player__render( &main_camera, &localplayer ); - render_water_texture( world, &main_camera ); + render_water_texture( view_world, &main_camera ); render_fb_bind( gpipeline.fb_main ); - render_water_surface( world, &main_camera ); - render_world_gates( world, &main_camera ); + render_water_surface( view_world, &main_camera ); + render_world_gates( view_world, &main_camera ); if( player_transparent && player_draw ) render_player_transparent(); diff --git a/world.h b/world.h index b80db37..7611c24 100644 --- a/world.h +++ b/world.h @@ -251,7 +251,9 @@ struct world_instance v4f q[2]; v2f dims; - m4x3f to_world, recv_to_world, transport; + m4x3f to_world, recv_to_world, /* TODO: can probably remove these */ + + transport; } gate; @@ -267,6 +269,16 @@ struct world_instance *gates; u32 gate_count; + struct nonlocal_gate + { + struct teleport_gate gate; + mdl_node *node; + + u32 target_map_index, working; + } + *nonlocal_gates; + u32 nonlocalgate_count; + struct route_collector { struct route_timing timing; diff --git a/world_gate.h b/world_gate.h index 1e8c262..b694251 100644 --- a/world_gate.h +++ b/world_gate.h @@ -81,30 +81,29 @@ VG_STATIC int render_gate( world_instance *world_inside, } /* update gate camera */ - static camera gate_view; - gate_view.fov = cam->fov; - gate_view.nearz = 0.1f; - gate_view.farz = 2000.0f; + gate_camera.fov = cam->fov; + gate_camera.nearz = 0.1f; + gate_camera.farz = 2000.0f; - m4x3_mul( gate->transport, cam->transform, gate_view.transform ); - camera_update_view( &gate_view ); - camera_update_projection( &gate_view ); + m4x3_mul( gate->transport, cam->transform, gate_camera.transform ); + camera_update_view( &gate_camera ); + camera_update_projection( &gate_camera ); /* Add special clipping plane to projection */ v4f surface; m3x3_mulv( gate->recv_to_world, (v3f){0.0f,0.0f,-1.0f}, surface ); surface[3] = v3_dot( surface, gate->co[1] ); - m4x3_mulp( gate_view.transform_inverse, surface, surface ); + m4x3_mulp( gate_camera.transform_inverse, surface, surface ); surface[3] = -fabsf(surface[3]); if( dist < -0.5f ) - m4x4_clip_projection( gate_view.mtx.p, surface ); + m4x4_clip_projection( gate_camera.mtx.p, surface ); /* Ready to draw with new camrea */ - camera_finalize( &gate_view ); + camera_finalize( &gate_camera ); - vg_line_pt3( gate_view.transform[3], 0.3f, 0xff00ff00 ); + vg_line_pt3( gate_camera.transform[3], 0.3f, 0xff00ff00 ); { m4x3f gate_xform; m4x3_copy( gate->to_world, gate_xform ); @@ -132,17 +131,17 @@ VG_STATIC int render_gate( world_instance *world_inside, glStencilMask( 0x00 ); } - render_world( world_inside, &gate_view ); + render_world( world_inside, &gate_camera ); { glDisable( GL_STENCIL_TEST ); - render_water_texture( world_inside, &gate_view ); + render_water_texture( world_inside, &gate_camera ); render_fb_bind( gpipeline.fb_main ); glEnable( GL_STENCIL_TEST ); - render_water_surface( world_inside, &gate_view ); + render_water_surface( world_inside, &gate_camera ); glStencilMask( 0xFF ); glStencilFunc( GL_ALWAYS, 1, 0xFF ); @@ -211,11 +210,18 @@ VG_STATIC int gate_intersect( teleport_gate *gate, v3f pos, v3f last ) return 0; } +struct gate_hit +{ + struct nonlocal_gate *nonlocal; + struct route_gate *route; + teleport_gate *gate; +}; + /* * Intersect all gates in the world */ -VG_STATIC teleport_gate *world_intersect_gates( world_instance *world, - v3f pos, v3f last ) +VG_STATIC int world_intersect_gates( world_instance *world, + v3f pos, v3f last, struct gate_hit *hit ) { for( int i=0; igate_count; i++ ) { @@ -223,10 +229,29 @@ VG_STATIC teleport_gate *world_intersect_gates( world_instance *world, teleport_gate *gate = &rg->gate; if( gate_intersect( gate, pos, last ) ) - return gate; + { + hit->gate = gate; + hit->nonlocal = NULL; + hit->route = rg; + return 1; + } } - return NULL; + for( int i=0; inonlocalgate_count; i++ ) + { + struct nonlocal_gate *nlg = &world->nonlocal_gates[i]; + teleport_gate *gate = &nlg->gate; + + if( gate_intersect( gate, pos, last ) ) + { + hit->gate = gate; + hit->nonlocal = nlg; + hit->route = NULL; + return 1; + } + } + + return 0; } #endif /* WORLD_GATE_H */ diff --git a/world_gen.h b/world_gen.h index 3290def..2b2ba57 100644 --- a/world_gen.h +++ b/world_gen.h @@ -187,6 +187,11 @@ VG_STATIC void world_ents_allocate( world_instance *world ) k_classtype_point_light, (void*)&world->lights, sizeof(struct world_light) + }, + { + k_classtype_nonlocal_gate, + (void*)&world->nonlocal_gates, + sizeof(struct nonlocal_gate) } }; @@ -341,6 +346,18 @@ VG_STATIC void world_pct_point_light( world_instance *world, mdl_node *pnode ) world->light_count ++; } +VG_STATIC void world_pct_nonlocal_gate( world_instance *world, mdl_node *pnode ) +{ + struct nonlocal_gate *gate = &world->nonlocal_gates[ + world->nonlocalgate_count ++ ]; + struct classtype_gate *inf = mdl_get_entdata( world->meta, pnode ); + + gate->working = 0; + gate->node = pnode; + gate->target_map_index = 0; + v2_copy( inf->dims, gate->gate.dims ); +} + VG_STATIC void world_entities_process( world_instance *world ) { struct entity_instruction @@ -356,7 +373,8 @@ VG_STATIC void world_entities_process( world_instance *world ) { k_classtype_trigger, world_pct_trigger }, { k_classtype_logic_relay, world_pct_relay }, { k_classtype_logic_achievement, world_pct_achievement }, - { k_classtype_point_light, world_pct_point_light } + { k_classtype_point_light, world_pct_point_light }, + { k_classtype_nonlocal_gate, world_pct_nonlocal_gate } }; for( int i=0; imeta->info.node_count; i++ ) @@ -376,6 +394,60 @@ VG_STATIC void world_entities_process( world_instance *world ) } } +VG_STATIC void world_link_nonlocal_gates( int index_a, int index_b ) +{ + vg_info( "Linking non-local gates\n" ); + world_instance *a = &world_global.worlds[ index_a ], + *b = &world_global.worlds[ index_b ]; + + for( int i=0; inonlocalgate_count; i++ ) + { + struct nonlocal_gate *ga = &a->nonlocal_gates[i]; + struct classtype_gate *ga_inf = mdl_get_entdata( a->meta, ga->node ); + const char *ga_name = mdl_pstr( a->meta, ga_inf->target ); + + for( int j=0; jnonlocalgate_count; j++ ) + { + struct nonlocal_gate *gb = &b->nonlocal_gates[j]; + struct classtype_gate *gb_inf = mdl_get_entdata( b->meta, gb->node ); + const char *gb_name = mdl_pstr( b->meta, gb_inf->target ); + + if( !strcmp( ga_name, gb_name ) ) + { + vg_success( "Created longjump for ID '%s'\n", ga_name ); + + v4f qYflip; + q_axis_angle( qYflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf ); + + /* TODO: Gates are created very wonkily. refactor. */ + ga->target_map_index = index_b; + gb->target_map_index = index_a; + ga->working = 1; + gb->working = 1; + + v4_copy( ga->node->q, ga->gate.q[0] ); + v4_copy( gb->node->q, ga->gate.q[1] ); + v3_copy( ga->node->co, ga->gate.co[0] ); + v3_copy( gb->node->co, ga->gate.co[1] ); + + v4_copy( gb->node->q, gb->gate.q[0] ); + v4_copy( ga->node->q, gb->gate.q[1] ); + v3_copy( gb->node->co, gb->gate.co[0] ); + v3_copy( ga->node->co, gb->gate.co[1] ); + + /* reverse B's direction */ + q_mul( gb->gate.q[0], qYflip, gb->gate.q[0] ); + q_mul( gb->gate.q[1], qYflip, gb->gate.q[1] ); + q_normalize( gb->gate.q[0] ); + q_normalize( gb->gate.q[1] ); + + gate_transform_update( &ga->gate ); + gate_transform_update( &gb->gate ); + } + } + } +} + VG_STATIC void world_scene_compute_light_clusters( world_instance *world, scene *sc ) { @@ -771,6 +843,9 @@ VG_STATIC void world_clean( world_instance *world ) world->collectors = NULL; world->collector_count = 0; + world->nonlocal_gates = NULL; + world->nonlocalgate_count = 0; + world->water.enabled = 0; diff --git a/world_render.h b/world_render.h index fd0b39f..873374f 100644 --- a/world_render.h +++ b/world_render.h @@ -295,26 +295,50 @@ VG_STATIC void render_sky( camera *cam ) VG_STATIC void render_world_gates( world_instance *world, camera *cam ) { - if( !world->gate_count ) - return; - float closest = INFINITY; - int id = 0; + + struct teleport_gate *gate = NULL; + world_instance *dest_world = world; for( int i=0; igate_count; i++ ) { struct route_gate *rg = &world->gates[i]; float dist = v3_dist2( rg->gate.co[0], cam->transform[3] ); + vg_line_pt3( rg->gate.co[0], 0.25f, VG__BLUE ); + + if( dist < closest ) + { + closest = dist; + gate = &rg->gate; + dest_world = world; + } + } + + for( int i=0; inonlocalgate_count; i++ ) + { + struct nonlocal_gate *nlg = &world->nonlocal_gates[i]; + + if( !nlg->working ) + { + vg_line_pt3( nlg->gate.co[0], 0.25f, VG__RED ); + continue; + } + else + vg_line_pt3( nlg->gate.co[0], 0.25f, VG__GREEN ); + + float dist = v3_dist2( nlg->gate.co[0], cam->transform[3] ); + if( dist < closest ) { closest = dist; - id = i; + gate = &nlg->gate; + dest_world = &world_global.worlds[ nlg->target_map_index ]; } } - /* TODO: non-local portals! :D */ - render_gate( world, &world->gates[id].gate, cam ); + if( gate ) + render_gate( dest_world, gate, cam ); } VG_STATIC void render_world( world_instance *world, camera *cam )