void update_key_frame( player_data_t *plyr, scalar_t dt ) { int idx; scalar_t frac; point_t pos; scalar_t v; matrixgl_t cob_mat, rot_mat; char *root; char *lsh; char *rsh; char *lhp; char *rhp; char *lkn; char *rkn; char *lank; char *rank; char *head; char *neck; char *tail; root = get_tux_root_node(); lsh = get_tux_left_shoulder_joint(); rsh = get_tux_right_shoulder_joint(); lhp = get_tux_left_hip_joint(); rhp = get_tux_right_hip_joint(); lkn = get_tux_left_knee_joint(); rkn = get_tux_right_knee_joint(); lank = get_tux_left_ankle_joint(); rank = get_tux_right_ankle_joint(); head = get_tux_head(); neck = get_tux_neck(); tail = get_tux_tail_joint(); keyTime += dt; for (idx = 1; idx < numFrames; idx ++) { if ( keyTime < frames[idx].time ) break; } if ( idx == numFrames || numFrames == 0 ) { set_game_mode( RACING ); return; } reset_scene_node( root ); reset_scene_node( lsh ); reset_scene_node( rsh ); reset_scene_node( lhp ); reset_scene_node( rhp ); reset_scene_node( lkn ); reset_scene_node( rkn ); reset_scene_node( lank ); reset_scene_node( rank ); reset_scene_node( head ); reset_scene_node( neck ); reset_scene_node( tail ); check_assertion( idx > 0, "invalid keyframe index" ); if ( fabs( frames[idx-1].time - frames[idx].time ) < EPS ) { frac = 1.; } else { frac = (keyTime - frames[idx].time) / ( frames[idx-1].time - frames[idx].time ); } pos.x = interp( frac, frames[idx-1].pos.x, frames[idx].pos.x ); pos.z = interp( frac, frames[idx-1].pos.z, frames[idx].pos.z ); pos.y = interp( frac, frames[idx-1].pos.y, frames[idx].pos.y ); pos.y += find_y_coord( pos.x, pos.z ); set_tux_pos( plyr, pos ); make_identity_matrix( cob_mat ); v = interp( frac, frames[idx-1].yaw, frames[idx].yaw ); rotate_scene_node( root, 'y', v ); make_rotation_matrix( rot_mat, v, 'y' ); multiply_matrices( cob_mat, cob_mat, rot_mat ); v = interp( frac, frames[idx-1].pitch, frames[idx].pitch ); rotate_scene_node( root, 'x', v ); make_rotation_matrix( rot_mat, v, 'x' ); multiply_matrices( cob_mat, cob_mat, rot_mat ); v = interp( frac, frames[idx-1].l_shldr, frames[idx].l_shldr ); rotate_scene_node( lsh, 'z', v ); v = interp( frac, frames[idx-1].r_shldr, frames[idx].r_shldr ); rotate_scene_node( rsh, 'z', v ); v = interp( frac, frames[idx-1].l_hip, frames[idx].l_hip ); rotate_scene_node( lhp, 'z', v ); v = interp( frac, frames[idx-1].r_hip, frames[idx].r_hip ); rotate_scene_node( rhp, 'z', v ); /* Set orientation */ plyr->orientation = make_quaternion_from_matrix( cob_mat ); plyr->orientation_initialized = True; }
/** * Updates Tux's position taking into account gravity, friction, tree * collisions, etc. This is the main physics function. */ void update_player_pos(float timestep) { ppogl::Vec3d surf_nml; // normal vector of terrain ppogl::Vec3d tmp_vel; float speed; float paddling_factor; ppogl::Vec3d local_force; float flap_factor; pp::Plane surf_plane; float dist_from_surface; if(timestep > 2.0*EPS){ for(int i=0; i<GameMgr::getInstance().numPlayers; i++){ solve_ode_system(players[i], timestep); } } for(int i=0; i<GameMgr::getInstance().numPlayers; i++){ Player& plyr=players[i]; tmp_vel = plyr.vel; //Set position, orientation, generate particles surf_plane = get_local_course_plane( plyr.pos ); surf_nml = surf_plane.nml; dist_from_surface = surf_plane.distance( plyr.pos ); adjust_velocity( &plyr.vel, surf_plane ); adjust_position( &plyr.pos, surf_plane, dist_from_surface ); speed = tmp_vel.normalize(); set_tux_pos( plyr, plyr.pos ); adjust_orientation( plyr, timestep, plyr.vel, dist_from_surface, surf_nml ); flap_factor = 0; if(plyr.control.is_paddling){ double factor; factor = (GameMgr::getInstance().time - plyr.control.paddle_time) / PADDLING_DURATION; if(plyr.airborne){ paddling_factor = 0; flap_factor = factor; }else{ paddling_factor = factor; flap_factor = 0; } }else{ paddling_factor = 0.0; } // calculate force in Tux's local coordinate system local_force = plyr.orientation.conjugate().rotate(plyr.net_force); if(plyr.control.jumping){ flap_factor = (GameMgr::getInstance().time - plyr.control.jump_start_time) / JUMP_FORCE_DURATION; } tux[i].adjustJoints( plyr.control.turn_animation, plyr.control.is_braking, paddling_factor, speed, local_force, flap_factor ); } }