From: hgn Date: Wed, 22 Feb 2023 19:59:33 +0000 (+0000) Subject: added scene_vert struct, result is good X-Git-Url: https://skaterift.com/git/?a=commitdiff_plain;h=3e8fda9c7cbc50d1ae95195905c953bdeedf71b9;p=carveJwlIkooP6JGAAIwe30JlM.git added scene_vert struct, result is good --- diff --git a/maps_src/mp_gridmap.mdl b/maps_src/mp_gridmap.mdl index 926e2ed..465de6c 100644 Binary files a/maps_src/mp_gridmap.mdl and b/maps_src/mp_gridmap.mdl differ diff --git a/model.h b/model.h index 287eefd..12a05b1 100644 --- a/model.h +++ b/model.h @@ -90,14 +90,16 @@ enum bone_flag #pragma pack(push,1) +/* 48 byte */ struct mdl_vert { - v3f co, - norm; - v2f uv; - u8 colour[4]; - u16 weights[4]; - u8 groups[4]; + v3f co, /* 3*32 */ + norm; /* 3*32 */ + v2f uv; /* 2*32 */ + + u8 colour[4]; /* 4*8 */ + u16 weights[4];/* 4*16 */ + u8 groups[4]; /* 4*8 */ }; struct mdl_submesh diff --git a/player.c b/player.c index 9ab9706..10f5cc5 100644 --- a/player.c +++ b/player.c @@ -178,8 +178,12 @@ VG_STATIC void player_apply_transport_to_cam( m4x3f transport ) m4x4_mul( main_camera.mtx.v, transport_4, main_camera.mtx.v ); } +__attribute__ ((deprecated)) VG_STATIC void gate_rotate_angles( teleport_gate *gate, v3f angles, v3f d ) { + v3_copy( angles, d ); + return; + v3f fwd_dir = { cosf(angles[0]), 0.0f, sinf(angles[0])}; @@ -197,10 +201,18 @@ void player__pass_gate( player_instance *player, teleport_gate *gate ) { player->gate_waiting = gate; - gate_rotate_angles( gate, player->angles, player->angles ); m4x3_mulv( gate->transport, player->tpv_lpf, player->tpv_lpf ); m3x3_mulv( gate->transport, player->cam_velocity_smooth, player->cam_velocity_smooth ); + + m3x3_copy( player->basis, player->basis_gate ); + + v4f q; + m3x3_q( 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 ); } VG_STATIC void player__pre_render( player_instance *player ) @@ -277,16 +289,8 @@ PLAYER_API void player__im_gui( player_instance *player ) vg_uictx.cursor[0] = vg.window_x; -#if 0 - player__debugtext( 1, "%.2f %.2f %.2f", player->cam.pos[0], - player->cam.pos[1], - player->cam.pos[2] ); -#endif - player__debugtext( 1, "%.2f %.2f %.2f (%.2f)", - player->cam.angles[0], - player->cam.angles[1], - player->cam.angles[2], - player->cam.fov); + player__debugtext( 1, "angles: " PRINTF_v3f( player->cam.angles ) ); + player__debugtext( 1, "basis: " PRINTF_v4f( player->qbasis ) ); if( _player_im_gui[ player->subsystem ] ) _player_im_gui[ player->subsystem ]( player ); @@ -304,6 +308,10 @@ PLAYER_API void player__spawn( player_instance *player, q_identity( player->rb.q ); rb_update_transform( &player->rb ); + q_identity( player->qbasis ); + m3x3_identity( player->basis ); + m3x3_identity( player->invbasis ); + player->subsystem = k_player_subsystem_walk; if( _player_reset[ player->subsystem ] ) diff --git a/player.h b/player.h index 5092983..3dce2f0 100644 --- a/player.h +++ b/player.h @@ -14,6 +14,9 @@ struct player_instance rigidbody rb; v3f angles; + v4f qbasis; + m3x3f basis, invbasis, basis_gate; + /* * Camera management * --------------------------- diff --git a/player_common.c b/player_common.c index 3ce7c9c..43112f9 100644 --- a/player_common.c +++ b/player_common.c @@ -23,6 +23,7 @@ VG_STATIC float player_get_heading_yaw( player_instance *player ) { v3f xz; q_mulv( player->rb.q, (v3f){ 0.0f,0.0f,1.0f }, xz ); + m3x3_mulv( player->invbasis, xz, xz ); return atan2f( xz[0], xz[2] ); } @@ -49,12 +50,14 @@ VG_STATIC void player_camera_portal_correction( player_instance *player ) m4x3_invert_affine( player->gate_waiting->transport, inverse ); m4x3_mulv( inverse, player->cam.pos, player->cam.pos ); +#if 0 /* TODO: Find robust method for this */ v3f fwd_dir = { cosf(player->cam.angles[0]), 0.0f, sinf(player->cam.angles[0])}; m3x3_mulv( inverse, fwd_dir, fwd_dir ); player->cam.angles[0] = atan2f( fwd_dir[2], fwd_dir[0] ); +#endif struct skeleton *sk = &player->playeravatar->sk; skeleton_apply_transform( sk, inverse ); @@ -137,7 +140,10 @@ VG_STATIC void player__cam_iterate( player_instance *player ) v3f velocity_angles; v3_lerp( player->cam_velocity_smooth, player->rb.v, 4.0f*vg.frame_delta, player->cam_velocity_smooth ); - player_vector_angles( velocity_angles, player->cam_velocity_smooth, + + v3f velocity_local; + m3x3_mulv( player->invbasis, player->cam_velocity_smooth, velocity_local ); + player_vector_angles( velocity_angles, velocity_local, player->cam_velocity_coefficient_smooth, player->cam_velocity_constant_smooth ); @@ -155,10 +161,13 @@ VG_STATIC void player__cam_iterate( player_instance *player ) */ /* no idea what this technique is called, it acts like clamped position based - * on some derivative of where the final camera would end up .... */ + * on some derivative of where the final camera would end up .... + * + * it is done in the local basis then transformed back */ v3f future; v3_muls( player->rb.v, 0.4f*vg.frame_delta, future ); + m3x3_mulv( player->invbasis, future, future ); v3f camera_follow_dir = { -sinf( player->angles[0] ) * cosf( player->angles[1] ), @@ -173,14 +182,9 @@ VG_STATIC void player__cam_iterate( player_instance *player ) follow_angles[0] = atan2f( -v0[0], v0[2] ); follow_angles[1] = 0.3f + velocity_angles[1] * 0.2f; - float ya = atan2f - ( - -player->cam_velocity_smooth[1], - 30.0f - ); + float ya = atan2f( -velocity_local[1], 30.0f ); follow_angles[1] = 0.3f + ya; - camera_lerp_angles( player->angles, follow_angles, inf_tpv, player->angles ); @@ -190,13 +194,16 @@ VG_STATIC void player__cam_iterate( player_instance *player ) rb_extrapolate( &player->rb, pco, pq ); v3_lerp( player->tpv_lpf, pco, 20.0f*vg.frame_delta, player->tpv_lpf ); + /* now move into world */ + + m3x3_mulv( player->basis, camera_follow_dir, camera_follow_dir ); v3f tpv_pos, tpv_offset; + v3_muladds( player->tpv_lpf, camera_follow_dir, 1.8f, tpv_pos ); q_mulv( pq, player->tpv_offset_smooth, tpv_offset ); v3_add( tpv_offset, tpv_pos, tpv_pos ); v3_muladds( tpv_pos, player->cam_velocity_smooth, -0.025f, tpv_pos ); - /* * Blend cameras */ diff --git a/player_skate.c b/player_skate.c index 32e792f..542f105 100644 --- a/player_skate.c +++ b/player_skate.c @@ -66,7 +66,8 @@ struct grind_info v3f co, dir, n; }; -VG_STATIC int skate_grind_scansq( v3f pos, v3f dir, float r, +VG_STATIC int skate_grind_scansq( player_instance *player, + v3f pos, v3f dir, float r, struct grind_info *inf ) { v4f plane; @@ -96,7 +97,7 @@ VG_STATIC int skate_grind_scansq( v3f pos, v3f dir, float r, support_max; v3f support_axis; - v3_cross( plane, (v3f){0.0f,1.0f,0.0f}, support_axis ); + v3_cross( plane, player->basis[1], support_axis ); v3_normalize( support_axis ); while( bh_next( world.geo_bh, &it, box, &idx ) ) @@ -132,9 +133,9 @@ VG_STATIC int skate_grind_scansq( v3f pos, v3f dir, float r, v3_cross( va, vb, normal ); sample->normal[0] = v3_dot( support_axis, normal ); - sample->normal[1] = normal[1]; + sample->normal[1] = v3_dot( player->basis[1], normal ); sample->co[0] = v3_dot( support_axis, d ); - sample->co[1] = d[1]; + sample->co[1] = v3_dot( player->basis[1], d ); v3_copy( normal, sample->normal3 ); /* normalize later if we want to us it */ @@ -211,7 +212,10 @@ too_many_samples: v3_muls( dir, vg_signf(v3_dot(dir,plane)), dir ); v3_add( average_direction, dir, average_direction ); - if( si->normal3[1] > sj->normal3[1] ) + float yi = v3_dot( player->basis[1], si->normal3 ), + yj = v3_dot( player->basis[1], sj->normal3 ); + + if( yi > yj ) v3_add( si->normal3, average_normal, average_normal ); else v3_add( sj->normal3, average_normal, average_normal ); @@ -256,14 +260,18 @@ VG_STATIC int solve_prediction_for_target( player_instance *player, v3f v0; v3_sub( target, player->rb.co, v0 ); + m3x3_mulv( player->invbasis, v0, v0 ); v3f ax; v3_copy( v0, ax ); ax[1] = 0.0f; v3_normalize( ax ); - v2f d = { v3_dot( v0, ax ), v0[1] }, - v = { v3_dot( player->rb.v, ax ), player->rb.v[1] }; + v3f v_local; + m3x3_mulv( player->invbasis, player->rb.v, v_local ); + + v2f d = { v3_dot( ax, v0 ), v0[1] }, + v = { v3_dot( ax, player->rb.v ), v_local[1] }; float a = atan2f( v[1], v[0] ), m = v2_length( v ), @@ -290,6 +298,8 @@ VG_STATIC int solve_prediction_for_target( player_instance *player, v3_muls( ax, cosf( a0 ) * m, p->v ); p->v[1] += sinf( a0 ) * m; + m3x3_mulv( player->basis, p->v, p->v ); + p->land_dist = d[0] / (cosf(a0)*m); /* add a trace */ @@ -299,7 +309,7 @@ VG_STATIC int solve_prediction_for_target( player_instance *player, v3f p0; v3_muls( p->v, t, p0 ); - p0[1] += -0.5f * p->gravity * t*t; + v3_muladds( p0, player->basis[1], -0.5f * p->gravity * t*t, p0 ); v3_add( player->rb.co, p0, p->log[ p->log_length ++ ] ); } @@ -327,7 +337,8 @@ void player__approximate_best_trajectory( player_instance *player ) v3_normalize( axis ); /* at high slopes, Y component is low */ - float angle_begin = -(1.0f-fabsf( player->rb.to_world[1][1] )), + float upness = v3_dot( player->rb.to_world[1], player->basis[1] ), + angle_begin = -(1.0f-fabsf( upness )), angle_end = 1.0f; struct grind_info grind; @@ -354,7 +365,7 @@ void player__approximate_best_trajectory( player_instance *player ) q_axis_angle( qbias, axis, ang ); q_mulv( qbias, launch_v, launch_v ); - float yaw_sketch = 1.0f-fabsf(player->rb.to_world[1][1]); + float yaw_sketch = 1.0f-fabsf(upness); float yaw_bias = ((float)(m%3) - 1.0f) * 0.08f * yaw_sketch; q_axis_angle( qbias, player->rb.to_world[1], yaw_bias ); @@ -372,29 +383,33 @@ void player__approximate_best_trajectory( player_instance *player ) float t = (float)i * k_trace_delta; v3_muls( launch_v, t, co1 ); - co1[1] += -0.5f * gravity * t*t; + v3_muladds( co1, player->basis[1], -0.5f * gravity * t*t, co1 ); v3_add( launch_co, co1, co1 ); - if( !grind_located && (launch_v[1] - gravity*t < 0.0f) ) + float launch_vy = v3_dot( launch_v,player->basis[1] ); + if( !grind_located && (launch_vy - gravity*t < 0.0f) ) { v3f closest; if( bh_closest_point( world.geo_bh, co1, closest, 1.0f ) != -1 ) { v3f ve; v3_copy( launch_v, ve ); - ve[1] -= gravity * t; + v3_muladds( ve, player->basis[1], -gravity * t, ve ); - if( skate_grind_scansq( closest, ve, 0.5f, &grind ) ) + if( skate_grind_scansq( player, closest, ve, 0.5f, &grind ) ) { - v2f v0 = { ve[0], ve[2] }, - v1 = { grind.dir[0], grind.dir[2] }; + /* check alignment */ + v2f v0 = { v3_dot( ve, player->basis[0] ), + v3_dot( ve, player->basis[2] ) }, + v1 = { v3_dot( grind.dir, player->basis[0] ), + v3_dot( grind.dir, player->basis[2] ) }; v2_normalize( v0 ); v2_normalize( v1 ); float a = v2_dot( v0, v1 ); - if( a >= cosf( VG_PIf * 0.125f ) ) + if( a >= cosf( VG_PIf * 0.185f ) ) { grind_located = 1; } @@ -417,10 +432,10 @@ void player__approximate_best_trajectory( player_instance *player ) v3f ve; v3_copy( launch_v, ve ); - ve[1] -= gravity * t; + v3_muladds( ve, player->basis[1], -gravity * t, ve ); struct grind_info replace_grind; - if( skate_grind_scansq( co, ve, 0.3f, &replace_grind ) ) + if( skate_grind_scansq( player, co, ve, 0.3f, &replace_grind ) ) { v3_copy( replace_grind.n, p->n ); p->type = k_prediction_grind; @@ -462,7 +477,7 @@ void player__approximate_best_trajectory( player_instance *player ) /* determine score */ v3f ve; v3_copy( p->v, ve ); - ve[1] -= p->gravity * p->land_dist; + v3_muladds( ve, player->basis[1], -p->gravity * p->land_dist, ve ); p->score = -v3_dot( ve, grind.n ) * 0.85f; s->prediction_count ++; @@ -532,7 +547,7 @@ void player__approximate_best_trajectory( player_instance *player ) } else { - v3_copy( (v3f){0.0f,1.0f,0.0f}, s->land_normal ); + v3_copy( player->basis[1], s->land_normal ); } } @@ -810,7 +825,7 @@ VG_STATIC void skate_apply_jump_model( player_instance *player ) v3f jumpdir; /* Launch more up if alignment is up else improve velocity */ - float aup = v3_dot( (v3f){0.0f,1.0f,0.0f}, player->rb.to_world[1] ), + float aup = v3_dot( player->basis[1], player->rb.to_world[1] ), mod = 0.5f, dir = mod + fabsf(aup)*(1.0f-mod); @@ -923,7 +938,9 @@ VG_STATIC void skate_apply_cog_model( player_instance *player ) /* Apply forces & intergrate */ v3_muladds( s->state.cog_v, F, -rb, s->state.cog_v ); - s->state.cog_v[1] += -9.8f * k_rb_delta; + v3_muladds( s->state.cog_v, player->basis[1], -9.8f * k_rb_delta, + s->state.cog_v ); + v3_muladds( s->state.cog, s->state.cog_v, k_rb_delta, s->state.cog ); } @@ -1270,7 +1287,7 @@ VG_STATIC void skate_adjust_up_direction( player_instance *player ) } else { - v3_lerp( s->state.up_dir, (v3f){0.0f,1.0f,0.0f}, + v3_lerp( s->state.up_dir, player->basis[1], 12.0f * s->substep_delta, s->state.up_dir ); } } @@ -1374,8 +1391,6 @@ VG_STATIC void skate_grind_truck_apply( player_instance *player, v3_normalize( fwd ); - - float way = player->input_js1v->axis.value * vg_signf( v3_dot( raw_nplane, player->rb.v ) ); @@ -1498,7 +1513,7 @@ VG_STATIC int skate_grind_truck_renew( player_instance *player, float sign, m4x3_mulv( player->rb.to_world, grind_co, grind_co ); /* Exit condition: lost grind tracking */ - if( !skate_grind_scansq( grind_co, player->rb.v, 0.3f, inf ) ) + if( !skate_grind_scansq( player, grind_co, player->rb.v, 0.3f, inf ) ) return 0; /* Exit condition: cant see grind target directly */ @@ -1531,7 +1546,7 @@ VG_STATIC int skate_grind_truck_entry( player_instance *player, float sign, m3x3_mulv( player->rb.to_world, ra, raw ); v3_add( player->rb.co, raw, wsp ); - if( skate_grind_scansq( wsp, player->rb.v, 0.3, inf ) ) + if( skate_grind_scansq( player, wsp, player->rb.v, 0.3, inf ) ) { if( fabsf(v3_dot( player->rb.v, inf->dir )) < k_grind_axel_min_vel ) return 0; @@ -1628,7 +1643,7 @@ VG_STATIC int skate_boardslide_entry( player_instance *player, { struct player_skate *s = &player->_skate; - if( skate_grind_scansq( player->rb.co, + if( skate_grind_scansq( player, player->rb.co, player->rb.to_world[0], k_board_length, inf ) ) { @@ -1655,7 +1670,7 @@ VG_STATIC int skate_boardslide_renew( player_instance *player, { struct player_skate *s = &player->_skate; - if( !skate_grind_scansq( player->rb.co, + if( !skate_grind_scansq( player, player->rb.co, player->rb.to_world[0], k_board_length, inf ) ) return 0; @@ -1997,7 +2012,8 @@ begin_collision:; } rb_update_transform( &player->rb ); - player->rb.v[1] += -s->state.gravity_bias * s->substep_delta; + v3_muladds( player->rb.v, player->basis[1], + -s->state.gravity_bias * s->substep_delta, player->rb.v ); s->substep -= s->substep_delta; @@ -2205,6 +2221,7 @@ begin_collision:; m3x3_mulv( gate->transport, s->state.throw_v, s->state.throw_v ); m3x3_mulv( gate->transport, s->state.head_position, s->state.head_position ); + m3x3_mulv( gate->transport, s->state.up_dir, s->state.up_dir ); v4f transport_rotation; m3x3_q( gate->transport, transport_rotation ); diff --git a/player_skate.h b/player_skate.h index 0a29caa..4c8bbd4 100644 --- a/player_skate.h +++ b/player_skate.h @@ -52,7 +52,6 @@ struct player_skate #endif v3f up_dir; - v3f head_position; int lift_frames; diff --git a/player_walk.c b/player_walk.c index 4dd56e3..c86c9db 100644 --- a/player_walk.c +++ b/player_walk.c @@ -8,12 +8,21 @@ VG_STATIC void player_walk_drop_in_vector( player_instance *player, v3f vec ) struct player_walk *w = &player->_walk; v3f axis, init_dir; - v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis ); + v3_cross( player->basis[1], w->state.drop_in_normal, axis ); v3_cross( axis, w->state.drop_in_normal, init_dir ); v3_normalize( init_dir ); v3_muls( init_dir, 7.0f, vec ); } +VG_STATIC float player_xyspeed2( player_instance *player ) +{ + v3f xy; + v3_muladds( player->rb.v, player->basis[1], + -v3_dot( player->basis[1], player->rb.v ), xy ); + + return v3_length2(xy); +} + VG_STATIC void player_walk_generic_to_skate( player_instance *player, enum skate_activity init, float yaw ) @@ -23,12 +32,9 @@ VG_STATIC void player_walk_generic_to_skate( player_instance *player, struct player_walk *w = &player->_walk; struct player_skate *s = &player->_skate; - v3f xy_speed, v; - - v3_copy( player->rb.v, xy_speed ); - xy_speed[1] = 0.0f; + v3f v; - if( v3_length2( xy_speed ) < 0.1f * 0.1f ) + if( player_xyspeed2(player) < 0.1f * 0.1f ) q_mulv( player->rb.q, (v3f){0.0f,0.0f,1.6f}, v ); else v3_copy( player->rb.v, v ); @@ -39,11 +45,15 @@ VG_STATIC void player_walk_generic_to_skate( player_instance *player, v3f dir; v3_copy( v, dir ); v3_normalize( dir ); + m3x3_mulv( player->invbasis, dir, dir ); - q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, - atan2f( -dir[0], -dir[2] ) ); + q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(-dir[0],-dir[2]) ); + q_mul( player->qbasis, player->rb.q, player->rb.q ); + q_normalize( player->rb.q ); + + q_mulv( player->rb.q, (v3f){0.0f,1.0f,0.0f}, s->state.cog ); + v3_add( s->state.cog, player->rb.co, s->state.cog ); - v3_muladds( player->rb.co, player->rb.to_world[1], 1.0f, s->state.cog ); v3_copy( v, s->state.cog_v ); v3_copy( v, player->rb.v ); @@ -86,7 +96,7 @@ VG_STATIC void player_walk_drop_in_overhang_transform( player_instance *player, struct player_walk *w = &player->_walk; v3f axis; - v3_cross( (v3f){0.0f,1.0f,0.0f}, w->state.drop_in_normal, axis ); + v3_cross( player->basis[1], w->state.drop_in_normal, axis ); v3_normalize( axis ); float a = acosf( w->state.drop_in_normal[1] ) * t; @@ -293,11 +303,7 @@ VG_STATIC void player__walk_pre_update( player_instance *player ) w->state.outro_start_time = vg.time; w->state.activity = k_walk_activity_lockedmove; - v3f xy_speed; - v3_copy( player->rb.v, xy_speed ); - xy_speed[1] = 0.0f; - - if( v3_length2( xy_speed ) < 0.1f * 0.1f ) + if( player_xyspeed2(player) < 0.1f * 0.1f ) q_mulv( player->rb.q, (v3f){0.0f,0.0f,1.6f}, player->rb.v ); } } @@ -311,9 +317,9 @@ VG_STATIC void player__walk_pre_update( player_instance *player ) } } -VG_STATIC int player_walk_normal_standable( v3f n ) +VG_STATIC int player_walk_normal_standable( player_instance *player, v3f n ) { - return n[1] > 0.70710678118f; + return v3_dot( n, player->basis[1] ) > 0.70710678118f; } VG_STATIC void player_accelerate( v3f v, v3f movedir, float speed, float accel ) @@ -361,8 +367,8 @@ VG_STATIC void player__walk_update( player_instance *player ) w->collider.radius = 0.3f; m4x3f mtx; - m3x3_identity( mtx ); - v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); + m3x3_copy( player->rb.to_world, mtx ); + v3_add( player->rb.co, player->basis[1], mtx[3] ); debug_capsule( mtx, w->collider.radius, w->collider.height, VG__WHITE ); @@ -374,6 +380,10 @@ VG_STATIC void player__walk_update( player_instance *player ) v3f forward_dir = { sinf(yaw), 0.0f, -cosf(yaw) }; v3f right_dir = { -forward_dir[2], 0.0f, forward_dir[0] }; + m3x3_mulv( player->basis, forward_dir, forward_dir ); + m3x3_mulv( player->basis, right_dir, right_dir ); + + v2f walk = { player->input_walkh->axis.value, player->input_walkv->axis.value }; @@ -400,7 +410,7 @@ VG_STATIC void player__walk_update( player_instance *player ) struct contact *ct = &manifold[i]; rb_debug_contact( ct ); - if( player_walk_normal_standable( ct->n ) ) + if( player_walk_normal_standable( player, ct->n ) ) { if( w->state.activity != k_walk_activity_lockedmove ) w->state.activity = k_walk_activity_ground; @@ -439,7 +449,7 @@ VG_STATIC void player__walk_update( player_instance *player ) /* jump */ if( player->input_jump->button.value ) { - player->rb.v[1] = 5.0f; + v3_muladds( player->rb.v, player->basis[1], 5.0f, player->rb.v ); w->state.activity = k_walk_activity_air; accel_speed = k_walk_air_accel; nominal_speed = k_airspeed; @@ -524,12 +534,13 @@ VG_STATIC void player__walk_update( player_instance *player ) /* integrate */ if( w->state.activity == k_walk_activity_air ) - player->rb.v[1] += -k_gravity * k_rb_delta; + { + v3_muladds( player->rb.v, player->basis[1], -k_gravity*k_rb_delta, + player->rb.v ); + } v3_muladds( player->rb.co, player->rb.v, k_rb_delta, player->rb.co ); - - - v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); + v3_add( player->rb.co, player->basis[1], mtx[3] ); debug_capsule( mtx, w->collider.radius, w->collider.height, VG__GREEN ); /* @@ -560,7 +571,7 @@ VG_STATIC void player__walk_update( player_instance *player ) player->rb.co[1] -= w->collider.radius; rb_update_transform( &player->rb ); - v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); + v3_add( player->rb.co, player->basis[1], mtx[3] ); debug_capsule( mtx, w->collider.radius, w->collider.height, VG__RED ); } } @@ -570,6 +581,11 @@ VG_STATIC void player__walk_update( player_instance *player ) { m4x3_mulv( gate->transport, player->rb.co, player->rb.co ); m3x3_mulv( gate->transport, player->rb.v, player->rb.v ); + + v4f transport_rotation; + m3x3_q( gate->transport, transport_rotation ); + q_mul( transport_rotation, player->rb.q, player->rb.q ); + rb_update_transform( &player->rb ); w->state_gate_storage = w->state; @@ -583,7 +599,7 @@ VG_STATIC void player__walk_post_update( player_instance *player ) m4x3f mtx; m3x3_copy( player->rb.to_world, mtx ); - v3_add( player->rb.co, (v3f){0.0f, 1.0f, 0.0f}, mtx[3] ); + v3_add( player->rb.co, player->basis[1], mtx[3] ); float substep = vg_clampf( vg.accumulator / k_rb_delta, 0.0f, 1.0f ); v3_muladds( mtx[3], player->rb.v, k_rb_delta*substep, mtx[3] ); @@ -591,15 +607,16 @@ VG_STATIC void player__walk_post_update( player_instance *player ) /* Calculate header */ - v3f xy_speed, v; - - v3_copy( player->rb.v, xy_speed ); - xy_speed[1] = 0.0f; - - if( v3_length2( xy_speed ) > 0.1f * 0.1f ) + v3f v; + if( player_xyspeed2(player) > 0.1f*0.1f ) { - float a = atan2f( player->rb.v[0], player->rb.v[2] ); + v3f v_xy; + m3x3_mulv( player->invbasis, player->rb.v, v_xy ); + float a = atan2f( v_xy[0], v_xy[2] ); + q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, a ); + q_mul( player->qbasis, player->rb.q, player->rb.q ); + q_normalize( player->rb.q ); } vg_line_pt3( w->state.drop_in_target, 0.1f, VG__GREEN ); @@ -617,6 +634,7 @@ VG_STATIC void player__walk_post_update( player_instance *player ) p1[0] = sinf( a ); p1[1] = 0.0f; p1[2] = cosf( a ); + m3x3_mulv( player->basis, p1, p1 ); v3_add( player->rb.co, p1, p1 ); vg_line( player->rb.co, p1, VG__PINK ); @@ -762,6 +780,8 @@ VG_STATIC void player__walk_animate( player_instance *player, } q_axis_angle( dest->root_q, (v3f){0.0f,1.0f,0.0f}, walk_yaw + VG_PIf ); + q_mul( player->qbasis, dest->root_q, dest->root_q ); + q_normalize( dest->root_q ); } VG_STATIC void player__walk_post_animate( player_instance *player ) @@ -834,9 +854,12 @@ VG_STATIC void player__walk_transition( player_instance *player, v3f angles ) v3f fwd = { 0.0f, 0.0f, 1.0f }; q_mulv( player->rb.q, fwd, fwd ); + m3x3_mulv( player->invbasis, fwd, fwd ); + + q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, atan2f(fwd[0], fwd[2]) ); + q_mul( player->qbasis, player->rb.q, player->rb.q ); + q_normalize( player->rb.q ); - q_axis_angle( player->rb.q, (v3f){0.0f,1.0f,0.0f}, - atan2f( fwd[0], fwd[2] ) ); rb_update_transform( &player->rb ); } diff --git a/scene.h b/scene.h index b4491fa..d0615d5 100644 --- a/scene.h +++ b/scene.h @@ -5,11 +5,26 @@ #include "model.h" #include "bvh.h" -typedef struct scene scene; +typedef struct scene scene; +typedef struct scene_vert scene_vert; + +#pragma pack(push,1) + +/* 24 byte vertexs, we don't care about the normals too much, + * maybe possible to bring down uv to i16s too */ +struct scene_vert +{ + v3f co; /* 3*32 */ + v2f uv; /* 2*32 */ + i8 norm[4]; /* 4*8 */ +}; + +#pragma pack(pop) struct scene { - mdl_vert *arrvertices; + scene_vert *arrvertices; + u32 *arrindices; u32 vertex_count, indice_count, @@ -22,13 +37,13 @@ struct scene /* Initialize a scene description with bounded buffers */ VG_STATIC scene *scene_init( void *lin_alloc, u32 max_verts, u32 max_indices ) { - u32 vertex_length = max_verts * sizeof(mdl_vert), + u32 vertex_length = max_verts * sizeof(scene_vert), index_length = max_indices * sizeof(u32), tot_size = sizeof(scene) + vertex_length + index_length; scene *pscene = vg_linear_alloc( lin_alloc, tot_size ); - pscene->arrvertices = (mdl_vert *)(pscene+1); + pscene->arrvertices = (scene_vert *)(pscene+1); pscene->arrindices = (u32 *)( pscene->arrvertices + max_verts ); pscene->vertex_count = 0; @@ -44,11 +59,23 @@ VG_STATIC scene *scene_init( void *lin_alloc, u32 max_verts, u32 max_indices ) return pscene; } +VG_STATIC void scene_vert_pack_norm( scene_vert *vert, v3f norm ) +{ + v3f n; + v3_muls( norm, 127.0f, n ); + v3_minv( n, (v3f){ 127.0f, 127.0f, 127.0f }, n ); + v3_maxv( n, (v3f){ -127.0f, -127.0f, -127.0f }, n ); + vert->norm[0] = n[0]; + vert->norm[1] = n[1]; + vert->norm[2] = n[2]; + vert->norm[3] = 0; /* free byte :D */ +} + /* * Append a model into the scene with a given transform */ -VG_STATIC void scene_add_submesh( scene *pscene, mdl_context *mdl, - mdl_submesh *sm, m4x3f transform ) +VG_STATIC void scene_add_mdl_submesh( scene *pscene, mdl_context *mdl, + mdl_submesh *sm, m4x3f transform ) { if( pscene->vertex_count + sm->vertex_count > pscene->max_vertices ) { @@ -70,8 +97,8 @@ VG_STATIC void scene_add_submesh( scene *pscene, mdl_context *mdl, vg_fatal_exit_loop( "Scene index buffer overflow" ); } - mdl_vert *src_verts = mdl_submesh_vertices( mdl, sm ), - *dst_verts = &pscene->arrvertices[ pscene->vertex_count ]; + mdl_vert *src_verts = mdl_submesh_vertices( mdl, sm ); + scene_vert *dst_verts = &pscene->arrvertices[ pscene->vertex_count ]; u32 *src_indices = mdl_submesh_indices( mdl, sm ), *dst_indices = &pscene->arrindices[ pscene->indice_count ]; @@ -90,27 +117,20 @@ VG_STATIC void scene_add_submesh( scene *pscene, mdl_context *mdl, for( u32 i=0; ivertex_count; i++ ) { - mdl_vert *pvert = &dst_verts[ i ], - *src = &src_verts[ i ]; + mdl_vert *src = &src_verts[ i ]; + scene_vert *pvert = &dst_verts[ i ]; m4x3_mulv( transform, src->co, pvert->co ); - m3x3_mulv( normal_matrix, src->norm, pvert->norm ); + + v3f normal; + m3x3_mulv( normal_matrix, src->norm, normal ); + scene_vert_pack_norm( pvert, normal ); - pvert->colour[0] = src->colour[0]; - pvert->colour[1] = src->colour[1]; - pvert->colour[2] = src->colour[2]; - pvert->colour[3] = src->colour[3]; - pvert->weights[0] = src->weights[0]; - pvert->weights[1] = src->weights[1]; - pvert->weights[2] = src->weights[2]; - pvert->weights[3] = src->weights[3]; v2_copy( src->uv, pvert->uv ); } for( u32 i=0; iindice_count; i++ ) - { dst_indices[i] = src_indices[i] + pscene->vertex_count; - } pscene->vertex_count += sm->vertex_count; pscene->indice_count += sm->indice_count; @@ -133,12 +153,12 @@ VG_STATIC void scene_push_tri( scene *pscene, u32 tri[3] ) pscene->indice_count += 3; } -VG_STATIC void scene_push_vert( scene *pscene, mdl_vert *v ) +VG_STATIC void scene_push_vert( scene *pscene, scene_vert *v ) { if( pscene->vertex_count + 1 > pscene->max_vertices ) vg_fatal_exit_loop( "Scene vertex buffer overflow" ); - mdl_vert *dst = &pscene->arrvertices[ pscene->vertex_count ]; + scene_vert *dst = &pscene->arrvertices[ pscene->vertex_count ]; *dst = *v; pscene->vertex_count ++; @@ -160,10 +180,12 @@ VG_STATIC void scene_copy_slice( scene *pscene, mdl_submesh *sm ) __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, - vertex_length = vertex_count * sizeof(mdl_vert), + vertex_length = vertex_count * sizeof(scene_vert), index_length = indice_count * sizeof(u32), tot_size = sizeof(scene) + vertex_length + index_length; @@ -174,7 +196,7 @@ VG_STATIC scene *scene_fix( void *lin_alloc, scene *pscene ) /* realloc */ pscene = vg_linear_resize( lin_alloc, pscene, tot_size ); - pscene->arrvertices = (mdl_vert *)(pscene+1); + pscene->arrvertices = (scene_vert *)(pscene+1); pscene->arrindices = (u32 *)(pscene->arrvertices+vertex_count); pscene->max_vertices = vertex_count; pscene->max_indices = indice_count; @@ -205,13 +227,46 @@ VG_STATIC scene *scene_free_offline_buffers( void *lin_alloc, scene *pscene ) VG_STATIC void scene_upload( scene *pscene, glmesh *mesh ) { - mesh_upload( mesh, - pscene->arrvertices, pscene->vertex_count, - pscene->arrindices, pscene->indice_count ); + //assert( mesh->loaded == 0 ); + + glGenVertexArrays( 1, &mesh->vao ); + glGenBuffers( 1, &mesh->vbo ); + glGenBuffers( 1, &mesh->ebo ); + glBindVertexArray( mesh->vao ); + + size_t stride = sizeof(scene_vert); + + glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo ); + glBufferData( GL_ARRAY_BUFFER, pscene->vertex_count*stride, + pscene->arrvertices, GL_STATIC_DRAW ); + + glBindVertexArray( mesh->vao ); + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, pscene->indice_count*sizeof(u32), + pscene->arrindices, GL_STATIC_DRAW ); + + /* 0: coordinates */ + glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0 ); + glEnableVertexAttribArray( 0 ); + + /* 1: normal */ + glVertexAttribPointer( 1, 3, GL_BYTE, GL_TRUE, + stride, (void *)offsetof(scene_vert, norm) ); + glEnableVertexAttribArray( 1 ); + + /* 2: uv */ + glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, + stride, (void *)offsetof(scene_vert, uv) ); + glEnableVertexAttribArray( 2 ); + + VG_CHECK_GL_ERR(); + + mesh->indice_count = pscene->indice_count; + mesh->loaded = 1; - vg_info( "Scene upload\n" ); + vg_info( "Scene upload ( XYZ_f32 UV_f32 XYZW_i8 )[ u32 ]\n" ); vg_info( " indices:%u\n", pscene->indice_count ); - vg_info( " verts:%u\n", pscene->vertex_count ); + vg_info( " verts:%u\n", pscene->vertex_count ); } /* @@ -221,9 +276,9 @@ VG_STATIC void scene_upload( scene *pscene, glmesh *mesh ) VG_STATIC void scene_bh_expand_bound( void *user, boxf bound, u32 item_index ) { scene *s = user; - mdl_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ], - *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ], - *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ]; + scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ], + *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ], + *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ]; box_addpt( bound, pa->co ); box_addpt( bound, pb->co ); @@ -233,9 +288,9 @@ VG_STATIC void scene_bh_expand_bound( void *user, boxf bound, u32 item_index ) VG_STATIC float scene_bh_centroid( void *user, u32 item_index, int axis ) { scene *s = user; - mdl_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ], - *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ], - *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ]; + scene_vert *pa = &s->arrvertices[ s->arrindices[item_index*3+0] ], + *pb = &s->arrvertices[ s->arrindices[item_index*3+1] ], + *pc = &s->arrvertices[ s->arrindices[item_index*3+2] ]; return (pa->co[axis] + pb->co[axis] + pc->co[axis]) * (1.0f/3.0f); } @@ -265,9 +320,9 @@ VG_STATIC void scene_bh_debug( void *user, u32 item_index ) { scene *s = user; u32 idx = item_index*3; - mdl_vert *pa = &s->arrvertices[ s->arrindices[ idx+0 ] ], - *pb = &s->arrvertices[ s->arrindices[ idx+1 ] ], - *pc = &s->arrvertices[ s->arrindices[ idx+2 ] ]; + scene_vert *pa = &s->arrvertices[ s->arrindices[ idx+0 ] ], + *pb = &s->arrvertices[ s->arrindices[ idx+1 ] ], + *pc = &s->arrvertices[ s->arrindices[ idx+2 ] ]; vg_line( pa->co, pb->co, 0xff0000ff ); vg_line( pb->co, pc->co, 0xff0000ff ); diff --git a/skaterift.c b/skaterift.c index fa10ecb..c724906 100644 --- a/skaterift.c +++ b/skaterift.c @@ -480,6 +480,18 @@ VG_STATIC void render_main_game(void) main_camera.farz = 2100.0f; camera_update_transform( &main_camera ); + + if( localplayer.gate_waiting ) + { + m3x3_mul( localplayer.basis_gate, main_camera.transform, + main_camera.transform ); + } + else + { + m3x3_mul( localplayer.basis, main_camera.transform, + main_camera.transform ); + } + camera_update_view( &main_camera ); camera_update_projection( &main_camera ); camera_finalize( &main_camera ); diff --git a/world_gen.h b/world_gen.h index bf858d7..89fea39 100644 --- a/world_gen.h +++ b/world_gen.h @@ -27,7 +27,7 @@ VG_STATIC void world_add_all_if_material( m4x3f transform, scene *pscene, mdl_node_transform( pnode, transform2 ); m4x3_mul( transform, transform2, transform2 ); - scene_add_submesh( pscene, mdl, sm, transform2 ); + scene_add_mdl_submesh( pscene, mdl, sm, transform2 ); } } } @@ -48,7 +48,7 @@ VG_STATIC void world_add_blob( scene *pscene, ray_hit *hit ) q_m3x3( qsurface, transform ); v3_copy( hit->pos, transform[3] ); - mdl_vert verts[] = + scene_vert verts[] = { { .co = { -1.00f, 0.0f, 0.0f } }, { .co = { 1.00f, 0.0f, 0.0f } }, @@ -66,27 +66,18 @@ VG_STATIC void world_add_blob( scene *pscene, ray_hit *hit ) if( pscene->indice_count + vg_list_size(indices) > pscene->max_indices ) vg_fatal_exit_loop( "Scene index buffer overflow" ); - mdl_vert *dst_verts = &pscene->arrvertices[ pscene->vertex_count ]; - u32 *dst_indices = &pscene->arrindices [ pscene->indice_count ]; + scene_vert *dst_verts = &pscene->arrvertices[ pscene->vertex_count ]; + u32 *dst_indices = &pscene->arrindices [ pscene->indice_count ]; - mdl_vert *ref = &world.scene_geo->arrvertices[ hit->tri[0] ]; + scene_vert *ref = &world.scene_geo->arrvertices[ hit->tri[0] ]; for( u32 i=0; ico, pvert->co ); - v3_copy( transform[1], pvert->norm ); - - pvert->colour[0] = 0; - pvert->colour[1] = 0; - pvert->colour[2] = 0; - pvert->colour[3] = 0; - pvert->weights[0] = 0; - pvert->weights[1] = 0; - pvert->weights[2] = 0; - pvert->weights[3] = 0; + m4x3_mulv( transform, src->co, pvert->co ); + scene_vert_pack_norm( pvert, transform[1] ); v2_copy( ref->uv, pvert->uv ); } diff --git a/world_routes.h b/world_routes.h index 3aeaf05..4e455d3 100644 --- a/world_routes.h +++ b/world_routes.h @@ -746,12 +746,13 @@ VG_STATIC void world_routes_create_mesh( u32 route_id ) if( ray_world( sa, down, &ha ) && ray_world( sb, down, &hb )) { - mdl_vert va, vb; + scene_vert va, vb; v3_muladds( ha.pos, up, 0.06f, va.co ); v3_muladds( hb.pos, up, 0.06f, vb.co ); - v3_copy( up, va.norm ); - v3_copy( up, vb.norm ); + + scene_vert_pack_norm( &va, up ); + scene_vert_pack_norm( &vb, up ); v2_zero( va.uv ); v2_zero( vb.uv ); diff --git a/world_sfd.h b/world_sfd.h index 9f41992..d7aeb55 100644 --- a/world_sfd.h +++ b/world_sfd.h @@ -184,11 +184,13 @@ VG_STATIC void world_sfd_init(void) m4x3f identity; m4x3_identity( identity ); + /* FIXME: dont use scene header for this you fucking idiots */ for( int i=4;i<6;i++ ) { u32 vert_start = sc->vertex_count; - scene_add_submesh( sc, mboard, card, identity ); + scene_add_mdl_submesh( sc, mboard, card, identity ); +#if 0 for( int j=0; jvertex_count; j++ ) { mdl_vert *vert = &sc->arrvertices[ vert_start+j ]; @@ -198,6 +200,7 @@ VG_STATIC void world_sfd_init(void) vert->colour[0] = 0.0f; vert->colour[1] = i*36; } +#endif } vg_acquire_thread_sync();