pp::Plane get_local_course_plane(const ppogl::Vec3d& pt) { pp::Plane plane; plane.nml = find_course_normal( pt ); plane.d = -( plane.nml.x() * pt.x() + plane.nml.y() * find_y_coord(pt) + plane.nml.z() * pt.z() ); return plane; }
void init_physical_simulation() { ppogl::Vec3d nml; pp::Matrix rotMat; float ycoord; ppogl::Vec3d init_vel; ppogl::Vec3d init_f; for(int i=0; i<GameMgr::getInstance().numPlayers; i++){ Player& plyr = players[i]; ycoord = find_y_coord( plyr.pos ); nml = find_course_normal(plyr.pos); rotMat.makeRotation( -90., ppogl::AXIS_X ); init_vel = rotMat.transformVector( nml ); init_vel = INIT_TUX_SPEED*init_vel; init_f = ppogl::Vec3d( 0., 0., 0. ); plyr.pos.y() = ycoord; plyr.vel = init_vel; plyr.net_force = init_f; plyr.control.turn_fact = 0.0; plyr.control.turn_animation = 0.0; plyr.control.barrel_roll_factor = 0.0; plyr.control.flip_factor = 0.0; plyr.control.is_braking = false; plyr.orientation_initialized = false; plyr.plane_nml = nml; plyr.direction = init_vel; plyr.normal_force = ppogl::Vec3d(0,0,0); plyr.airborne = false; plyr.collision = false; plyr.control.jump_amt = 0; plyr.control.is_paddling = false; plyr.control.jumping = false; plyr.control.jump_charging = false; plyr.control.barrel_roll_left = false; plyr.control.barrel_roll_right = false; plyr.control.barrel_roll_factor = 0; plyr.control.front_flip = false; plyr.control.back_flip = false; } ode_time_step = -1; }
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; }
void update_view( player_data_t *plyr, scalar_t dt ) { point_t view_pt; vector_t view_dir, up_dir, vel_dir, view_vec; scalar_t ycoord; scalar_t course_angle; vector_t axis; matrixgl_t rot_mat; vector_t y_vec; vector_t mz_vec; vector_t vel_proj; quaternion_t rot_quat; scalar_t speed; vector_t vel_cpy; scalar_t time_constant_mult; vel_cpy = plyr->vel; speed = normalize_vector( &vel_cpy ); time_constant_mult = 1.0 / min( 1.0, max( 0.0, ( speed - NO_INTERPOLATION_SPEED ) / ( BASELINE_INTERPOLATION_SPEED - NO_INTERPOLATION_SPEED ))); up_dir = make_vector( 0, 1, 0 ); vel_dir = plyr->vel; normalize_vector( &vel_dir ); course_angle = get_course_angle(); switch( plyr->view.mode ) { case TUXEYE: { scalar_t f = 2; vector_t v = plyr->plane_nml; scalar_t n = 1.; view_pt = plyr->pos; view_pt.x += v.x / n * 0.3; view_pt.y += v.y / n * 0.3; view_pt.y += 0.1; view_pt.z += v.z / n * 0.3; if(plyr->control.flip_factor || plyr->control.barrel_roll_factor) { matrixgl_t mat1, mat; vector_t right; scalar_t n = sqrt(plyr->viewdir_for_tuxeye.x * plyr->viewdir_for_tuxeye.x + plyr->viewdir_for_tuxeye.y * plyr->viewdir_for_tuxeye.y + plyr->viewdir_for_tuxeye.z * plyr->viewdir_for_tuxeye.z); plyr->viewdir_for_tuxeye.x /= n; plyr->viewdir_for_tuxeye.y /= n; plyr->viewdir_for_tuxeye.z /= n; n = sqrt(plyr->updir_for_tuxeye.x * plyr->updir_for_tuxeye.x + plyr->updir_for_tuxeye.y * plyr->updir_for_tuxeye.y + plyr->updir_for_tuxeye.z * plyr->updir_for_tuxeye.z); plyr->updir_for_tuxeye.x /= n; plyr->updir_for_tuxeye.y /= n; plyr->updir_for_tuxeye.z /= n; right = cross_product(plyr->updir_for_tuxeye, plyr->viewdir_for_tuxeye); make_rotation_about_vector_matrix( mat1, right, jump_from_time(plyr->control.flip_factor) * 360 ); make_rotation_about_vector_matrix( mat, plyr->viewdir_for_tuxeye, jump_from_time(plyr->control.barrel_roll_factor) * 360 ); multiply_matrices(mat, mat1, mat); view_dir = transform_vector(mat, plyr->viewdir_for_tuxeye); up_dir = transform_vector(mat, plyr->updir_for_tuxeye); } else { view_dir = plyr->direction; view_dir.y += 0.1; view_dir.x = (plyr->view.dir.x * f + view_dir.x) / (f + 1); view_dir.y = (plyr->view.dir.y * f + view_dir.y) / (f + 1); view_dir.z = (plyr->view.dir.z * f + view_dir.z) / (f + 1); plyr->viewdir_for_tuxeye = view_dir; up_dir = plyr->plane_nml; up_dir.x = (plyr->view.up.x * f + up_dir.x) / (f + 1); up_dir.y = (plyr->view.up.y * f + up_dir.y) / (f + 1); up_dir.z = (plyr->view.up.z * f + up_dir.z) / (f + 1); plyr->updir_for_tuxeye = up_dir; } break; } case BEHIND: { /* Camera-on-a-string mode */ /* Construct vector from player to camera */ view_vec = make_vector( 0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = scale_vector( CAMERA_DISTANCE, view_vec ); y_vec = make_vector( 0.0, 1.0, 0.0 ); mz_vec = make_vector( 0.0, 0.0, -1.0 ); vel_proj = project_into_plane( y_vec, vel_dir ); normalize_vector( &vel_proj ); /* Rotate view_vec so that it places the camera behind player */ rot_quat = make_rotation_quaternion( mz_vec, vel_proj ); view_vec = rotate_vector( rot_quat, view_vec ); /* Construct view point */ view_pt = move_point( plyr->pos, view_vec ); /* Make sure view point is above terrain */ ycoord = find_y_coord( view_pt.x, view_pt.z ); if ( view_pt.y < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y = ycoord + MIN_CAMERA_HEIGHT; } /* Interpolate view point */ if ( plyr->view.initialized ) { /* Interpolate twice to get a second-order filter */ int i; for (i=0; i<2; i++) { view_pt = interpolate_view_pos( plyr->pos, plyr->pos, MAX_CAMERA_PITCH, plyr->view.pos, view_pt, CAMERA_DISTANCE, dt, BEHIND_ORBIT_TIME_CONSTANT * time_constant_mult ); } } /* Make sure interpolated view point is above terrain */ ycoord = find_y_coord( view_pt.x, view_pt.z ); if ( view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT ) { view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = subtract_points( view_pt, plyr->pos ); axis = cross_product( y_vec, view_vec ); normalize_vector( &axis ); make_rotation_about_vector_matrix( rot_mat, axis, PLAYER_ANGLE_IN_CAMERA ); view_dir = scale_vector( -1.0, transform_vector( rot_mat, view_vec ) ); /* Interpolate orientation of camera */ if ( plyr->view.initialized ) { /* Interpolate twice to get a second-order filter */ int i; for (i=0; i<2; i++) { interpolate_view_frame( plyr->view.up, plyr->view.dir, &up_dir, &view_dir, dt, BEHIND_ORIENT_TIME_CONSTANT ); up_dir = make_vector( 0.0, 1.0, 0.0 ); } } break; } case FOLLOW: { /* Camera follows player (above and behind) */ up_dir = make_vector( 0, 1, 0 ); /* Construct vector from player to camera */ view_vec = make_vector( 0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = scale_vector( CAMERA_DISTANCE, view_vec ); y_vec = make_vector( 0.0, 1.0, 0.0 ); mz_vec = make_vector( 0.0, 0.0, -1.0 ); vel_proj = project_into_plane( y_vec, vel_dir ); normalize_vector( &vel_proj ); /* Rotate view_vec so that it places the camera behind player */ rot_quat = make_rotation_quaternion( mz_vec, vel_proj ); view_vec = rotate_vector( rot_quat, view_vec ); /* Construct view point */ view_pt = move_point( plyr->pos, view_vec ); /* Make sure view point is above terrain */ ycoord = find_y_coord( view_pt.x, view_pt.z ); if ( view_pt.y < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y = ycoord + MIN_CAMERA_HEIGHT; } /* Interpolate view point */ if ( plyr->view.initialized ) { /* Interpolate twice to get a second-order filter */ int i; for ( i=0; i<2; i++ ) { view_pt = interpolate_view_pos( plyr->view.plyr_pos, plyr->pos, MAX_CAMERA_PITCH, plyr->view.pos, view_pt, CAMERA_DISTANCE, dt, FOLLOW_ORBIT_TIME_CONSTANT * time_constant_mult ); } } /* Make sure interpolate view point is above terrain */ ycoord = find_y_coord( view_pt.x, view_pt.z ); if ( view_pt.y < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT ) { view_pt.y = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = subtract_points( view_pt, plyr->pos ); axis = cross_product( y_vec, view_vec ); normalize_vector( &axis ); make_rotation_about_vector_matrix( rot_mat, axis, PLAYER_ANGLE_IN_CAMERA ); view_dir = scale_vector( -1.0, transform_vector( rot_mat, view_vec ) ); /* Interpolate orientation of camera */ if ( plyr->view.initialized ) { /* Interpolate twice to get a second-order filter */ int i; for ( i=0; i<2; i++ ) { interpolate_view_frame( plyr->view.up, plyr->view.dir, &up_dir, &view_dir, dt, FOLLOW_ORIENT_TIME_CONSTANT ); up_dir = make_vector( 0.0, 1.0, 0.0 ); } } break; } case ABOVE: { /* Camera always uphill of player */ up_dir = make_vector( 0, 1, 0 ); /* Construct vector from player to camera */ view_vec = make_vector( 0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE+ PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE+ PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = scale_vector( CAMERA_DISTANCE, view_vec ); /* Construct view point */ view_pt = move_point( plyr->pos, view_vec ); /* Make sure view point is above terrain */ ycoord = find_y_coord( view_pt.x, view_pt.z ); if ( view_pt.y < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y = ycoord + MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = subtract_points( view_pt, plyr->pos ); make_rotation_matrix( rot_mat, PLAYER_ANGLE_IN_CAMERA, 'x' ); view_dir = scale_vector( -1.0, transform_vector( rot_mat, view_vec ) ); break; } default: code_not_reached(); } /* Create view matrix */ plyr->view.pos = view_pt; plyr->view.dir = view_dir; plyr->view.up = up_dir; plyr->view.plyr_pos = plyr->pos; plyr->view.initialized = True; setup_view_matrix( plyr ); }
/*! Updates camera and sets the view matrix \pre plyr != NULL, plyr has been initialized with position & velocity info., plyr->view.mode has been set \arg \c plyr pointer to player data \arg \c dt time step size \return none \author jfpatry \date Created: 2000-08-26 \date Modified: 2000-08-26 */ void update_view(Player& plyr, const float dt) { ppogl::Vec3d view_pt; ppogl::Vec3d view_dir; ppogl::Vec3d vel_cpy = plyr.vel; const float speed = vel_cpy.normalize(); const float time_constant_mult = 1.0 / MIN( 1.0, MAX( 0.0, ( speed - NO_INTERPOLATION_SPEED ) / ( BASELINE_INTERPOLATION_SPEED - NO_INTERPOLATION_SPEED ))); ppogl::Vec3d up_dir = ppogl::Vec3d( 0, 1, 0 ); ppogl::Vec3d vel_dir = plyr.vel; vel_dir.normalize(); const float course_angle = Course::getAngle(); switch(plyr.view.mode){ case BEHIND: { /* Camera-on-a-string mode */ /* Construct vector from player to camera */ ppogl::Vec3d view_vec(0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = CAMERA_DISTANCE*view_vec; ppogl::Vec3d y_vec(0.0, 1.0, 0.0); ppogl::Vec3d mz_vec(0.0, 0.0, -1.0); ppogl::Vec3d vel_proj = projectIntoPlane( y_vec, vel_dir ); vel_proj.normalize(); /* Rotate view_vec so that it places the camera behind player */ pp::Quat rot_quat(mz_vec, vel_proj); view_vec = rot_quat.rotate(view_vec); /* Construct view point */ view_pt = plyr.pos - view_vec; /* Make sure view point is above terrain */ float ycoord = find_y_coord( view_pt ); if ( view_pt.y() < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y() = ycoord + MIN_CAMERA_HEIGHT; } /* Interpolate view point */ if ( plyr.view.initialized ) { /* Interpolate twice to get a second-order filter */ for (int i=0; i<2; i++) { view_pt = interpolate_view_pos( plyr.pos, plyr.pos, MAX_CAMERA_PITCH, plyr.view.pos, view_pt, CAMERA_DISTANCE, dt, BEHIND_ORBIT_TIME_CONSTANT * time_constant_mult ); } } /* Make sure interpolated view point is above terrain */ ycoord = find_y_coord( view_pt ); if ( view_pt.y() < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT ) { view_pt.y() = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = view_pt - plyr.pos; ppogl::Vec3d axis = y_vec^view_vec; axis.normalize(); pp::Matrix rot_mat; rot_mat.makeRotationAboutVector( axis, PLAYER_ANGLE_IN_CAMERA ); view_dir = -1.0*rot_mat.transformVector( view_vec ); /* Interpolate orientation of camera */ if ( plyr.view.initialized ) { /* Interpolate twice to get a second-order filter */ for (int i=0; i<2; i++) { interpolate_view_frame( plyr.view.up, plyr.view.dir, up_dir, view_dir, dt, BEHIND_ORIENT_TIME_CONSTANT ); up_dir = ppogl::Vec3d( 0.0, 1.0, 0.0 ); } } break; } case FOLLOW: { /* Camera follows player (above and behind) */ up_dir = ppogl::Vec3d( 0, 1, 0 ); /* Construct vector from player to camera */ ppogl::Vec3d view_vec( 0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE + PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = CAMERA_DISTANCE*view_vec; ppogl::Vec3d y_vec(0.0, 1.0, 0.0); ppogl::Vec3d mz_vec(0.0, 0.0, -1.0); ppogl::Vec3d vel_proj = projectIntoPlane( y_vec, vel_dir ); vel_proj.normalize(); /* Rotate view_vec so that it places the camera behind player */ pp::Quat rot_quat(mz_vec, vel_proj); view_vec = rot_quat.rotate( view_vec ); /* Construct view point */ view_pt = plyr.pos + view_vec; /* Make sure view point is above terrain */ float ycoord = find_y_coord( view_pt ); if ( view_pt.y() < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y() = ycoord + MIN_CAMERA_HEIGHT; } /* Interpolate view point */ if ( plyr.view.initialized ) { /* Interpolate twice to get a second-order filter */ for (int i=0; i<2; i++ ) { view_pt = interpolate_view_pos( plyr.view.plyr_pos, plyr.pos, MAX_CAMERA_PITCH, plyr.view.pos, view_pt, CAMERA_DISTANCE, dt, FOLLOW_ORBIT_TIME_CONSTANT * time_constant_mult ); } } /* Make sure interpolate view point is above terrain */ ycoord = find_y_coord( view_pt ); if ( view_pt.y() < ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT ) { view_pt.y() = ycoord + ABSOLUTE_MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = view_pt - plyr.pos; ppogl::Vec3d axis = y_vec^view_vec; axis.normalize(); pp::Matrix rot_mat; rot_mat.makeRotationAboutVector( axis, PLAYER_ANGLE_IN_CAMERA ); view_dir = -1.0*rot_mat.transformVector( view_vec ); /* Interpolate orientation of camera */ if ( plyr.view.initialized ) { /* Interpolate twice to get a second-order filter */ for (int i=0; i<2; i++ ) { interpolate_view_frame( plyr.view.up, plyr.view.dir, up_dir, view_dir, dt, FOLLOW_ORIENT_TIME_CONSTANT ); up_dir = ppogl::Vec3d( 0.0, 1.0, 0.0 ); } } break; } case ABOVE: { /* Camera always uphill of player */ up_dir = ppogl::Vec3d( 0, 1, 0 ); /* Construct vector from player to camera */ ppogl::Vec3d view_vec( 0, sin( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE+ PLAYER_ANGLE_IN_CAMERA ) ), cos( ANGLES_TO_RADIANS( course_angle - CAMERA_ANGLE_ABOVE_SLOPE+ PLAYER_ANGLE_IN_CAMERA ) ) ); view_vec = CAMERA_DISTANCE*view_vec; /* Construct view point */ view_pt = plyr.pos + view_vec; /* Make sure view point is above terrain */ float ycoord = find_y_coord( view_pt ); if ( view_pt.y() < ycoord + MIN_CAMERA_HEIGHT ) { view_pt.y() = ycoord + MIN_CAMERA_HEIGHT; } /* Construct view direction */ view_vec = view_pt - plyr.pos; pp::Matrix rot_mat; rot_mat.makeRotation( PLAYER_ANGLE_IN_CAMERA, ppogl::AXIS_X ); view_dir = -1.0*rot_mat.transformVector( view_vec ); break; } default: PP_NOT_REACHED(); } /* Create view matrix */ plyr.view.pos = view_pt; plyr.view.dir = view_dir; plyr.view.up = up_dir; plyr.view.plyr_pos = plyr.pos; plyr.view.initialized = true; }
void Racing::loop(float timeStep) { int width, height; bool joy_left_turn = false; bool joy_right_turn = false; double joy_turn_fact = 0.0; bool joy_paddling = false; bool joy_braking = false; bool joy_tricks = false; bool joy_charging = false; bool airborne; pp::Vec3d dir; float speed; float terrain_weights[NUM_TERRAIN_TYPES]; int new_terrain = 0; int slide_volume; unsigned int i; if (Benchmark::getMode() == Benchmark::AUTO){ m_paddling = true; } dir = players[0].vel; speed = dir.normalize(); //set max_speed if (speed > players[0].max_speed) players[0].max_speed=int(speed); airborne = (bool) ( players[0].pos.y > ( find_y_coord(players[0].pos.x, players[0].pos.z) + JUMP_MAX_START_HEIGHT ) ); width = getparam_x_resolution(); height = getparam_y_resolution(); fpsCounter.update(); update_audio(); clear_rendering_context(); fogPlane.setup(); // Joystick if ( is_joystick_active() ) { float joy_x; float joy_y; update_joystick(); joy_x = get_joystick_x_axis(); joy_y = get_joystick_y_axis(); if ( joy_x > 0.1 ) { joy_right_turn = true; joy_turn_fact = joy_x; } else if ( joy_x < -0.1 ) { joy_left_turn = true; joy_turn_fact = joy_x; } if ( getparam_joystick_brake_button() >= 0 ) { joy_braking = is_joystick_button_down( getparam_joystick_brake_button() ); } if ( !joy_braking ) { joy_braking = (bool) ( joy_y > 0.5 ); } if ( getparam_joystick_paddle_button() >= 0 ) { joy_paddling = is_joystick_button_down( getparam_joystick_paddle_button() ); } if ( !joy_paddling ) { joy_paddling = (bool) ( joy_y < -0.5 ); } if ( getparam_joystick_jump_button() >= 0 ) { joy_charging = is_joystick_button_down( getparam_joystick_jump_button() ); } if ( getparam_joystick_trick_button() >= 0 ) { joy_tricks = is_joystick_button_down( getparam_joystick_trick_button() ); } } // Update braking players[0].control.is_braking = (bool) ( m_braking || joy_braking ); if ( airborne ) { new_terrain = (1<<4); // Tricks if ( m_trickModifier || joy_tricks ) { if ( m_leftTurn || joy_left_turn ) { players[0].control.barrel_roll_left = true; } if ( m_rightTurn || joy_right_turn ) { players[0].control.barrel_roll_right = true; } if ( m_paddling || joy_paddling ) { players[0].control.front_flip = true; } if ( players[0].control.is_braking ) { players[0].control.back_flip = true; } } for(i=0;i<num_terrains;i++){ if ( !terrain_texture[i].sound.empty() && terrain_texture[i].soundactive==true) { halt_sound( terrain_texture[i].sound.c_str() ); terrain_texture[i].soundactive=false; } } } else { get_surface_type(players[0].pos.x, players[0].pos.z, terrain_weights); //Play sliding sound slide_volume = int(MIN( (((pow(players[0].control.turn_fact, 2)*128)) + (players[0].control.is_braking?128:0) + (players[0].control.jumping?128:0) + 20) * (speed/10), 128 )); for(i=0;i<num_terrains;i++){ if ( !terrain_texture[i].sound.empty() ) { if (terrain_weights[i] > 0 ){ set_sound_volume(terrain_texture[i].sound.c_str(), int(slide_volume * terrain_weights[i])); if (terrain_texture[i].soundactive==false){ play_sound(terrain_texture[i].sound.c_str() , -1 ); terrain_texture[i].soundactive=true; } } else if (terrain_texture[i].soundactive==true){ halt_sound( terrain_texture[i].sound.c_str() ); terrain_texture[i].soundactive=false; } } } } // Jumping calcJumpAmt( timeStep ); if ( ( m_charging || joy_charging ) && !players[0].control.jump_charging && !players[0].control.jumping ) { players[0].control.jump_charging = true; m_chargeStartTime = gameMgr->time; } if ( ( !m_charging && !joy_charging ) && players[0].control.jump_charging ) { players[0].control.jump_charging = false; players[0].control.begin_jump = true; } // Turning if ( ( m_leftTurn || joy_left_turn ) ^ (m_rightTurn || joy_right_turn ) ) { bool turning_left = (bool) ( m_leftTurn || joy_left_turn ); if ( joy_left_turn || joy_right_turn ) { players[0].control.turn_fact = joy_turn_fact; } else { players[0].control.turn_fact = (turning_left?-1:1); } players[0].control.turn_animation += (turning_left?-1:1) * 0.15 * timeStep / 0.05; players[0].control.turn_animation = MIN(1.0, MAX(-1.0, players[0].control.turn_animation)); } else { players[0].control.turn_fact = 0; // Decay turn animation if ( timeStep < ROLL_DECAY_TIME_CONSTANT ) { players[0].control.turn_animation *= 1.0 - timeStep/ROLL_DECAY_TIME_CONSTANT; } else { players[0].control.turn_animation = 0.0; } } //Paddling if ( ( m_paddling || joy_paddling ) && players[0].control.is_paddling == false ) { players[0].control.is_paddling = true; players[0].control.paddle_time = gameMgr->time; } //Play flying sound if (new_terrain & (1<<4)) { set_sound_volume("flying_sound", int(MIN(128, speed*2))); if (!(m_lastTerrain & (1<<4))) { play_sound( "flying_sound", -1 ); } } else { if (m_lastTerrain & (1<<4)) { halt_sound( "flying_sound" ); } } m_lastTerrain = new_terrain; //Tricks if ( players[0].control.barrel_roll_left || players[0].control.barrel_roll_right ) { players[0].control.barrel_roll_factor += ( players[0].control.barrel_roll_left ? -1 : 1 ) * 0.15 * timeStep / 0.05; if ( (players[0].control.barrel_roll_factor > 1) || (players[0].control.barrel_roll_factor < -1) ) { players[0].control.barrel_roll_factor = 0; players[0].control.barrel_roll_left = players[0].control.barrel_roll_right = false; } } if ( players[0].control.front_flip || players[0].control.back_flip ) { players[0].control.flip_factor += ( players[0].control.back_flip ? -1 : 1 ) * 0.15 * timeStep / 0.05; if ( (players[0].control.flip_factor > 1) || (players[0].control.flip_factor < -1) ) { players[0].control.flip_factor = 0; players[0].control.front_flip = players[0].control.back_flip = false; } } update_player_pos( players[0], timeStep ); //Track Marks add_track_mark( players[0] ); update_view( players[0], timeStep ); setup_view_frustum( players[0], NEAR_CLIP_DIST, getparam_forward_clip_distance() ); draw_sky(players[0].view.pos); draw_fog_plane(); set_course_clipping( true ); set_course_eye_point( players[0].view.pos ); setup_course_lighting(); render_course(); //Draw snow update_snow( timeStep, false, players[0].view.pos ); draw_snow(players[0].view.pos); draw_trees(); if ( getparam_draw_particles() ) { update_particles( timeStep ); draw_particles( players[0] ); } ModelHndl->draw_tux(); draw_tux_shadow(); HUD1.draw(players[0]); reshape( width, height ); winsys_swap_buffers(); gameMgr->time += timeStep; if (airborne) gameMgr->airbornetime += timeStep; if(Benchmark::getMode() == Benchmark::PAUSED){ set_game_mode(PAUSED); } }
void racing_loop( scalar_t time_step ) { int width, height; player_data_t *plyr = get_player_data( local_player() ); bool_t joy_left_turn = False; bool_t joy_right_turn = False; scalar_t joy_turn_fact = 0.0; bool_t joy_paddling = False; bool_t joy_braking = False; bool_t joy_tricks = False; bool_t joy_charging = False; bool_t airborne; vector_t dir; scalar_t speed; scalar_t terrain_weights[NumTerrains]; int new_terrain = 0; int slide_volume; dir = plyr->vel; speed = normalize_vector(&dir); airborne = (bool_t) ( plyr->pos.y > ( find_y_coord(plyr->pos.x, plyr->pos.z) + JUMP_MAX_START_HEIGHT ) ); width = getparam_x_resolution(); height = getparam_y_resolution(); check_gl_error(); new_frame_for_fps_calc(); update_audio(); clear_rendering_context(); setup_fog(); /* * Joystick */ if ( is_joystick_active() ) { scalar_t joy_x; scalar_t joy_y; update_joystick(); joy_x = get_joystick_x_axis(); joy_y = get_joystick_y_axis(); if ( joy_x > 0.1 ) { joy_right_turn = True; joy_turn_fact = joy_x; } else if ( joy_x < -0.1 ) { joy_left_turn = True; joy_turn_fact = joy_x; } if ( getparam_joystick_brake_button() >= 0 ) { joy_braking = is_joystick_button_down( getparam_joystick_brake_button() ); } if ( !joy_braking ) { joy_braking = (bool_t) ( joy_y > 0.5 ); } if ( getparam_joystick_paddle_button() >= 0 ) { joy_paddling = is_joystick_button_down( getparam_joystick_paddle_button() ); } if ( !joy_paddling ) { joy_paddling = (bool_t) ( joy_y < -0.5 ); } if ( getparam_joystick_jump_button() >= 0 ) { joy_charging = is_joystick_button_down( getparam_joystick_jump_button() ); } if ( getparam_joystick_trick_button() >= 0 ) { joy_tricks = is_joystick_button_down( getparam_joystick_trick_button() ); } } /* Update braking */ plyr->control.is_braking = (bool_t) ( braking || joy_braking ); if ( airborne ) { new_terrain = (1<<NumTerrains); /* * Tricks */ if ( trick_modifier || joy_tricks ) { if ( left_turn || joy_left_turn ) { plyr->control.barrel_roll_left = True; } if ( right_turn || joy_right_turn ) { plyr->control.barrel_roll_right = True; } if ( paddling || joy_paddling ) { plyr->control.front_flip = True; } if ( plyr->control.is_braking ) { plyr->control.back_flip = True; } } } else { get_surface_type(plyr->pos.x, plyr->pos.z, terrain_weights); if (terrain_weights[Snow] > 0) { new_terrain |= (1<<Snow); } if (terrain_weights[Rock] > 0) { new_terrain |= (1<<Rock); } if (terrain_weights[Ice] > 0) { new_terrain |= (1<<Ice); } } /* * Jumping */ calc_jump_amt( time_step ); if ( ( charging || joy_charging ) && !plyr->control.jump_charging && !plyr->control.jumping ) { plyr->control.jump_charging = True; charge_start_time = g_game.time; } if ( ( !charging && !joy_charging ) && plyr->control.jump_charging ) { plyr->control.jump_charging = False; plyr->control.begin_jump = True; } /* * Turning */ if ( ( left_turn || joy_left_turn ) ^ (right_turn || joy_right_turn ) ) { bool_t turning_left = (bool_t) ( left_turn || joy_left_turn ); if ( joy_left_turn || joy_right_turn ) { plyr->control.turn_fact = joy_turn_fact; } else { plyr->control.turn_fact = (turning_left?-1:1); } plyr->control.turn_animation += (turning_left?-1:1) * 0.15 * time_step / 0.05; plyr->control.turn_animation = min(1.0, max(-1.0, plyr->control.turn_animation)); } else { plyr->control.turn_fact = 0; /* Decay turn animation */ if ( time_step < ROLL_DECAY_TIME_CONSTANT ) { plyr->control.turn_animation *= 1.0 - time_step/ROLL_DECAY_TIME_CONSTANT; } else { plyr->control.turn_animation = 0.0; } } /* * Paddling */ if ( ( paddling || joy_paddling ) && plyr->control.is_paddling == False ) { plyr->control.is_paddling = True; plyr->control.paddle_time = g_game.time; } /* * Play flying sound */ if (new_terrain & (1<<NumTerrains)) { set_sound_volume("flying_sound", min(128, speed*2)); if (!(last_terrain & (1<<NumTerrains))) { play_sound( "flying_sound", -1 ); } } else { if (last_terrain & (1<<NumTerrains)) { halt_sound( "flying_sound" ); } } /* * Play sliding sound */ slide_volume = min( (((pow(plyr->control.turn_fact, 2)*128)) + (plyr->control.is_braking?128:0) + (plyr->control.jumping?128:0) + 20) * (speed/10), 128 ); if (new_terrain & (1<<Snow)) { set_sound_volume("snow_sound", slide_volume * terrain_weights[Snow]); if (!(last_terrain & (1<<Snow))) { play_sound( "snow_sound", -1 ); } } else { if (last_terrain & (1<<Snow)) { halt_sound( "snow_sound" ); } } if (new_terrain & (1<<Rock)) { set_sound_volume("rock_sound", 128*pow((speed/2), 2) * terrain_weights[Rock]); if (!(last_terrain & (1<<Rock))) { play_sound( "rock_sound", -1 ); } } else { if (last_terrain & (1<<Rock)) { halt_sound( "rock_sound" ); } } if (new_terrain & (1<<Ice)) { set_sound_volume("ice_sound", slide_volume * terrain_weights[Ice]); if (!(last_terrain & (1<<Ice))) { play_sound( "ice_sound", -1 ); } } else { if (last_terrain & (1<<Ice)) { halt_sound( "ice_sound" ); } } last_terrain = new_terrain; /* * Tricks */ if ( plyr->control.barrel_roll_left || plyr->control.barrel_roll_right ) { plyr->control.barrel_roll_factor += ( plyr->control.barrel_roll_left ? -1 : 1 ) * 0.15 * time_step / 0.05; if ( (plyr->control.barrel_roll_factor > 1) || (plyr->control.barrel_roll_factor < -1) ) { plyr->control.barrel_roll_factor = 0; plyr->control.barrel_roll_left = plyr->control.barrel_roll_right = False; } } if ( plyr->control.front_flip || plyr->control.back_flip ) { plyr->control.flip_factor += ( plyr->control.back_flip ? -1 : 1 ) * 0.15 * time_step / 0.05; if ( (plyr->control.flip_factor > 1) || (plyr->control.flip_factor < -1) ) { plyr->control.flip_factor = 0; plyr->control.front_flip = plyr->control.back_flip = False; } } update_player_pos( plyr, time_step ); /* * Track Marks */ add_track_mark( plyr ); update_view( plyr, time_step ); setup_view_frustum( plyr, NEAR_CLIP_DIST, getparam_forward_clip_distance() ); draw_sky(plyr->view.pos); draw_fog_plane(); set_course_clipping( True ); set_course_eye_point( plyr->view.pos ); setup_course_lighting(); render_course(); draw_trees(); if ( getparam_draw_particles() ) { update_particles( time_step ); draw_particles( plyr ); } draw_tux(); draw_tux_shadow(); draw_hud( plyr ); reshape( width, height ); winsys_swap_buffers(); g_game.time += time_step; }
static void generate_particles(const Player& plyr, float dtime, const ppogl::Vec3d& pos, float speed) { float surf_weights[NUM_TERRAIN_TYPES]; get_surface_type( pos, surf_weights ); float surf_y = find_y_coord( pos ); bool particles_type=false; GLuint particle_binding = 0; for(unsigned int i=0;i<Course::numTerrains;i++){ if(Course::terrainTexture[i].particles){ if(surf_weights[i] > 0.5){ particles_type=true; particle_binding = Course::terrainTexture[i].particles->getID(); } } } if( particles_type==true && pos.y() < surf_y){ ppogl::Vec3d xvec =plyr.direction^plyr.plane_nml; ppogl::Vec3d right_part_pt = pos; ppogl::Vec3d left_part_pt = pos; right_part_pt = right_part_pt + ((TUX_WIDTH/2.0)*xvec ); left_part_pt = left_part_pt + ((-TUX_WIDTH/2.0)* xvec); right_part_pt.y() = left_part_pt.y() = surf_y; float brake_particles = dtime * BRAKE_PARTICLES * ( plyr.control.is_braking ? 1.0 : 0.0 ) * MIN( speed / PARTICLE_SPEED_FACTOR, 1.0 ); float turn_particles = dtime * MAX_TURN_PARTICLES * MIN( speed / PARTICLE_SPEED_FACTOR, 1.0 ); float roll_particles = dtime * MAX_ROLL_PARTICLES * MIN( speed / PARTICLE_SPEED_FACTOR, 1.0 ); float left_particles = turn_particles * fabs( MIN(plyr.control.turn_fact, 0.) ) + brake_particles + roll_particles * fabs( MIN(plyr.control.turn_animation, 0.) ); float right_particles = turn_particles * fabs( MAX(plyr.control.turn_fact, 0.) ) + brake_particles + roll_particles * fabs( MAX(plyr.control.turn_animation, 0.) ); left_particles = adjust_particle_count( left_particles ); right_particles = adjust_particle_count( right_particles ); pp::Matrix rot_mat; // Create particle velocitites rot_mat.makeRotationAboutVector( plyr.direction, MAX( -MAX_PARTICLE_ANGLE, -MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED ) ); ppogl::Vec3d left_part_vel = rot_mat.transformVector(plyr.plane_nml); left_part_vel = MIN( MAX_PARTICLE_SPEED, speed * PARTICLE_SPEED_MULTIPLIER )* left_part_vel; rot_mat.makeRotationAboutVector( plyr.direction, MIN( MAX_PARTICLE_ANGLE, MAX_PARTICLE_ANGLE * speed / MAX_PARTICLE_ANGLE_SPEED ) ); ppogl::Vec3d right_part_vel = rot_mat.transformVector( plyr.plane_nml ); right_part_vel = MIN( MAX_PARTICLE_SPEED, speed * PARTICLE_SPEED_MULTIPLIER )* right_part_vel; partsys[plyr.num].createParticles( left_part_pt, left_part_vel, int(left_particles), particle_binding ); partsys[plyr.num].createParticles( right_part_pt, right_part_vel, int(right_particles), particle_binding ); } }