⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix4.cpp

📁 <B>DirectX9.0 3D游戏编程</B>
💻 CPP
字号:
/*******************************************************************
 *         Advanced 3D Game Programming using DirectX 9.0
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * copyright (c) 2003 by Peter A Walsh and Adrian Perez
 * See license.txt for modification and distribution information
 ******************************************************************/

#include "point3.h"
#include "matrix4.h"

const matrix4 matrix4::Identity = matrix4(
	1,0,0,0,
	0,1,0,0,
	0,0,1,0,
	0,0,0,1);

//returns matrix4*matrix4
matrix4 operator*(matrix4 const &a, matrix4 const &b)
{
    matrix4 out;      // temporary matrix4 for storing result
    for (int j = 0; j < 4; j++)         // transform by columns first
        for (int i = 0; i < 4; i++)     // then by rows
            out.m[i][j] = a.m[i][0] * b.m[0][j] + a.m[i][1] * b.m[1][j] +
                           a.m[i][2] * b.m[2][j] + a.m[i][3] * b.m[3][j];
	return out;
};

// Multiplies two matrices together
void MatMult( const matrix4 &a, const matrix4& b, matrix4* result )
{
    for (int j = 0; j < 4; j++)         // transform by columns first
        for (int i = 0; i < 4; i++)     // then by rows
            result->m[i][j] = a.m[i][0] * b.m[0][j] + a.m[i][1] * b.m[1][j] +
                              a.m[i][2] * b.m[2][j] + a.m[i][3] * b.m[3][j];
}


void matrix4::Rotate( float yaw, float pitch, float roll )
{
    int i;
    float sinangx,cosangx,sinangy,cosangy,sinangz,cosangz;
    float xold,yold,zold,xnew,ynew,znew;//temporary rotation results to prevent round off error
    sinangx=(float)sin(yaw);
    cosangx=(float)cos(yaw);
    sinangy=(float)sin(pitch);
    cosangy=(float)cos(pitch);
    sinangz=(float)sin(roll);
    cosangz=(float)cos(roll);
    for(i=0; i<3; i++)
    {
////////init points/////////////////////
        xold=m[i][0];
        yold=m[i][1];
        zold=m[i][2];
////////rotate point locally////////////        
        //xrot
        xnew=xold;
        ynew=(yold*cosangx)-(zold*sinangx);
        znew=(yold*sinangx)+(zold*cosangx);
        xold=xnew;
        yold=ynew;
        zold=znew;
        //yrot            
        xnew=((xold*cosangy)+(zold*sinangy));
        ynew=yold;
        znew=((-1*(xold*sinangy))+(zold*cosangy));
        xold=xnew;
        yold=ynew;
        zold=znew;
        //zrot
        xnew=((xold*cosangz)-(yold*sinangz));
        ynew=((yold*cosangz)+(xold*sinangz));
        znew=zold;
        //change object location
        m[i][0]=xnew;
        m[i][1]=ynew;
        m[i][2]=znew;
    }
}

void matrix4::Translate( const point3& amt)
{
    _41 += amt.x;
    _42 += amt.y;
    _43 += amt.z;
}

void matrix4::Place( const point3& loc)
{
    _41 = loc.x;
    _42 = loc.y;
    _43 = loc.z;
}

void matrix4::MakeIdent()
{
	_11 = 1.f;	_22 = 1.f;	_33 = 1.f;	_44 = 1.f;
	_12 = 0.f;  _13 = 0.f;  _14 = 0.f;	_21 = 0.f;
	_23 = 0.f;	_24 = 0.f;	_31 = 0.f;	_32 = 0.f;	
	_34 = 0.f;	_41 = 0.f;	_42 = 0.f;	_43 = 0.f;	
}

//==========--------------------------  

void matrix4::ToObjectLookAt( const point3& loc, const point3& lookAt, const point3& inUp )
{

    point3 viewVec = lookAt - loc;
 
    float mag = viewVec.Mag();
 
    viewVec /= mag;
 
    float fDot = inUp * viewVec;
 
    point3 upVec = inUp - fDot * viewVec;
 
	upVec.Normalize();
	
    point3 rightVec = upVec ^ viewVec;


    // Start building the matrix. The first three rows contains the basis
    // vectors used to rotate the view to point at the lookat point
    _11 = rightVec.x;    _21 = upVec.x;    _31 = viewVec.x;
    _12 = rightVec.y;    _22 = upVec.y;    _32 = viewVec.y;
    _13 = rightVec.z;    _23 = upVec.z;    _33 = viewVec.z;
 
    // Do the translation values (rotations are still about the eyepoint)
    _41 = loc.x;
    _42 = loc.y;
    _43 = loc.z;

    _14 = 0;
    _24 = 0;
    _34 = 0;
    _44 = 1;


}

matrix4 matrix4::ObjectLookAt( 
	const point3& loc, 
	const point3& lookAt, 
	const point3& inUp )
{
	matrix4 out;
	out.ToObjectLookAt( loc, lookAt, inUp );
	return out;
}

//==========--------------------------  

void matrix4::ToCameraLookAt( const point3& loc, const point3& lookAt, const point3& inUp )
{

    point3 viewVec = lookAt - loc;
 
    float mag = viewVec.Mag();
 
    viewVec /= mag;
 
    float fDot = inUp * viewVec;
 
    point3 upVec = inUp - fDot * viewVec;
 
	upVec.Normalize();
	
    point3 rightVec = upVec ^ viewVec;


    // Start building the matrix. The first three rows contains the basis
    // vectors used to rotate the view to point at the lookat point
    _11 = rightVec.x;    _12 = upVec.x;    _13 = viewVec.x;
    _21 = rightVec.y;    _22 = upVec.y;    _23 = viewVec.y;
    _31 = rightVec.z;    _32 = upVec.z;    _33 = viewVec.z;
 
    // Do the translation values (rotations are still about the eyepoint)
    _41 = - (loc * rightVec);
    _42 = - (loc * upVec);
    _43 = - (loc * viewVec);

    _14 = 0;
    _24 = 0;
    _34 = 0;
    _44 = 1;
}


matrix4 matrix4::CameraLookAt( 
	const point3& loc, 
	const point3& lookAt, 
	const point3& inUp )
{
	matrix4 out;
	out.ToCameraLookAt( loc, lookAt, inUp );
	return out;
}

//==========--------------------------  

void matrix4::ToXRot( float theta )
{
	float c = (float) cos(theta);
	float s = (float) sin(theta);
	MakeIdent();
	_22 = c;
	_23 = s;
	_32 = -s;
	_33 = c;
}

matrix4 matrix4::XRot( float theta )
{
	matrix4 out;
	out.ToXRot( theta );
	return out;
}

//==========--------------------------  

void matrix4::ToYRot( float theta )
{
	float c = (float) cos(theta);
	float s = (float) sin(theta);
	MakeIdent();
	_11 = c;
	_13 = -s;
	_31 = s;
	_33 = c;
}

matrix4 matrix4::YRot( float theta )
{
	matrix4 out;
	out.ToYRot( theta );
	return out;
}

//==========--------------------------  

void matrix4::ToZRot( float theta )
{
	float c = (float) cos(theta);
	float s = (float) sin(theta);
	MakeIdent();
	_11 = c;
	_12 = s;
	_21 = -s;
	_22 = c;
}

matrix4 matrix4::ZRot( float theta )
{
	matrix4 out;
	out.ToZRot( theta );
	return out;
}

//==========--------------------------  

void matrix4::ToAxisAngle( const point3& inAxis, float angle )
{
	point3 axis = inAxis.Normalized();
	float s = (float)sin( angle );
	float c = (float)cos( angle );
	float x = axis.x, y = axis.y, z = axis.z;

	_11 = x*x*(1-c)+c;
	_21 = x*y*(1-c)-(z*s);
	_31 = x*z*(1-c)+(y*s);
	_41 = 0;
	_12 = y*x*(1-c)+(z*s);
	_22 = y*y*(1-c)+c;
	_32 = y*z*(1-c)-(x*s);
	_42 = 0;
	_13 = z*x*(1-c)-(y*s);
	_23 = z*y*(1-c)+(x*s);
	_33 = z*z*(1-c)+c;
	_43 = 0;
	_14 = 0;
	_24 = 0;
	_34 = 0;
	_44 = 1;
}

matrix4 matrix4::AxisAngle( const point3& axis, float angle )
{
	matrix4 out;
	out.ToAxisAngle( axis, angle );
	return out;
}


//==========--------------------------  

void matrix4::ToTranslation( const point3& p )
{
	MakeIdent();
	_41 = p.x;
	_42 = p.y;
	_43 = p.z;
}

matrix4 matrix4::Translation( const point3& p )
{
	matrix4 out;
	out.ToTranslation( p );
	return out;
}


//==========--------------------------  

void matrix4::ToScale( const point3& scale )
{
	MakeIdent();
	_11 = scale.x;
	_22 = scale.y;
	_33 = scale.z;
}

matrix4 matrix4::Scale( const point3& scale )
{
	matrix4 out;
	out.ToScale( scale );
	return out;
}

//==========--------------------------  

void matrix4::ToInverse( const matrix4& in )
{

	// first transpose the rotation matrix
	_11 = in._11;
	_12 = in._21;
	_13 = in._31;
	_21 = in._12;
	_22 = in._22;
	_23 = in._32;
	_31 = in._13;
	_32 = in._23;
	_33 = in._33;

	// fix right column
	_14 = 0;
	_24 = 0;
	_34 = 0;
	_44 = 1;

	// now get the new translation vector
	point3 temp = in.GetLoc();

	_41 = -(temp.x * in._11 + temp.y * in._12 + temp.z * in._13);
	_42 = -(temp.x * in._21 + temp.y * in._22 + temp.z * in._23);
	_43 = -(temp.x * in._31 + temp.y * in._32 + temp.z * in._33);

}

matrix4 matrix4::Inverse( const matrix4& in )
{
	matrix4 out;
	out.ToInverse( in );
	return out;
}

//==========--------------------------  

const point3 matrix4::GetLoc() const
{
	return point3( _41, _42, _43 );
}

point3 matrix4::GetAxis( int axis ) const
{
	return point3
	(
		m[axis][0],
		m[axis][1],
		m[axis][2]
	);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -