XNA Math Vectors

在direct3D 9 和10中,包含3D数学库的D3DX库支持向量和其他核心类型的计算。在direct11中,D3DX库不在包含3D数学库,取而代之的是XNA数学库。XNA利用的是特殊的硬件寄存器。在windows环境中,XNA
数学库使用SSE2(Streaming SIMD Extension 2)指令集。它使用128-bits大小的SIMD(single instruction multiple data)寄存器,可以用一个指令操作4个32-bits浮点型数据或整型数据。
例如:u + v = (ux + vx, uy + vy, uz + vz)
我们用3个加法指令将每个分量加起来。但通过使用SIMD,我们可以只用一个SIMD指令做4D向量加法,而不是用4个标量指令。如果你操作3D向量,我们仍然可以使用SIMD,
我们只需将向量的第四个分量置为0并且忽略它。在2D中类似。
为了使用XNA数学库,我们只需添加头文件#include<xnamath.h> 。当然,你也可以通过包含头文件#include<d3dx10.h>,并且链接静态库d3dx10.lib使用D3DX10数学库。

在XNA数学库中,关键的向量类型是XMVECTOR. 它是一个128-bits类型,可以被单个SIMD指令处理。
它被这样定义:

 typedef __m128 XMVECTOR;

这里,__m128是一个特殊的SIMD类型。对于类数据成员,最好使用XMFLOAT2,XMFLOAT3,XMFLAOT4。它们被如下定义:

 typedef struct _XMFLOAT4
{
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT w;
}XMFLOAT4;

然而,如果我们直接使用这些类型进行计算,将不能利用SIMD硬件。我们需要将这些类型的实例转化为XMFLOAT类型。这些是XNA载入函数(loading functions)的工作。相反地,XNA还提供存储函数(storage functions)将
XMVECTOR转化为XMFLOAT*类型。

Loading 和 Storage 函数

Loading函数:

 XMVECTOR XMLoadFloat2(CONST XMFLOAT2 *pSource); // 将XMFLOAT2转化为XMVECTOR类型
XMVECTOR XMLoadFloat3(CONST XMFLOAT3 *pSource); // 将XMFLOAT3转化为XMVECTOR类型
XMVECTOR XMLoadFloat4(CONST XMFLOAT4 *pSource); // 将XMFLOAT4转化为XMVECTOR类型

还有很多方法将其他类型转化为XMVECTOR类型,下面是一些例子:

 XMVECTOR XMLoadInt3(CONST UINT* pSource);    // Loads 3-element UINT array into XMVECTOR
XMVECTOR XMLoadColor(CONST XMCOLOR *pSource); // Loads XMCOLOR into XMVECTOR
XMVECTOR XMLoadByte4(CONST XMBYTE4 *pSource); // Loads XMBYTE4 into XMVECTOR

Storage函数:

 VOID XMStoreFloat2(XMFLOAT2 *pDestination,FXMVECTOR V); // 将XMVECTOR转化为XMFLOAT2类型

还有很多方法将XMVECTOR转化为其他类型,下面是一些例子:

 VOID XMStoreInt3(UINT* pDestination, FXMVECTOR V);
VOID XMStoreColor(XMCOLOR* pDestination, FXMVECTOR V);
VOID XMStoreByte4(XMBYTE4 *pDestination, FXMVECTOR V);

有时,我们只想获取或者设置XMVECTOR的一个分量,可以使用下面的函数完成:

 FLOAT XMVectorGetX(FXMVECTOR V);
XMVECTOR XMVectorSetX(FXMVECTOR V,Float x);

传递参数的规则

为了利用SIMD,将参数传递给XMVECTOR类型的函数有一些规则需要遵守,这些规则根据平台的不同而不同。尤其是32-bit Windows、64-bit Windows和XBOX 360. 为了独立于平台,
我们使用类型CXMVECTOR和FXMVECTOR传递XMVECTOR的参数。对于Windows,它们被定义如下:

 // 32-bit Windows
typedef const XMVECTOR FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;
// 64-bit Windows
typedef const XMVECTOR& FXMVECTOR;
typedef const XMVECTOR& CXMVECTOR;

它们的不同点是,我们可以直接传递XMVECTOR的副本还是我们必须传递一个引用。现在,传递XMVECTOR参数的规则如下:
前三个XMVECTOR参数应该是FXMVECTOR类型,后面的为CXMVECTOR类型。

 XMINLINE XMMATRIX XMMatrixTransformation(
FXMVECTOR ScalingOrigin,
FXMVECTOR ScalingOrientationQuaternion,
FXMVECTOR Scaling,
CXMVECTOR RotationOrigin,
CXMVECTOR RotationQuaternion,
CXMVECTOR Translation);

注意,你可以拥有非XMVECTOR类型的参数,前面的规则仍然有效:

 XMINLINE XMMATRIX XMMatrixTransformation2D(
FXMVECTOR ScalingOrigin,
FLOAT ScalingOrientation, // FLOAT类型
FXMVECTOR Scaling,
FXMVECTOR RotationOrigin,
FLOAT Rotation, // FLOAT类型
CXMVECTOR Translation);

对于常量XMVECTOR实例,我们应该使用XMVECTORF32类型存储浮点型向量。这儿有一些例子:

 static const XMVECTORF32 g_vZero = { 0.0f, 0.0f, 0.0f, 0.0f };

 XMVECTORF32 vRightTop = {
vViewFrust.RightSlope,
vViewFrust.TopSlope,
1.0f,1.0f
};

使用XMVECTORU32存储整型向量:

 static const XMVECTORU32 vGrabY = {
0x00000000,0xFFFFFFFF,0x00000000,0x00000000
};

XNA数学库定义了一些与PI有关的常量:

 #defineXM_PI 3.141592654f
#defineXM_2PI 6.283185307f
#defineXM_1DIVPI 0.318309886f // 1/PI
#defineXM_1DIV2PI 0.159154943f // 1/2PI
#defineXM_PIDIV2 1.570796327f // PI/2
#defineXM_PIDIV4 0.785398163f // PI/4

它还定义了如下内联函数用来在角度和弧度之间进行转换:

 XMFINLINE FLOAT XMConvertToRadians(FLOAT fDegrees)
{
return fDegrees*(XM_PI/180.0f);
} XMFINLINE FLOAT XMConvertToDegrees(FLOAT fRadians)
{
return fRadians*(180.0f/XM_PI);
}

它也定义了最大最小宏:

 #define XMMin(a,b) (((a) < (b)) ? (a) : (b))
#define XMMax(a, b) (((a) > (b)) ? (a) : (b))

XNA数学库提供了下列函数来设置XMVECTOR的内容:

 XMVECTOR XMVectorZero(); // 返回0向量(0,0,0,0)
XMVECTOR XMVectorSplatOne(); // 返回向量(1, 1, 1, 1)
XMVECTOR XMVectorSet(FLOAT x, FLOAT y, FLOAT z,FLOAT w); // 返回向量(x, y, z, w)
XMVECTOR XMVectorReplicate(FLOAT s); // 返回向量(s, s, s, s)
XMVECTOR XMVectorSplatX(FXMVECTOR V);// 返回向量(vx, vx, vx,vx)
XMVECTOR XMVectorSplatY(FXMVECTOR V);// 返回向量(vy, vy, vy,vy)
XMVECTOR XMVectorSplatZ(FXMVECTOR V);// 返回向量(vz, vz, vz,vz)

一些向量计算的函数:(下面为3D的例子,2D,4D同理,只需将函数名中的3替换为2、4)

 XMVECTOR XMVector3Length(FXMVECTOR V);    // Returns || v ||
XMVECTOR XMVector3LengthSq(FXMVECTOR V); // Returns || v ||的二次方
XMVECTOR XMVector3Dot(FXMVECTOR V1, FXMVECTOR V2); // Returns v1 • v2
XMVECTOR XMVector3Cross(FXMVECTOR V1, FXMVECTOR V2); //Returns v1 × v2
XMVECTOR XMVector3Normalize(FXMVECTOR V); // Returns v/|| v ||
XMVECTOR XMVector3Orthogonal(FXMVECTOR V); // Returns a vector orthogonal to v
XMVector3AngleBetweenVectors(FXMVECTOR V1, FXMVECTOR V2); // Returns the angle between v1 and v2
VOID XMVector3ComponentsFromNormal(XMVECTOR* pParallel,XMVECTOR* pPerpendicular, FXMVECTOR V, FXMVECTORNormal); // Returns projn(v)// Returns prepn(v)
BOOL XMVector3Equal(FXMVECTOR V1, FXMVECTOR V2); // Returns v1 = v2
BOOL XMVector3NotEqual(FXMVECTOR V1, FXMVECTOR V2); // Returns v1 ≠ v2

还有一些估算方法,如果你不在乎精确度,而在乎速度,可以使用如下函数:

MFINLINE XMVECTOR XMVector3LengthEst(XMVECTOR V); // Returns estimated || v ||
MFINLINE XMVECTOR XMVector3NormalizeEst(XMVECTOR V); // Returns estimated v/|| v ||

众所周知,浮点数的操作结果是不精确的。
可以定义一个阙值来解决:

 const float Epsilon = 0.001f;
bool Equals(float lhs, float rhs)
{
return fabs(lhs - rhs) < Epsilon ? true : false;
}

在XNA数学库中有类似的函数:XMVector3NearEqual()

 // Returns
// abs(U.x – V.x) <= Epsilon.x &&
// abs(U.y – V.y) <= Epsilon.y &&
// abs(U.z – V.z) <= Epsilon.z
XMFINLINE BOOL XMVector3NearEqual(
FXMVECTOR U,
FXMVECTOR V,
FXMVECTOR Epsilon);

为了在XNA数学库中表示4x4矩阵,我们使用XMMATRIX类,它被这样定义:

 union
{
XMVECTOR r[];
struct
{
FLOAT _11, _12, _13, _14;
FLOAT _21, _22, _23, _24;
FLOAT _31, _32, _33, _34;
FLOAT _41, _42, _43, _44;
};
FLOAT m[][];
};

正如上面定义的,XMMATRIX被用4个使用SIMD的XMVECTOR实例表示。
除了使用各种各样的构造函数,XMMATRIX还可以通过XMMatrixSet函数创建:

 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,XMFLOAT3,XMFLOAT4,同样,在表示类数据成员时,我们被推荐使用XMFLOAT4x4类型存储矩阵。

XNA数学库中包括下面与矩阵有关的函数:

 XMMATRIX XMMatrixIdentitu();    // 返回单位矩阵 I
Bool XMMatrixIsIdentity(CXMMATRIX M); // 如果M为单位矩阵,返回true
XMMATRIX XMMatrixMultiply(CXMMATRIX A,CXMMATRIX B); // 返回 矩阵A,B的乘积
XMMATRIX XMMatrixTranspose(CXMMATRIX M); // 返回矩阵M的转置矩阵
XMVECTOR XMMatrixDeterminant(CXMMATRIX M); // 返回向量(det M,det M,det M,det M)
XMMATRIX XMMatrixInverse(XMVECTOR* pDeterminant,CXMMATRIX M); // 返回矩阵M的逆矩阵

XMMATRIX参数的类型应该为CXMAATRIX,这将保证XMMATRIX参数在Windows和Xbox平台上被正确传递。

XNA中的变换函数:

 XMMATRIX XMMatrixScaling(
FLOAT ScaleX,
FLOAT ScaleY,
FLOAT ScaleZ); // 缩放函数
XMMATRIX XMMatrixScalingFromVector(
FXMVECTOR Scale); // //Constructs a scaling matrix from components in vector
XMMATRIX XMMatrixRotationX(
FLOAT Angle); // 绕X轴旋转
XMMATRIX XMMatrixRotationY(
FLOAT Angle); // 绕Y轴旋转
XMMATRIX XMMatrixRotationZ(
FLOAT Angle); // 绕Z轴旋转
XMMATRIX XMMatrixRotationAxis(
FXMVECTOR Axis,
FLOAT Angle); // 绕任意轴n旋转
XMMATRIX XMMatrixTranslation(
FLOAT OffsetX,
FLOAT OffsetY,
FLOAT OffsetZ); // 平移矩阵
XMMATRIX XMMatrixTranslationFromVector(
FXMVECTOR Offset); // Constructs a translation matrix from components in a vector
XMVECTOR XMVector3Transform(
FXMVECTOR V,
CXMMATRIX M); //计算向量V和矩阵M的积
XMVECTOR XMVector3TransformCoord(
FXMVECTOR V,
CXMMATRIX M); //Computes the vector-matrix product vM where vw = 1 for transforming points
XMVECTOR XMVector3TransformNormal(
FXMVECTOR V,
CXMMATRIX M); //Computes the vector-matrix product vM where vw = 0 for transforming vectors

注意:最后两个函数XMVector3TransformCoord()和XMVector3TransformNormal(),你不需要明确地指定vw=1 或者 vw =0,因为函数会自动完成。

XNA数学库的更多相关文章

  1. DX11 Without DirectX SDK--06 DirectXMath数学库

    回到 DirectX11--使用Windows SDK来进行开发 xnamath.h原本是位于DirectX SDK的一个数学库,但是现在Windows SDK包含的数学库已经抛弃掉原来的xnamat ...

  2. DirectX11 With Windows SDK--06 DirectXMath数学库

    前言 xnamath.h原本是位于DirectX SDK的一个数学库,但是现在Windows SDK包含的数学库已经抛弃掉原来的xnamath.h,并演变成了现在的DirectXMath.h.其实本质 ...

  3. 微软数学库XNAMATH(DirectXMath)

    这篇文章只是对着MSDN文档的一些吐槽和总结记录,个人笔记之类的 运行库与头文件 老实说,这个数学库微软还是更像蛮频繁的,我这里有的最早版本是伴随DX9的,在这个头文件里面 最近在使用DXUT,顺便也 ...

  4. 一个很cool的C#的高性能数学库

    High Performance Math Library for C# and .NET是一个很cool的C#的高性能数学库,3D效果也很不错,下图是首页上的一个例子.他也有一个交互的网页,你可以自 ...

  5. Chapter 18_0 数学库

    从今天起,开始接触Lua的标准库(数学库.table库.字符库.I/O库.操作系统库.调试库). 一路走来,从最基本的变量.函数.迭代器.协同程序到稍微复杂的元表.元方法.环境.模块,以及最后被整蒙了 ...

  6. 几个经典的数学库之一学习---VCGlib(2)

    几个经典的数学库之一学习---VCGlib(2) 1. Optional Component(可选的组件) 有许多Vertex和Face的属性并不是一直都是必要的,如Face-Face的邻接关系.VC ...

  7. <泛> C++3D数学库设计详解 向量篇

    // 注:本内容为作者原创,禁止在其他网站复述内容以及用于商业盈利,如需引用,请标明出处:http://www.cnblogs.com/lv_anchoret/ Preface 为了支持光线追踪的学习 ...

  8. lua中的数学库

    Lua5.1中数学库的所有函数如下表: 使用数学库,不需要require,直接math.function就可以math.pi 为圆周率常量 = 3.14159265358979323846 abs 取 ...

  9. Lua_第17 章 数学库

    第17 章 数学库 在这一章中(以下关于标准库的几章中相同)我的主要目的不是对每个函数给出完整地说明,而是告诉你标准库可以提供什么功能.为了可以清楚地说明问题,我可能 会忽略一些小的选项或者行为.基本 ...

随机推荐

  1. Paths中的几个重要元素

    Paths中的几个重要元素 Points void CGContextMoveToPoint (    CGContextRef c,    CGFloat x,    CGFloat y ); 指定 ...

  2. pat 乙级 1093 字符串A+B (20 分)

    给定两个字符串 A 和 B,本题要求你输出 A+B,即两个字符串的并集.要求先输出 A,再输出 B,但重复的字符必须被剔除. 输入格式: 输入在两行中分别给出 A 和 B,均为长度不超过 1的.由可见 ...

  3. Altera的几个常用的Synthesis attributes(转载)

    各厂商综合工具,对HDL综合时都定义了一些综合属性这些属性可指定a declaration,a module item,a statement, or a port connection 不同的综合方 ...

  4. BZOJ4057 [Cerc2012]Kingdoms

    题意 有一些王国陷入了一系列的经济危机.在很多年以前,他们私底下互相借了许多钱.现在,随着他们的负债被揭发,王国的崩溃不可避免地发生了--现在有n个王国,对于每对王国A和B,A欠B的钱被记为d_AB( ...

  5. @EnableAutoConfiguration注解原理

    前言 Spring Boot中引入了自动配置,让开发者利用起来更加的简便.快捷.比如内嵌的tomcat端口默认配置是8080,这些都属于Spring Boot自动配置的范畴,当然其自动配置相当多. s ...

  6. [MEF]第05篇 MEF的目录(Catalog)筛选

    一.演示概述本示例演示如何使用MEF提供的目录(Catalog)的扩展机制实现可过滤导出部件的自定义目录类.主要是通过继承ComposablePartCatalog基类,并实现接口INotifyCom ...

  7. nginx 获取请求头,URL参数

    获取url参数 在 ngx_lua 中访问 Nginx 内置变量 ngx.var.arg_PARAMETER 即可获得GET参数PARAMETER的内容. 在 nginx配置中,通过$arg_PARA ...

  8. 转发 Java火焰图在Netflix的实践

    为了分析不同软件或软件的不同版本使用CPU的情况,相关设计人员通常需要进行函数的堆栈性能分析.相比于定期采样获得数据的方式,利用定时中断来收集程序运行时的PC寄存器值.函数地址以及整个堆栈轨迹更加高效 ...

  9. 笔记:服务器压缩方案 来源于 Accept-Encoding: gzip, deflate 问题

    笔记:服务器压缩方案 来源于 Accept-Encoding: gzip, deflate 问题 事情起因:odoo demo 没有启动web 压缩 目前流行的 web 压缩技术 gzip br 支持 ...

  10. 7.Python使用pandans遇到的坑

    1.开始入门Pandas,然后跟着网上的例子,编写以下代码: import pandas as pd import datetime import pandas.io.data as web star ...