added scene_vert struct, result is good
authorhgn <hgodden00@gmail.com>
Wed, 22 Feb 2023 19:59:33 +0000 (19:59 +0000)
committerhgn <hgodden00@gmail.com>
Wed, 22 Feb 2023 19:59:33 +0000 (19:59 +0000)
13 files changed:
maps_src/mp_gridmap.mdl
model.h
player.c
player.h
player_common.c
player_skate.c
player_skate.h
player_walk.c
scene.h
skaterift.c
world_gen.h
world_routes.h
world_sfd.h

index 926e2ed5943fa06689e9b7de0f76400b084febe5..465de6c8a6cfdbe150c078a6af6a0691d464c252 100644 (file)
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 287eefd6e203692233ac71aaf973e632f7b8208f..12a05b1678b36a64e350a79c3de9843f8afc4d4d 100644 (file)
--- 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
index 9ab970652852525fbd5fa47404e3bcaf6c34bee5..10f5cc5d3d99e9659461ba2af1239f8b74d5752d 100644 (file)
--- 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 ] )
index 50929831ef0c81d93c79f8f94d11342500ec4f5f..3dce2f01a8ffb6e57d802781f26c2c36e51c0ac8 100644 (file)
--- 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
     * ---------------------------
index 3ce7c9cdc7d6143aaf52c77a8f6dc49e81ba0abf..43112f94cd7b12022b8f65dfd20472807d8cde75 100644 (file)
@@ -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 
     */
index 32e792f5ba51c46d9c6cc9b999e8a4821abfdf72..542f105225453f9f56e964fb663e02131a6f237f 100644 (file)
@@ -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 );
index 0a29caa9b9b0f8fc14e9c2eedb7961db3a5b217d..4c8bbd4afc83d93fdaf23e6226d41e2dce44fd21 100644 (file)
@@ -52,7 +52,6 @@ struct player_skate
 #endif
 
       v3f up_dir;
-
       v3f head_position;
 
       int lift_frames;
index 4dd56e391fff9439690cc72f7ab9538cfbe9e645..c86c9dba385d28ac8f3da4b0a22ad0013659c59b 100644 (file)
@@ -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 b4491fa083f3d2000906171e07642944b24339f1..d0615d52688a36b18d3656a5c64a8551f58fb1b9 100644 (file)
--- 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; i<sm->vertex_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; i<sm->indice_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 );
index fa10ecb3e87736da6b1ad1e0f954247b420e2927..c724906a2a1ff5c88da28825fb169648c8520cc4 100644 (file)
@@ -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 );
index bf858d78b05cee3d690aea84763393ee137641f4..89fea39c9f5068227257a806da896f1aad23db4a 100644 (file)
@@ -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; i<vg_list_size(verts); i++ )
    {
-      mdl_vert *pvert = &dst_verts[ i ],
-               *src   = &verts[ i ];
+      scene_vert *pvert = &dst_verts[ i ],
+                 *src   = &verts[ i ];
 
-      m4x3_mulv( transform, src->co,   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 );
    }
index 3aeaf05e931afe3885f880ee6772bcef1c9f7352..4e455d345b8f4728ae2cdc9c3c305aefb9a76203 100644 (file)
@@ -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 );
 
index 9f41992bc84de7d43e42634797bd9d22038cc7a1..d7aeb552fb55b585131a33ec3327007b09f63f2a 100644 (file)
@@ -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; j<card->vertex_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();