Пример #1
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
}
Пример #2
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 );
}