void init_key_frame() { keyTime = frames[0].time; reset_scene_node( get_tux_head() ); reset_scene_node( get_tux_neck() ); }
void set_tux_pos(Player& plyr, ppogl::Vec3d newPos) { const ppogl::Vec2d& playDim = Course::getPlayDimensions(); const ppogl::Vec2d& courseDim = Course::getDimensions(); const float boundaryWidth = ( courseDim.x() - playDim.x() ) / 2; if(newPos.x() < boundaryWidth){ newPos.x() = boundaryWidth; }else if(newPos.x() > courseDim.x() - boundaryWidth){ newPos.x() = courseDim.x() - boundaryWidth; } if(newPos.z()>0){ newPos.z() = 0; }else if(-newPos.z() >= playDim.y()){ newPos.z() = -playDim.y(); GameMode::setMode(GameMode::GAME_OVER); } plyr.pos = newPos; const float disp_y = newPos.y() + TUX_Y_CORRECTION_ON_STOMACH; const std::string& tuxRoot = tux[plyr.num].getRootNode(); reset_scene_node( tuxRoot ); translate_scene_node( tuxRoot, ppogl::Vec3d( newPos.x(), disp_y, newPos.z() ) ); }
void adjust_tux_joints( scalar_t turnFact, bool_t isBraking, scalar_t paddling_factor, scalar_t speed, vector_t net_force, scalar_t flap_factor ) { scalar_t turning_angle[2] = {0., 0.}; scalar_t paddling_angle = 0.; scalar_t ext_paddling_angle = 0.; /* arm extension during paddling */ scalar_t kick_paddling_angle = 0.; /* leg kicking during paddling */ scalar_t braking_angle = 0.; scalar_t force_angle = 0.; /* amount that legs move because of force */ scalar_t turn_leg_angle = 0.; /* amount legs move when turning */ scalar_t flap_angle = 0.; /* move arms */ reset_scene_node( tuxLeftShoulderJoint ); reset_scene_node( tuxRightShoulderJoint ); if ( isBraking ) { braking_angle = MAX_ARM_ANGLE; } paddling_angle = MAX_PADDLING_ANGLE * sin(paddling_factor * M_PI); ext_paddling_angle = MAX_EXT_PADDLING_ANGLE * sin(paddling_factor * M_PI); kick_paddling_angle = MAX_KICK_PADDLING_ANGLE * sin(paddling_factor * M_PI * 2.0); turning_angle[0] = max(-turnFact,0.0) * MAX_ARM_ANGLE; turning_angle[1] = max(turnFact,0.0) * MAX_ARM_ANGLE; flap_angle = MAX_ARM_ANGLE * (0.5 + 0.5*sin(M_PI*flap_factor*6-M_PI/2)); /* Adjust arms for turning */ rotate_scene_node( tuxLeftShoulderJoint, 'z', min( braking_angle + paddling_angle + turning_angle[0], MAX_ARM_ANGLE ) + flap_angle ); rotate_scene_node( tuxRightShoulderJoint, 'z', min( braking_angle + paddling_angle + turning_angle[1], MAX_ARM_ANGLE ) + flap_angle ); /* Adjust arms for paddling */ rotate_scene_node( tuxLeftShoulderJoint, 'y', -ext_paddling_angle ); rotate_scene_node( tuxRightShoulderJoint, 'y', ext_paddling_angle ); force_angle = max( -20.0, min( 20.0, -net_force.z / 300.0 ) ); turn_leg_angle = turnFact * 10; /* Adjust hip joints */ reset_scene_node( tuxLeftHipJoint ); rotate_scene_node( tuxLeftHipJoint, 'z', -20 + turn_leg_angle + force_angle ); reset_scene_node( tuxRightHipJoint ); rotate_scene_node( tuxRightHipJoint, 'z', -20 - turn_leg_angle + force_angle ); /* Adjust knees */ reset_scene_node( tuxLeftKneeJoint ); rotate_scene_node( tuxLeftKneeJoint, 'z', -10 + turn_leg_angle - min( 35, speed ) + kick_paddling_angle + force_angle ); reset_scene_node( tuxRightKneeJoint ); rotate_scene_node( tuxRightKneeJoint, 'z', -10 - turn_leg_angle - min( 35, speed ) - kick_paddling_angle + force_angle ); /* Adjust ankles */ reset_scene_node( tuxLeftAnkleJoint ); rotate_scene_node( tuxLeftAnkleJoint, 'z', -20 + min(50, speed ) ); reset_scene_node( tuxRightAnkleJoint ); rotate_scene_node( tuxRightAnkleJoint, 'z', -20 + min(50, speed ) ); /* Turn tail */ reset_scene_node( tuxTailJoint ); rotate_scene_node( tuxTailJoint, 'z', turnFact * 20 ); /* Adjust head and neck */ reset_scene_node( tuxNeck ); rotate_scene_node( tuxNeck, 'z', -50 ); reset_scene_node( tuxHead ); rotate_scene_node( tuxHead, 'z', -30 ); /* Turn head when turning */ rotate_scene_node( tuxHead, 'y', -turnFact * 70 ); }
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; }
static bool check_model_collisions(Player& plyr, const ppogl::Vec3d& pos, ppogl::Vec3d *tree_loc, float *tree_diam) { if(GameConfig::disableCollisionDetection){ return false; } if(modelLocs.empty()){ //no models? what a boring course... return false; } pp::Matrix mat; bool hit = false; ppogl::Vec3d distvec; float squared_dist; /* These variables are used to cache collision detection results */ static bool last_collision = false; static ppogl::Vec3d last_collision_tree_loc( -999, -999, -999 ); static double last_collision_tree_diam = 0; static ppogl::Vec3d last_collision_pos( -999, -999, -999 ); /* If we haven't moved very much since the last call, we re-use the results of the last call (significant speed-up) */ ppogl::Vec3d dist_vec = pos - last_collision_pos; if ( dist_vec.length2() < COLLISION_TOLERANCE ) { if ( last_collision ) { if ( tree_loc != NULL ) { *tree_loc = last_collision_tree_loc; } if ( tree_diam != NULL ) { *tree_diam = last_collision_tree_diam; } return true; } else { return false; } } ppogl::RefPtr<ModelType> model_type = (*modelLocs.begin()).getType(); ppogl::Polyhedron *ph = model_type->ph; float diam=0.0; float height; ppogl::Vec3d loc; std::list<Model>::iterator it; for(it=modelLocs.begin();it!=modelLocs.end();it++) { diam = (*it).getDiameter(); height = (*it).getHeight(); loc = (*it).getPosition(); distvec = ppogl::Vec3d( loc.x() - pos.x(), 0.0, loc.z() - pos.z() ); /* check distance from tree; .6 is the radius of a bounding sphere around tux (approximate) */ squared_dist = ( diam/2. + 0.6 ); squared_dist *= squared_dist; if ( distvec.length2() > squared_dist ) { continue; } /* have to look at polyhedron - switch to correct one if necessary */ if ( model_type != ((*it).getType()) ) { model_type = (*it).getType(); ph = model_type->ph; } ppogl::Polyhedron ph2(*ph); mat.makeScaling( diam, diam, diam ); trans_polyhedron( mat, ph2 ); mat.makeTranslation( loc.x(), loc.y(), loc.z() ); trans_polyhedron( mat, ph2 ); const std::string& tux_root = tux[plyr.num].getRootNode(); reset_scene_node( tux_root ); translate_scene_node( tux_root, ppogl::Vec3d( pos.x(), pos.y(), pos.z() ) ); hit = collide( tux_root, ph2 ); if ( hit == true ) { if ( tree_loc != NULL ) { *tree_loc = loc; } if ( tree_diam != NULL ) { *tree_diam = diam; } break; } } last_collision_tree_loc = loc; last_collision_tree_diam = diam; last_collision_pos = pos; if(hit){ last_collision = true; // Record collision in player data so that health can be adjusted plyr.collision = true; }else{ last_collision = false; } return hit; }