2.8 XNA 矩阵

2.8 XNA 矩阵

为了变换点和向量,我们使用1x4的行向量和4x4的矩阵,原因将在在下章中介绍。下面我们重点来看下表示4x4矩阵的类型。

2.8.1矩阵类型

为了在XNA数学库中表示4x4的矩阵,我们使用XMMATRIX类,它被定义在xnamath.h头文件中,示例如下:(其中我们添加了额外的注释)

//  Matrix type:  Sixteen  32  bitfloating point  components  aligned on  a

//  16 byte  boundary and mapped  to four  hardware vector  registers

//16个32位浮点型分量组成一个16字节宽,映射到4个硬件寄存器。

#if (defined(_XM_X86_)  ||  defined(_XM_X64_)) &&  defined(_XM_NO_INTRINSICS_) typedef  struct _XMMATRIX

#else

typedef _DECLSPEC_ALIGN_16_  struct  _XMMATRIX #endif

{

union
{

// Use  4  XMVECTORs to  represent  the matrix for SIMD. XMVECTORr[4];

struct

{

FLOAT _11,  _12,  _13, _14;
FLOAT  _21,  _22, _23,  _24;
FLOAT  _31,  _32, _33,  _34;
FLOAT  _41,  _42, _43,  _44;
};

FLOAT  m[4][4];
};

#ifdef  __cplusplus
_XMMATRIX()  {};

//  Initialize matrix  by  specifying 4  row vectors.

_XMMATRIX(FXMVECTOR  R0, FXMVECTOR R1, FXMVECTOR  R2, CXMVECTOR  R3); // Initialize  matrix  by specifying  the  16 elements.
_XMMATRIX(FLOAT  m00,  FLOAT m01,  FLOAT  m02, FLOAT  m03,
FLOAT  m10, FLOAT  m11,  FLOAT m12,  FLOAT  m13,
FLOAT  m20,  FLOAT m21,  FLOAT  m22, FLOAT  m23,
FLOAT  m30,  FLOAT m31,  FLOAT  m32, FLOAT  m33);
//  Pass array  of  sixteen floats  to  construct matrix.
_XMMATRIX(CONST  FLOAT *pArray);

FLOAT  operator() (UINT  Row,  UINT Column)  CONST  { return  m[Row][Column];  } FLOAT& operator()  (UINT  Row, UINT  Column)  { return  m[Row][Column];  }
_XMMATRIX&  operator= (CONST  _XMMATRIX&  M);

#ifndef  XM_NO_OPERATOR_OVERLOADS

_XMMATRIX&  operator*= (CONST  _XMMATRIX&  M);

_XMMATRIX  operator* (CONST  _XMMATRIX&  M) CONST; #endif  // !XM_NO_OPERATOR_OVERLOADS

#endif  // __cplusplus

}  XMMATRIX;

通过这些代码,我们可以看到XMMATRIX使用了4个XMVECTOR实例,以便使用SIMD。此外,XMMATRIX提供了重载运算符用于多行矩阵;提供插入成员操作的重载,用来访问或者修改指定的行或列的元素分量。

除了使用多种构造函数,也可以使用XMMatrixSet来创建XMMATRIX实例:

XMMATRIX XMMatrixSet(FLOAT  m00, FLOAT  m01,  FLOAT m02,  FLOAT  m03, FLOAT m10,  FLOAT  m11, FLOAT  m12,  FLOAT m13,

FLOAT m20,  FLOAT  m21, FLOAT  m22,  FLOAT m23,
FLOAT  m30, FLOAT  m31,  FLOAT m32,  FLOAT  m33);

正如我们使用XMFLOAT2  (2D), XMFLOAT3 (3D),和XMFLOAT4  (4D)在类中存储向量那样,XNA数学库的帮助文档建议使用XMFLOAT4x4类型来存储矩阵数据作为类的成员变量。

//  4x4Matrix:  32  bit floating point  components typedef  struct _XMFLOAT4X4

{

union
{

struct
{

FLOAT _11,  _12,  _13, _14;
FLOAT  _21,  _22, _23,  _24;
FLOAT  _31,  _32, _33,  _34;
FLOAT  _41,  _42, _43,  _44;
};

FLOAT  m[4][4];
};

#ifdef  __cplusplus
_XMFLOAT4X4()  {};

_XMFLOAT4X4(FLOAT  m00, FLOAT  m01,  FLOAT m02,  FLOAT  m03, FLOAT m10,  FLOAT  m11, FLOAT  m12,  FLOAT m13,
FLOAT  m20,  FLOAT m21,  FLOAT  m22, FLOAT  m23,
FLOAT  m30,  FLOAT m31,  FLOAT  m32, FLOAT  m33);
_XMFLOAT4X4(CONST  FLOAT *pArray);

FLOAT  operator() (UINT  Row,  UINT Column)  CONST  { return  m[Row][Column];  } FLOAT& operator()  (UINT  Row, UINT  Column)  { return  m[Row][Column];  }
_XMFLOAT4X4&  operator= (CONST  _XMFLOAT4X4&  Float4x4);
#endif  //  __cplusplus

}  XMFLOAT4X4;

 

2.8.2 矩阵函数

 

XNA数学库包含如下使用的矩阵方法:

 

XMMATRIXXMMatrixIdentity();  //  返回单位矩阵I

BOOL  XMMatrixIsIdentity(   //  返回真假,若M为单位矩阵,返回真……

 matrix CXMMATRIX  M);  // Input M

XMMATRIX XMMatrixMultiply(  //  返回AB

CXMMATRIX  A, //  Input  A

CXMMATRIX  B); //  Input  B

XMMATRIX XMMatrixTranspose(//返回MT

CXMMATRIX  M); //  Input  M

 

XMVECTOR XMMatrixDeterminant(  //  返回  (det M,det M,det M,det

 M) CXMMATRIX  M); //  Input  M

XMMATRIXXMMatrixInverse(  //  Returns M-1

XMVECTOR* pDeterminant,  //  Input (det  M,det M,det M,det M) CXMMATRIX  M); //  Input  M

注意:XMMATRIX的参数必须为CXMMATRIX,这样可以确保XMMATRIX参数在XBOX360和windows平台上正确的运行

// Fix-up  for XMMATRIXparameters  to  pass in-register on  Xbox  360, // by  reference  otherwise

#ifdefined(_XM_VMX128_INTRINSICS_)
typedef  const  XMMATRIXCXMMATRIX;

#elif  defined(__cplusplus)

 

typedef  const XMMATRIX&  CXMMATRIX;

2.8.3 XNA矩阵示例程序

下列代码演示了如何使用XMMATRIX类及前一节中提到的大多数函数

#include   //  for FLOAT definition #include 

#include 
using  namespace std;

// 重载"<<"运算符,这样我们可以用它输出XMVECTOR 和 XMMATRIX 对象

ostream& operator<<(ostream&  os,

FXMVECTOR  v)
{

XMFLOAT4 dest;

XMStoreFloat4(&dest,  v);

os  << "("  <<  dest.x <<  ",  " <<  dest.y  << ",  " <<  dest.z <<  ",  " <<  dest.w  << ")";
return  os;

}

ostream& operator<<(ostream&  os, CXMMATRIX m)
{

for(int  i =  0;  i <  4;  ++i)
{

for(int  j =  0;  j <  4;  ++j)
os  << m(i,  j)  << "\t";
os  << endl;

}

return  os;
}

int main()
{

//  Check  support for SSE2  (Pentium4,  AMD K8, and above). if(  !XMVerifyCPUSupport()  )

{

cout <<  "xna  math not supported"  <<  endl; return 0;

}

XMMATRIX A(1.0f,  0.0f, 0.0f,  0.0f,

0.0f,  2.0f, 0.0f,  0.0f,

0.0f,  0.0f, 4.0f,  0.0f,

1.0f,  2.0f, 3.0f,  1.0f);

XMMATRIX B  = XMMatrixIdentity();
XMMATRIX C  = A  *  B;

XMMATRIX D  = XMMatrixTranspose(A);

XMVECTOR det =  XMMatrixDeterminant(A); XMMATRIX E  = XMMatrixInverse(&det,  A); XMMATRIX F  = A  *  E;

cout  << "A  =  " <<  endl  << A  <<  endl;

cout  << "B  =  " <<  endl  << B  <<  endl;

cout  << "C  =  A*B  =  " <<  endl  << C  <<  endl;

cout  << "D  =  transpose(A) =  "  << endl  <<  D <<  endl;

cout  << "det  =  determinant(A)  = "  <<  det <<  endl  << endl; cout  << "E  =  inverse(A) =  "  << endl  <<  E <<  endl;
cout  << "F  =  A*E  =  " <<  endl  << F  <<  endl;
return  0;

}

 

2.8 XNA 矩阵_第1张图片

2.8 XNA 矩阵_第2张图片

2.9 小结

2.10 练习

你可能感兴趣的:(Introduction,to,3D,Game,Programming,with,DirectX,11学习笔记)