port/common: platform-independent D3DX8 math layer

D3DXVECTOR2/3/4, D3DXMATRIX, D3DXQUATERNION, D3DXPLANE, D3DXCOLOR with
d3dx8math.inl operator semantics, plus the D3DX* functions the 2V3 slice
logic uses. Covered by port.common; port_gate passes on macOS, Android,
iOS and Windows (mingw).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-22 20:02:15 +09:00
co-authored by Claude Opus 5
parent 2bae8d7644
commit 0f2eee0b24
4 changed files with 775 additions and 1 deletions
+9 -1
View File
@@ -126,7 +126,15 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
单独构建;每个 `port/**.h` 独立编译两次的门禁 `port_header_gate``port.common` 测试。编译宏取 40250 发布版
`Metin2Distribute.exe``Distribute|Win32` 配置:所有库 `NDEBUG`GameLib 加 `USE_LOD`UserInterface 加
`USE_LOD;_DISTRIBUTE`;不定义 `WIN32`
- 完成:D3DX 数学层、闭包头文件照抄(步骤 2)、platform 接口骨架(步骤 4)。
- 完成:D3DX 数学层 `port/common/D3DXMath.{h,cpp}`。内容包括:
- 基础结构 `D3DVECTOR`/`D3DCOLORVALUE`/`D3DMATRIX`
- 类型 `D3DXVECTOR2/3/4``D3DXMATRIX``D3DXQUATERNION``D3DXPLANE``D3DXCOLOR`,运算符照 `d3dx8math.inl`
(例如 `v / f` 实现为乘以 `1/f`);
- 2V3 切片用到的 `D3DXVec*``D3DXMatrix*``D3DXQuaternion*` 函数,采用行向量、左手旋转、D3DX 的乘法顺序;
后续单元用到新函数时再按需补。
这一层不包含 D3D8 渲染枚举和结构(`D3DLIGHT8``D3DRS_*` 等),它们归 platform 层。测试在 `port.common` 里。
- 未完成:闭包头文件照抄(步骤 2)、platform 接口骨架(步骤 4)。
| 平台 | port_gate |
| --- | --- |
+304
View File
@@ -0,0 +1,304 @@
#include "D3DXMath.h"
D3DXMATRIX& D3DXMATRIX::operator*=(const D3DXMATRIX& mat)
{
D3DXMatrixMultiply(this, this, &mat);
return *this;
}
D3DXMATRIX D3DXMATRIX::operator*(const D3DXMATRIX& mat) const
{
D3DXMATRIX matT;
D3DXMatrixMultiply(&matT, this, &mat);
return matT;
}
BOOL D3DXMATRIX::operator==(const D3DXMATRIX& mat) const
{
for (int i = 0; i < 16; ++i)
if ((&_11)[i] != (&mat._11)[i])
return FALSE;
return TRUE;
}
D3DXQUATERNION& D3DXQUATERNION::operator*=(const D3DXQUATERNION& q)
{
D3DXQuaternionMultiply(this, this, &q);
return *this;
}
D3DXQUATERNION D3DXQUATERNION::operator*(const D3DXQUATERNION& q) const
{
D3DXQUATERNION qT;
D3DXQuaternionMultiply(&qT, this, &q);
return qT;
}
D3DXVECTOR2* D3DXVec2Normalize(D3DXVECTOR2* pOut, const D3DXVECTOR2* pV)
{
const FLOAT norm = D3DXVec2Length(pV);
if (!norm)
{
pOut->x = 0.0f;
pOut->y = 0.0f;
}
else
{
pOut->x = pV->x / norm;
pOut->y = pV->y / norm;
}
return pOut;
}
D3DXVECTOR3* D3DXVec3Normalize(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV)
{
const FLOAT norm = D3DXVec3Length(pV);
if (!norm)
{
pOut->x = 0.0f;
pOut->y = 0.0f;
pOut->z = 0.0f;
}
else
{
pOut->x = pV->x / norm;
pOut->y = pV->y / norm;
pOut->z = pV->z / norm;
}
return pOut;
}
D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
{
D3DXVECTOR4 out;
out.x = pM->m[0][0] * pV->x + pM->m[1][0] * pV->y + pM->m[2][0] * pV->z + pM->m[3][0];
out.y = pM->m[0][1] * pV->x + pM->m[1][1] * pV->y + pM->m[2][1] * pV->z + pM->m[3][1];
out.z = pM->m[0][2] * pV->x + pM->m[1][2] * pV->y + pM->m[2][2] * pV->z + pM->m[3][2];
out.w = pM->m[0][3] * pV->x + pM->m[1][3] * pV->y + pM->m[2][3] * pV->z + pM->m[3][3];
*pOut = out;
return pOut;
}
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
{
const FLOAT norm = pM->m[0][3] * pV->x + pM->m[1][3] * pV->y + pM->m[2][3] * pV->z + pM->m[3][3];
D3DXVECTOR3 out;
out.x = (pM->m[0][0] * pV->x + pM->m[1][0] * pV->y + pM->m[2][0] * pV->z + pM->m[3][0]) / norm;
out.y = (pM->m[0][1] * pV->x + pM->m[1][1] * pV->y + pM->m[2][1] * pV->z + pM->m[3][1]) / norm;
out.z = (pM->m[0][2] * pV->x + pM->m[1][2] * pV->y + pM->m[2][2] * pV->z + pM->m[3][2]) / norm;
*pOut = out;
return pOut;
}
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM)
{
D3DXVECTOR3 out;
out.x = pM->m[0][0] * pV->x + pM->m[1][0] * pV->y + pM->m[2][0] * pV->z;
out.y = pM->m[0][1] * pV->x + pM->m[1][1] * pV->y + pM->m[2][1] * pV->z;
out.z = pM->m[0][2] * pV->x + pM->m[1][2] * pV->y + pM->m[2][2] * pV->z;
*pOut = out;
return pOut;
}
D3DXMATRIX* D3DXMatrixMultiply(D3DXMATRIX* pOut, const D3DXMATRIX* pM1, const D3DXMATRIX* pM2)
{
D3DXMATRIX out;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
out.m[i][j] = pM1->m[i][0] * pM2->m[0][j] + pM1->m[i][1] * pM2->m[1][j] +
pM1->m[i][2] * pM2->m[2][j] + pM1->m[i][3] * pM2->m[3][j];
*pOut = out;
return pOut;
}
D3DXMATRIX* D3DXMatrixTranspose(D3DXMATRIX* pOut, const D3DXMATRIX* pM)
{
D3DXMATRIX out;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
out.m[i][j] = pM->m[j][i];
*pOut = out;
return pOut;
}
D3DXMATRIX* D3DXMatrixInverse(D3DXMATRIX* pOut, FLOAT* pDeterminant, const D3DXMATRIX* pM)
{
const float* a = &pM->_11;
float inv[16];
inv[0] = a[5] * a[10] * a[15] - a[5] * a[11] * a[14] - a[9] * a[6] * a[15] + a[9] * a[7] * a[14] + a[13] * a[6] * a[11] - a[13] * a[7] * a[10];
inv[4] = -a[4] * a[10] * a[15] + a[4] * a[11] * a[14] + a[8] * a[6] * a[15] - a[8] * a[7] * a[14] - a[12] * a[6] * a[11] + a[12] * a[7] * a[10];
inv[8] = a[4] * a[9] * a[15] - a[4] * a[11] * a[13] - a[8] * a[5] * a[15] + a[8] * a[7] * a[13] + a[12] * a[5] * a[11] - a[12] * a[7] * a[9];
inv[12] = -a[4] * a[9] * a[14] + a[4] * a[10] * a[13] + a[8] * a[5] * a[14] - a[8] * a[6] * a[13] - a[12] * a[5] * a[10] + a[12] * a[6] * a[9];
inv[1] = -a[1] * a[10] * a[15] + a[1] * a[11] * a[14] + a[9] * a[2] * a[15] - a[9] * a[3] * a[14] - a[13] * a[2] * a[11] + a[13] * a[3] * a[10];
inv[5] = a[0] * a[10] * a[15] - a[0] * a[11] * a[14] - a[8] * a[2] * a[15] + a[8] * a[3] * a[14] + a[12] * a[2] * a[11] - a[12] * a[3] * a[10];
inv[9] = -a[0] * a[9] * a[15] + a[0] * a[11] * a[13] + a[8] * a[1] * a[15] - a[8] * a[3] * a[13] - a[12] * a[1] * a[11] + a[12] * a[3] * a[9];
inv[13] = a[0] * a[9] * a[14] - a[0] * a[10] * a[13] - a[8] * a[1] * a[14] + a[8] * a[2] * a[13] + a[12] * a[1] * a[10] - a[12] * a[2] * a[9];
inv[2] = a[1] * a[6] * a[15] - a[1] * a[7] * a[14] - a[5] * a[2] * a[15] + a[5] * a[3] * a[14] + a[13] * a[2] * a[7] - a[13] * a[3] * a[6];
inv[6] = -a[0] * a[6] * a[15] + a[0] * a[7] * a[14] + a[4] * a[2] * a[15] - a[4] * a[3] * a[14] - a[12] * a[2] * a[7] + a[12] * a[3] * a[6];
inv[10] = a[0] * a[5] * a[15] - a[0] * a[7] * a[13] - a[4] * a[1] * a[15] + a[4] * a[3] * a[13] + a[12] * a[1] * a[7] - a[12] * a[3] * a[5];
inv[14] = -a[0] * a[5] * a[14] + a[0] * a[6] * a[13] + a[4] * a[1] * a[14] - a[4] * a[2] * a[13] - a[12] * a[1] * a[6] + a[12] * a[2] * a[5];
inv[3] = -a[1] * a[6] * a[11] + a[1] * a[7] * a[10] + a[5] * a[2] * a[11] - a[5] * a[3] * a[10] - a[9] * a[2] * a[7] + a[9] * a[3] * a[6];
inv[7] = a[0] * a[6] * a[11] - a[0] * a[7] * a[10] - a[4] * a[2] * a[11] + a[4] * a[3] * a[10] + a[8] * a[2] * a[7] - a[8] * a[3] * a[6];
inv[11] = -a[0] * a[5] * a[11] + a[0] * a[7] * a[9] + a[4] * a[1] * a[11] - a[4] * a[3] * a[9] - a[8] * a[1] * a[7] + a[8] * a[3] * a[5];
inv[15] = a[0] * a[5] * a[10] - a[0] * a[6] * a[9] - a[4] * a[1] * a[10] + a[4] * a[2] * a[9] + a[8] * a[1] * a[6] - a[8] * a[2] * a[5];
const float det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
if (pDeterminant)
*pDeterminant = det;
if (det == 0.0f)
return nullptr;
const float invDet = 1.0f / det;
for (int i = 0; i < 16; ++i)
(&pOut->_11)[i] = inv[i] * invDet;
return pOut;
}
D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX* pOut, FLOAT sx, FLOAT sy, FLOAT sz)
{
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = sx;
pOut->m[1][1] = sy;
pOut->m[2][2] = sz;
return pOut;
}
D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX* pOut, FLOAT x, FLOAT y, FLOAT z)
{
D3DXMatrixIdentity(pOut);
pOut->m[3][0] = x;
pOut->m[3][1] = y;
pOut->m[3][2] = z;
return pOut;
}
D3DXMATRIX* D3DXMatrixRotationX(D3DXMATRIX* pOut, FLOAT angle)
{
const FLOAT s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[1][1] = c;
pOut->m[1][2] = s;
pOut->m[2][1] = -s;
pOut->m[2][2] = c;
return pOut;
}
D3DXMATRIX* D3DXMatrixRotationY(D3DXMATRIX* pOut, FLOAT angle)
{
const FLOAT s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = c;
pOut->m[0][2] = -s;
pOut->m[2][0] = s;
pOut->m[2][2] = c;
return pOut;
}
D3DXMATRIX* D3DXMatrixRotationZ(D3DXMATRIX* pOut, FLOAT angle)
{
const FLOAT s = sinf(angle), c = cosf(angle);
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = c;
pOut->m[0][1] = s;
pOut->m[1][0] = -s;
pOut->m[1][1] = c;
return pOut;
}
D3DXMATRIX* D3DXMatrixRotationAxis(D3DXMATRIX* pOut, const D3DXVECTOR3* pV, FLOAT angle)
{
D3DXVECTOR3 v;
D3DXVec3Normalize(&v, pV);
const FLOAT s = sinf(angle), c = cosf(angle), cdiff = 1.0f - c;
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = cdiff * v.x * v.x + c;
pOut->m[1][0] = cdiff * v.x * v.y - s * v.z;
pOut->m[2][0] = cdiff * v.x * v.z + s * v.y;
pOut->m[0][1] = cdiff * v.y * v.x + s * v.z;
pOut->m[1][1] = cdiff * v.y * v.y + c;
pOut->m[2][1] = cdiff * v.y * v.z - s * v.x;
pOut->m[0][2] = cdiff * v.z * v.x - s * v.y;
pOut->m[1][2] = cdiff * v.z * v.y + s * v.x;
pOut->m[2][2] = cdiff * v.z * v.z + c;
return pOut;
}
D3DXMATRIX* D3DXMatrixRotationQuaternion(D3DXMATRIX* pOut, const D3DXQUATERNION* pQ)
{
D3DXMatrixIdentity(pOut);
pOut->m[0][0] = 1.0f - 2.0f * (pQ->y * pQ->y + pQ->z * pQ->z);
pOut->m[0][1] = 2.0f * (pQ->x * pQ->y + pQ->z * pQ->w);
pOut->m[0][2] = 2.0f * (pQ->x * pQ->z - pQ->y * pQ->w);
pOut->m[1][0] = 2.0f * (pQ->x * pQ->y - pQ->z * pQ->w);
pOut->m[1][1] = 1.0f - 2.0f * (pQ->x * pQ->x + pQ->z * pQ->z);
pOut->m[1][2] = 2.0f * (pQ->y * pQ->z + pQ->x * pQ->w);
pOut->m[2][0] = 2.0f * (pQ->x * pQ->z + pQ->y * pQ->w);
pOut->m[2][1] = 2.0f * (pQ->y * pQ->z - pQ->x * pQ->w);
pOut->m[2][2] = 1.0f - 2.0f * (pQ->x * pQ->x + pQ->y * pQ->y);
return pOut;
}
// Roll about Z, then pitch about X, then yaw about Y (row vectors: M = Rz * Rx * Ry).
D3DXMATRIX* D3DXMatrixRotationYawPitchRoll(D3DXMATRIX* pOut, FLOAT yaw, FLOAT pitch, FLOAT roll)
{
D3DXMATRIX z, x, y;
D3DXMatrixRotationZ(&z, roll);
D3DXMatrixRotationX(&x, pitch);
D3DXMatrixRotationY(&y, yaw);
D3DXMatrixMultiply(pOut, &z, &x);
D3DXMatrixMultiply(pOut, pOut, &y);
return pOut;
}
// D3DX order: the result is the rotation pQ1 followed by pQ2 (the product pQ2 * pQ1).
D3DXQUATERNION* D3DXQuaternionMultiply(D3DXQUATERNION* pOut, const D3DXQUATERNION* pQ1, const D3DXQUATERNION* pQ2)
{
D3DXQUATERNION out;
out.x = pQ2->w * pQ1->x + pQ2->x * pQ1->w + pQ2->y * pQ1->z - pQ2->z * pQ1->y;
out.y = pQ2->w * pQ1->y - pQ2->x * pQ1->z + pQ2->y * pQ1->w + pQ2->z * pQ1->x;
out.z = pQ2->w * pQ1->z + pQ2->x * pQ1->y - pQ2->y * pQ1->x + pQ2->z * pQ1->w;
out.w = pQ2->w * pQ1->w - pQ2->x * pQ1->x - pQ2->y * pQ1->y - pQ2->z * pQ1->z;
*pOut = out;
return pOut;
}
D3DXQUATERNION* D3DXQuaternionNormalize(D3DXQUATERNION* pOut, const D3DXQUATERNION* pQ)
{
const FLOAT norm = sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z + pQ->w * pQ->w);
if (!norm)
{
pOut->x = pOut->y = pOut->z = pOut->w = 0.0f;
}
else
{
pOut->x = pQ->x / norm;
pOut->y = pQ->y / norm;
pOut->z = pQ->z / norm;
pOut->w = pQ->w / norm;
}
return pOut;
}
D3DXQUATERNION* D3DXQuaternionRotationAxis(D3DXQUATERNION* pOut, const D3DXVECTOR3* pV, FLOAT angle)
{
D3DXVECTOR3 v;
D3DXVec3Normalize(&v, pV);
const FLOAT s = sinf(angle / 2.0f);
pOut->x = s * v.x;
pOut->y = s * v.y;
pOut->z = s * v.z;
pOut->w = cosf(angle / 2.0f);
return pOut;
}
D3DXQUATERNION* D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION* pOut, FLOAT yaw, FLOAT pitch, FLOAT roll)
{
const FLOAT syaw = sinf(yaw / 2.0f), cyaw = cosf(yaw / 2.0f);
const FLOAT spitch = sinf(pitch / 2.0f), cpitch = cosf(pitch / 2.0f);
const FLOAT sroll = sinf(roll / 2.0f), croll = cosf(roll / 2.0f);
pOut->x = syaw * cpitch * sroll + cyaw * spitch * croll;
pOut->y = syaw * cpitch * croll - cyaw * spitch * sroll;
pOut->z = cyaw * cpitch * sroll - syaw * spitch * croll;
pOut->w = cyaw * cpitch * croll + syaw * spitch * sroll;
return pOut;
}
+413
View File
@@ -0,0 +1,413 @@
#pragma once
// Platform-independent D3DX8 math (d3dx8math.h/.inl) for ported 40250 logic: GameLib/UserInterface
// use these types as data (TPixelPosition is a D3DXVECTOR3), not only for rendering. Operators keep
// the d3dx8math.inl formulas and evaluation order (e.g. `v / f` multiplies by `1.0f / f`); the
// D3DX* functions follow the documented D3DX conventions (row vectors, left-handed rotations).
// Functions are added on demand as ported units call them.
#include "Win32Types.h"
#include <math.h>
#define D3DX_PI ((FLOAT)3.141592654f)
#define D3DX_1BYPI ((FLOAT)0.318309886f)
#define D3DXToRadian(degree) ((degree) * (D3DX_PI / 180.0f))
#define D3DXToDegree(radian) ((radian) * (180.0f / D3DX_PI))
typedef DWORD D3DCOLOR;
typedef struct _D3DVECTOR
{
float x;
float y;
float z;
} D3DVECTOR;
typedef struct _D3DCOLORVALUE
{
float r;
float g;
float b;
float a;
} D3DCOLORVALUE;
typedef struct _D3DMATRIX
{
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];
};
} D3DMATRIX;
struct D3DXVECTOR2
{
D3DXVECTOR2() {}
D3DXVECTOR2(const FLOAT* pf) : x(pf[0]), y(pf[1]) {}
D3DXVECTOR2(FLOAT fx, FLOAT fy) : x(fx), y(fy) {}
operator FLOAT*() { return &x; }
operator const FLOAT*() const { return &x; }
D3DXVECTOR2& operator+=(const D3DXVECTOR2& v) { x += v.x; y += v.y; return *this; }
D3DXVECTOR2& operator-=(const D3DXVECTOR2& v) { x -= v.x; y -= v.y; return *this; }
D3DXVECTOR2& operator*=(FLOAT f) { x *= f; y *= f; return *this; }
D3DXVECTOR2& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; x *= fInv; y *= fInv; return *this; }
D3DXVECTOR2 operator+() const { return *this; }
D3DXVECTOR2 operator-() const { return D3DXVECTOR2(-x, -y); }
D3DXVECTOR2 operator+(const D3DXVECTOR2& v) const { return D3DXVECTOR2(x + v.x, y + v.y); }
D3DXVECTOR2 operator-(const D3DXVECTOR2& v) const { return D3DXVECTOR2(x - v.x, y - v.y); }
D3DXVECTOR2 operator*(FLOAT f) const { return D3DXVECTOR2(x * f, y * f); }
D3DXVECTOR2 operator/(FLOAT f) const { FLOAT fInv = 1.0f / f; return D3DXVECTOR2(x * fInv, y * fInv); }
friend D3DXVECTOR2 operator*(FLOAT f, const D3DXVECTOR2& v) { return D3DXVECTOR2(f * v.x, f * v.y); }
BOOL operator==(const D3DXVECTOR2& v) const { return x == v.x && y == v.y; }
BOOL operator!=(const D3DXVECTOR2& v) const { return x != v.x || y != v.y; }
FLOAT x, y;
};
struct D3DXVECTOR3 : public D3DVECTOR
{
D3DXVECTOR3() {}
D3DXVECTOR3(const FLOAT* pf) { x = pf[0]; y = pf[1]; z = pf[2]; }
D3DXVECTOR3(const D3DVECTOR& v) { x = v.x; y = v.y; z = v.z; }
D3DXVECTOR3(FLOAT fx, FLOAT fy, FLOAT fz) { x = fx; y = fy; z = fz; }
operator FLOAT*() { return &x; }
operator const FLOAT*() const { return &x; }
D3DXVECTOR3& operator+=(const D3DXVECTOR3& v) { x += v.x; y += v.y; z += v.z; return *this; }
D3DXVECTOR3& operator-=(const D3DXVECTOR3& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
D3DXVECTOR3& operator*=(FLOAT f) { x *= f; y *= f; z *= f; return *this; }
D3DXVECTOR3& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; x *= fInv; y *= fInv; z *= fInv; return *this; }
D3DXVECTOR3 operator+() const { return *this; }
D3DXVECTOR3 operator-() const { return D3DXVECTOR3(-x, -y, -z); }
D3DXVECTOR3 operator+(const D3DXVECTOR3& v) const { return D3DXVECTOR3(x + v.x, y + v.y, z + v.z); }
D3DXVECTOR3 operator-(const D3DXVECTOR3& v) const { return D3DXVECTOR3(x - v.x, y - v.y, z - v.z); }
D3DXVECTOR3 operator*(FLOAT f) const { return D3DXVECTOR3(x * f, y * f, z * f); }
D3DXVECTOR3 operator/(FLOAT f) const { FLOAT fInv = 1.0f / f; return D3DXVECTOR3(x * fInv, y * fInv, z * fInv); }
friend D3DXVECTOR3 operator*(FLOAT f, const D3DXVECTOR3& v) { return D3DXVECTOR3(f * v.x, f * v.y, f * v.z); }
BOOL operator==(const D3DXVECTOR3& v) const { return x == v.x && y == v.y && z == v.z; }
BOOL operator!=(const D3DXVECTOR3& v) const { return x != v.x || y != v.y || z != v.z; }
};
struct D3DXVECTOR4
{
D3DXVECTOR4() {}
D3DXVECTOR4(const FLOAT* pf) : x(pf[0]), y(pf[1]), z(pf[2]), w(pf[3]) {}
D3DXVECTOR4(FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw) : x(fx), y(fy), z(fz), w(fw) {}
operator FLOAT*() { return &x; }
operator const FLOAT*() const { return &x; }
D3DXVECTOR4& operator+=(const D3DXVECTOR4& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
D3DXVECTOR4& operator-=(const D3DXVECTOR4& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
D3DXVECTOR4& operator*=(FLOAT f) { x *= f; y *= f; z *= f; w *= f; return *this; }
D3DXVECTOR4& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; x *= fInv; y *= fInv; z *= fInv; w *= fInv; return *this; }
D3DXVECTOR4 operator+() const { return *this; }
D3DXVECTOR4 operator-() const { return D3DXVECTOR4(-x, -y, -z, -w); }
D3DXVECTOR4 operator+(const D3DXVECTOR4& v) const { return D3DXVECTOR4(x + v.x, y + v.y, z + v.z, w + v.w); }
D3DXVECTOR4 operator-(const D3DXVECTOR4& v) const { return D3DXVECTOR4(x - v.x, y - v.y, z - v.z, w - v.w); }
D3DXVECTOR4 operator*(FLOAT f) const { return D3DXVECTOR4(x * f, y * f, z * f, w * f); }
D3DXVECTOR4 operator/(FLOAT f) const { FLOAT fInv = 1.0f / f; return D3DXVECTOR4(x * fInv, y * fInv, z * fInv, w * fInv); }
friend D3DXVECTOR4 operator*(FLOAT f, const D3DXVECTOR4& v) { return D3DXVECTOR4(f * v.x, f * v.y, f * v.z, f * v.w); }
BOOL operator==(const D3DXVECTOR4& v) const { return x == v.x && y == v.y && z == v.z && w == v.w; }
BOOL operator!=(const D3DXVECTOR4& v) const { return x != v.x || y != v.y || z != v.z || w != v.w; }
FLOAT x, y, z, w;
};
struct D3DXMATRIX : public D3DMATRIX
{
D3DXMATRIX() {}
D3DXMATRIX(const FLOAT* pf) { for (int i = 0; i < 16; ++i) (&_11)[i] = pf[i]; }
D3DXMATRIX(const D3DMATRIX& mat) : D3DMATRIX(mat) {}
D3DXMATRIX(FLOAT f11, FLOAT f12, FLOAT f13, FLOAT f14,
FLOAT f21, FLOAT f22, FLOAT f23, FLOAT f24,
FLOAT f31, FLOAT f32, FLOAT f33, FLOAT f34,
FLOAT f41, FLOAT f42, FLOAT f43, FLOAT f44)
{
_11 = f11; _12 = f12; _13 = f13; _14 = f14;
_21 = f21; _22 = f22; _23 = f23; _24 = f24;
_31 = f31; _32 = f32; _33 = f33; _34 = f34;
_41 = f41; _42 = f42; _43 = f43; _44 = f44;
}
FLOAT& operator()(UINT iRow, UINT iCol) { return m[iRow][iCol]; }
FLOAT operator()(UINT iRow, UINT iCol) const { return m[iRow][iCol]; }
operator FLOAT*() { return &_11; }
operator const FLOAT*() const { return &_11; }
D3DXMATRIX& operator*=(const D3DXMATRIX& mat);
D3DXMATRIX& operator+=(const D3DXMATRIX& mat) { for (int i = 0; i < 16; ++i) (&_11)[i] += (&mat._11)[i]; return *this; }
D3DXMATRIX& operator-=(const D3DXMATRIX& mat) { for (int i = 0; i < 16; ++i) (&_11)[i] -= (&mat._11)[i]; return *this; }
D3DXMATRIX& operator*=(FLOAT f) { for (int i = 0; i < 16; ++i) (&_11)[i] *= f; return *this; }
D3DXMATRIX& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; for (int i = 0; i < 16; ++i) (&_11)[i] *= fInv; return *this; }
D3DXMATRIX operator+() const { return *this; }
D3DXMATRIX operator-() const { D3DXMATRIX r; for (int i = 0; i < 16; ++i) (&r._11)[i] = -(&_11)[i]; return r; }
D3DXMATRIX operator*(const D3DXMATRIX& mat) const;
D3DXMATRIX operator+(const D3DXMATRIX& mat) const { D3DXMATRIX r(*this); return r += mat; }
D3DXMATRIX operator-(const D3DXMATRIX& mat) const { D3DXMATRIX r(*this); return r -= mat; }
D3DXMATRIX operator*(FLOAT f) const { D3DXMATRIX r(*this); return r *= f; }
D3DXMATRIX operator/(FLOAT f) const { D3DXMATRIX r(*this); return r /= f; }
friend D3DXMATRIX operator*(FLOAT f, const D3DXMATRIX& mat) { D3DXMATRIX r(mat); return r *= f; }
BOOL operator==(const D3DXMATRIX& mat) const;
BOOL operator!=(const D3DXMATRIX& mat) const { return !(*this == mat); }
};
struct D3DXQUATERNION
{
D3DXQUATERNION() {}
D3DXQUATERNION(const FLOAT* pf) : x(pf[0]), y(pf[1]), z(pf[2]), w(pf[3]) {}
D3DXQUATERNION(FLOAT fx, FLOAT fy, FLOAT fz, FLOAT fw) : x(fx), y(fy), z(fz), w(fw) {}
operator FLOAT*() { return &x; }
operator const FLOAT*() const { return &x; }
D3DXQUATERNION& operator+=(const D3DXQUATERNION& q) { x += q.x; y += q.y; z += q.z; w += q.w; return *this; }
D3DXQUATERNION& operator-=(const D3DXQUATERNION& q) { x -= q.x; y -= q.y; z -= q.z; w -= q.w; return *this; }
D3DXQUATERNION& operator*=(const D3DXQUATERNION& q);
D3DXQUATERNION& operator*=(FLOAT f) { x *= f; y *= f; z *= f; w *= f; return *this; }
D3DXQUATERNION& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; x *= fInv; y *= fInv; z *= fInv; w *= fInv; return *this; }
D3DXQUATERNION operator+() const { return *this; }
D3DXQUATERNION operator-() const { return D3DXQUATERNION(-x, -y, -z, -w); }
D3DXQUATERNION operator+(const D3DXQUATERNION& q) const { return D3DXQUATERNION(x + q.x, y + q.y, z + q.z, w + q.w); }
D3DXQUATERNION operator-(const D3DXQUATERNION& q) const { return D3DXQUATERNION(x - q.x, y - q.y, z - q.z, w - q.w); }
D3DXQUATERNION operator*(const D3DXQUATERNION& q) const;
D3DXQUATERNION operator*(FLOAT f) const { return D3DXQUATERNION(x * f, y * f, z * f, w * f); }
D3DXQUATERNION operator/(FLOAT f) const { FLOAT fInv = 1.0f / f; return D3DXQUATERNION(x * fInv, y * fInv, z * fInv, w * fInv); }
friend D3DXQUATERNION operator*(FLOAT f, const D3DXQUATERNION& q) { return D3DXQUATERNION(f * q.x, f * q.y, f * q.z, f * q.w); }
BOOL operator==(const D3DXQUATERNION& q) const { return x == q.x && y == q.y && z == q.z && w == q.w; }
BOOL operator!=(const D3DXQUATERNION& q) const { return x != q.x || y != q.y || z != q.z || w != q.w; }
FLOAT x, y, z, w;
};
struct D3DXPLANE
{
D3DXPLANE() {}
D3DXPLANE(const FLOAT* pf) : a(pf[0]), b(pf[1]), c(pf[2]), d(pf[3]) {}
D3DXPLANE(FLOAT fa, FLOAT fb, FLOAT fc, FLOAT fd) : a(fa), b(fb), c(fc), d(fd) {}
operator FLOAT*() { return &a; }
operator const FLOAT*() const { return &a; }
D3DXPLANE operator+() const { return *this; }
D3DXPLANE operator-() const { return D3DXPLANE(-a, -b, -c, -d); }
BOOL operator==(const D3DXPLANE& p) const { return a == p.a && b == p.b && c == p.c && d == p.d; }
BOOL operator!=(const D3DXPLANE& p) const { return a != p.a || b != p.b || c != p.c || d != p.d; }
FLOAT a, b, c, d;
};
struct D3DXCOLOR
{
D3DXCOLOR() {}
D3DXCOLOR(DWORD argb)
{
const FLOAT f = 1.0f / 255.0f;
r = f * (FLOAT)(unsigned char)(argb >> 16);
g = f * (FLOAT)(unsigned char)(argb >> 8);
b = f * (FLOAT)(unsigned char)(argb >> 0);
a = f * (FLOAT)(unsigned char)(argb >> 24);
}
D3DXCOLOR(const FLOAT* pf) : r(pf[0]), g(pf[1]), b(pf[2]), a(pf[3]) {}
D3DXCOLOR(const D3DCOLORVALUE& c) : r(c.r), g(c.g), b(c.b), a(c.a) {}
D3DXCOLOR(FLOAT fr, FLOAT fg, FLOAT fb, FLOAT fa) : r(fr), g(fg), b(fb), a(fa) {}
operator DWORD() const
{
DWORD dwR = r >= 1.0f ? 0xff : r <= 0.0f ? 0x00 : (DWORD)(r * 255.0f + 0.5f);
DWORD dwG = g >= 1.0f ? 0xff : g <= 0.0f ? 0x00 : (DWORD)(g * 255.0f + 0.5f);
DWORD dwB = b >= 1.0f ? 0xff : b <= 0.0f ? 0x00 : (DWORD)(b * 255.0f + 0.5f);
DWORD dwA = a >= 1.0f ? 0xff : a <= 0.0f ? 0x00 : (DWORD)(a * 255.0f + 0.5f);
return (dwA << 24) | (dwR << 16) | (dwG << 8) | dwB;
}
operator FLOAT*() { return &r; }
operator const FLOAT*() const { return &r; }
operator D3DCOLORVALUE*() { return (D3DCOLORVALUE*)&r; }
operator const D3DCOLORVALUE*() const { return (const D3DCOLORVALUE*)&r; }
operator D3DCOLORVALUE&() { return *((D3DCOLORVALUE*)&r); }
operator const D3DCOLORVALUE&() const { return *((const D3DCOLORVALUE*)&r); }
D3DXCOLOR& operator+=(const D3DXCOLOR& c) { r += c.r; g += c.g; b += c.b; a += c.a; return *this; }
D3DXCOLOR& operator-=(const D3DXCOLOR& c) { r -= c.r; g -= c.g; b -= c.b; a -= c.a; return *this; }
D3DXCOLOR& operator*=(FLOAT f) { r *= f; g *= f; b *= f; a *= f; return *this; }
D3DXCOLOR& operator/=(FLOAT f) { FLOAT fInv = 1.0f / f; r *= fInv; g *= fInv; b *= fInv; a *= fInv; return *this; }
D3DXCOLOR operator+() const { return *this; }
D3DXCOLOR operator-() const { return D3DXCOLOR(-r, -g, -b, -a); }
D3DXCOLOR operator+(const D3DXCOLOR& c) const { return D3DXCOLOR(r + c.r, g + c.g, b + c.b, a + c.a); }
D3DXCOLOR operator-(const D3DXCOLOR& c) const { return D3DXCOLOR(r - c.r, g - c.g, b - c.b, a - c.a); }
D3DXCOLOR operator*(FLOAT f) const { return D3DXCOLOR(r * f, g * f, b * f, a * f); }
D3DXCOLOR operator/(FLOAT f) const { FLOAT fInv = 1.0f / f; return D3DXCOLOR(r * fInv, g * fInv, b * fInv, a * fInv); }
friend D3DXCOLOR operator*(FLOAT f, const D3DXCOLOR& c) { return D3DXCOLOR(f * c.r, f * c.g, f * c.b, f * c.a); }
BOOL operator==(const D3DXCOLOR& c) const { return r == c.r && g == c.g && b == c.b && a == c.a; }
BOOL operator!=(const D3DXCOLOR& c) const { return r != c.r || g != c.g || b != c.b || a != c.a; }
FLOAT r, g, b, a;
};
static_assert(sizeof(D3DXVECTOR2) == 8 && sizeof(D3DXVECTOR3) == 12 && sizeof(D3DXVECTOR4) == 16, "D3DX vector layout");
static_assert(sizeof(D3DXMATRIX) == 64 && sizeof(D3DXQUATERNION) == 16 && sizeof(D3DXCOLOR) == 16, "D3DX layout");
static_assert(sizeof(D3DXPLANE) == 16 && sizeof(D3DCOLORVALUE) == 16, "D3DX layout");
// --- D3DXVECTOR2 ---
inline FLOAT D3DXVec2Length(const D3DXVECTOR2* pV) { return sqrtf(pV->x * pV->x + pV->y * pV->y); }
inline FLOAT D3DXVec2LengthSq(const D3DXVECTOR2* pV) { return pV->x * pV->x + pV->y * pV->y; }
inline FLOAT D3DXVec2Dot(const D3DXVECTOR2* pV1, const D3DXVECTOR2* pV2) { return pV1->x * pV2->x + pV1->y * pV2->y; }
inline D3DXVECTOR2* D3DXVec2Add(D3DXVECTOR2* pOut, const D3DXVECTOR2* pV1, const D3DXVECTOR2* pV2)
{
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
return pOut;
}
inline D3DXVECTOR2* D3DXVec2Subtract(D3DXVECTOR2* pOut, const D3DXVECTOR2* pV1, const D3DXVECTOR2* pV2)
{
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
return pOut;
}
inline D3DXVECTOR2* D3DXVec2Scale(D3DXVECTOR2* pOut, const D3DXVECTOR2* pV, FLOAT s)
{
pOut->x = pV->x * s;
pOut->y = pV->y * s;
return pOut;
}
D3DXVECTOR2* D3DXVec2Normalize(D3DXVECTOR2* pOut, const D3DXVECTOR2* pV);
// --- D3DXVECTOR3 ---
inline FLOAT D3DXVec3Length(const D3DXVECTOR3* pV) { return sqrtf(pV->x * pV->x + pV->y * pV->y + pV->z * pV->z); }
inline FLOAT D3DXVec3LengthSq(const D3DXVECTOR3* pV) { return pV->x * pV->x + pV->y * pV->y + pV->z * pV->z; }
inline FLOAT D3DXVec3Dot(const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z;
}
inline D3DXVECTOR3* D3DXVec3Cross(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
D3DXVECTOR3 v;
v.x = pV1->y * pV2->z - pV1->z * pV2->y;
v.y = pV1->z * pV2->x - pV1->x * pV2->z;
v.z = pV1->x * pV2->y - pV1->y * pV2->x;
*pOut = v;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Add(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
pOut->x = pV1->x + pV2->x;
pOut->y = pV1->y + pV2->y;
pOut->z = pV1->z + pV2->z;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Subtract(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
pOut->x = pV1->x - pV2->x;
pOut->y = pV1->y - pV2->y;
pOut->z = pV1->z - pV2->z;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Minimize(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
pOut->x = pV1->x < pV2->x ? pV1->x : pV2->x;
pOut->y = pV1->y < pV2->y ? pV1->y : pV2->y;
pOut->z = pV1->z < pV2->z ? pV1->z : pV2->z;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Maximize(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2)
{
pOut->x = pV1->x > pV2->x ? pV1->x : pV2->x;
pOut->y = pV1->y > pV2->y ? pV1->y : pV2->y;
pOut->z = pV1->z > pV2->z ? pV1->z : pV2->z;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Scale(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, FLOAT s)
{
pOut->x = pV->x * s;
pOut->y = pV->y * s;
pOut->z = pV->z * s;
return pOut;
}
inline D3DXVECTOR3* D3DXVec3Lerp(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV1, const D3DXVECTOR3* pV2, FLOAT s)
{
pOut->x = pV1->x + s * (pV2->x - pV1->x);
pOut->y = pV1->y + s * (pV2->y - pV1->y);
pOut->z = pV1->z + s * (pV2->z - pV1->z);
return pOut;
}
D3DXVECTOR3* D3DXVec3Normalize(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV);
D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, const D3DXVECTOR3* pV, const D3DXMATRIX* pM);
// --- D3DXMATRIX ---
inline D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX* pOut)
{
pOut->m[0][1] = pOut->m[0][2] = pOut->m[0][3] =
pOut->m[1][0] = pOut->m[1][2] = pOut->m[1][3] =
pOut->m[2][0] = pOut->m[2][1] = pOut->m[2][3] =
pOut->m[3][0] = pOut->m[3][1] = pOut->m[3][2] = 0.0f;
pOut->m[0][0] = pOut->m[1][1] = pOut->m[2][2] = pOut->m[3][3] = 1.0f;
return pOut;
}
inline BOOL D3DXMatrixIsIdentity(const D3DXMATRIX* pM)
{
return pM->m[0][0] == 1.0f && pM->m[0][1] == 0.0f && pM->m[0][2] == 0.0f && pM->m[0][3] == 0.0f &&
pM->m[1][0] == 0.0f && pM->m[1][1] == 1.0f && pM->m[1][2] == 0.0f && pM->m[1][3] == 0.0f &&
pM->m[2][0] == 0.0f && pM->m[2][1] == 0.0f && pM->m[2][2] == 1.0f && pM->m[2][3] == 0.0f &&
pM->m[3][0] == 0.0f && pM->m[3][1] == 0.0f && pM->m[3][2] == 0.0f && pM->m[3][3] == 1.0f;
}
D3DXMATRIX* D3DXMatrixMultiply(D3DXMATRIX* pOut, const D3DXMATRIX* pM1, const D3DXMATRIX* pM2);
D3DXMATRIX* D3DXMatrixTranspose(D3DXMATRIX* pOut, const D3DXMATRIX* pM);
D3DXMATRIX* D3DXMatrixInverse(D3DXMATRIX* pOut, FLOAT* pDeterminant, const D3DXMATRIX* pM);
D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX* pOut, FLOAT sx, FLOAT sy, FLOAT sz);
D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX* pOut, FLOAT x, FLOAT y, FLOAT z);
D3DXMATRIX* D3DXMatrixRotationX(D3DXMATRIX* pOut, FLOAT angle);
D3DXMATRIX* D3DXMatrixRotationY(D3DXMATRIX* pOut, FLOAT angle);
D3DXMATRIX* D3DXMatrixRotationZ(D3DXMATRIX* pOut, FLOAT angle);
D3DXMATRIX* D3DXMatrixRotationAxis(D3DXMATRIX* pOut, const D3DXVECTOR3* pV, FLOAT angle);
D3DXMATRIX* D3DXMatrixRotationQuaternion(D3DXMATRIX* pOut, const D3DXQUATERNION* pQ);
D3DXMATRIX* D3DXMatrixRotationYawPitchRoll(D3DXMATRIX* pOut, FLOAT yaw, FLOAT pitch, FLOAT roll);
// --- D3DXQUATERNION ---
inline D3DXQUATERNION* D3DXQuaternionIdentity(D3DXQUATERNION* pOut)
{
pOut->x = pOut->y = pOut->z = 0.0f;
pOut->w = 1.0f;
return pOut;
}
D3DXQUATERNION* D3DXQuaternionMultiply(D3DXQUATERNION* pOut, const D3DXQUATERNION* pQ1, const D3DXQUATERNION* pQ2);
D3DXQUATERNION* D3DXQuaternionNormalize(D3DXQUATERNION* pOut, const D3DXQUATERNION* pQ);
D3DXQUATERNION* D3DXQuaternionRotationAxis(D3DXQUATERNION* pOut, const D3DXVECTOR3* pV, FLOAT angle);
D3DXQUATERNION* D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION* pOut, FLOAT yaw, FLOAT pitch, FLOAT roll);
// --- D3DXPLANE ---
inline FLOAT D3DXPlaneDotCoord(const D3DXPLANE* pP, const D3DXVECTOR3* pV)
{
return pP->a * pV->x + pP->b * pV->y + pP->c * pV->z + pP->d;
}
+49
View File
@@ -1,6 +1,8 @@
// port/common: Win32 widths and MSVC CRT semantics the ported 40250 logic relies on.
#include "common/StdAfx.h"
#include "common/D3DXMath.h"
#include <cmath>
#include <cstdio>
#include <cstdlib>
@@ -48,6 +50,53 @@ int main()
const DWORD b = timeGetTime();
CHECK(static_cast<DWORD>(b - a) < 1000);
// D3DX8 math: row vectors, left-handed rotations, D3DX multiply order.
const auto near = [](float x, float y) { return std::fabs(x - y) < 1e-5f; };
D3DXVECTOR3 v(3.0f, 0.0f, 4.0f);
CHECK(D3DXVec3Length(&v) == 5.0f && D3DXVec3LengthSq(&v) == 25.0f);
D3DXVECTOR3 n;
D3DXVec3Normalize(&n, &v);
CHECK(near(n.x, 0.6f) && n.y == 0.0f && near(n.z, 0.8f));
D3DXVECTOR3 zero(0.0f, 0.0f, 0.0f);
D3DXVec3Normalize(&n, &zero);
CHECK(n == zero);
CHECK((v / 2.0f) == D3DXVECTOR3(1.5f, 0.0f, 2.0f) && (2.0f * v) == D3DXVECTOR3(6.0f, 0.0f, 8.0f));
CHECK(near(D3DXToRadian(180.0f), D3DX_PI) && near(D3DXToDegree(D3DX_PI / 2.0f), 90.0f));
D3DXMATRIX rz, tr, m;
D3DXMatrixRotationZ(&rz, D3DX_PI / 2.0f); // x axis -> +y
D3DXVECTOR3 p(1.0f, 0.0f, 0.0f), q;
D3DXVec3TransformCoord(&q, &p, &rz);
CHECK(near(q.x, 0.0f) && near(q.y, 1.0f) && near(q.z, 0.0f));
D3DXMatrixTranslation(&tr, 10.0f, 20.0f, 30.0f);
m = rz * tr; // rotate, then translate
D3DXVec3TransformCoord(&q, &p, &m);
CHECK(near(q.x, 10.0f) && near(q.y, 21.0f) && near(q.z, 30.0f));
D3DXMATRIX inv, id;
CHECK(D3DXMatrixInverse(&inv, nullptr, &m) != nullptr);
D3DXMatrixMultiply(&id, &m, &inv);
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
CHECK(near(id.m[i][j], i == j ? 1.0f : 0.0f));
D3DXQUATERNION qz;
D3DXVECTOR3 zAxis(0.0f, 0.0f, 1.0f);
D3DXQuaternionRotationAxis(&qz, &zAxis, D3DX_PI / 2.0f);
D3DXMATRIX mq;
D3DXMatrixRotationQuaternion(&mq, &qz);
for (int i = 0; i < 16; ++i)
CHECK(near((&mq._11)[i], (&rz._11)[i]));
D3DXMATRIX ypr, ypr2;
D3DXQUATERNION qypr;
D3DXMatrixRotationYawPitchRoll(&ypr, 0.3f, 0.5f, 0.7f);
D3DXQuaternionRotationYawPitchRoll(&qypr, 0.3f, 0.5f, 0.7f);
D3DXMatrixRotationQuaternion(&ypr2, &qypr);
for (int i = 0; i < 16; ++i)
CHECK(near((&ypr._11)[i], (&ypr2._11)[i]));
CHECK(static_cast<DWORD>(D3DXCOLOR(0xFF804020u)) == 0xFF804020u);
CHECK(static_cast<DWORD>(D3DXCOLOR(2.0f, -1.0f, 0.5f, 1.0f)) == 0xFFFF0080u);
if (g_failures)
return EXIT_FAILURE;
std::puts("port_common_test: ok");