Back to index

extremetuxracer  0.5beta
Functions
view.h File Reference
#include "pp_types.h"
#include "player.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void set_view_mode (Player &plyr, view_mode_t mode)
view_mode_t get_view_mode (Player &plyr)
void traverse_dag_for_view_point (scene_node_t *node, pp::Matrix trans)
pp::Vec3d get_tux_view_pt ()
void set_tux_eye (tux_eye_t which_eye, pp::Vec3d pt)
void update_view (Player &plyr, double dt)
 Updates camera and sets the view matrix.
void setup_view_matrix (Player &plyr)

Function Documentation

Definition at line 82 of file view.cpp.

{
    return plyr.view.mode;
} 
void set_tux_eye ( tux_eye_t  which_eye,
pp::Vec3d  pt 
)

Definition at line 129 of file view.cpp.

{
    tux_eye_pts[ which_eye ] = pt;

    tux_view_pt.x = ( tux_eye_pts[0].x + tux_eye_pts[1].x ) / 2.0; 
    tux_view_pt.y = ( tux_eye_pts[0].y + tux_eye_pts[1].y ) / 2.0; 
    tux_view_pt.z = ( tux_eye_pts[0].z + tux_eye_pts[1].z ) / 2.0; 
}

Here is the caller graph for this function:

void set_view_mode ( Player plyr,
view_mode_t  mode 
)

Definition at line 76 of file view.cpp.

{
    plyr.view.mode = mode;
    print_debug( DEBUG_VIEW, "View mode: %d", plyr.view.mode );
} 

Here is the call graph for this function:

Here is the caller graph for this function:

void setup_view_matrix ( Player plyr)

Definition at line 277 of file view.cpp.

{
    pp::Vec3d view_x, view_y, view_z;
    pp::Matrix view_mat;
    pp::Vec3d viewpt_in_view_frame;

    view_z = -1*plyr.view.dir;
    view_x = plyr.view.up^view_z;
    view_y = view_z^view_x;
    view_z.normalize();
    view_x.normalize();
    view_y.normalize();

    plyr.view.inv_view_mat.makeIdentity();

    plyr.view.inv_view_mat.data[0][0] = view_x.x;
    plyr.view.inv_view_mat.data[0][1] = view_x.y;
    plyr.view.inv_view_mat.data[0][2] = view_x.z;

    plyr.view.inv_view_mat.data[1][0] = view_y.x;
    plyr.view.inv_view_mat.data[1][1] = view_y.y;
    plyr.view.inv_view_mat.data[1][2] = view_y.z;

    plyr.view.inv_view_mat.data[2][0] = view_z.x;
    plyr.view.inv_view_mat.data[2][1] = view_z.y;
    plyr.view.inv_view_mat.data[2][2] = view_z.z;

    plyr.view.inv_view_mat.data[3][0] = plyr.view.pos.x;
    plyr.view.inv_view_mat.data[3][1] = plyr.view.pos.y;
    plyr.view.inv_view_mat.data[3][2] = plyr.view.pos.z;
    plyr.view.inv_view_mat.data[3][3] = 1;
    
    view_mat.transpose(plyr.view.inv_view_mat);

    view_mat.data[0][3] = 0;
    view_mat.data[1][3] = 0;
    view_mat.data[2][3] = 0;
    
    viewpt_in_view_frame = view_mat.transformPoint( plyr.view.pos );
    
    view_mat.data[3][0] = -viewpt_in_view_frame.x;
    view_mat.data[3][1] = -viewpt_in_view_frame.y;
    view_mat.data[3][2] = -viewpt_in_view_frame.z;
    
    glLoadIdentity();
    glMultMatrixd( (double *) view_mat.data );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void traverse_dag_for_view_point ( scene_node_t node,
pp::Matrix  trans 
)

Definition at line 87 of file view.cpp.

{
    pp::Matrix new_trans;
    scene_node_t *child;

    check_assertion( node != NULL, "node is NULL" );

    new_trans=trans*node->trans;

    if ( node->eye == true ) {
       set_tux_eye( node->which_eye,
                   new_trans.transformPoint( pp::Vec3d( 0., 0., 0. ) ) );
    }

    child = node->child;
    while (child != NULL) {
        traverse_dag_for_view_point( child, new_trans );
        child = child->next;
    } 
}

Here is the call graph for this function:

Here is the caller graph for this function:

void update_view ( Player plyr,
double  dt 
)

Updates camera and sets the view matrix.

Precondition:
plyr != NULL, plyr has been initialized with position & velocity info., plyr->view.mode has been set
  • plyr pointer to player data
  • dt time step size
Returns:
none
Author:
jfpatry
Date:
Created: 2000-08-26
Modified: 2000-08-26

Definition at line 337 of file view.cpp.

{
    pp::Vec3d view_pt;
    pp::Vec3d view_dir, up_dir, vel_dir, view_vec;
    double ycoord;
    double course_angle;
    pp::Vec3d axis;
    pp::Matrix rot_mat;
    pp::Vec3d y_vec;
    pp::Vec3d mz_vec;
    pp::Vec3d vel_proj;
    pp::Quat rot_quat;
    double speed;
    pp::Vec3d vel_cpy;
    double time_constant_mult;

    vel_cpy = plyr.vel;
    speed = vel_cpy.normalize();

    time_constant_mult = 1.0 /
       MIN( 1.0, 
            MAX( 0.0, 
                ( speed - NO_INTERPOLATION_SPEED ) /
                ( BASELINE_INTERPOLATION_SPEED - NO_INTERPOLATION_SPEED )));

    up_dir = pp::Vec3d( 0, 1, 0 );

    vel_dir = plyr.vel;
    vel_dir.normalize();

    course_angle = get_course_angle();

    switch( plyr.view.mode ) {

    case BEHIND:
    {
       /* Camera-on-a-string mode */

       /* Construct vector from player to camera */
       view_vec = pp::Vec3d( 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;

       y_vec = pp::Vec3d( 0.0, 1.0, 0.0 );
       mz_vec = pp::Vec3d( 0.0, 0.0, -1.0 );
       vel_proj = projectIntoPlane( y_vec, vel_dir );

       vel_proj.normalize();

       /* Rotate view_vec so that it places the camera behind player */
       rot_quat = pp::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 */
        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 = view_pt - plyr.pos;
       
       axis = y_vec^view_vec;
       axis.normalize();
       
       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 */
           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 = pp::Vec3d( 0.0, 1.0, 0.0 );
           }
       }

        break;
    }

    case FOLLOW: 
    {
       /* Camera follows player (above and behind) */

       up_dir = pp::Vec3d( 0, 1, 0 );

       /* Construct vector from player to camera */
       view_vec = pp::Vec3d( 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;

       y_vec = pp::Vec3d( 0.0, 1.0, 0.0 );
       mz_vec = pp::Vec3d( 0.0, 0.0, -1.0 );
       vel_proj = projectIntoPlane( y_vec, vel_dir );

       vel_proj.normalize();

       /* Rotate view_vec so that it places the camera behind player */
       rot_quat = pp::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 */
        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 = view_pt - plyr.pos;
       
       axis = y_vec^view_vec;
       axis.normalize();
       
       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 */
           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 = pp::Vec3d( 0.0, 1.0, 0.0 );
           }
       }

        break;
    }

    case ABOVE:
    {
       /* Camera always uphill of player */

       up_dir = pp::Vec3d( 0, 1, 0 );


       /* Construct vector from player to camera */
       view_vec = pp::Vec3d( 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 */
        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 = view_pt - plyr.pos;

       rot_mat.makeRotation( PLAYER_ANGLE_IN_CAMERA, 'x' );
       view_dir = -1.0*rot_mat.transformVector( 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 );
}

Here is the call graph for this function:

Here is the caller graph for this function: