Ejemplo n.º 1
0
void CCharShape::AdjustOrientation (CControl *ctrl, bool eps,
                                    ETR_DOUBLE dist_from_surface, const TVector3d& surf_nml) {
	TVector3d new_y, new_z;
	static const TVector3d minus_z_vec(0, 0, -1);
	static const TVector3d y_vec(0, 1, 0);

	if (dist_from_surface > 0) {
		new_y = ctrl->cvel;
		new_y.Norm();
		new_z = ProjectToPlane (new_y, TVector3d(0, -1, 0));
		new_z.Norm();
		new_z = AdjustRollvector (ctrl, ctrl->cvel, new_z);
	} else {
		new_z = -1.0 * surf_nml;
		new_z = AdjustRollvector (ctrl, ctrl->cvel, new_z);
		new_y = ProjectToPlane (surf_nml, ctrl->cvel);
		new_y.Norm();
	}

	TVector3d new_x = CrossProduct (new_y, new_z);
	TMatrix<4, 4> cob_mat(new_x, new_y, new_z);
	TQuaternion new_orient = MakeQuaternionFromMatrix (cob_mat);

	if (!ctrl->orientation_initialized) {
		ctrl->orientation_initialized = true;
		ctrl->corientation = new_orient;
	}

	ETR_DOUBLE time_constant = dist_from_surface > 0 ? TO_AIR_TIME : TO_TIME;

	float dtime = eps ? EPS : g_game.time_step;
	ctrl->corientation = InterpolateQuaternions (
	                         ctrl->corientation, new_orient,
	                         min (dtime / time_constant, 1.0));

	ctrl->plane_nml = RotateVector (ctrl->corientation, minus_z_vec);
	ctrl->cdirection = RotateVector (ctrl->corientation, y_vec);
	cob_mat = MakeMatrixFromQuaternion(ctrl->corientation);

	// Trick rotations
	new_y = TVector3d (cob_mat[1][0], cob_mat[1][1], cob_mat[1][2]);
	TMatrix<4, 4> rot_mat = RotateAboutVectorMatrix(new_y, (ctrl->roll_factor * 360));
	cob_mat = rot_mat * cob_mat;
	new_x = TVector3d (cob_mat[0][0], cob_mat[0][1], cob_mat[0][2]);
	rot_mat = RotateAboutVectorMatrix (new_x, ctrl->flip_factor * 360);
	cob_mat = rot_mat * cob_mat;

	TransformNode (0, cob_mat, cob_mat.GetTransposed());
}
Ejemplo n.º 2
0
static void
adjust_orientation(Player& plyr, float dtime, const ppogl::Vec3d& vel,
			 float dist_from_surface, const ppogl::Vec3d& surf_nml)
{
    static ppogl::Vec3d minus_z_vec(0., 0., -1.);
    static ppogl::Vec3d y_vec(0., 1., 0.);

    ppogl::Vec3d new_y, new_z;
    if( dist_from_surface > 0 ){
		new_y = 1.*vel;
		new_y.normalize();
		new_z = projectIntoPlane( new_y, ppogl::Vec3d(0., -1., 0.) );
		new_z.normalize();
		new_z = adjust_tux_zvec_for_roll( plyr, vel, new_z );
    }else{ 
		new_z = -1.*surf_nml;
		new_z = adjust_tux_zvec_for_roll( plyr, vel, new_z );
		new_y = projectIntoPlane( surf_nml,1.*vel);
		new_y.normalize();
    }

    ppogl::Vec3d new_x = new_y^new_z;
	pp::Quat new_orient;
	pp::Matrix inv_cob_mat;
	pp::Matrix rot_mat;
	
	{
		pp::Matrix cob_mat;    
		pp::Matrix::makeChangeOfBasisMatrix( cob_mat, inv_cob_mat, new_x, new_y, new_z );
	    new_orient = pp::Quat(cob_mat);
	}
    
	if( !plyr.orientation_initialized ){
		plyr.orientation_initialized = true;
		plyr.orientation = new_orient;
    }

	float time_constant = dist_from_surface > 0
		? TUX_ORIENTATION_AIRBORNE_TIME_CONSTANT
		: TUX_ORIENTATION_TIME_CONSTANT;

    plyr.orientation = pp::Quat::interpolate( 
	plyr.orientation, new_orient, 
	MIN( dtime / time_constant, 1.0 ) );

    plyr.plane_nml = plyr.orientation.rotate( minus_z_vec );
    plyr.direction = plyr.orientation.rotate( y_vec );

    pp::Matrix cob_mat( plyr.orientation );


    // Trick rotations
    new_y = ppogl::Vec3d( cob_mat.data[1][0], cob_mat.data[1][1], cob_mat.data[1][2] ); 
    rot_mat.makeRotationAboutVector( new_y, 
				       ( plyr.control.barrel_roll_factor * 360 ) );
    cob_mat=rot_mat*cob_mat;
    new_x = ppogl::Vec3d( cob_mat.data[0][0], cob_mat.data[0][1], cob_mat.data[0][2] ); 
    rot_mat.makeRotationAboutVector( new_x, 
				       plyr.control.flip_factor * 360 );
    cob_mat=rot_mat*cob_mat;



    inv_cob_mat.transpose(cob_mat);

    const std::string& tux_root = tux[plyr.num].getRootNode();
    transform_scene_node( tux_root, cob_mat, inv_cob_mat ); 
}