Exemplo 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 ) );

}
Exemplo n.º 2
0
static ppogl::Vec3d
interpolate_view_pos(const ppogl::Vec3d& plyr_pos1, const ppogl::Vec3d& plyr_pos2,
			      const double max_vec_angle,
			      const ppogl::Vec3d& pos1, const ppogl::Vec3d& pos2,
			      const double dist, const double dt,
			      const double time_constant )
{
    static ppogl::Vec3d y_vec(0.0, 1.0, 0.0);

    ppogl::Vec3d vec1 = pos1 - plyr_pos1;
    ppogl::Vec3d vec2 = pos2 - plyr_pos2;

    vec1.normalize();
    vec2.normalize();

    const pp::Quat q1(y_vec, vec1);
    pp::Quat q2(y_vec, vec2);

    const double alpha = MIN( MAX_INTERPOLATION_VALUE,
		 1.0 - exp ( -dt / time_constant ) );

    q2 = pp::Quat::interpolate( q1, q2, alpha );

    vec2 = q2.rotate( y_vec );

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

    if(theta > max_vec_angle){
		ppogl::Vec3d axis = y_vec^vec2;
		axis.normalize();
    
		pp::Matrix rot_mat;
		rot_mat.makeRotationAboutVector( axis, 
					   theta-max_vec_angle );
		vec2 = rot_mat.transformVector( vec2 );
    }

    return plyr_pos2+dist*vec2;
}
Exemplo n.º 3
0
void DrawWind(float dir, float speed, const CControl *ctrl) {
	if (g_game.wind_id < 1) return;

	//float dir_angle = RADIANS_TO_ANGLES(atan2(ctrl->cvel.x, ctrl->cvel.z));
	string windstr = Int_StrN ((int)speed, 3);

	glPushMatrix();
	glTranslatef (32, 28, 0);
	glRotatef(dir, 0, 0, 1);
	glTranslatef (-32, -28, 0);
	Tex.Draw(ARROW_ICON, 0, Winsys.resolution.height - 60, 1);
	glPopMatrix();

	Tex.DrawNumStr(windstr, 60, Winsys.resolution.height - 46, 1, colWhite);

#if 0
	if (g_game.wind_id < 1) return;

	Tex.Draw (SPEEDMETER, 0, Winsys.resolution.height-140, 1.0);
	glDisable (GL_TEXTURE_2D);


	float alpha, red, blue;
	if (speed <= 50) {
		alpha = speed / 50;
		red = 0;
	} else {
		alpha = 1.0;
		red = (speed - 50) / 50;
	}
	blue = 1.0 - red;

	glPushMatrix ();
	glColor4f (red, 0, blue, alpha);
	glTranslatef (72, 66, 0);
	glRotatef(dir, 0, 0, 1);
	glEnableClientState(GL_VERTEX_ARRAY);
	static const int len = 45;
	static const GLshort vtx1 [] = {
		-5, 0.0,
		5, 0.0,
		5, -len,
		- 5, -len
	};
	glVertexPointer(2, GL_SHORT, 0, vtx1);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

	// direction indicator
	float dir_angle = RADIANS_TO_ANGLES(atan2(ctrl->cvel.x, ctrl->cvel.z));

	glColor4f (0, 0.5, 0, 1.0);
	glRotatef (dir_angle - dir, 0, 0, 1);
	static const GLshort vtx2 [] = {
		-2, 0,
		2, 0,
		2, -50,
		-2, -50
	};
	glVertexPointer(2, GL_SHORT, 0, vtx2);
	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
	glDisableClientState(GL_VERTEX_ARRAY);
	glPopMatrix ();

	glEnable (GL_TEXTURE_2D);

	Tex.Draw (SPEED_KNOB, 64, Winsys.resolution.height - 74, 1.0);
	string windstr = Int_StrN ((int)speed, 3);
	if (param.use_papercut_font < 2) {
		Tex.DrawNumStr (windstr, 130, Winsys.resolution.height - 55, 1, colWhite);
	} else {
		FT.SetColor (colBlue);
		FT.DrawString (130, Winsys.resolution.height - 55, windstr);
	}
#endif
}
Exemplo n.º 4
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;
}