Ejemplo n.º 1
0
/*! 
  Interpolates between camera positions.
  \arg \c  plyr_pos1 \c pos1 is relative to this position
  \arg \c  plyr_pos2 \c pos2 is relative to this position
  \arg \c  max_vec_angle Maximum downward pitch of vector from camera to player
  \arg \c  pos1 original camera position
  \arg \c  pos2 target camera position
  \arg \c  dist distance of interpolated camera position from player
  \arg \c  dt time step size (s)
  \arg \c  time_constant time constant to use in interpolation (s)

  \return  Interpolated camera position
  \author  jfpatry
  \date    Created:  2000-08-26
  \date    Modified: 2000-08-26
*/
point_t interpolate_view_pos( point_t plyr_pos1, point_t plyr_pos2,
			      scalar_t max_vec_angle,
			      point_t pos1, point_t pos2,
			      scalar_t dist, scalar_t dt,
			      scalar_t time_constant )
{
    static vector_t y_vec = { 0.0, 1.0, 0.0 };

    quaternion_t q1, q2;
    vector_t vec1, vec2;
    scalar_t alpha;
    scalar_t theta;
    matrixgl_t rot_mat;
    vector_t axis;

    vec1 = subtract_points( pos1, plyr_pos1 );
    vec2 = subtract_points( pos2, plyr_pos2 );

    normalize_vector( &vec1 );
    normalize_vector( &vec2 );

    q1 = make_rotation_quaternion( y_vec, vec1 );
    q2 = make_rotation_quaternion( y_vec, vec2 );

    alpha = min( MAX_INTERPOLATION_VALUE,
		 1.0 - exp ( -dt / time_constant ) );

    q2 = interpolate_quaternions( q1, q2, alpha );

    vec2 = rotate_vector( q2, y_vec );

    /* Constrain angle with x-z plane */
    theta = RADIANS_TO_ANGLES( M_PI/2 - acos( dot_product( vec2, y_vec ) ) );

    if ( theta > max_vec_angle )
    {
	axis = cross_product( y_vec, vec2 );
	normalize_vector( &axis );

	make_rotation_about_vector_matrix( rot_mat, axis, 
					   theta-max_vec_angle );
	vec2 = transform_vector( rot_mat, vec2 );
    }

    return move_point( plyr_pos2, 
		       scale_vector( dist, vec2 ) );

}
Ejemplo n.º 2
0
/*
 * make_normal - creates the normal vector for the surface defined by a convex
 * polygon; points in polygon must be specifed in counter-clockwise direction
 * when viewed from outside the shape for the normal to be outward-facing
 */
vector_t make_normal( polygon_t p, point_t *v )
{
    vector_t normal, v1, v2;
    scalar_t old_len;
    
    check_assertion( p.num_vertices > 2, "number of vertices must be > 2" );
    
    v1 = subtract_points( v[p.vertices[1]], v[p.vertices[0]] );
    v2 = subtract_points( v[p.vertices[p.num_vertices-1]], v[p.vertices[0]] );
    normal = cross_product( v1, v2 );
    
    old_len = normalize_vector( &normal );
    check_assertion( old_len > 0, "normal vector has length 0" );
    
    return normal;
} 
Ejemplo n.º 3
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.º 4
0
void calc_normals(const char *course)
{
    scalar_t *elevation;
    scalar_t courseWidth, courseLength;
    int nx, ny;
    int x,y;
    point_t p0, p1, p2;
    vector_t n, nml, v1, v2;
    char buff[BUFF_LEN];
	
    sprintf( buff, "%s/courses/%s/normal.data", getparam_data_dir(), course );
	
    get_course_dimensions( &courseWidth, &courseLength );
    get_course_divisions( &nx, &ny );
	
    if(nmls != (void*)-1 && nmls_fd != -1) 
    {
        munmap(nmls, nmls_len);
        close(nmls_fd);
    }
#if 0
    else {
        free(nmls);
    }
#endif
	
    struct stat buf;
    int exists = (stat(buff, &buf) == 0);
	
    if(exists) {
        nmls_fd = open(buff, O_RDONLY);
        if ( nmls_fd == -1) {
            handle_system_error( 1, "can't open file failed" );
        }
		
        TRDebugLog("mapping to memory normal.data\n");
        nmls_len = sizeof(vector_t)*nx*ny;
        nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED,nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "read mmap failed" );
        }
    }
    else {
        nmls_len = sizeof(vector_t)*nx*ny;
		
#if TARGET_IPHONE_SIMULATOR
        nmls_fd = open(buff, O_RDWR | O_CREAT | O_TRUNC, 0644);
        if ( nmls_fd == -1) {
            handle_system_error( 1, "can't open file failed" );
        }
		
		
        int result = lseek(nmls_fd, nmls_len-1, SEEK_SET);
        if (result == -1) {
            handle_system_error( 1, "can't write file failed" );
        }
        
        result = write(nmls_fd, "", 1);
        if (result != 1) {
            handle_system_error( 1, "can't write file failed" );
        }
		
        nmls = mmap(NULL, nmls_len, PROT_READ | PROT_WRITE, MAP_SHARED, nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "write mmap failed" );
        }
		
        TRDebugLog("Writing to normal.data\n");
#else
# ifdef TR_DEBUG_MODE
        abort(); // This shouldn't be reached on simulator. Crash to indicate.
# endif
        nmls = malloc(nmls_len);
#endif
        
        elevation = get_course_elev_data();
		
        for ( y=0; y<ny; y++) {
            for ( x=0; x<nx; x++) {
                nml = make_vector( 0., 0., 0. );
                
                p0 = make_point( XCD(x), ELEV(x,y), ZCD(y) );
                
                /* The terrain is meshed as follows:
                 ...
                 +-+-+-+-+            x<---+
                 |\|/|\|/|                 |
                 ...+-+-+-+-+...              V
                 |/|\|/|\|                 y
                 +-+-+-+-+
                 ...
                 
                 So there are two types of vertices: those surrounded by
                 four triangles (x+y is odd), and those surrounded by
                 eight (x+y is even).
                 */
                
#define POINT(x,y) make_point( XCD(x), ELEV(x,y), ZCD(y) )
                
                if ( (x + y) % 2 == 0 ) {
                    if ( x > 0 && y > 0 ) {
                        p1 = POINT(x,  y-1);
                        p2 = POINT(x-1,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x-1,y-1);
                        p2 = POINT(x-1,y  );
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x > 0 && y < ny-1 ) {
                        p1 = POINT(x-1,y  );
                        p2 = POINT(x-1,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x-1,y+1);
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y > 0 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x+1,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x+1,y-1);
                        p2 = POINT(x  ,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y < ny-1 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x+1,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                        p1 = POINT(x+1,y+1);
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                        
                    } 
                } else {
                    /* x + y is odd */
                    if ( x > 0 && y > 0 ) {
                        p1 = POINT(x,  y-1);
                        p2 = POINT(x-1,y  );
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x > 0 && y < ny-1 ) {
                        p1 = POINT(x-1,y  );
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y > 0 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x  ,y-1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v2, v1 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                    if ( x < nx-1 && y < ny-1 ) {
                        p1 = POINT(x+1,y  );
                        p2 = POINT(x  ,y+1);
                        v1 = subtract_points( p1, p0 );
                        v2 = subtract_points( p2, p0 );
                        n = cross_product( v1, v2 );
                        
                        check_assertion( n.y > 0, "course normal points down" );
                        
                        normalize_vector( &n );
                        nml = add_vectors( nml, n );
                    } 
                }
                
                normalize_vector( &nml );
                NORMAL(x,y) = nml;
                continue;
            } 
#undef POINT
        }
#if TARGET_IPHONE_SIMULATOR
        munmap(nmls, nmls_len);
        close(nmls_fd);
		
        nmls_fd = open(buff, O_RDONLY);
        if (nmls_fd == -1) {
            handle_system_error( 1, "can't remount normal.data" );
        }
		
        TRDebugLog("remounting to memory normal.data\n");
        nmls_len = sizeof(vector_t)*nx*ny;
        nmls = mmap(NULL, nmls_len, PROT_READ, MAP_SHARED, nmls_fd, 0);
        if ( nmls == (void *)-1 ) {
            handle_system_error( 1, "remount mmap failed" );
        }
#endif
    }
} 
Ejemplo n.º 5
0
void draw_trees() 
{
    tree_t    *treeLocs;
    int       numTrees;
    scalar_t  treeRadius;
    scalar_t  treeHeight;
    int       i;
    GLuint    texture_id = 0;
    vector_t  normal;
    scalar_t  fwd_clip_limit, bwd_clip_limit, fwd_tree_detail_limit;
    
    int tree_type = -1;
    char *tree_name = 0;
    
    
    scalar_t  itemRadius;
    scalar_t  itemHeight;
    int       item_type = -1;
    char *    item_name = 0;
    item_type_t *item_types;
    
    treeLocs = treeLocsOrderedByZ;
    numTrees = get_num_trees();
    item_types = get_item_types();
    
    fwd_clip_limit = getparam_forward_clip_distance();
    bwd_clip_limit = getparam_backward_clip_distance();
    fwd_tree_detail_limit = getparam_tree_detail_distance();
    
    set_gl_options( TREES );
    
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    set_material( white, black, 1.0 );
    
#ifdef __APPLE__
#undef glVertexPointer
#undef glTexCoordPointer
#undef glEnableClientState
#undef glDisableClientState
#undef glDrawArrays
    static const GLfloat verticesTree []=
    {
        -1.0, 0.0, 0.0,
        1.0, 0.0, 0.0,
        1.0, 1.0, 0.0,
        -1.0, 1.0, 0.0,
        -1.0, 0.0, 0.0,
        1.0, 1.0, 0.0,
        
        0.0, 0.0, -1.0,
        0.0, 0.0,  1.0,
        0.0, 1.0,  1.0,
        0.0, 1.0, -1.0,
        0.0, 0.0, -1.0,
        0.0, 1.0,  1.0,
        
    };
    static const GLfloat texCoordsTree []=
    {
        0.0, 0.0 ,
        1.0, 0.0 ,
        1.0, 1.0 ,
        0.0, 1.0 ,
        0.0, 0.0 ,
        1.0, 1.0 ,
        
        0.0, 0.0 ,
        1.0, 0.0 ,
        1.0, 1.0 ,
        0.0, 1.0 ,
        0.0, 0.0 ,
        1.0, 1.0 ,
        
    };
    glVertexPointer (3, GL_FLOAT , 0, verticesTree);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoordsTree);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
    
    for (i = first_tree_to_check; i< numTrees; i++ ) {
        if ( clip_course ) {
            if ( eye_pt.z - treeLocs[i].ray.pt.z > fwd_clip_limit ) 
                //printf("break :  eye_pt.z - treeLocs[i].ray.pt.z = %f > fwd_clip_limit = %f\n",eye_pt.z - treeLocs[i].ray.pt.z,fwd_clip_limit);
                break;
            if ( treeLocs[i].ray.pt.z - eye_pt.z > bwd_clip_limit ){
                first_tree_to_check = i;
                //printf("continue : treeLocs[i].ray.pt.z - eye_pt.z = %f > bwd_clip_limit = %f\n",treeLocs[i].ray.pt.z - eye_pt.z,bwd_clip_limit);
                continue;
            }
            //printf("condition 1 : eye_pt.z - treeLocs[i].ray.pt.z = %f > fwd_clip_limit = %f\n",eye_pt.z - treeLocs[i].ray.pt.z,fwd_clip_limit);
			// printf("condition 2 : treeLocs[i].ray.pt.z - eye_pt.z = %f > bwd_clip_limit = %f\n",treeLocs[i].ray.pt.z - eye_pt.z,bwd_clip_limit);
        }
        /* verify that the correct texture is bound */
        if (treeLocs[i].tree_type != tree_type) {
            tree_type = treeLocs[i].tree_type;
            tree_name = get_tree_name(tree_type);
            if (!get_texture_binding( tree_name, &texture_id ) ) {
                texture_id = 0;
            }
            glBindTexture( GL_TEXTURE_2D, texture_id );
        }
        
        glPushMatrix();
        glTranslatef( treeLocs[i].ray.pt.x, treeLocs[i].ray.pt.y, 
                     treeLocs[i].ray.pt.z );
        
        treeRadius = treeLocs[i].diam/2.;
        treeHeight = treeLocs[i].height;
        
        normal = subtract_points( eye_pt, treeLocs[i].ray.pt );
        normalize_vector( &normal );
        
        glNormal3f( normal.x, normal.y, normal.z );
        
#ifdef __APPLE__
        glScalef(treeRadius, treeHeight, treeRadius);
        
        bool drawTwoPlanes = false;
        if ( !clip_course ||
            eye_pt.z - treeLocs[i].ray.pt.z < fwd_tree_detail_limit )
            drawTwoPlanes = true;
        
        glDrawArrays(GL_TRIANGLES, 0, 6 + drawTwoPlanes ? 6 : 0);
        
#else
        glBegin( GL_QUADS );
        glTexCoord2f( 0., 0. );
        glVertex3f( -treeRadius, 0.0, 0.0 );
        glTexCoord2f( 1., 0. );
        glVertex3f( treeRadius, 0.0, 0.0 );
        glTexCoord2f( 1., 1. );
        glVertex3f( treeRadius, treeHeight, 0.0 );
        glTexCoord2f( 0., 1. );
        glVertex3f( -treeRadius, treeHeight, 0.0 );
        
        if ( !clip_course ||
            eye_pt.z - treeLocs[i].ray.pt.z < fwd_tree_detail_limit )
        {
            glTexCoord2f( 0., 0. );
            glVertex3f( 0.0, 0.0, -treeRadius );
            glTexCoord2f( 1., 0. );
            glVertex3f( 0.0, 0.0, treeRadius );
            glTexCoord2f( 1., 1. );
            glVertex3f( 0.0, treeHeight, treeRadius );
            glTexCoord2f( 0., 1. );
            glVertex3f( 0.0, treeHeight, -treeRadius );
        }
        
        glEnd();
        
#endif
        
        glPopMatrix();
    } 
    
	
	
	
#ifdef __APPLE__
	static const GLfloat verticesItem []=
	{
		-1.0, 0.0,  1.0,
		1.0, 0.0, -1.0,
		1.0, 1.0, -1.0,
		-1.0, 1.0,  1.0,
		-1.0, 0.0,  1.0,
		1.0, 1.0, -1.0,
	};
	
	static const GLfloat texCoordsItem []=
	{
		0.0, 0.0 ,
		1.0, 0.0 ,
		1.0, 1.0 ,
		0.0, 1.0 ,
		0.0, 0.0 ,
		1.0, 1.0 ,
	};
	glVertexPointer (3, GL_FLOAT , 0, verticesItem);
	glTexCoordPointer(2, GL_FLOAT, 0, texCoordsItem);
#endif
	texture_id = 0;
	for (i = 0; i< numItems; i++ ) {
#ifdef __APPLE__
		if (g_game.is_speed_only_mode || !g_game.practicing) {
			if ( itemLocs[i].collectable == 1) {
				/* In speed mode or in tutorial we don't want to draw fishes*/
				continue;
			}
		}
#endif
		if ( itemLocs[i].collectable == 0 || itemLocs[i].drawable == False) {
			/* already collected or not to be drawn*/
			continue;
		}
		if ( clip_course ) {
			if ( eye_pt.z - itemLocs[i].ray.pt.z > fwd_clip_limit ) 
				continue;
			
			if ( itemLocs[i].ray.pt.z - eye_pt.z > bwd_clip_limit )
				continue;
		}
		
		/*  load texture id if needed */
		if (!itemLocs[i].sponsor_binded)
		{
			itemLocs[i].sponsor_binded = True;

			if(itemLocs[i].item_type == kFlagType)
			{
				int r = rand() % 2;
				item_name = r ? "flag_furlan" : "flag_zag";		/*un drapeau sur 2 portera le logo zag ou furlan, au hasard*/			
			}
			else {
				item_name = get_item_name(itemLocs[i].item_type);
			}
			if (!get_texture_binding( item_name, &itemLocs[i].tid ) ) {
				itemLocs[i].tid = 0;
			}
		}

		/* verify that the correct texture is bound */
		if (itemLocs[i].tid != texture_id) {
			glBindTexture( GL_TEXTURE_2D, itemLocs[i].tid );
			texture_id = itemLocs[i].tid;
		}
				
		glPushMatrix();
		{
			glTranslatef( itemLocs[i].ray.pt.x, itemLocs[i].ray.pt.y, 
						 itemLocs[i].ray.pt.z );
			
			itemRadius = itemLocs[i].diam/2.;
			itemHeight = itemLocs[i].height;
			
			if ( item_types[item_type].use_normal ) {
				normal = item_types[item_type].normal;
			} else {
				normal = subtract_points( eye_pt, itemLocs[i].ray.pt );
				normalize_vector( &normal );
			}
			
			if (normal.y == 1.0) {
				continue;
			}
			
			glNormal3f( normal.x, normal.y, normal.z );
			
			normal.y = 0.0;
			normalize_vector( &normal );
			
#ifdef __APPLE__
			glScalef(itemRadius*normal.z, itemHeight, itemRadius*normal.x);
			glDrawArrays(GL_TRIANGLES, 0, 6);
#else
			
			glBegin( GL_QUADS );
			{
				glTexCoord2f( 0., 0. );
				glVertex3f( -itemRadius*normal.z, 
						   0.0, 
						   itemRadius*normal.x );
				glTexCoord2f( 1., 0. );
				glVertex3f( itemRadius*normal.z, 
						   0.0, 
						   -itemRadius*normal.x );
				glTexCoord2f( 1., 1. );
				glVertex3f( itemRadius*normal.z, 
						   itemHeight, 
						   -itemRadius*normal.x );
				glTexCoord2f( 0., 1. );
				glVertex3f( -itemRadius*normal.z, 
						   itemHeight, 
						   itemRadius*normal.x );
			}
			glEnd();
#endif
		}
		glPopMatrix();
	} 
	
#ifdef __APPLE__
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
} 
Ejemplo n.º 6
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.º 7
0
/* Returns True iff the specified polygon intersections a unit-radius sphere
 * centered at the origin.  */
bool_t intersect_polygon( polygon_t p, point_t *v )
{
    ray_t ray; 
    vector_t nml, edge_nml, edge_vec;
    point_t pt;
    double d, s, nuDotProd, wec;
    double edge_len, t, distsq;
    int i;
    
    /* create a ray from origin along polygon normal */
    nml = make_normal( p, v );
    ray.pt = make_point( 0., 0., 0. );
    ray.vec = nml;
    
    nuDotProd = dot_product( nml, ray.vec );
    if ( fabs(nuDotProd) < EPS )
        return False;
    
    /* determine distance of plane from origin */
    d = -( nml.x * v[p.vertices[0]].x + 
          nml.y * v[p.vertices[0]].y + 
          nml.z * v[p.vertices[0]].z );
    
    /* if plane's distance to origin > 1, immediately reject */
    if ( fabs( d ) > 1 )
        return False;
    
    /* check distances of edges from origin */
    for ( i=0; i < p.num_vertices; i++ ) {
        point_t *v0, *v1;
        
        v0 = &v[p.vertices[i]];
        v1 = &v[p.vertices[ (i+1) % p.num_vertices ]]; 
        
        edge_vec = subtract_points( *v1, *v0 );
        edge_len = normalize_vector( &edge_vec );
        
        /* t is the distance from v0 of the closest point on the line
         to the origin */
        t = - dot_product( *((vector_t *) v0), edge_vec );
        
        if ( t < 0 ) {
            /* use distance from v0 */
            distsq = MAG_SQD( *v0 );
        } else if ( t > edge_len ) {
            /* use distance from v1 */
            distsq = MAG_SQD( *v1 );
        } else {
            /* closest point to origin is on the line segment */
            *v0 = move_point( *v0, scale_vector( t, edge_vec ) );
            distsq = MAG_SQD( *v0 );
        }
        
        if ( distsq <= 1 ) {
            return True;
        }
    }
    
    /* find intersection point of ray and plane */
    s = - ( d + dot_product( nml, make_vector(ray.pt.x, ray.pt.y, ray.pt.z) ) ) /
    nuDotProd;
    
    pt = move_point( ray.pt, scale_vector( s, ray.vec ) );
    
    /* test if intersection point is in polygon by clipping against it 
     * (we are assuming that polygon is convex) */
    for ( i=0; i < p.num_vertices; i++ ) {
        edge_nml = cross_product( nml, 
                                 subtract_points( v[p.vertices[ (i+1) % p.num_vertices ]], v[p.vertices[i]] ) );
        
        wec = dot_product( subtract_points( pt, v[p.vertices[i]] ), edge_nml );
        if (wec < 0)
            return False;
    } 
    
    return True;
}