예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
} 
예제 #4
0
파일: view.c 프로젝트: Jisby/TuxRacer-SDL2
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 );
} 
예제 #5
0
/*! 
  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;
}
예제 #6
0
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);
	}
}
예제 #7
0
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;
} 
예제 #8
0
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 );
    } 
}