/*! Interpolates between camera orientations \pre p_up2, p_dir2 != NULL; *p_up2 is the target up vector; *p_dir2 is the target view direction \arg \c up1 original up vector \arg \c dir1 original view direction \arg \c p_up2 pointer to target up vector; is overwritten with interpolated up vector \arg \c p_dir2 pointer to target view direction; is overwritten with interpolated view direction \arg \c dt time step \arg \c time_constant interpolation time constant \return none \author jfpatry \date Created: 2000-08-26 \date Modified: 2000-08-26 */ void interpolate_view_frame( vector_t up1, vector_t dir1, vector_t *p_up2, vector_t *p_dir2, scalar_t dt, scalar_t time_constant ) { quaternion_t q1, q2; scalar_t alpha; vector_t x1, y1, z1; vector_t x2, y2, z2; matrixgl_t cob_mat1, inv_cob_mat1; matrixgl_t cob_mat2, inv_cob_mat2; /* Now interpolate between camera orientations */ z1 = scale_vector( -1.0, dir1 ); normalize_vector( &z1 ); y1 = project_into_plane( z1, up1 ); normalize_vector( &y1 ); x1 = cross_product( y1, z1 ); make_change_of_basis_matrix( cob_mat1, inv_cob_mat1, x1, y1, z1 ); q1 = make_quaternion_from_matrix( cob_mat1 ); z2 = scale_vector( -1.0, *p_dir2 ); normalize_vector( &z2 ); y2 = project_into_plane( z2, *p_up2 ); normalize_vector( &y2 ); x2 = cross_product( y2, z2 ); make_change_of_basis_matrix( cob_mat2, inv_cob_mat2, x2, y2, z2 ); q2 = make_quaternion_from_matrix( cob_mat2 ); alpha = min( MAX_INTERPOLATION_VALUE, 1.0 - exp( -dt / time_constant ) ); q2 = interpolate_quaternions( q1, q2, alpha ); make_matrix_from_quaternion( cob_mat2, q2 ); p_up2->x = cob_mat2[1][0]; p_up2->y = cob_mat2[1][1]; p_up2->z = cob_mat2[1][2]; p_dir2->x = -cob_mat2[2][0]; p_dir2->y = -cob_mat2[2][1]; p_dir2->z = -cob_mat2[2][2]; }
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; }