- player.jump_charge = 1;
- }
-
- if( !vg_get_button("break") && vg_get_button( "push" ) )
- {
- player.pushing = 1.0f;
- player.push_time = vg_time-start_push;
-
- float cycle_time = player.push_time*k_push_cycle_rate,
- amt = k_push_accel * (sinf(cycle_time)*0.5f+0.5f)*ktimestep,
- current = v3_length( vel ),
- new_vel = vg_minf( current + amt, k_max_push_speed );
-
- new_vel -= vg_minf(current, k_max_push_speed);
- vel[2] -= new_vel * player.reverse;
- }
-
- /* Pumping */
- static float previous = 0.0f;
- float delta = previous - player.grab,
- pump = delta * k_pump_force*ktimestep;
- previous = player.grab;
-
- v3f p1;
- v3_muladds( player.rb.co, player.rb.up, pump, p1 );
- vg_line( player.rb.co, p1, 0xff0000ff );
-
- vel[1] += pump;
-
-
- m3x3_mulv( player.rb.to_world, vel, player.rb.v );
-
- float steer = vg_get_axis( "horizontal" );
- player.iY -= vg_signf(steer)*powf(steer,2.0f) * k_steer_ground * ktimestep;
-
- v2_lerp( player.board_xy, (v2f){ slip*0.25f, 0.0f },
- ktimestep*5.0f, player.board_xy);
-}
-
-static void player_physics_control_air(void)
-{
- m3x3_mulv( player.vr, player.rb.v, player.rb.v );
- draw_cross( player.land_target, 0xff0000ff, 0.25f );
-
- ray_hit hit;
-
- /*
- * Prediction
- */
- float pstep = ktimestep*10.0f;
-
- v3f pco, pco1, pv;
- v3_copy( player.rb.co, pco );
- v3_copy( player.rb.v, pv );
-
- float time_to_impact = 0.0f;
- float limiter = 1.0f;
-
- for( int i=0; i<50; i++ )
- {
- v3_copy( pco, pco1 );
- m3x3_mulv( player.vr_pstep, pv, pv );
- apply_gravity( pv, pstep );
- v3_muladds( pco, pv, pstep, pco );
-
- //vg_line( pco, pco1, i&0x1?0xff000000:0xffffffff );
-
- ray_hit contact;
- v3f vdir;
-
- v3_sub( pco, pco1, vdir );
- contact.dist = v3_length( vdir );
- v3_divs( vdir, contact.dist, vdir);
-
- float orig_dist = contact.dist;
- if( ray_world( pco1, vdir, &contact ))
- {
- float angle = v3_dot( player.rb.up, contact.normal );
- v3f axis;
- v3_cross( player.rb.up, contact.normal, axis );
-
- time_to_impact += (contact.dist/orig_dist)*pstep;
- limiter = vg_minf( 5.0f, time_to_impact )/5.0f;
- limiter = 1.0f-limiter;
- limiter *= limiter;
- limiter = 1.0f-limiter;
-
- if( angle < 0.99f )
- {
- v4f correction;
- q_axis_angle( correction, axis, acosf(angle)*0.05f*(1.0f-limiter) );
- q_mul( correction, player.rb.q, player.rb.q );
- }
-
- draw_cross( contact.pos, 0xffff0000, 0.25f );
- break;
- }
- time_to_impact += pstep;
- }
-
- player.iY -= vg_get_axis( "horizontal" ) * k_steer_air * ktimestep;
- {
- float iX = vg_get_axis( "vertical" ) *
- player.reverse * k_steer_air * limiter * ktimestep;
-
- static float siX = 0.0f;
- siX = vg_lerpf( siX, iX, k_steer_air_lerp );
-
- v4f rotate;
- q_axis_angle( rotate, player.rb.right, siX );
- q_mul( rotate, player.rb.q, player.rb.q );
- }
-
- v2f target = {0.0f,0.0f};
- v2_muladds( target, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") },
- player.grab, target );
- v2_lerp( player.board_xy, target, ktimestep*3.0f, player.board_xy );
-}
-
-static void player_init(void)
-{
- rb_init( &player.collide_front );
- rb_init( &player.collide_back );
-}
-
-static void player_walk_physics(void)
-{
- rigidbody *rbf = &player.collide_front,
- *rbb = &player.collide_back;
-
- m3x3_copy( player.rb.to_world, player.collide_front.to_world );
- m3x3_copy( player.rb.to_world, player.collide_back.to_world );
-
- float h0 = 0.3f,
- h1 = 0.9f;
-
- m4x3_mulv( player.rb.to_world, (v3f){0.0f,h0,0.0f}, rbf->co );
- v3_copy( rbf->co, rbf->to_world[3] );
- m4x3_mulv( player.rb.to_world, (v3f){0.0f,h1,0.0f}, rbb->co );
- v3_copy( rbb->co, rbb->to_world[3] );
-
- m4x3_invert_affine( rbf->to_world, rbf->to_local );
- m4x3_invert_affine( rbb->to_world, rbb->to_local );
-
- rb_update_bounds( rbf );
- rb_update_bounds( rbb );
-
- rb_debug( rbf, 0xff0000ff );
- rb_debug( rbb, 0xff0000ff );
-
- rb_ct manifold[64];
- int len = 0;
-
- len += rb_sphere_scene( rbf, &world.rb_geo, manifold+len );
- len += rb_sphere_scene( rbb, &world.rb_geo, manifold+len );
-
- rb_presolve_contacts( manifold, len );
-
- for( int j=0; j<5; j++ )
- {
- for( int i=0; i<len; i++ )
- {
- struct contact *ct = &manifold[i];
-
- /*normal */
- float vn = -v3_dot( player.rb.v, ct->n );
- vn += ct->bias;
-
- float temp = ct->norm_impulse;
- ct->norm_impulse = vg_maxf( temp + vn, 0.0f );
- vn = ct->norm_impulse - temp;
-
- v3f impulse;
- v3_muls( ct->n, vn, impulse );
-
- v3_add( impulse, player.rb.v, player.rb.v );
-
- /* friction */
- for( int j=0; j<2; j++ )
- {
- float f = k_friction * ct->norm_impulse,
- vt = v3_dot( player.rb.v, ct->t[j] ),
- lambda = -vt;
-
- float temp = ct->tangent_impulse[j];
- ct->tangent_impulse[j] = vg_clampf( temp + lambda, -f, f );
- lambda = ct->tangent_impulse[j] - temp;
-
- v3_muladds( player.rb.v, ct->t[j], lambda, player.rb.v );
- }
- }
- }
-
- player.in_air = len==0?1:0;
-
- v3_zero( player.rb.w );
- q_axis_angle( player.rb.q, (v3f){0.0f,1.0f,0.0f}, -player.angles[0] );
-
- v3f forward_dir = { sinf(player.angles[0]),0.0f,-cosf(player.angles[0]) };
-
- v3f p1;
- v3_muladds( player.rb.co, forward_dir, 2.0f, p1 );
- vg_line( player.rb.co, p1, 0xff0000ff );
-
- float move_dead = 0.1f,
- move = vg_get_axis("grabr")*0.5f + 0.5f - move_dead;
-
- if( move > 0.0f )
- {
- float move_norm = move * (1.0f/(1.0f-move_dead)),
- speed = vg_lerpf( 0.1f*k_runspeed, k_runspeed, move_norm ),
- amt = k_walk_accel * ktimestep,
- zvel = v3_dot( player.rb.v, forward_dir ),
- new_vel = vg_minf( zvel + amt, speed ),
- diff = new_vel - vg_minf( zvel, speed );
-
- v3_muladds( player.rb.v, forward_dir, diff, player.rb.v );
-
- /* TODO move */
- float walk_norm = 30.0f/(float)player.mdl.anim_walk->length,
- run_norm = 30.0f/(float)player.mdl.anim_run->length ;
-
- player.walk_timer += ktimestep * vg_lerpf( walk_norm,run_norm,move_norm );
- }
- else
- {
- player.walk_timer = 0.0f;
- }
-
- player.rb.v[0] *= 1.0f - (ktimestep*k_walk_friction);
- player.rb.v[2] *= 1.0f - (ktimestep*k_walk_friction);
-}
-
-static void player_physics(void)
-{