Ejemplo n.º 1
0
void MakeRotationMatrix (TMatrix mat, double angle, char axis) {
	double sinv, cosv;
	sinv = sin (ANGLES_TO_RADIANS (angle));
	cosv = cos (ANGLES_TO_RADIANS (angle));

	MakeIdentityMatrix (mat);

	switch (axis) {
	case 'x':
		mat[1][1] = cosv;
		mat[2][1] = -sinv;
		mat[1][2] = sinv;
		mat[2][2] = cosv;
		break;

	case 'y':
		mat[0][0] = cosv;
		mat[2][0] = sinv;
		mat[0][2] = -sinv;
		mat[2][2] = cosv;
		break;

	case 'z':
		mat[0][0] = cosv;
		mat[1][0] = -sinv;
		mat[0][1] = sinv;
		mat[1][1] = cosv;
		break;
	}
}
Ejemplo n.º 2
0
ppogl::Vec2d
HUD::calc_new_fan_pt(const double angle )
{
    return ppogl::Vec2d(
    	ENERGY_GAUGE_CENTER_X + cos( ANGLES_TO_RADIANS( angle ) ) * 
				SPEEDBAR_OUTER_RADIUS,
    	ENERGY_GAUGE_CENTER_Y + sin( ANGLES_TO_RADIANS( angle ) ) *
				SPEEDBAR_OUTER_RADIUS
	);
}
Ejemplo n.º 3
0
bool CCourse::LoadElevMap () {
	CImage img;

	if (!img.LoadPng (CourseDir.c_str(), "elev.png", true)) {
		Message ("unable to open elev.png");
		return false;
	}

    nx = img.nx;
    ny = img.ny;
	try {
		elevation = new double[nx * ny];
	} catch(...) {
		Message ("Allocation failed in LoadElevMap");
		return false;
    }

    double slope = tan (ANGLES_TO_RADIANS (curr_course->angle));
    int pad = 0;
    for (int y=0; y<ny; y++) {
        for (int x=0; x<nx; x++) {
			elevation [(nx-1-x) + nx * (ny-1-y)] =
				((img.data [(x+nx*y) * img.depth + pad]
			    - base_height_value) / 255.0) * curr_course->scale
				- (double)(ny-1-y) / ny * curr_course->size.y * slope;
	     }
        pad += (nx * img.depth) % 4;
    }
	return true;
}
Ejemplo n.º 4
0
double CCourse::GetBaseHeight (double distance) const {
    double slope = tan (ANGLES_TO_RADIANS (curr_course->angle));
    double base_height;

    base_height = -slope * distance -
	base_height_value / 255.0 * curr_course->scale;
    return base_height;
}
Ejemplo n.º 5
0
TVector2 calc_new_fan_pt (double angle) {
    TVector2 pt;
    pt.x = ENERGY_GAUGE_CENTER_X + cos (ANGLES_TO_RADIANS (angle)) * SPEEDBAR_OUTER_RADIUS;
    pt.y = ENERGY_GAUGE_CENTER_Y + sin (ANGLES_TO_RADIANS (angle)) * SPEEDBAR_OUTER_RADIUS;
    return pt;
}
Ejemplo n.º 6
0
void CEnvironment::DrawFog () {
	if (!fog.is_on)
		return;

    TPlane bottom_plane, top_plane;
    TVector3 left, right, vpoint;
    TVector3 topleft, topright;
    TVector3 bottomleft, bottomright;

	// the clipping planes are calculated by view frustum (view.cpp)
	const TPlane& leftclip = get_left_clip_plane ();
	const TPlane& rightclip = get_right_clip_plane ();
	const TPlane& farclip = get_far_clip_plane ();
	const TPlane& bottomclip = get_bottom_clip_plane ();

	// --------------- calculate the planes ---------------------------

    float slope = tan (ANGLES_TO_RADIANS (Course.GetCourseAngle()));
//	TPlane left_edge_plane = MakePlane (1.0, 0.0, 0.0, 0.0);
//	TPlane right_edge_plane = MakePlane (-1.0, 0.0, 0.0, Course.width);

    bottom_plane.nml = TVector3(0.0, 1, -slope);
    float height = Course.GetBaseHeight (0);
    bottom_plane.d = -height * bottom_plane.nml.y;

    top_plane.nml = bottom_plane.nml;
    height = Course.GetMaxHeight (0) + fog.height;
    top_plane.d = -height * top_plane.nml.y;


    if (!IntersectPlanes (bottom_plane, farclip, leftclip,  &left)) return;
    if (!IntersectPlanes (bottom_plane, farclip, rightclip, &right)) return;
    if (!IntersectPlanes (top_plane,    farclip, leftclip,  &topleft)) return;
    if (!IntersectPlanes (top_plane,    farclip, rightclip, &topright)) return;
    if (!IntersectPlanes (bottomclip,   farclip, leftclip,  &bottomleft)) return;
    if (!IntersectPlanes (bottomclip,   farclip, rightclip, &bottomright)) return;

	TVector3 leftvec  = SubtractVectors (topleft, left);
    TVector3 rightvec = SubtractVectors (topright, right);

	// --------------- draw the fog plane -----------------------------

	ScopedRenderMode rm(FOG_PLANE);
    glEnable (GL_FOG);

	// only the alpha channel is used
	float bottom_dens[4]     = {0, 0, 0, 1.0};
	float top_dens[4]        = {0, 0, 0, 0.9};
	float leftright_dens[4]  = {0, 0, 0, 0.3};
	float top_bottom_dens[4] = {0, 0, 0, 0.0};

    glBegin (GL_QUAD_STRIP);
	    glColor4fv (bottom_dens);
	    glVertex3f (bottomleft.x, bottomleft.y, bottomleft.z);
    	glVertex3f (bottomright.x, bottomright.y, bottomright.z);
	    glVertex3f (left.x, left.y, left.z);
    	glVertex3f (right.x, right.y, right.z);

	    glColor4fv (top_dens);
    	glVertex3f (topleft.x, topleft.y, topleft.z);
    	glVertex3f (topright.x, topright.y, topright.z);

	    glColor4fv (leftright_dens);
    	vpoint = AddVectors (topleft, leftvec);
	    glVertex3f (vpoint.x, vpoint.y, vpoint.z);
    	vpoint = AddVectors (topright, rightvec);
	    glVertex3f (vpoint.x, vpoint.y, vpoint.z);

	    glColor4fv (top_bottom_dens);
	    vpoint = AddVectors (topleft, ScaleVector (3.0, leftvec));
    	glVertex3f (vpoint.x, vpoint.y, vpoint.z);
	    vpoint = AddVectors (topright, ScaleVector (3.0, rightvec));
    	glVertex3f (vpoint.x, vpoint.y, vpoint.z);
    glEnd();
}
Ejemplo n.º 7
0
void CEnvironment::DrawFog () {
    TPlane bottom_plane, top_plane;
    TVector3 left, right;
    TVector3 topleft, topright;
    TVector3 bottomleft = NullVec; 
    TVector3 bottomright = NullVec;
    float height;

    if (!fog.is_on) return;

    // the clipping planes are calculated by view frustum (view.cpp)
    leftclip = get_left_clip_plane ();
    rightclip = get_right_clip_plane ();
    farclip = get_far_clip_plane ();
    bottomclip = get_bottom_clip_plane ();

    // --------------- calculate the planes ---------------------------

    float slope = tan (ANGLES_TO_RADIANS (Course.GetCourseAngle()));
//	TPlane left_edge_plane = MakePlane (1.0, 0.0, 0.0, 0.0);
//	TPlane right_edge_plane = MakePlane (-1.0, 0.0, 0.0, Course.width);

    bottom_plane.nml = MakeVector (0.0, 1, -slope);
    height = Course.GetBaseHeight (0);
    bottom_plane.d = -height * bottom_plane.nml.y;

    top_plane.nml = bottom_plane.nml;
    height = Course.GetMaxHeight (0) + fog.height;
    top_plane.d = -height * top_plane.nml.y;

    if (!IntersectPlanes (bottom_plane, farclip, leftclip,  &left)) return;
    if (!IntersectPlanes (bottom_plane, farclip, rightclip, &right)) return;
    if (!IntersectPlanes (top_plane,    farclip, leftclip,  &topleft)) return;
    if (!IntersectPlanes (top_plane,    farclip, rightclip, &topright)) return;
    if (!IntersectPlanes (bottomclip,   farclip, leftclip,  &bottomleft)) return;
    if (!IntersectPlanes (bottomclip,   farclip, rightclip, &bottomright)) return;

    TVector3 leftvec  = SubtractVectors (topleft, left);
    TVector3 rightvec = SubtractVectors (topright, right);

    TVector3 vpoint1 = AddVectors (topleft, leftvec);
    TVector3 vpoint2 = AddVectors (topright, rightvec);
    TVector3 vpoint3 = AddVectors (topleft, ScaleVector (3.0, leftvec));
    TVector3 vpoint4 = AddVectors (topright, ScaleVector (3.0, rightvec));

    // --------------- draw the fog plane -----------------------------

    set_gl_options (FOG_PLANE);
    glEnable (GL_FOG);

    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

	// only the alpha channel is used
	const GLfloat col[] = {
		// bottom density
		0, 0, 0, 1.0,
		0, 0, 0, 1.0,
		0, 0, 0, 1.0,
		0, 0, 0, 1.0,

		// top density
		0, 0, 0, 0.9,
		0, 0, 0, 0.9,

		// left/right density
		0, 0, 0, 0.3,
		0, 0, 0, 0.3,

		// top/bottom density
		0, 0, 0, 0.0,
		0, 0, 0, 0.0
	};

	const GLfloat vtx[] = {
		bottomleft.x, bottomleft.y, bottomleft.z,
		bottomright.x, bottomright.y, bottomright.z,
		left.x, left.y, left.z,
		right.x, right.y, right.z,
		topleft.x, topleft.y, topleft.z,
		topright.x, topright.y, topright.z,
		vpoint1.x, vpoint1.y, vpoint1.z,
		vpoint2.x, vpoint2.y, vpoint2.z,
		vpoint3.x, vpoint3.y, vpoint3.z,
		vpoint4.x, vpoint4.y, vpoint4.z
	};

	glColorPointer(4, GL_FLOAT, 0, col);
	glVertexPointer(3, GL_FLOAT, 0, vtx);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}
Ejemplo n.º 8
0
/*! 
 Draws a fog plane at the far clipping plane to mask out clipping of terrain.
 
 \return  none
 \author  jfpatry
 \date    Created:  2000-08-31
 \date    Modified: 2000-08-31
 */
void draw_fog_plane()
{
	plane_t left_edge_plane, right_edge_plane;
	plane_t left_clip_plane, right_clip_plane;
	plane_t far_clip_plane;
	plane_t bottom_clip_plane;
	plane_t bottom_plane, top_plane;
	
	scalar_t course_width, course_length;
	scalar_t course_angle, slope;
	
	point_t left_pt, right_pt, pt;
	point_t top_left_pt, top_right_pt;
	point_t bottom_left_pt, bottom_right_pt;
	vector_t left_vec, right_vec;
	scalar_t height;
	
	GLfloat *fog_colour;
	
	if ( is_fog_on() == False ) {
		return;
	}
	
	set_gl_options( FOG_PLANE );
	
	get_course_dimensions( &course_width, &course_length );
	course_angle = get_course_angle();
	slope = tan( ANGLES_TO_RADIANS( course_angle ) );
	
	left_edge_plane = make_plane( 1.0, 0.0, 0.0, 0.0 );
	
	right_edge_plane = make_plane( -1.0, 0.0, 0.0, course_width );
	
	far_clip_plane = get_far_clip_plane();
	left_clip_plane = get_left_clip_plane();
	right_clip_plane = get_right_clip_plane();
	bottom_clip_plane = get_bottom_clip_plane();
	
	
	/* Find the bottom plane */
	bottom_plane.nml = make_vector( 0.0, 1, -slope );
	height = get_terrain_base_height( 0 );
	
	/* Unoptimized version
	 pt = make_point( 0, height, 0 );
	 bottom_plane.d = -( pt.x * bottom_plane.nml.x +
	 pt.y * bottom_plane.nml.y +
	 pt.z * bottom_plane.nml.z );
	 */
	bottom_plane.d = -height * bottom_plane.nml.y;
	
	/* Find the top plane */
	top_plane.nml = bottom_plane.nml;
	height = get_terrain_max_height( 0 );
	top_plane.d = -height * top_plane.nml.y;
	
	
	if(get_player_data(local_player())->view.mode == TUXEYE)
	{
		bottom_clip_plane.nml = make_vector( 0.0, 1, -slope );
		height = get_terrain_base_height( 0 ) - 40;
		bottom_clip_plane.d = -height * bottom_clip_plane.nml.y;
	}
	
	/* Now find the bottom left and right points of the fog plane */
	if ( !intersect_planes( bottom_plane, far_clip_plane, left_clip_plane, &left_pt ) )
		return;
	
	if ( !intersect_planes( bottom_plane, far_clip_plane, right_clip_plane, &right_pt ) )
		return;
	
	if ( !intersect_planes( top_plane, far_clip_plane, left_clip_plane, &top_left_pt ) )
		return;
	
	if ( !intersect_planes( top_plane, far_clip_plane, right_clip_plane, &top_right_pt ) )
		return;
	
	if ( !intersect_planes( bottom_clip_plane, far_clip_plane, left_clip_plane, &bottom_left_pt ) )
		return;
	
	if ( !intersect_planes( bottom_clip_plane, far_clip_plane, right_clip_plane, &bottom_right_pt ) )
		return;
	
	left_vec = subtract_points( top_left_pt, left_pt );
	right_vec = subtract_points( top_right_pt, right_pt );
	
	
	/* Now draw the fog plane */
	
	set_gl_options( FOG_PLANE );
	
	fog_colour = get_fog_colour();
	
	glColor4fv( fog_colour );
	
#ifdef __APPLE__DISABLED__
#undef glEnableClientState
#undef glDisableClientState
#undef glVertexPointer
#undef glColorPointer
#undef glDrawArrays
	
	point_t pt1,pt2,pt3,pt4;
	
	pt1 = move_point( top_left_pt, left_vec );
	pt2 = move_point( top_right_pt, right_vec );
	pt3 = move_point( top_left_pt, scale_vector( 3.0, left_vec ) );
	pt4 = move_point( top_right_pt, scale_vector( 3.0, right_vec ) );
	
	const GLfloat verticesFog []=
	{
		bottom_left_pt.x, bottom_left_pt.y, bottom_left_pt.z,
		bottom_right_pt.x, bottom_right_pt.y, bottom_right_pt.z,
		left_pt.x, left_pt.y, left_pt.z,
		right_pt.x, right_pt.y, right_pt.z,
		
		top_left_pt.x, top_left_pt.y, top_left_pt.z,
		top_right_pt.x, top_right_pt.y, top_right_pt.z,
		
		pt1.x, pt1.y, pt1.z,
		pt2.x, pt2.y, pt2.z,
		pt3.x, pt3.y, pt3.z,
		pt4.x, pt4.y, pt4.z	
	};
	
	const GLfloat colorsFog []=
	{
		fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3],
		fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3],
		fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3],
		fog_colour[0], fog_colour[1], fog_colour[2], fog_colour[3],
		fog_colour[0], fog_colour[1], fog_colour[2], 0.9 ,
		fog_colour[0], fog_colour[1], fog_colour[2], 0.9 ,
		fog_colour[0], fog_colour[1], fog_colour[2], 0.3 ,
		fog_colour[0], fog_colour[1], fog_colour[2], 0.3 ,
		fog_colour[0], fog_colour[1], fog_colour[2], 0.0 ,
		fog_colour[0], fog_colour[1], fog_colour[2], 0.0 ,	
	};
	
	glEnableClientState (GL_VERTEX_ARRAY);
	//   glEnableClientState (GL_COLOR_ARRAY);
	//  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glVertexPointer (3, GL_FLOAT , 0, verticesFog);	
	glColorPointer(4, GL_FLOAT, 0, colorsFog);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 10);
	//glDisableClientState(GL_COLOR_ARRAY_POINTER);
	
#else
	glBegin( GL_QUAD_STRIP );
	
	glVertex3f( bottom_left_pt.x, bottom_left_pt.y, bottom_left_pt.z );
	glVertex3f( bottom_right_pt.x, bottom_right_pt.y, bottom_right_pt.z );
	glVertex3f( left_pt.x, left_pt.y, left_pt.z );
	glVertex3f( right_pt.x, right_pt.y, right_pt.z );
	
	glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.9 );
	glVertex3f( top_left_pt.x, top_left_pt.y, top_left_pt.z );
	glVertex3f( top_right_pt.x, top_right_pt.y, top_right_pt.z );
	
	glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.3 );
	pt = move_point( top_left_pt, left_vec );
	glVertex3f( pt.x, pt.y, pt.z );
	pt = move_point( top_right_pt, right_vec );
	glVertex3f( pt.x, pt.y, pt.z );
	
	glColor4f( fog_colour[0], fog_colour[1], fog_colour[2], 0.0 );
	pt = move_point( top_left_pt, scale_vector( 3.0, left_vec ) );
	glVertex3f( pt.x, pt.y, pt.z );
	pt = move_point( top_right_pt, scale_vector( 3.0, right_vec ) );
	glVertex3f( pt.x, pt.y, pt.z );
	
	glEnd();
	
#endif
}
Ejemplo n.º 9
0
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 );
} 
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
static ppogl::Vec3d
calc_net_force(Player& plyr, const ppogl::Vec3d& pos, 
				const ppogl::Vec3d& vel)
{
    ppogl::Vec3d nml_f;      /* normal force */
    ppogl::Vec3d unclamped_nml_f; /* unclamped normal force (for damage calc) */
    ppogl::Vec3d fric_f;     /* frictional force */
    float fric_f_mag; /* frictional force magnitude */
    ppogl::Vec3d fric_dir;   /* direction of frictional force */
    ppogl::Vec3d grav_f;     /* gravitational force */
    ppogl::Vec3d air_f;      /* air resistance force */
    ppogl::Vec3d brake_f;    /* braking force */
    ppogl::Vec3d paddling_f; /* paddling force */
    ppogl::Vec3d net_force;  /* the net force (sum of all other forces) */
    float comp_depth; /* depth to which the terrain can be compressed */
    float speed;      /* speed (m/s) */
    ppogl::Vec3d orig_surf_nml; /* normal to terrain at current position */
    ppogl::Vec3d surf_nml;   /* normal to terrain w/ roll effect */
    float glute_compression; /* amt that Tux's tush has been compressed */
    float steer_angle; /* Angle to rotate fricitonal force for turning */
    pp::Matrix fric_rot_mat; /* Matrix to rotate frictional force */
    ppogl::Vec3d jump_f;
    pp::Plane surf_plane;
    float dist_from_surface;
    float surf_weights[NUM_TERRAIN_TYPES];
    float surf_fric_coeff;
    unsigned int i;

    get_surface_type( pos, surf_weights );
    surf_plane = get_local_course_plane(pos);
    orig_surf_nml = surf_plane.nml;

    surf_fric_coeff = 0;
    for (i=0; i<Course::numTerrains; i++) {
		surf_fric_coeff += surf_weights[i] * Course::terrainTexture[i].friction;
    }
    surf_nml = adjust_surf_nml_for_roll( plyr, vel, surf_fric_coeff,
					 orig_surf_nml );
    
    comp_depth = 0;
    for (i=0; i<Course::numTerrains; i++) {
		comp_depth += surf_weights[i] * Course::terrainTexture[i].compression;
    }

    grav_f = ppogl::Vec3d( 0, -EARTH_GRAV * TUX_MASS, 0 );

    dist_from_surface = surf_plane.distance( pos );

    if ( dist_from_surface <= 0 ) {
	plyr.airborne = false;
    } else {
	plyr.airborne = true;
    }

    /*
     * Calculate normal force
     */
    nml_f = ppogl::Vec3d( 0., 0., 0. );
    if ( dist_from_surface <= -comp_depth ) {
	/*
	 * Tux ended up below the surface.
	 * Calculate the spring force exterted by his rear end. :-)
	 */
	glute_compression = -dist_from_surface - comp_depth;
	PP_ASSERT( glute_compression >= 0, 
			 "unexpected negative compression" );

	nml_f = calc_spring_force( glute_compression, vel, surf_nml,
				   &unclamped_nml_f );
    }

    /* Check if player is trying to jump */
    if ( plyr.control.begin_jump == true ) {
	plyr.control.begin_jump = false;
	if ( dist_from_surface <= 0 ) {
	    plyr.control.jumping = true;
	    plyr.control.jump_start_time = GameMgr::getInstance().time;
	} else {
	    plyr.control.jumping = false;
	}
    }


    /* Apply jump force in up direction for JUMP_FORCE_DURATION */
    if ( ( plyr.control.jumping ) &&
	 ( GameMgr::getInstance().time - plyr.control.jump_start_time < 
	   JUMP_FORCE_DURATION ) ) 
    {
	jump_f = ppogl::Vec3d( 
	    0, 
	    BASE_JUMP_G_FORCE * TUX_MASS * EARTH_GRAV + 
	    plyr.control.jump_amt * 
	    (MAX_JUMP_G_FORCE-BASE_JUMP_G_FORCE) * TUX_MASS * EARTH_GRAV, 
	    0 );

    } else {
	jump_f = ppogl::Vec3d( 0, 0, 0 );
	plyr.control.jumping = false;
    }

    /* Use the unclamped normal force for damage calculation purposes */
    plyr.normal_force = unclamped_nml_f;

    /* 
     * Calculate frictional force
     */
    fric_dir = vel;
    speed = fric_dir.normalize();
    fric_dir = -1.0*fric_dir;
    
    if ( dist_from_surface < 0 && speed > MIN_FRICTION_SPEED ) {
	ppogl::Vec3d tmp_nml_f = nml_f;

	fric_f_mag = tmp_nml_f.normalize() * surf_fric_coeff;

	fric_f_mag = MIN( MAX_FRICTIONAL_FORCE, fric_f_mag );

	fric_f = fric_f_mag*fric_dir;


	/*
	 * Adjust friction for steering
	 */
	steer_angle = plyr.control.turn_fact * MAX_TURN_ANGLE;

	if ( fabs( fric_f_mag * sin( ANGLES_TO_RADIANS( steer_angle ) ) ) >
	     MAX_TURN_PERPENDICULAR_FORCE ) 
	{
	    //check_assertion( fabs( plyr->control.turn_fact ) > 0,
		//	     "steer angle is non-zero when player is not "
		//	     "turning" );
	    steer_angle = RADIANS_TO_ANGLES( 
		asin( MAX_TURN_PERPENDICULAR_FORCE / fric_f_mag ) ) * 
		plyr.control.turn_fact / fabs( plyr.control.turn_fact );
	}
	fric_rot_mat.makeRotationAboutVector( orig_surf_nml, steer_angle );
	fric_f = fric_rot_mat.transformVector( fric_f );
	fric_f = (1.0 + MAX_TURN_PENALTY)*fric_f;


	/*
	 * Calculate braking force
	 */
	if ( speed > MIN_TUX_SPEED && plyr.control.is_braking ) {
	    brake_f = (surf_fric_coeff * BRAKE_FORCE)*fric_dir; 
	} else {
	    brake_f = ppogl::Vec3d( 0., 0., 0. );
	}
	
    } else {
	fric_f = brake_f = ppogl::Vec3d( 0., 0., 0. );
    }

    /*
     * Calculate air resistance
     */
    air_f = calc_wind_force( vel );


    /*
     * Calculate force from paddling
     */
    update_paddling( plyr );
    if ( plyr.control.is_paddling ) {
	if ( plyr.airborne ) {
	    paddling_f = ppogl::Vec3d( 0, 0, -TUX_MASS * EARTH_GRAV / 4.0 );
	    paddling_f = plyr.orientation.rotate( paddling_f );
	} else {
	    paddling_f = ( 
		-1 * MIN( MAX_PADDLING_FORCE,  
			  MAX_PADDLING_FORCE * 
			  ( MAX_PADDLING_SPEED - speed ) / MAX_PADDLING_SPEED * 
			  MIN(1.0, 
			      surf_fric_coeff/IDEAL_PADDLING_FRIC_COEFF)))*
		fric_dir;
	}
    } else {
	paddling_f = ppogl::Vec3d( 0., 0., 0. );
    }

    
    /*
     * Add all the forces 
     */
    net_force = jump_f+grav_f+nml_f+fric_f+air_f+brake_f+paddling_f;

    return net_force;
}