X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vehicle.h;h=c2429b90ae12ec6b1c18684a295e1f8d6b273034;hb=e8a65239f85784e2e596d2622c2baddda9fb5fae;hp=a08871c2e3f116eff1f9a936b79b5ffa29bb9fca;hpb=6c1541ad6a2915912e7439661820a786cb145af4;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/vehicle.h b/vehicle.h index a08871c..c2429b9 100644 --- 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, @@ -14,12 +14,14 @@ VG_STATIC float k_car_spring = 1.0f, k_car_friction_lat = 0.6f, k_car_friction_roll = 0.01f, k_car_drive_force = 1.0f, - k_car_air_resistance = 0.1f; + 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]; @@ -35,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[] ) @@ -45,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" ); } @@ -68,40 +70,45 @@ 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_function_push( (struct vg_cmd){ - .name = "spawn_car", - .function = spawn_car - }); - - v3_copy((v3f){ -1.0f, -0.25f, -1.0f }, gzoomer.wheels_local[0] ); - v3_copy((v3f){ 1.0f, -0.25f, -1.0f }, gzoomer.wheels_local[1] ); - v3_copy((v3f){ -1.0f, -0.25f, 1.0f }, gzoomer.wheels_local[2] ); - v3_copy((v3f){ 1.0f, -0.25f, 1.0f }, gzoomer.wheels_local[3] ); + 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_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] ); + v3_copy((v3f){ -1.0f, -0.25f, 1.5f }, gzoomer.wheels_local[2] ); + v3_copy((v3f){ 1.0f, -0.25f, 1.5f }, gzoomer.wheels_local[3] ); } 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 @@ -120,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 * -------------------------------------------------------------*/ @@ -155,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] ); @@ -167,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; @@ -200,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], @@ -226,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 ); } } @@ -236,29 +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.2f, - 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 */ - v3_muladds( gzoomer.rb.v, gzoomer.rb.v, - -k_car_air_resistance * k_rb_delta, gzoomer.rb.v ); + v3f Fair, Fdown; + + 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( 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; jrb_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 ); @@ -266,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) @@ -281,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 );