fnugz's idea
[carveJwlIkooP6JGAAIwe30JlM.git] / vehicle.h
index 4caf21cbbc91f1ad15fe553427bda84a674f717d..c2429b90ae12ec6b1c18684a295e1f8d6b273034 100644 (file)
--- a/vehicle.h
+++ b/vehicle.h
@@ -5,7 +5,7 @@
 #include "vg/vg.h"
 #include "rigidbody.h"
 #include "world.h"
-#include "player_physics.h"
+#include "player.h"
 
 VG_STATIC float k_car_spring = 1.0f,
                 k_car_spring_damp = 0.001f,
@@ -17,10 +17,11 @@ VG_STATIC float k_car_spring = 1.0f,
                 k_car_air_resistance = 0.1f,
                 k_car_downforce      = 0.5f;
 
-VG_STATIC struct gvehicle
+typedef struct drivable_vehicle drivable_vehicle;
+VG_STATIC struct drivable_vehicle
 {
    int alive, inside;
-   rigidbody rb;
+   rb_object obj;
 
    v3f wheels[4];
 
@@ -36,7 +37,7 @@ VG_STATIC struct gvehicle
 }
 gzoomer =
 {
-   .rb = { .type = k_rb_shape_sphere, .inf.sphere.radius = 1.0f }
+   .obj = { .type = k_rb_shape_sphere, .inf.sphere.radius = 1.0f }
 };
 
 VG_STATIC int spawn_car( int argc, const char *argv[] )
@@ -46,21 +47,21 @@ VG_STATIC int spawn_car( int argc, const char *argv[] )
    v3_muladds( ra, main_camera.transform[2], -10.0f, rb );
 
    float t;
-   if( spherecast_world( ra, rb, gzoomer.rb.inf.sphere.radius, &t, rx ) != -1 )
+   if( spherecast_world( get_active_world(), ra, rb, 
+                         gzoomer.obj.inf.sphere.radius, &t, rx ) != -1 )
    {
-      v3_lerp( ra, rb, t, gzoomer.rb.co );
-      gzoomer.rb.co[1] += 4.0f;
-      q_axis_angle( gzoomer.rb.q, (v3f){1.0f,0.0f,0.0f}, 0.001f );
-      v3_zero( gzoomer.rb.v );
-      v3_zero( gzoomer.rb.w );
+      v3_lerp( ra, rb, t, gzoomer.obj.rb.co );
+      gzoomer.obj.rb.co[1] += 4.0f;
+      q_axis_angle( gzoomer.obj.rb.q, (v3f){1.0f,0.0f,0.0f}, 0.001f );
+      v3_zero( gzoomer.obj.rb.v );
+      v3_zero( gzoomer.obj.rb.w );
       
-      rb_update_transform( &gzoomer.rb );
+      rb_update_transform( &gzoomer.obj.rb );
       gzoomer.alive = 1;
 
       vg_success( "Spawned car\n" );
    }
-   else
-   {
+   else{
       vg_error( "Can't spawn here\n" );
    }
 
@@ -69,25 +70,25 @@ VG_STATIC int spawn_car( int argc, const char *argv[] )
 
 VG_STATIC void vehicle_init(void)
 {
-   q_identity( gzoomer.rb.q );
-   rb_init( &gzoomer.rb );
-
-   VG_VAR_F32_PERSISTENT( k_car_spring );
-   VG_VAR_F32_PERSISTENT( k_car_spring_damp );
-   VG_VAR_F32_PERSISTENT( k_car_spring_length );
-   VG_VAR_F32_PERSISTENT( k_car_wheel_radius );
-   VG_VAR_F32_PERSISTENT( k_car_friction_lat );
-   VG_VAR_F32_PERSISTENT( k_car_friction_roll );
-   VG_VAR_F32_PERSISTENT( k_car_drive_force );
-   VG_VAR_F32_PERSISTENT( k_car_air_resistance );
-   VG_VAR_F32_PERSISTENT( k_car_downforce );
+   q_identity( gzoomer.obj.rb.q );
+   v3_zero( gzoomer.obj.rb.w );
+   v3_zero( gzoomer.obj.rb.v );
+   v3_zero( gzoomer.obj.rb.co );
+   rb_init_object( &gzoomer.obj );
+
+   VG_VAR_F32( k_car_spring,        flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_spring_damp,   flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_spring_length, flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_wheel_radius,  flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_friction_lat,  flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_friction_roll, flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_drive_force,   flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_air_resistance,flags=VG_VAR_PERSISTENT );
+   VG_VAR_F32( k_car_downforce,     flags=VG_VAR_PERSISTENT );
 
    VG_VAR_I32( gzoomer.inside );
 
-       vg_function_push( (struct vg_cmd){
-               .name = "spawn_car",
-               .function = spawn_car
-       });
+   vg_console_reg_cmd( "spawn_car", spawn_car, NULL );
 
    v3_copy((v3f){ -1.0f, -0.25f, -1.5f }, gzoomer.wheels_local[0] );
    v3_copy((v3f){  1.0f, -0.25f, -1.5f }, gzoomer.wheels_local[1] );
@@ -98,14 +99,16 @@ VG_STATIC void vehicle_init(void)
 VG_STATIC void vehicle_wheel_force( int index )
 {
    v3f pa, pb, n;
-   m4x3_mulv( gzoomer.rb.to_world, gzoomer.wheels_local[index], pa );
-   v3_muladds( pa, gzoomer.rb.up, -k_car_spring_length, pb );
+   m4x3_mulv( gzoomer.obj.rb.to_world, gzoomer.wheels_local[index], pa );
+   v3_muladds( pa, gzoomer.obj.rb.to_world[1], -k_car_spring_length, pb );
 
 
 #if 1
    float t;
-   if( spherecast_world( pa, pb, k_car_wheel_radius, &t, n ) == -1 )
-      t = 1.0f;
+   if( spherecast_world( get_active_world(), pa, pb, 
+                         k_car_wheel_radius, &t, n ) == -1 )
+   { t = 1.0f;
+   }
 
 #else
 
@@ -124,33 +127,33 @@ VG_STATIC void vehicle_wheel_force( int index )
    v3_lerp( pa, pb, t, pc );
 
    m4x3f mtx;
-   m3x3_copy( gzoomer.rb.to_world, mtx );
+   m3x3_copy( gzoomer.obj.rb.to_world, mtx );
    v3_copy( pc, mtx[3] );
    debug_sphere( mtx, k_car_wheel_radius, VG__BLACK );
    vg_line( pa, pc, VG__WHITE );
    v3_copy( pc, gzoomer.wheels[index] );
 
-   if( t < 1.0f )
-   {
+   if( t < 1.0f ){
       /* spring force */
       float Fv = (1.0f-t) * k_car_spring*k_rb_delta;
       
       v3f delta;
-      v3_sub( pa, gzoomer.rb.co, delta );
+      v3_sub( pa, gzoomer.obj.rb.co, delta );
 
       v3f rv;
-      v3_cross( gzoomer.rb.w, delta, rv );
-      v3_add( gzoomer.rb.v, rv, rv );
+      v3_cross( gzoomer.obj.rb.w, delta, rv );
+      v3_add( gzoomer.obj.rb.v, rv, rv );
 
-      Fv += v3_dot( rv, gzoomer.rb.up ) * -k_car_spring_damp*k_rb_delta;
+      Fv += v3_dot( rv, gzoomer.obj.rb.to_world[1] ) 
+               * -k_car_spring_damp*k_rb_delta;
 
       /* scale by normal incident */
-      Fv *= v3_dot( n, gzoomer.rb.up );
+      Fv *= v3_dot( n, gzoomer.obj.rb.to_world[1] );
 
       v3f F;
-      v3_muls( gzoomer.rb.up, Fv, F );
+      v3_muls( gzoomer.obj.rb.to_world[1], Fv, F );
 
-      rb_linear_impulse( &gzoomer.rb, delta, F );
+      rb_linear_impulse( &gzoomer.obj.rb, delta, F );
 
       /* friction vectors
        * -------------------------------------------------------------*/
@@ -159,7 +162,7 @@ VG_STATIC void vehicle_wheel_force( int index )
       if( index <= 1 )
          v3_cross( gzoomer.steerv, n, tx );
       else
-         v3_cross( gzoomer.rb.forward, n, tx );
+         v3_cross( n, gzoomer.obj.rb.to_world[2], tx );
       v3_cross( tx, n, ty );
 
       v3_copy( tx, gzoomer.tangent_vectors[ index ][0] );
@@ -171,31 +174,29 @@ VG_STATIC void vehicle_wheel_force( int index )
 
       /* orient inverse inertia tensors */
       v3f raW;
-      m3x3_mulv( gzoomer.rb.to_world, gzoomer.wheels_local[index], raW );
+      m3x3_mulv( gzoomer.obj.rb.to_world, gzoomer.wheels_local[index], raW );
 
       v3f raCtx, raCtxI, raCty, raCtyI;
       v3_cross( tx, raW, raCtx );
       v3_cross( ty, raW, raCty );
-      m3x3_mulv( gzoomer.rb.iIw, raCtx, raCtxI );
-      m3x3_mulv( gzoomer.rb.iIw, raCty, raCtyI );
+      m3x3_mulv( gzoomer.obj.rb.iIw, raCtx, raCtxI );
+      m3x3_mulv( gzoomer.obj.rb.iIw, raCty, raCtyI );
 
-      gzoomer.tangent_mass[index][0] = gzoomer.rb.inv_mass;
+      gzoomer.tangent_mass[index][0] = gzoomer.obj.rb.inv_mass;
       gzoomer.tangent_mass[index][0] += v3_dot( raCtx, raCtxI );
       gzoomer.tangent_mass[index][0] = 1.0f/gzoomer.tangent_mass[index][0];
       
-      gzoomer.tangent_mass[index][1] = gzoomer.rb.inv_mass;
+      gzoomer.tangent_mass[index][1] = gzoomer.obj.rb.inv_mass;
       gzoomer.tangent_mass[index][1] += v3_dot( raCty, raCtyI );
       gzoomer.tangent_mass[index][1] = 1.0f/gzoomer.tangent_mass[index][1];
 
       /* apply drive force */
-      if( index >= 2 )
-      {
-         v3_muls( ty, gzoomer.drive * k_car_drive_force * k_rb_delta, F );
-         rb_linear_impulse( &gzoomer.rb, raW, F );
+      if( index >= 2 ){
+         v3_muls( ty, -gzoomer.drive * k_car_drive_force * k_rb_delta, F );
+         rb_linear_impulse( &gzoomer.obj.rb, raW, F );
       }
    }
-   else
-   {
+   else{
       gzoomer.normal_forces[ index ] = 0.0f;
       gzoomer.tangent_forces[ index ][0] = 0.0f;
       gzoomer.tangent_forces[ index ][1] = 0.0f;
@@ -204,14 +205,14 @@ VG_STATIC void vehicle_wheel_force( int index )
 
 VG_STATIC void vehicle_solve_friction(void)
 {
-   for( int i=0; i<4; i++ )
-   {
+   rigidbody *rb = &gzoomer.obj.rb;
+   for( int i=0; i<4; i++ ){
       v3f raW;
-      m3x3_mulv( gzoomer.rb.to_world, gzoomer.wheels_local[i], raW );
+      m3x3_mulv( rb->to_world, gzoomer.wheels_local[i], raW );
 
       v3f rv;
-      v3_cross( gzoomer.rb.w, raW, rv );
-      v3_add( gzoomer.rb.v, rv, rv );
+      v3_cross( rb->w, raW, rv );
+      v3_add( rb->v, rv, rv );
 
       float     fx = k_car_friction_lat * gzoomer.normal_forces[i],
                 fy = k_car_friction_roll * gzoomer.normal_forces[i],
@@ -230,8 +231,8 @@ VG_STATIC void vehicle_solve_friction(void)
       v3f impulsex, impulsey;
       v3_muls( gzoomer.tangent_vectors[i][0], lambdax, impulsex );
       v3_muls( gzoomer.tangent_vectors[i][1], lambday, impulsey );
-      rb_linear_impulse( &gzoomer.rb, raW, impulsex );
-      rb_linear_impulse( &gzoomer.rb, raW, impulsey );
+      rb_linear_impulse( rb, raW, impulsex );
+      rb_linear_impulse( rb, raW, impulsey );
    }
 }
 
@@ -240,35 +241,36 @@ VG_STATIC void vehicle_update_fixed(void)
    if( !gzoomer.alive )
       return;
 
-   gzoomer.steer = vg_lerpf( gzoomer.steer, 
-                             player.input_walkh->axis.value * 0.4f,
-                             k_rb_delta * 8.0f );
+   rigidbody *rb = &gzoomer.obj.rb;
 
-   gzoomer.drive = player.input_walkv->axis.value * k_car_drive_force;
-   v3_muls( gzoomer.rb.forward, cosf(gzoomer.steer), gzoomer.steerv );
-   v3_muladds( gzoomer.steerv, gzoomer.rb.right, 
+   v3_muls( rb->to_world[2], -cosf(gzoomer.steer), gzoomer.steerv );
+   v3_muladds( gzoomer.steerv, rb->to_world[0], 
                sinf(gzoomer.steer), gzoomer.steerv );
 
    /* apply air resistance */
    v3f Fair, Fdown;
 
-   v3_muls( gzoomer.rb.v, -k_car_air_resistance, Fair );
-   v3_muls( gzoomer.rb.up, -fabsf(v3_dot( gzoomer.rb.v, gzoomer.rb.forward )) *
+   v3_muls( rb->v, -k_car_air_resistance, Fair );
+   v3_muls( rb->to_world[1], -fabsf(v3_dot( rb->v, rb->to_world[2] )) *
                                  k_car_downforce, Fdown );
 
-   v3_muladds( gzoomer.rb.v, Fair,  k_rb_delta, gzoomer.rb.v );
-   v3_muladds( gzoomer.rb.v, Fdown, k_rb_delta, gzoomer.rb.v );
+   v3_muladds( rb->v, Fair,  k_rb_delta, rb->v );
+   v3_muladds( rb->v, Fdown, k_rb_delta, rb->v );
    
    for( int i=0; i<4; i++ )
       vehicle_wheel_force( i );
 
    rb_ct manifold[64];
-
-   int len = rb_sphere_scene( &gzoomer.rb, &world.rb_geo, manifold );
+   int len = rb_sphere__scene( rb->to_world, &gzoomer.obj.inf.sphere, 
+                               NULL, &get_active_world()->rb_geo.inf.scene, 
+                               manifold );
+   for( int j=0; j<len; j++ ){
+      manifold[j].rba = rb;
+      manifold[j].rbb = &get_active_world()->rb_geo.rb;
+   }
    rb_manifold_filter_coplanar( manifold, len, 0.05f );
 
-   if( len > 1 )
-   {
+   if( len > 1 ){
       rb_manifold_filter_backface( manifold, len );
       rb_manifold_filter_joint_edges( manifold, len, 0.05f );
       rb_manifold_filter_pairs( manifold, len, 0.05f );
@@ -276,14 +278,13 @@ VG_STATIC void vehicle_update_fixed(void)
    len = rb_manifold_apply_filtered( manifold, len );
 
    rb_presolve_contacts( manifold, len );
-   for( int i=0; i<8; i++ )
-   {
+   for( int i=0; i<8; i++ ){
       rb_solve_contacts( manifold, len );
       vehicle_solve_friction();
    }
 
-   rb_iter( &gzoomer.rb );
-   rb_update_transform( &gzoomer.rb );
+   rb_iter( rb );
+   rb_update_transform( rb );
 }
 
 VG_STATIC void vehicle_update_post(void)
@@ -291,14 +292,12 @@ VG_STATIC void vehicle_update_post(void)
    if( !gzoomer.alive )
       return;
 
-   rb_debug( &gzoomer.rb, VG__WHITE );
-   vg_line( player.phys.rb.co, gzoomer.rb.co, VG__WHITE );
+   rb_object_debug( &gzoomer.obj, VG__WHITE );
 
    /* draw friction vectors */
    v3f p0, px, py;
 
-   for( int i=0; i<4; i++ )
-   {
+   for( int i=0; i<4; i++ ){
       v3_copy( gzoomer.wheels[i], p0 );
       v3_muladds( p0, gzoomer.tangent_vectors[i][0], 0.5f, px );
       v3_muladds( p0, gzoomer.tangent_vectors[i][1], 0.5f, py );
@@ -308,23 +307,4 @@ VG_STATIC void vehicle_update_post(void)
    }
 }
 
-VG_STATIC void vehicle_camera(void)
-{
-   float yaw = atan2f( gzoomer.rb.forward[0], -gzoomer.rb.forward[2] ),
-       pitch = atan2f
-               ( 
-                   -gzoomer.rb.forward[1], 
-                   sqrtf
-                   (
-                     gzoomer.rb.forward[0]*gzoomer.rb.forward[0] + 
-                     gzoomer.rb.forward[2]*gzoomer.rb.forward[2]
-                   )
-               );
-               
-
-   main_camera.angles[0] = yaw;
-   main_camera.angles[1] = pitch;
-   v3_copy( gzoomer.rb.co, main_camera.pos );
-}
-
 #endif /* VEHICLE_H */