return 1;
}
+static void align_to_board( struct character *ch, enum character_part id )
+{
+ /* Calculate rotation between board and feet */
+ m4x3f *mats = ch->matrices;
+
+ v3f foot_pos, foot_fwd, foot_target, board_norm, board_origin;
+ v3_copy( mats[id][3], foot_pos );
+ m3x3_mulv( mats[id], (v3f){1.0f,0.0f,0.0f}, foot_fwd );
+ v3_add( foot_fwd, foot_pos, foot_target );
+
+ m3x3_mulv( mats[k_chpart_board], (v3f){0.0f,1.0f,0.0f}, board_norm );
+ m4x3_mulv( mats[k_chpart_board], (v3f){0.0f,0.13f,0.0f}, board_origin );
+
+ vg_line( foot_pos, foot_target, 0xff00ff00 );
+
+ v3f v0;
+ v3_sub( board_origin, foot_target, v0 );
+ float t = v3_dot( v0, board_norm ) / board_norm[1];
+ foot_target[1] += t;
+ vg_line( foot_pos, foot_target, 0xff00ffff );
+
+ v3_sub( foot_target, foot_pos, foot_target );
+ v3_normalize( foot_target );
+ float ang = acosf( v3_dot( foot_target, foot_fwd ) );
+
+ v4f qcorrection; m3x3f correction;
+ q_axis_angle( qcorrection, (v3f){0.0f,0.0f,1.0f}, -ang );
+ q_m3x3( qcorrection, correction );
+ m3x3_mul( mats[id], correction, mats[id] );
+}
+
static void character_eval( struct character *ch )
{
m4x3f *mats = ch->matrices;
k_ikY, k_iknX );
ik_basic( &ch->ik_leg_r, mats[k_chpart_leg_r0], mats[k_chpart_leg_r1],
k_ikY, k_iknX );
-
- /* Feet */
- m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] );
- m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] );
- m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l],
- mats[k_chpart_foot_l][3] );
- m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r],
- mats[k_chpart_foot_r][3] );
/* Hands */
m3x3_copy( mats[k_chpart_arm_l1], mats[k_chpart_hand_l] );
//m3x3_mul( mats[k_chpart_neck], mats[k_chpart_head], mats[k_chpart_head] );
m4x3_mulv( mats[k_chpart_neck], offs[k_chpart_head], mats[k_chpart_head][3]);
+ /* Feet */
+ m3x3_copy( mats[k_chpart_leg_l1], mats[k_chpart_foot_l] );
+ m3x3_copy( mats[k_chpart_leg_r1], mats[k_chpart_foot_r] );
+ m4x3_mulv( mats[k_chpart_leg_l1], offs[k_chpart_foot_l],
+ mats[k_chpart_foot_l][3] );
+ m4x3_mulv( mats[k_chpart_leg_r1], offs[k_chpart_foot_r],
+ mats[k_chpart_foot_r][3] );
+
+ align_to_board( ch, k_chpart_foot_l );
+ align_to_board( ch, k_chpart_foot_r );
+
for( int i=0; i<PART_COUNT; i++ )
m4x3_mul( ch->mroot, ch->matrices[i], ch->matrices[i] );
}
return 0;
}
+static float stable_force( float current, float diff )
+{
+ float new = current + diff;
+
+ if( new * current < 0.0f )
+ return 0.0f;
+
+ return new;
+}
+
static void player_physics_ground(void)
{
/*
float substep = ktimestep * 0.2f;
for( int i=0; i<5; i++ )
{
- if( fabsf(vel[2]) >= 0.02f*substep )
- vel[2] += vg_signf( vel[2] ) * -0.02f * substep;
- if( fabsf(vel[0]) >= 7.0f*substep )
- vel[0] += vg_signf( vel[0] ) * -7.0f * substep;
+ vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * -0.02f*substep );
+ vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -7.0f *substep );
}
m3x3_mulv( player.to_world, vel, player.v );
float steer = vg_get_axis( "horizontal" );
player.iY -= vg_signf(steer)*powf(steer,2.0f) * 1.5f * ktimestep;
+
+ /* Too much lean and it starts to look like a snowboard here */
+ v2_lerp( player.board_xy, (v2f){ slip*0.25f, 0.0f },
+ ktimestep*5.0f, player.board_xy);
}
static void draw_cross(v3f pos,u32 colour)
}
player.iY -= vg_get_axis( "horizontal" ) * 3.6f * ktimestep;
+
+ 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_animate(void);
/* New board transformation */
v4f board_rotation; v3f board_location;
-
- /* TODO: Move this out of animate into update */
- v2_lerp( player.board_xy, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") },
- ktimestep*3.0f, player.board_xy );
v4f rz, rx;
q_axis_angle( rz, (v3f){ 0.0f, 0.0f, 1.0f }, player.board_xy[0] );