2665 lines
63 KiB
C++
2665 lines
63 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// File: d3dxmath.cpp
|
|
// Content:
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pchmath.h"
|
|
#define EPSILON 0.00001f
|
|
|
|
|
|
|
|
//
|
|
// WithinEpsilon - Are two values within EPSILON of each other?
|
|
//
|
|
|
|
static inline BOOL
|
|
WithinEpsilon(float a, float b)
|
|
{
|
|
float f = a - b;
|
|
return -EPSILON <= f && f <= EPSILON;
|
|
}
|
|
|
|
|
|
//
|
|
// sincosf - Compute the sin and cos of an angle at the same time
|
|
//
|
|
|
|
static inline void
|
|
sincosf(float angle, float *psin, float *pcos)
|
|
{
|
|
#ifdef _X86_
|
|
#define fsincos __asm _emit 0xd9 __asm _emit 0xfb
|
|
__asm {
|
|
mov eax, psin
|
|
mov edx, pcos
|
|
fld angle
|
|
fsincos
|
|
fstp DWORD ptr [edx]
|
|
fstp DWORD ptr [eax]
|
|
}
|
|
#undef fsincos
|
|
#else //!_X86_
|
|
*psin = sinf(angle);
|
|
*pcos = cosf(angle);
|
|
#endif //!_X86_
|
|
}
|
|
|
|
|
|
//--------------------------
|
|
// 2D Vector
|
|
//--------------------------
|
|
|
|
D3DXVECTOR2* WINAPI VB_D3DXVec2Normalize
|
|
( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = VB_D3DXVec2LengthSq(pV);
|
|
|
|
if(WithinEpsilon(f, 1.0f))
|
|
{
|
|
if(pOut != pV)
|
|
*pOut = *pV;
|
|
}
|
|
else if(f > EPSILON * EPSILON)
|
|
{
|
|
*pOut = *pV / sqrtf(f);
|
|
}
|
|
else
|
|
{
|
|
pOut->x = 0.0f;
|
|
pOut->y = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR2* WINAPI VB_D3DXVec2Hermite
|
|
( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV1, const D3DXVECTOR2 *pT1,
|
|
const D3DXVECTOR2 *pV2, const D3DXVECTOR2 *pT2, float s )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s2 = s * s;
|
|
float s3 = s * s2;
|
|
|
|
float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
|
|
float sT1 = s3 - 2.0f * s2 + s;
|
|
float sV2 = -2.0f * s3 + 3.0f * s2;
|
|
float sT2 = s3 - s2;
|
|
|
|
pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
|
|
pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR2* WINAPI VB_D3DXVec2BaryCentric
|
|
( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV1, const D3DXVECTOR2 *pV2,
|
|
D3DXVECTOR2 *pV3, float f, float g)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pV2 || !pV3)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
|
|
pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec2Transform
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+2)*4] ; M02
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+3)*4] ; M03
|
|
fxch st(3)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+2)*4] ; M12
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+3)*4] ; M13
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [edx+(3*4+0)*4] ; M30
|
|
faddp st(1), st
|
|
fld DWORD PTR [edx+(3*4+1)*4] ; M31
|
|
faddp st(2), st
|
|
fld DWORD PTR [edx+(3*4+2)*4] ; M32
|
|
faddp st(3), st
|
|
fld DWORD PTR [edx+(3*4+3)*4] ; M33
|
|
faddp st(4), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
fstp DWORD PTR [ecx+3*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR4 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pM->m30;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pM->m31;
|
|
v.z = pV->x * pM->m02 + pV->y * pM->m12 + pM->m32;
|
|
v.w = pV->x * pM->m03 + pV->y * pM->m13 + pM->m33;
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
D3DXVECTOR2* WINAPI VB_D3DXVec2TransformCoord
|
|
( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
float w;
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+3)*4] ; M03
|
|
fxch st(2)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+3)*4] ; M13
|
|
fxch st(2)
|
|
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+0)*4] ; M20
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+1)*4] ; M21
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+3)*4] ; M23
|
|
fxch st(2)
|
|
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
|
|
fld DWORD PTR [edx+(3*4+0)*4] ; M30
|
|
faddp st(1), st
|
|
fld DWORD PTR [edx+(3*4+1)*4] ; M31
|
|
faddp st(2), st
|
|
fld DWORD PTR [edx+(3*4+3)*4] ; M33
|
|
faddp st(3), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [w]
|
|
}
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR4 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pM->m30;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pM->m31;
|
|
w = pV->x * pM->m03 + pV->y * pM->m13 + pM->m33;
|
|
|
|
*pOut = *((D3DXVECTOR2 *) &v);
|
|
#endif // !_X86_
|
|
|
|
if(!WithinEpsilon(w, 1.0f))
|
|
*pOut /= w;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR2* WINAPI VB_D3DXVec2TransformNormal
|
|
( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fxch st(1)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fxch st(1)
|
|
|
|
faddp st(2), st
|
|
faddp st(2), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR2 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11;
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
|
|
//--------------------------
|
|
// 3D Vector
|
|
//--------------------------
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXVec3Normalize
|
|
( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = VB_D3DXVec3LengthSq(pV);
|
|
|
|
if(WithinEpsilon(f, 1.0f))
|
|
{
|
|
if(pOut != pV)
|
|
*pOut = *pV;
|
|
}
|
|
else if(f > EPSILON * EPSILON)
|
|
{
|
|
*pOut = *pV / sqrtf(f);
|
|
}
|
|
else
|
|
{
|
|
pOut->x = 0.0f;
|
|
pOut->y = 0.0f;
|
|
pOut->z = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXVec3Hermite
|
|
( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pT1,
|
|
const D3DXVECTOR3 *pV2, const D3DXVECTOR3 *pT2, float s )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s2 = s * s;
|
|
float s3 = s * s2;
|
|
|
|
float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
|
|
float sT1 = s3 - 2.0f * s2 + s;
|
|
float sV2 = -2.0f * s3 + 3.0f * s2;
|
|
float sT2 = s3 - s2;
|
|
|
|
pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
|
|
pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
|
|
pOut->z = sV1 * pV1->z + sT1 * pT1->z + sV2 * pV2->z + sT2 * pT2->z;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXVec3BaryCentric
|
|
( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pV2,
|
|
const D3DXVECTOR3 *pV3, float f, float g)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pV2 || !pV3)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
|
|
pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
|
|
pOut->z = pV1->z + f * (pV2->z - pV1->z) + g * (pV3->z - pV1->z);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec3Transform
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+2)*4] ; M02
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+3)*4] ; M03
|
|
fxch st(3)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+2)*4] ; M12
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+3)*4] ; M13
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+0)*4] ; M20
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+2)*4] ; M22
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+1)*4] ; M21
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+3)*4] ; M23
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [edx+(3*4+0)*4] ; M30
|
|
faddp st(1), st
|
|
fld DWORD PTR [edx+(3*4+1)*4] ; M31
|
|
faddp st(2), st
|
|
fld DWORD PTR [edx+(3*4+2)*4] ; M32
|
|
faddp st(3), st
|
|
fld DWORD PTR [edx+(3*4+3)*4] ; M33
|
|
faddp st(4), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
fstp DWORD PTR [ecx+3*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR4 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pM->m30;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pM->m31;
|
|
v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pM->m32;
|
|
v.w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pM->m33;
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXVec3TransformCoord
|
|
( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
float w;
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+2)*4] ; M02
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+3)*4] ; M03
|
|
fxch st(3)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+2)*4] ; M12
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+3)*4] ; M13
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+0)*4] ; M20
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+2)*4] ; M22
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+1)*4] ; M21
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+3)*4] ; M23
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [edx+(3*4+0)*4] ; M30
|
|
faddp st(1), st
|
|
fld DWORD PTR [edx+(3*4+1)*4] ; M31
|
|
faddp st(2), st
|
|
fld DWORD PTR [edx+(3*4+2)*4] ; M32
|
|
faddp st(3), st
|
|
fld DWORD PTR [edx+(3*4+3)*4] ; M33
|
|
faddp st(4), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
fstp DWORD PTR [w]
|
|
}
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR3 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pM->m30;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pM->m31;
|
|
v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pM->m32;
|
|
w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pM->m33;
|
|
|
|
*pOut = v;
|
|
#endif // !_X86_
|
|
|
|
if(!WithinEpsilon(w, 1.0f))
|
|
*pOut /= w;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXVec3TransformNormal
|
|
( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+2)*4] ; M02
|
|
fxch st(2)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+2)*4] ; M12
|
|
fxch st(2)
|
|
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+0)*4] ; M20
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+1)*4] ; M21
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+2)*4] ; M22
|
|
fxch st(2)
|
|
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
faddp st(3), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR3 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21;
|
|
v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22;
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
|
|
|
|
//--------------------------
|
|
// 4D Vector
|
|
//--------------------------
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec4Cross
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pV2,
|
|
const D3DXVECTOR4 *pV3)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pV2 || !pV3)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXVECTOR4 v;
|
|
|
|
v.x = pV1->y * (pV2->z * pV3->w - pV3->z * pV2->w) -
|
|
pV1->z * (pV2->y * pV3->w - pV3->y * pV2->w) +
|
|
pV1->w * (pV2->y * pV3->z - pV3->y * pV2->z);
|
|
|
|
v.y = pV1->x * (pV3->z * pV2->w - pV2->z * pV3->w) -
|
|
pV1->z * (pV3->x * pV2->w - pV2->x * pV3->w) +
|
|
pV1->w * (pV3->x * pV2->z - pV2->x * pV3->z);
|
|
|
|
v.z = pV1->x * (pV2->y * pV3->w - pV3->y * pV2->w) -
|
|
pV1->y * (pV2->x * pV3->w - pV3->x * pV2->w) +
|
|
pV1->w * (pV2->x * pV3->y - pV3->x * pV2->y);
|
|
|
|
v.w = pV1->x * (pV3->y * pV2->z - pV2->y * pV3->z) -
|
|
pV1->y * (pV3->x * pV2->z - pV2->x * pV3->z) +
|
|
pV1->z * (pV3->x * pV2->y - pV2->x * pV3->y);
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec4Normalize
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = D3DXVec4LengthSq(pV);
|
|
|
|
if(WithinEpsilon(f, 1.0f))
|
|
{
|
|
if(pOut != pV)
|
|
*pOut = *pV;
|
|
}
|
|
else if(f > EPSILON * EPSILON)
|
|
{
|
|
*pOut = *pV / sqrtf(f);
|
|
}
|
|
else
|
|
{
|
|
pOut->x = 0.0f;
|
|
pOut->y = 0.0f;
|
|
pOut->z = 0.0f;
|
|
pOut->w = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec4Hermite
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pT1,
|
|
const D3DXVECTOR4 *pV2, const D3DXVECTOR4 *pT2, float s )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s2 = s * s;
|
|
float s3 = s * s2;
|
|
|
|
float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
|
|
float sT1 = s3 - 2.0f * s2 + s;
|
|
float sV2 = -2.0f * s3 + 3.0f * s2;
|
|
float sT2 = s3 - s2;
|
|
|
|
pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
|
|
pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
|
|
pOut->z = sV1 * pV1->z + sT1 * pT1->z + sV2 * pV2->z + sT2 * pT2->z;
|
|
pOut->w = sV1 * pV1->w + sT1 * pT1->w + sV2 * pV2->w + sT2 * pT2->w;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec4BaryCentric
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pV2,
|
|
const D3DXVECTOR4 *pV3, float f, float g)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pV2 || !pV3)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
|
|
pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
|
|
pOut->z = pV1->z + f * (pV2->z - pV1->z) + g * (pV3->z - pV1->z);
|
|
pOut->w = pV1->w + f * (pV2->w - pV1->w) + g * (pV3->w - pV1->w);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR4* WINAPI VB_D3DXVec4Transform
|
|
( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pV]
|
|
mov edx, DWORD PTR [pM]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+0)*4] ; M00
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+2)*4] ; M02
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+1)*4] ; M01
|
|
fld DWORD PTR [eax+0*4] ; X
|
|
fmul DWORD PTR [edx+(0*4+3)*4] ; M03
|
|
fxch st(3)
|
|
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+0)*4] ; M10
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+2)*4] ; M12
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+1)*4] ; M11
|
|
fld DWORD PTR [eax+1*4] ; Y
|
|
fmul DWORD PTR [edx+(1*4+3)*4] ; M13
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+0)*4] ; M20
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+2)*4] ; M22
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+1)*4] ; M21
|
|
fld DWORD PTR [eax+2*4] ; Z
|
|
fmul DWORD PTR [edx+(2*4+3)*4] ; M23
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fld DWORD PTR [eax+3*4] ; W
|
|
fmul DWORD PTR [edx+(3*4+0)*4] ; M30
|
|
fld DWORD PTR [eax+3*4] ; W
|
|
fmul DWORD PTR [edx+(3*4+2)*4] ; M32
|
|
fld DWORD PTR [eax+3*4] ; W
|
|
fmul DWORD PTR [edx+(3*4+1)*4] ; M31
|
|
fld DWORD PTR [eax+3*4] ; W
|
|
fmul DWORD PTR [edx+(3*4+3)*4] ; M33
|
|
fxch st(3)
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
fstp DWORD PTR [ecx+3*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXVECTOR4 v;
|
|
|
|
v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pV->w * pM->m30;
|
|
v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pV->w * pM->m31;
|
|
v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pV->w * pM->m32;
|
|
v.w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pV->w * pM->m33;
|
|
|
|
*pOut = v;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
|
|
//--------------------------
|
|
// 4D Matrix
|
|
//--------------------------
|
|
|
|
float WINAPI VB_D3DXMatrixfDeterminant
|
|
( const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pM)
|
|
return 0.0f;
|
|
#endif
|
|
|
|
return (pM->m00 * (pM->m11 * (pM->m22 * pM->m33 - pM->m32 * pM->m23) -
|
|
pM->m12 * (pM->m21 * pM->m33 - pM->m31 * pM->m23) +
|
|
pM->m13 * (pM->m21 * pM->m32 - pM->m31 * pM->m22)))
|
|
|
|
- (pM->m01 * (pM->m10 * (pM->m22 * pM->m33 - pM->m32 * pM->m23) -
|
|
pM->m12 * (pM->m20 * pM->m33 - pM->m30 * pM->m23) +
|
|
pM->m13 * (pM->m20 * pM->m32 - pM->m30 * pM->m22)))
|
|
|
|
+ (pM->m02 * (pM->m10 * (pM->m21 * pM->m33 - pM->m31 * pM->m23) -
|
|
pM->m11 * (pM->m20 * pM->m33 - pM->m30 * pM->m23) +
|
|
pM->m13 * (pM->m20 * pM->m31 - pM->m30 * pM->m21)))
|
|
|
|
- (pM->m03 * (pM->m10 * (pM->m21 * pM->m32 - pM->m31 * pM->m22) -
|
|
pM->m11 * (pM->m20 * pM->m32 - pM->m30 * pM->m22) +
|
|
pM->m12 * (pM->m20 * pM->m31 - pM->m30 * pM->m21)));
|
|
}
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixMultiply
|
|
( D3DXMATRIX *pOut, const D3DXMATRIX *pM1, const D3DXMATRIX *pM2 )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pM1 || !pM2)
|
|
return NULL;
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
#define MAT(m,a,b) DWORD PTR [(m)+(a)*4+(b)*4]
|
|
|
|
D3DXMATRIX Out;
|
|
|
|
if(pM2 != pOut)
|
|
goto LRowByColumn;
|
|
if(pM1 != pOut)
|
|
goto LColumnByRow;
|
|
|
|
Out = *pM2;
|
|
pM2 = &Out;
|
|
goto LRowByColumn;
|
|
|
|
|
|
LRowByColumn:
|
|
__asm {
|
|
mov ebx, DWORD PTR[pOut] // result
|
|
mov ecx, DWORD PTR[pM1] // a
|
|
mov edx, DWORD PTR[pM2] // b
|
|
mov edi, -4
|
|
|
|
LLoopRow:
|
|
mov esi, -4
|
|
|
|
fld MAT(ecx, 0, 0) // a0
|
|
fld MAT(ecx, 0, 1) // a1
|
|
fld MAT(ecx, 0, 2) // a2
|
|
fld MAT(ecx, 0, 3) // a3
|
|
|
|
LLoopColumn:
|
|
fld st(3) // a0
|
|
fmul MAT(edx, esi, 1*4) // a0*b0
|
|
fld st(3) // a1
|
|
fmul MAT(edx, esi, 2*4) // a1*b1
|
|
fld st(3) // a2
|
|
fmul MAT(edx, esi, 3*4) // a2*b2
|
|
fld st(3) // a3
|
|
fmul MAT(edx, esi, 4*4) // a3*b3
|
|
|
|
fxch st(3)
|
|
faddp st(1), st // a2*b2+a0*b0
|
|
fxch st(2)
|
|
faddp st(1), st // a3*b3+a1*b1
|
|
faddp st(1), st // a3*b3+a1*b1+a2*b2+a0*b0
|
|
fstp MAT(ebx, esi, 4)
|
|
|
|
inc esi
|
|
jnz LLoopColumn
|
|
|
|
ffree st(3)
|
|
ffree st(2)
|
|
ffree st(1)
|
|
ffree st(0)
|
|
|
|
lea ecx, MAT(ecx, 0, 4)
|
|
lea ebx, MAT(ebx, 0, 4)
|
|
|
|
inc edi
|
|
jnz LLoopRow
|
|
}
|
|
|
|
return pOut;
|
|
|
|
|
|
LColumnByRow:
|
|
__asm {
|
|
mov ebx, DWORD PTR[pOut] // result
|
|
mov ecx, DWORD PTR[pM1] // a
|
|
mov edx, DWORD PTR[pM2] // b
|
|
mov edi, -4
|
|
|
|
LLoopColumn2:
|
|
mov esi, -16
|
|
|
|
fld MAT(edx, edi, 1*4); // b0
|
|
fld MAT(edx, edi, 2*4); // b1
|
|
fld MAT(edx, edi, 3*4); // b2
|
|
fld MAT(edx, edi, 4*4); // b3
|
|
|
|
LLoopRow2:
|
|
fld st(3) // b0
|
|
fmul MAT(ecx, esi, 0+16) // a0*b0
|
|
fld st(3) // b1
|
|
fmul MAT(ecx, esi, 1+16) // a1*b1
|
|
fld st(3) // b2
|
|
fmul MAT(ecx, esi, 2+16) // a2*b2
|
|
fld st(3) // b3
|
|
fmul MAT(ecx, esi, 3+16) // a3*b3
|
|
|
|
fxch st(3)
|
|
faddp st(1), st // a2*b2+a0*b0
|
|
fxch st(2)
|
|
faddp st(1), st // a3*b3+a1*b1
|
|
faddp st(1), st // a3*b3+a1*b1+a2*b2+a0*b0
|
|
fstp MAT(ebx, esi, 0+16)
|
|
|
|
add esi, 4
|
|
jnz LLoopRow2
|
|
|
|
ffree st(3)
|
|
ffree st(2)
|
|
ffree st(1)
|
|
ffree st(0)
|
|
|
|
lea ebx, MAT(ebx, 0, 1)
|
|
inc edi
|
|
jnz LLoopColumn2
|
|
}
|
|
|
|
return pOut;
|
|
#undef MAT
|
|
#else //!_X86_
|
|
D3DXMATRIX Out;
|
|
D3DXMATRIX *pM = (pOut == pM1 || pOut == pM2) ? &Out : pOut;
|
|
|
|
pM->m00 = pM1->m00 * pM2->m00 + pM1->m01 * pM2->m10 + pM1->m02 * pM2->m20 + pM1->m03 * pM2->m30;
|
|
pM->m01 = pM1->m00 * pM2->m01 + pM1->m01 * pM2->m11 + pM1->m02 * pM2->m21 + pM1->m03 * pM2->m31;
|
|
pM->m02 = pM1->m00 * pM2->m02 + pM1->m01 * pM2->m12 + pM1->m02 * pM2->m22 + pM1->m03 * pM2->m32;
|
|
pM->m03 = pM1->m00 * pM2->m03 + pM1->m01 * pM2->m13 + pM1->m02 * pM2->m23 + pM1->m03 * pM2->m33;
|
|
|
|
pM->m10 = pM1->m10 * pM2->m00 + pM1->m11 * pM2->m10 + pM1->m12 * pM2->m20 + pM1->m13 * pM2->m30;
|
|
pM->m11 = pM1->m10 * pM2->m01 + pM1->m11 * pM2->m11 + pM1->m12 * pM2->m21 + pM1->m13 * pM2->m31;
|
|
pM->m12 = pM1->m10 * pM2->m02 + pM1->m11 * pM2->m12 + pM1->m12 * pM2->m22 + pM1->m13 * pM2->m32;
|
|
pM->m13 = pM1->m10 * pM2->m03 + pM1->m11 * pM2->m13 + pM1->m12 * pM2->m23 + pM1->m13 * pM2->m33;
|
|
|
|
pM->m20 = pM1->m20 * pM2->m00 + pM1->m21 * pM2->m10 + pM1->m22 * pM2->m20 + pM1->m23 * pM2->m30;
|
|
pM->m21 = pM1->m20 * pM2->m01 + pM1->m21 * pM2->m11 + pM1->m22 * pM2->m21 + pM1->m23 * pM2->m31;
|
|
pM->m22 = pM1->m20 * pM2->m02 + pM1->m21 * pM2->m12 + pM1->m22 * pM2->m22 + pM1->m23 * pM2->m32;
|
|
pM->m23 = pM1->m20 * pM2->m03 + pM1->m21 * pM2->m13 + pM1->m22 * pM2->m23 + pM1->m23 * pM2->m33;
|
|
|
|
pM->m30 = pM1->m30 * pM2->m00 + pM1->m31 * pM2->m10 + pM1->m32 * pM2->m20 + pM1->m33 * pM2->m30;
|
|
pM->m31 = pM1->m30 * pM2->m01 + pM1->m31 * pM2->m11 + pM1->m32 * pM2->m21 + pM1->m33 * pM2->m31;
|
|
pM->m32 = pM1->m30 * pM2->m02 + pM1->m31 * pM2->m12 + pM1->m32 * pM2->m22 + pM1->m33 * pM2->m32;
|
|
pM->m33 = pM1->m30 * pM2->m03 + pM1->m31 * pM2->m13 + pM1->m32 * pM2->m23 + pM1->m33 * pM2->m33;
|
|
|
|
if(pM != pOut)
|
|
*pOut = *pM;
|
|
|
|
return pOut;
|
|
#endif //!_X86_
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixTranspose
|
|
( D3DXMATRIX *pOut, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f;
|
|
|
|
f = pM->m01; pOut->m01 = pM->m10; pOut->m10 = f;
|
|
f = pM->m02; pOut->m02 = pM->m20; pOut->m20 = f;
|
|
f = pM->m03; pOut->m03 = pM->m30; pOut->m30 = f;
|
|
f = pM->m12; pOut->m12 = pM->m21; pOut->m21 = f;
|
|
f = pM->m13; pOut->m13 = pM->m31; pOut->m31 = f;
|
|
f = pM->m23; pOut->m23 = pM->m32; pOut->m32 = f;
|
|
|
|
if(pOut != pM)
|
|
{
|
|
pOut->m00 = pM->m00;
|
|
pOut->m11 = pM->m11;
|
|
pOut->m22 = pM->m22;
|
|
pOut->m33 = pM->m33;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixInverse
|
|
( D3DXMATRIX *pOut, float *pfDeterminant, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
// XXXlorenmcq - The code was designed to work on a processor with more
|
|
// than 4 general-purpose registers. Is there a more optimal way of
|
|
// doing this on X86?
|
|
|
|
float fX00, fX01, fX02;
|
|
float fX10, fX11, fX12;
|
|
float fX20, fX21, fX22;
|
|
float fX30, fX31, fX32;
|
|
float fY01, fY02, fY03, fY12, fY13, fY23;
|
|
float fZ02, fZ03, fZ12, fZ13, fZ22, fZ23, fZ32, fZ33;
|
|
|
|
#define fX03 fX01
|
|
#define fX13 fX11
|
|
#define fX23 fX21
|
|
#define fX33 fX31
|
|
#define fZ00 fX02
|
|
#define fZ10 fX12
|
|
#define fZ20 fX22
|
|
#define fZ30 fX32
|
|
#define fZ01 fX03
|
|
#define fZ11 fX13
|
|
#define fZ21 fX23
|
|
#define fZ31 fX33
|
|
#define fDet fY01
|
|
#define fRcp fY02
|
|
|
|
// read 1st two columns of matrix
|
|
fX00 = pM->m00;
|
|
fX01 = pM->m01;
|
|
fX10 = pM->m10;
|
|
fX11 = pM->m11;
|
|
fX20 = pM->m20;
|
|
fX21 = pM->m21;
|
|
fX30 = pM->m30;
|
|
fX31 = pM->m31;
|
|
|
|
// compute all six 2x2 determinants of 1st two columns
|
|
fY01 = fX00 * fX11 - fX10 * fX01;
|
|
fY02 = fX00 * fX21 - fX20 * fX01;
|
|
fY03 = fX00 * fX31 - fX30 * fX01;
|
|
fY12 = fX10 * fX21 - fX20 * fX11;
|
|
fY13 = fX10 * fX31 - fX30 * fX11;
|
|
fY23 = fX20 * fX31 - fX30 * fX21;
|
|
|
|
// read 2nd two columns of matrix
|
|
fX02 = pM->m02;
|
|
fX03 = pM->m03;
|
|
fX12 = pM->m12;
|
|
fX13 = pM->m13;
|
|
fX22 = pM->m22;
|
|
fX23 = pM->m23;
|
|
fX32 = pM->m32;
|
|
fX33 = pM->m33;
|
|
|
|
// compute all 3x3 cofactors for 2nd two columns
|
|
fZ33 = fX02 * fY12 - fX12 * fY02 + fX22 * fY01;
|
|
fZ23 = fX12 * fY03 - fX32 * fY01 - fX02 * fY13;
|
|
fZ13 = fX02 * fY23 - fX22 * fY03 + fX32 * fY02;
|
|
fZ03 = fX22 * fY13 - fX32 * fY12 - fX12 * fY23;
|
|
fZ32 = fX13 * fY02 - fX23 * fY01 - fX03 * fY12;
|
|
fZ22 = fX03 * fY13 - fX13 * fY03 + fX33 * fY01;
|
|
fZ12 = fX23 * fY03 - fX33 * fY02 - fX03 * fY23;
|
|
fZ02 = fX13 * fY23 - fX23 * fY13 + fX33 * fY12;
|
|
|
|
// compute all six 2x2 determinants of 2nd two columns
|
|
fY01 = fX02 * fX13 - fX12 * fX03;
|
|
fY02 = fX02 * fX23 - fX22 * fX03;
|
|
fY03 = fX02 * fX33 - fX32 * fX03;
|
|
fY12 = fX12 * fX23 - fX22 * fX13;
|
|
fY13 = fX12 * fX33 - fX32 * fX13;
|
|
fY23 = fX22 * fX33 - fX32 * fX23;
|
|
|
|
// read 1st two columns of matrix
|
|
fX00 = pM->m00;
|
|
fX01 = pM->m01;
|
|
fX10 = pM->m10;
|
|
fX11 = pM->m11;
|
|
fX20 = pM->m20;
|
|
fX21 = pM->m21;
|
|
fX30 = pM->m30;
|
|
fX31 = pM->m31;
|
|
|
|
// compute all 3x3 cofactors for 1st two columns
|
|
fZ30 = fX11 * fY02 - fX21 * fY01 - fX01 * fY12;
|
|
fZ20 = fX01 * fY13 - fX11 * fY03 + fX31 * fY01;
|
|
fZ10 = fX21 * fY03 - fX31 * fY02 - fX01 * fY23;
|
|
fZ00 = fX11 * fY23 - fX21 * fY13 + fX31 * fY12;
|
|
fZ31 = fX00 * fY12 - fX10 * fY02 + fX20 * fY01;
|
|
fZ21 = fX10 * fY03 - fX30 * fY01 - fX00 * fY13;
|
|
fZ11 = fX00 * fY23 - fX20 * fY03 + fX30 * fY02;
|
|
fZ01 = fX20 * fY13 - fX30 * fY12 - fX10 * fY23;
|
|
|
|
// compute 4x4 determinant & its reciprocal
|
|
fDet = fX30 * fZ30 + fX20 * fZ20 + fX10 * fZ10 + fX00 * fZ00;
|
|
|
|
if(pfDeterminant)
|
|
*pfDeterminant = fDet;
|
|
|
|
fRcp = 1.0f / fDet;
|
|
|
|
if(!_finite(fRcp))
|
|
return NULL;
|
|
|
|
|
|
// multiply all 3x3 cofactors by reciprocal & transpose
|
|
pOut->m00 = fZ00 * fRcp;
|
|
pOut->m01 = fZ10 * fRcp;
|
|
pOut->m02 = fZ20 * fRcp;
|
|
pOut->m03 = fZ30 * fRcp;
|
|
pOut->m10 = fZ01 * fRcp;
|
|
pOut->m11 = fZ11 * fRcp;
|
|
pOut->m12 = fZ21 * fRcp;
|
|
pOut->m13 = fZ31 * fRcp;
|
|
pOut->m20 = fZ02 * fRcp;
|
|
pOut->m21 = fZ12 * fRcp;
|
|
pOut->m22 = fZ22 * fRcp;
|
|
pOut->m23 = fZ32 * fRcp;
|
|
pOut->m30 = fZ03 * fRcp;
|
|
pOut->m31 = fZ13 * fRcp;
|
|
pOut->m32 = fZ23 * fRcp;
|
|
pOut->m33 = fZ33 * fRcp;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixScaling
|
|
( D3DXMATRIX *pOut, float sx, float sy, float sz )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m01 = pOut->m02 = pOut->m03 =
|
|
pOut->m10 = pOut->m12 = pOut->m13 =
|
|
pOut->m20 = pOut->m21 = pOut->m23 =
|
|
pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
|
|
|
|
pOut->m00 = sx;
|
|
pOut->m11 = sy;
|
|
pOut->m22 = sz;
|
|
pOut->m33 = 1.0f;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixTranslation
|
|
( D3DXMATRIX *pOut, float x, float y, float z )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m01 = pOut->m02 = pOut->m03 =
|
|
pOut->m10 = pOut->m12 = pOut->m13 =
|
|
pOut->m20 = pOut->m21 = pOut->m23 = 0.0f;
|
|
|
|
pOut->m00 = pOut->m11 = pOut->m22 = pOut->m33 = 1.0f;
|
|
|
|
pOut->m30 = x;
|
|
pOut->m31 = y;
|
|
pOut->m32 = z;
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationX
|
|
( D3DXMATRIX *pOut, float angle )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(angle, &s, &c);
|
|
|
|
pOut->m00 = 1.0f; pOut->m01 = 0.0f; pOut->m02 = 0.0f; pOut->m03 = 0.0f;
|
|
pOut->m10 = 0.0f; pOut->m11 = c; pOut->m12 = s; pOut->m13 = 0.0f;
|
|
pOut->m20 = 0.0f; pOut->m21 = -s; pOut->m22 = c; pOut->m23 = 0.0f;
|
|
pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationY
|
|
( D3DXMATRIX *pOut, float angle )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(angle, &s, &c);
|
|
|
|
pOut->m00 = c; pOut->m01 = 0.0f; pOut->m02 = -s; pOut->m03 = 0.0f;
|
|
pOut->m10 = 0.0f; pOut->m11 = 1.0f; pOut->m12 = 0.0f; pOut->m13 = 0.0f;
|
|
pOut->m20 = s; pOut->m21 = 0.0f; pOut->m22 = c; pOut->m23 = 0.0f;
|
|
pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationZ
|
|
( D3DXMATRIX *pOut, float angle )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(angle, &s, &c);
|
|
|
|
pOut->m00 = c; pOut->m01 = s; pOut->m02 = 0.0f; pOut->m03 = 0.0f;
|
|
pOut->m10 = -s; pOut->m11 = c; pOut->m12 = 0.0f; pOut->m13 = 0.0f;
|
|
pOut->m20 = 0.0f; pOut->m21 = 0.0f; pOut->m22 = 1.0f; pOut->m23 = 0.0f;
|
|
pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationAxis
|
|
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pV, float angle )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(angle, &s, &c);
|
|
float c1 = 1 - c;
|
|
|
|
D3DXVECTOR3 v = *pV;
|
|
VB_D3DXVec3Normalize(&v, &v);
|
|
|
|
float xyc1 = v.x * v.y * c1;
|
|
float yzc1 = v.y * v.z * c1;
|
|
float zxc1 = v.z * v.x * c1;
|
|
|
|
pOut->m00 = v.x * v.x * c1 + c;
|
|
pOut->m01 = xyc1 + v.z * s;
|
|
pOut->m02 = zxc1 - v.y * s;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = xyc1 - v.z * s;
|
|
pOut->m11 = v.y * v.y * c1 + c;
|
|
pOut->m12 = yzc1 + v.x * s;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = zxc1 + v.y * s;
|
|
pOut->m21 = yzc1 - v.x * s;
|
|
pOut->m22 = v.z * v.z * c1 + c;
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = 0.0f;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationQuaternion
|
|
( D3DXMATRIX *pOut, const D3DXQUATERNION *pQ)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ)
|
|
return NULL;
|
|
#endif
|
|
|
|
float x2 = pQ->x + pQ->x;
|
|
float y2 = pQ->y + pQ->y;
|
|
float z2 = pQ->z + pQ->z;
|
|
|
|
float wx2 = pQ->w * x2;
|
|
float wy2 = pQ->w * y2;
|
|
float wz2 = pQ->w * z2;
|
|
float xx2 = pQ->x * x2;
|
|
float xy2 = pQ->x * y2;
|
|
float xz2 = pQ->x * z2;
|
|
float yy2 = pQ->y * y2;
|
|
float yz2 = pQ->y * z2;
|
|
float zz2 = pQ->z * z2;
|
|
|
|
pOut->m00 = 1.0f - yy2 - zz2;
|
|
pOut->m01 = xy2 + wz2;
|
|
pOut->m02 = xz2 - wy2;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = xy2 - wz2;
|
|
pOut->m11 = 1.0f - xx2 - zz2;
|
|
pOut->m12 = yz2 + wx2;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = xz2 + wy2;
|
|
pOut->m21 = yz2 - wx2;
|
|
pOut->m22 = 1.0f - xx2 - yy2;
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = 0.0f;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixRotationYawPitchRoll
|
|
( D3DXMATRIX *pOut, float yaw, float pitch, float roll )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXQUATERNION q;
|
|
|
|
VB_D3DXQuaternionRotationYawPitchRoll(&q, yaw, pitch, roll);
|
|
D3DXMatrixRotationQuaternion(pOut, &q);
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixTransformation
|
|
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pScalingCenter,
|
|
const D3DXQUATERNION *pScalingRotation, const D3DXVECTOR3 *pScaling,
|
|
const D3DXVECTOR3 *pRotationCenter, const D3DXQUATERNION *pRotation,
|
|
const D3DXVECTOR3 *pTranslation)
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXMATRIX matS, matR, matRI;
|
|
|
|
if (pScaling)
|
|
{
|
|
if (pScalingRotation)
|
|
{
|
|
matS.m01 = matS.m02 = matS.m03 =
|
|
matS.m10 = matS.m12 = matS.m13 =
|
|
matS.m20 = matS.m21 = matS.m23 =
|
|
matS.m30 = matS.m31 = matS.m32 = 0.0f;
|
|
|
|
matS.m00 = pScaling->x;
|
|
matS.m11 = pScaling->y;
|
|
matS.m22 = pScaling->z;
|
|
matS.m33 = 1.0f;
|
|
|
|
D3DXMatrixRotationQuaternion(&matR, pScalingRotation);
|
|
|
|
|
|
if (pScalingCenter)
|
|
{
|
|
// SC-1, SR-1, S, SR, SC
|
|
D3DXMatrixTranspose(&matRI, &matR);
|
|
D3DXMatrixIdentity(pOut);
|
|
|
|
pOut->m30 -= pScalingCenter->x;
|
|
pOut->m31 -= pScalingCenter->y;
|
|
pOut->m32 -= pScalingCenter->z;
|
|
|
|
D3DXMatrixMultiply(pOut, pOut, &matRI);
|
|
D3DXMatrixMultiply(pOut, pOut, &matS);
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
|
|
pOut->m30 += pScalingCenter->x;
|
|
pOut->m31 += pScalingCenter->y;
|
|
pOut->m32 += pScalingCenter->z;
|
|
}
|
|
else
|
|
{
|
|
// SR-1, S, SR
|
|
D3DXMatrixTranspose(pOut, &matR);
|
|
D3DXMatrixMultiply(pOut, pOut, &matS);
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// S
|
|
pOut->m01 = pOut->m02 = pOut->m03 =
|
|
pOut->m10 = pOut->m12 = pOut->m13 =
|
|
pOut->m20 = pOut->m21 = pOut->m23 =
|
|
pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
|
|
|
|
pOut->m00 = pScaling->x;
|
|
pOut->m11 = pScaling->y;
|
|
pOut->m22 = pScaling->z;
|
|
pOut->m33 = 1.0f;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
D3DXMatrixIdentity(pOut);
|
|
}
|
|
|
|
if (pRotation)
|
|
{
|
|
D3DXMatrixRotationQuaternion(&matR, pRotation);
|
|
|
|
if (pRotationCenter)
|
|
{
|
|
// RC-1, R, RC
|
|
pOut->m30 -= pRotationCenter->x;
|
|
pOut->m31 -= pRotationCenter->y;
|
|
pOut->m32 -= pRotationCenter->z;
|
|
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
|
|
pOut->m30 += pRotationCenter->x;
|
|
pOut->m31 += pRotationCenter->y;
|
|
pOut->m32 += pRotationCenter->z;
|
|
}
|
|
else
|
|
{
|
|
// R
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
}
|
|
}
|
|
|
|
if (pTranslation)
|
|
{
|
|
// T
|
|
pOut->m30 += pTranslation->x;
|
|
pOut->m31 += pTranslation->y;
|
|
pOut->m32 += pTranslation->z;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixAffineTransformation
|
|
( D3DXMATRIX *pOut, float Scaling, const D3DXVECTOR3 *pRotationCenter,
|
|
const D3DXQUATERNION *pRotation, const D3DXVECTOR3 *pTranslation)
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
// S
|
|
pOut->m01 = pOut->m02 = pOut->m03 =
|
|
pOut->m10 = pOut->m12 = pOut->m13 =
|
|
pOut->m20 = pOut->m21 = pOut->m23 =
|
|
pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
|
|
|
|
pOut->m00 = Scaling;
|
|
pOut->m11 = Scaling;
|
|
pOut->m22 = Scaling;
|
|
pOut->m33 = 1.0f;
|
|
|
|
|
|
if (pRotation)
|
|
{
|
|
D3DXMATRIX matR;
|
|
D3DXMatrixRotationQuaternion(&matR, pRotation);
|
|
|
|
if (pRotationCenter)
|
|
{
|
|
// RC-1, R, RC
|
|
pOut->m30 -= pRotationCenter->x;
|
|
pOut->m31 -= pRotationCenter->y;
|
|
pOut->m32 -= pRotationCenter->z;
|
|
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
|
|
pOut->m30 += pRotationCenter->x;
|
|
pOut->m31 += pRotationCenter->y;
|
|
pOut->m32 += pRotationCenter->z;
|
|
}
|
|
else
|
|
{
|
|
// R
|
|
D3DXMatrixMultiply(pOut, pOut, &matR);
|
|
}
|
|
}
|
|
|
|
|
|
if (pTranslation)
|
|
{
|
|
// T
|
|
pOut->m30 += pTranslation->x;
|
|
pOut->m31 += pTranslation->y;
|
|
pOut->m32 += pTranslation->z;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixLookAt
|
|
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
|
|
const D3DXVECTOR3 *pUp )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pEye || !pAt || !pUp)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXVECTOR3 XAxis, YAxis, ZAxis;
|
|
|
|
// Compute direction of gaze. (-Z)
|
|
VB_D3DXVec3Subtract(&ZAxis, pEye, pAt);
|
|
VB_D3DXVec3Normalize(&ZAxis, &ZAxis);
|
|
|
|
// Compute orthogonal axes from cross product of gaze and pUp vector.
|
|
VB_D3DXVec3Cross(&XAxis, pUp, &ZAxis);
|
|
VB_D3DXVec3Normalize(&XAxis, &XAxis);
|
|
VB_D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
|
|
|
|
// Set rotation and translate by pEye
|
|
pOut->m00 = XAxis.x;
|
|
pOut->m10 = XAxis.y;
|
|
pOut->m20 = XAxis.z;
|
|
pOut->m30 = -VB_D3DXVec3Dot(&XAxis, pEye);
|
|
|
|
pOut->m01 = YAxis.x;
|
|
pOut->m11 = YAxis.y;
|
|
pOut->m21 = YAxis.z;
|
|
pOut->m31 = -VB_D3DXVec3Dot(&YAxis, pEye);
|
|
|
|
pOut->m02 = ZAxis.x;
|
|
pOut->m12 = ZAxis.y;
|
|
pOut->m22 = ZAxis.z;
|
|
pOut->m32 = -VB_D3DXVec3Dot(&ZAxis, pEye);
|
|
|
|
pOut->m03 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
pOut->m23 = 0.0f;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixLookAtLH
|
|
( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
|
|
const D3DXVECTOR3 *pUp )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pEye || !pAt || !pUp)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXVECTOR3 XAxis, YAxis, ZAxis;
|
|
|
|
// Compute direction of gaze. (+Z)
|
|
VB_D3DXVec3Subtract(&ZAxis, pAt, pEye);
|
|
VB_D3DXVec3Normalize(&ZAxis, &ZAxis);
|
|
|
|
// Compute orthogonal axes from cross product of gaze and pUp vector.
|
|
VB_D3DXVec3Cross(&XAxis, &ZAxis, pUp);
|
|
VB_D3DXVec3Normalize(&XAxis, &XAxis);
|
|
VB_D3DXVec3Cross(&YAxis, &XAxis, &ZAxis);
|
|
|
|
// Set rotation and translate by pEye
|
|
pOut->m00 = XAxis.x;
|
|
pOut->m10 = XAxis.y;
|
|
pOut->m20 = XAxis.z;
|
|
pOut->m30 = -VB_D3DXVec3Dot(&XAxis, pEye);
|
|
|
|
pOut->m01 = YAxis.x;
|
|
pOut->m11 = YAxis.y;
|
|
pOut->m21 = YAxis.z;
|
|
pOut->m31 = -VB_D3DXVec3Dot(&YAxis, pEye);
|
|
|
|
pOut->m02 = ZAxis.x;
|
|
pOut->m12 = ZAxis.y;
|
|
pOut->m22 = ZAxis.z;
|
|
pOut->m32 = -VB_D3DXVec3Dot(&ZAxis, pEye);
|
|
|
|
pOut->m03 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
pOut->m23 = 0.0f;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspective
|
|
( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m00 = 2.0f * zn / w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * zn / h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = zf / (zn - zf);
|
|
pOut->m23 = -1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveLH
|
|
( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m00 = 2.0f * zn / w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * zn / h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = zf / (zf - zn);
|
|
pOut->m23 = 1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = -pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveFov
|
|
( D3DXMATRIX *pOut, float fovy, float aspect, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(0.5f * fovy, &s, &c);
|
|
|
|
float h = c / s;
|
|
float w = aspect * h;
|
|
|
|
pOut->m00 = w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = zf / (zn - zf);
|
|
pOut->m23 = -1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveFovLH
|
|
( D3DXMATRIX *pOut, float fovy, float aspect, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float s, c;
|
|
sincosf(0.5f * fovy, &s, &c);
|
|
|
|
float h = c / s;
|
|
float w = aspect * h;
|
|
|
|
pOut->m00 = w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = zf / (zf - zn);
|
|
pOut->m23 = 1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = -pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveOffCenter
|
|
( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
|
|
float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float wInv = 1.0f / (r - l);
|
|
float hInv = 1.0f / (t - b);
|
|
|
|
pOut->m00 = 2.0f * zn * wInv;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * zn * hInv;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = (l + r) * wInv;
|
|
pOut->m21 = (t + b) * hInv;
|
|
pOut->m22 = zf / (zn - zf);
|
|
pOut->m23 = -1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveOffCenterLH
|
|
( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
|
|
float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float wInv = 1.0f / (r - l);
|
|
float hInv = 1.0f / (t - b);
|
|
|
|
pOut->m00 = 2.0f * zn * wInv;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * zn * hInv;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = -(l + r) * wInv;
|
|
pOut->m21 = -(t + b) * hInv;
|
|
pOut->m22 = zf / (zf - zn);
|
|
pOut->m23 = 1.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = -pOut->m22 * zn;
|
|
pOut->m33 = 0.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixOrtho
|
|
( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m00 = 2.0f / w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f / h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = 1.0f / (zn - zf);
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = pOut->m22 * zn;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoLH
|
|
( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->m00 = 2.0f / w;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f / h;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = 1.0f / (zf - zn);
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = 0.0f;
|
|
pOut->m31 = 0.0f;
|
|
pOut->m32 = -pOut->m22 * zn;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoOffCenter
|
|
( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
|
|
float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float wInv = 1.0f / (r - l);
|
|
float hInv = 1.0f / (t - b);
|
|
|
|
pOut->m00 = 2.0f * wInv;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * hInv;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = 1.0f / (zn - zf);
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = -(l + r) * wInv;
|
|
pOut->m31 = -(t + b) * hInv;
|
|
pOut->m32 = pOut->m22 * zn;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoOffCenterLH
|
|
( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
|
|
float zf )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
float wInv = 1.0f / (r - l);
|
|
float hInv = 1.0f / (t - b);
|
|
|
|
pOut->m00 = 2.0f * wInv;
|
|
pOut->m01 = 0.0f;
|
|
pOut->m02 = 0.0f;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = 0.0f;
|
|
pOut->m11 = 2.0f * hInv;
|
|
pOut->m12 = 0.0f;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = 0.0f;
|
|
pOut->m21 = 0.0f;
|
|
pOut->m22 = 1.0f / (zf - zn);
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = -(l + r) * wInv;
|
|
pOut->m31 = -(t + b) * hInv;
|
|
pOut->m32 = -pOut->m22 * zn;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixShadow
|
|
( D3DXMATRIX *pOut, const D3DXVECTOR4 *pLight,
|
|
const D3DXPLANE *pPlane )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pLight || !pPlane)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXPLANE p;
|
|
VB_D3DXPlaneNormalize(&p, pPlane);
|
|
float dot = VB_D3DXPlaneDot(&p, pLight);
|
|
p = -p;
|
|
|
|
pOut->m00 = p.a * pLight->x + dot;
|
|
pOut->m10 = p.b * pLight->x;
|
|
pOut->m20 = p.c * pLight->x;
|
|
pOut->m30 = p.d * pLight->x;
|
|
|
|
pOut->m01 = p.a * pLight->y;
|
|
pOut->m11 = p.b * pLight->y + dot;
|
|
pOut->m21 = p.c * pLight->y;
|
|
pOut->m31 = p.d * pLight->y;
|
|
|
|
pOut->m02 = p.a * pLight->z;
|
|
pOut->m12 = p.b * pLight->z;
|
|
pOut->m22 = p.c * pLight->z + dot;
|
|
pOut->m32 = p.d * pLight->z;
|
|
|
|
pOut->m03 = p.a * pLight->w;
|
|
pOut->m13 = p.b * pLight->w;
|
|
pOut->m23 = p.c * pLight->w;
|
|
pOut->m33 = p.d * pLight->w + dot;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXMATRIX* WINAPI VB_D3DXMatrixReflect
|
|
( D3DXMATRIX *pOut, const D3DXPLANE *pPlane )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pPlane)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXPLANE p;
|
|
VB_D3DXPlaneNormalize(&p, pPlane);
|
|
|
|
float fa = -2.0f * p.a;
|
|
float fb = -2.0f * p.b;
|
|
float fc = -2.0f * p.c;
|
|
|
|
pOut->m00 = fa * p.a + 1.0f;
|
|
pOut->m01 = fb * p.a;
|
|
pOut->m02 = fc * p.a;
|
|
pOut->m03 = 0.0f;
|
|
|
|
pOut->m10 = fa * p.b;
|
|
pOut->m11 = fb * p.b + 1.0f;
|
|
pOut->m12 = fc * p.b;
|
|
pOut->m13 = 0.0f;
|
|
|
|
pOut->m20 = fa * p.c;
|
|
pOut->m21 = fb * p.c;
|
|
pOut->m22 = fc * p.c + 1.0f;
|
|
pOut->m23 = 0.0f;
|
|
|
|
pOut->m30 = fa * p.d;
|
|
pOut->m31 = fb * p.d;
|
|
pOut->m32 = fc * p.d;
|
|
pOut->m33 = 1.0f;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
//--------------------------
|
|
// Quaternion
|
|
//--------------------------
|
|
|
|
void WINAPI VB_D3DXQuaternionToAxisAngle
|
|
( const D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, float *pAngle )
|
|
{
|
|
#if DBG
|
|
if(!pQ)
|
|
return;
|
|
#endif
|
|
|
|
// expects unit quaternions!
|
|
// q = cos(A/2), sin(A/2) * v
|
|
|
|
float lsq = VB_D3DXQuaternionLengthSq(pQ);
|
|
|
|
if(lsq > EPSILON * EPSILON)
|
|
{
|
|
if(pAxis)
|
|
{
|
|
float scale = 1.0f / sqrtf(lsq);
|
|
pAxis->x = pQ->x * scale;
|
|
pAxis->y = pQ->y * scale;
|
|
pAxis->z = pQ->z * scale;
|
|
}
|
|
|
|
if(pAngle)
|
|
*pAngle = 2.0f * acosf(pQ->w);
|
|
|
|
}
|
|
else
|
|
{
|
|
if(pAxis)
|
|
{
|
|
pAxis->x = 1.0;
|
|
pAxis->y = 0.0;
|
|
pAxis->z = 0.0;
|
|
}
|
|
|
|
if(pAngle)
|
|
*pAngle = 0.0f;
|
|
}
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationMatrix
|
|
( D3DXQUATERNION *pOut, const D3DXMATRIX *pM)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
|
|
// article "Quaternion Calculus and Fast Animation". (Taken from GDMAG feb'98 p38)
|
|
|
|
float trace = pM->m00 + pM->m11 + pM->m22;
|
|
float root;
|
|
|
|
if ( trace > 0.0f )
|
|
{
|
|
// |w| > 1/2, may as well choose w > 1/2
|
|
|
|
root = sqrtf(trace + 1.0f); // 2w
|
|
pOut->w = 0.5f * root;
|
|
|
|
root = 0.5f / root; // 1/(4w)
|
|
pOut->x = (pM->m12 - pM->m21) * root;
|
|
pOut->y = (pM->m20 - pM->m02) * root;
|
|
pOut->z = (pM->m01 - pM->m10) * root;
|
|
}
|
|
else
|
|
{
|
|
// |w| <= 1/2
|
|
static const int next[3] = { 1, 2, 0 };
|
|
|
|
int i = 0;
|
|
i += (pM->m11 > pM->m00);
|
|
i += (pM->m22 > pM->m[i][i]);
|
|
|
|
int j = next[i];
|
|
int k = next[j];
|
|
|
|
root = sqrtf(pM->m[i][i] - pM->m[j][j] - pM->m[k][k] + 1.0f);
|
|
(*pOut)[i] = 0.5f * root;
|
|
|
|
if(0.0f != root)
|
|
root = 0.5f / root;
|
|
|
|
pOut->w = (pM->m[j][k] - pM->m[k][j]) * root;
|
|
(*pOut)[j] = (pM->m[i][j] + pM->m[j][i]) * root;
|
|
(*pOut)[k] = (pM->m[i][k] + pM->m[k][i]) * root;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationAxis
|
|
( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pV, float angle )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXVECTOR3 v;
|
|
VB_D3DXVec3Normalize(&v, pV);
|
|
|
|
float s;
|
|
sincosf(0.5f * angle, &s, &pOut->w);
|
|
|
|
pOut->x = v.x * s;
|
|
pOut->y = v.y * s;
|
|
pOut->z = v.z * s;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationYawPitchRoll
|
|
( D3DXQUATERNION *pOut, float yaw, float pitch, float roll )
|
|
{
|
|
#if DBG
|
|
if(!pOut)
|
|
return NULL;
|
|
#endif
|
|
|
|
// Roll first, about axis the object is facing, then
|
|
// pitch upward, then yaw to face into the new heading
|
|
|
|
float SR, CR, SP, CP, SY, CY;
|
|
|
|
sincosf(0.5f * roll, &SR, &CR);
|
|
sincosf(0.5f * pitch, &SP, &CP);
|
|
sincosf(0.5f * yaw, &SY, &CY);
|
|
|
|
pOut->x = CY*SP*CR + SY*CP*SR;
|
|
pOut->y = SY*CP*CR - CY*SP*SR;
|
|
pOut->z = CY*CP*SR - SY*SP*CR;
|
|
pOut->w = CY*CP*CR + SY*SP*SR;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionMultiply
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
|
|
const D3DXQUATERNION *pQ2 )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ1 || !pQ2)
|
|
return NULL;
|
|
#endif
|
|
|
|
|
|
#ifdef _X86_
|
|
__asm {
|
|
mov eax, DWORD PTR [pQ2]
|
|
mov edx, DWORD PTR [pQ1]
|
|
mov ecx, DWORD PTR [pOut]
|
|
|
|
fld DWORD PTR [eax+3*4]
|
|
fmul DWORD PTR [edx+0*4] ; wx
|
|
fld DWORD PTR [eax+3*4]
|
|
fmul DWORD PTR [edx+2*4] ; wz
|
|
fld DWORD PTR [eax+3*4]
|
|
fmul DWORD PTR [edx+1*4] ; wy
|
|
fld DWORD PTR [eax+3*4]
|
|
fmul DWORD PTR [edx+3*4] ; ww
|
|
fxch st(3)
|
|
// wx wy wz ww
|
|
|
|
fld DWORD PTR [eax+0*4]
|
|
fmul DWORD PTR [edx+3*4] ; xw
|
|
fld DWORD PTR [eax+0*4]
|
|
fmul DWORD PTR [edx+1*4] ; xy
|
|
fld DWORD PTR [eax+0*4]
|
|
fmul DWORD PTR [edx+2*4] ; xz
|
|
fld DWORD PTR [eax+0*4]
|
|
fmul DWORD PTR [edx+0*4] ; xx
|
|
fxch st(3)
|
|
// xw xz xy xx wx wy wz ww
|
|
|
|
faddp st(4), st
|
|
fsubp st(4), st
|
|
faddp st(4), st
|
|
fsubp st(4), st
|
|
// wx-xw wy-xz wz+xy ww-xx
|
|
|
|
fld DWORD PTR [eax+1*4]
|
|
fmul DWORD PTR [edx+2*4] ; yz
|
|
fld DWORD PTR [eax+1*4]
|
|
fmul DWORD PTR [edx+0*4] ; yx
|
|
fld DWORD PTR [eax+1*4]
|
|
fmul DWORD PTR [edx+3*4] ; yw
|
|
fld DWORD PTR [eax+1*4]
|
|
fmul DWORD PTR [edx+1*4] ; yy
|
|
fxch st(3)
|
|
// yz yw yx yy wx-xw wy-xz wz+xy ww-xx
|
|
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
fsubp st(4), st
|
|
fsubp st(4), st
|
|
// wx-xw+yz wy-xz+yw wz+xy-yx ww-xx-yy
|
|
|
|
fld DWORD PTR [eax+2*4]
|
|
fmul DWORD PTR [edx+1*4] ; zy
|
|
fld DWORD PTR [eax+2*4]
|
|
fmul DWORD PTR [edx+3*4] ; zw
|
|
fld DWORD PTR [eax+2*4]
|
|
fmul DWORD PTR [edx+0*4] ; zx
|
|
fld DWORD PTR [eax+2*4]
|
|
fmul DWORD PTR [edx+2*4] ; zz
|
|
fxch st(3)
|
|
// zy zx zw zz wx-xw+yz wy-xz+yw wz+xy-yx ww-xx-yy
|
|
|
|
fsubp st(4), st
|
|
faddp st(4), st
|
|
faddp st(4), st
|
|
fsubp st(4), st
|
|
// wx-xw+yz-zy wy-xz+yw+zx wz+xy-yx+zw ww-xx-yy-zz
|
|
|
|
fstp DWORD PTR [ecx+0*4]
|
|
fstp DWORD PTR [ecx+1*4]
|
|
fstp DWORD PTR [ecx+2*4]
|
|
fstp DWORD PTR [ecx+3*4]
|
|
}
|
|
|
|
return pOut;
|
|
|
|
#else // !_X86_
|
|
D3DXQUATERNION Q;
|
|
|
|
Q.x = pQ2->w * pQ1->x + pQ2->x * pQ1->w + pQ2->y * pQ1->z - pQ2->z * pQ1->y;
|
|
Q.y = pQ2->w * pQ1->y - pQ2->x * pQ1->z + pQ2->y * pQ1->w + pQ2->z * pQ1->x;
|
|
Q.z = pQ2->w * pQ1->z + pQ2->x * pQ1->y - pQ2->y * pQ1->x + pQ2->z * pQ1->w;
|
|
Q.w = pQ2->w * pQ1->w - pQ2->x * pQ1->x - pQ2->y * pQ1->y - pQ2->z * pQ1->z;
|
|
|
|
*pOut = Q;
|
|
return pOut;
|
|
#endif // !_X86_
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionNormalize
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = VB_D3DXQuaternionLengthSq(pQ);
|
|
|
|
if(WithinEpsilon(f, 1.0f))
|
|
{
|
|
if(pOut != pQ)
|
|
*pOut = *pQ;
|
|
}
|
|
else if(f > EPSILON * EPSILON)
|
|
{
|
|
*pOut = *pQ / sqrtf(f);
|
|
}
|
|
else
|
|
{
|
|
pOut->x = 0.0f;
|
|
pOut->y = 0.0f;
|
|
pOut->z = 0.0f;
|
|
pOut->w = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionInverse
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = VB_D3DXQuaternionLengthSq(pQ);
|
|
|
|
if(f > EPSILON*EPSILON)
|
|
{
|
|
VB_D3DXQuaternionConjugate(pOut, pQ);
|
|
|
|
if(!WithinEpsilon(f, 1.0f))
|
|
*pOut /= f;
|
|
}
|
|
else
|
|
{
|
|
pOut->x = 0.0f;
|
|
pOut->y = 0.0f;
|
|
pOut->z = 0.0f;
|
|
pOut->w = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionLn
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ)
|
|
return NULL;
|
|
#endif
|
|
|
|
// expects unit quaternions!
|
|
// q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v)
|
|
|
|
float theta, s, scale;
|
|
|
|
if(pQ->w < 1.0f)
|
|
{
|
|
theta = acosf(pQ->w);
|
|
s = sinf(theta);
|
|
|
|
if(!WithinEpsilon(s, 0.0f))
|
|
{
|
|
float scale = theta / s;
|
|
pOut->x = pQ->x * scale;
|
|
pOut->y = pQ->y * scale;
|
|
pOut->z = pQ->z * scale;
|
|
pOut->w = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
pOut->x = pQ->x;
|
|
pOut->y = pQ->y;
|
|
pOut->z = pQ->z;
|
|
pOut->w = 0.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pOut->x = pQ->x;
|
|
pOut->y = pQ->y;
|
|
pOut->z = pQ->z;
|
|
pOut->w = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionExp
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ)
|
|
return NULL;
|
|
#endif
|
|
|
|
// expects pure quaternions! (w == 0)
|
|
// q = (0, theta * v) ; exp(q) = (cos(theta), sin(theta) * v)
|
|
|
|
float theta, s;
|
|
|
|
theta = sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z);
|
|
sincosf(theta, &s, &pOut->w);
|
|
|
|
if(WithinEpsilon(s, 0.0f))
|
|
{
|
|
if(pOut != pQ)
|
|
{
|
|
pOut->x = pQ->x;
|
|
pOut->y = pQ->y;
|
|
pOut->z = pQ->z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s /= theta;
|
|
|
|
pOut->x = pQ->x * s;
|
|
pOut->y = pQ->y * s;
|
|
pOut->z = pQ->z * s;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionSlerp
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
|
|
const D3DXQUATERNION *pQ2, float b )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ1 || !pQ2)
|
|
return NULL;
|
|
#endif
|
|
|
|
// expects unit quaternions!
|
|
float a, c, flip, s, omega, sInv;
|
|
|
|
a = 1.0f - b;
|
|
c = VB_D3DXQuaternionDot(pQ1, pQ2);
|
|
flip = (c >= 0.0f) ? 1.0f : -1.0f;
|
|
c *= flip;
|
|
|
|
if(1.0f - c > EPSILON) {
|
|
s = sqrtf(1.0f - c * c);
|
|
omega = atan2f(s, c);
|
|
sInv = 1.0f / s;
|
|
|
|
a = sinf(a * omega) * sInv;
|
|
b = sinf(b * omega) * sInv;
|
|
}
|
|
|
|
b *= flip;
|
|
|
|
pOut->x = a * pQ1->x + b * pQ2->x;
|
|
pOut->y = a * pQ1->y + b * pQ2->y;
|
|
pOut->z = a * pQ1->z + b * pQ2->z;
|
|
pOut->w = a * pQ1->w + b * pQ2->w;
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionSquad
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
|
|
const D3DXQUATERNION *pQ2, const D3DXQUATERNION *pQ3,
|
|
const D3DXQUATERNION *pQ4, float t )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ1 || !pQ2 || !pQ3 || !pQ4)
|
|
return NULL;
|
|
#endif
|
|
|
|
// expects unit quaternions!
|
|
D3DXQUATERNION QA, QB;
|
|
|
|
VB_D3DXQuaternionSlerp(&QA, pQ1, pQ4, t);
|
|
VB_D3DXQuaternionSlerp(&QB, pQ2, pQ3, t);
|
|
VB_D3DXQuaternionSlerp(pOut, &QA, &QB, 2.0f * t * (1.0f - t));
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXQUATERNION* WINAPI VB_D3DXQuaternionBaryCentric
|
|
( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
|
|
const D3DXQUATERNION *pQ2, const D3DXQUATERNION *pQ3,
|
|
float f, float g )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pQ1 || !pQ2 || !pQ3)
|
|
return NULL;
|
|
#endif
|
|
|
|
// expects unit quaternions!
|
|
D3DXQUATERNION QA, QB;
|
|
float s = f + g;
|
|
|
|
if(WithinEpsilon(s, 0.0f))
|
|
{
|
|
if(pOut != pQ1)
|
|
*pOut = *pQ1;
|
|
}
|
|
else
|
|
{
|
|
VB_D3DXQuaternionSlerp(&QA, pQ1, pQ2, s);
|
|
VB_D3DXQuaternionSlerp(&QB, pQ1, pQ3, s);
|
|
VB_D3DXQuaternionSlerp(pOut, &QA, &QB, g / s);
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
|
|
//--------------------------
|
|
// Plane
|
|
//--------------------------
|
|
|
|
D3DXPLANE* WINAPI VB_D3DXPlaneNormalize
|
|
( D3DXPLANE *pOut, const D3DXPLANE *pP )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pP)
|
|
return NULL;
|
|
#endif
|
|
|
|
float f = pP->a * pP->a + pP->b * pP->b + pP->c * pP->c;
|
|
|
|
if(WithinEpsilon(f, 1.0f))
|
|
{
|
|
if(pOut != pP)
|
|
*pOut = *pP;
|
|
}
|
|
else if(f > EPSILON * EPSILON)
|
|
{
|
|
float fInv = 1.0f / sqrtf(f);
|
|
|
|
pOut->a = pP->a * fInv;
|
|
pOut->b = pP->b * fInv;
|
|
pOut->c = pP->c * fInv;
|
|
pOut->d = pP->d * fInv;
|
|
}
|
|
else
|
|
{
|
|
pOut->a = 0.0f;
|
|
pOut->b = 0.0f;
|
|
pOut->c = 0.0f;
|
|
pOut->d = 0.0f;
|
|
}
|
|
|
|
return pOut;
|
|
}
|
|
|
|
D3DXVECTOR3* WINAPI VB_D3DXPlaneIntersectLine
|
|
( D3DXVECTOR3 *pOut, const D3DXPLANE *pP, const D3DXVECTOR3 *pV1,
|
|
const D3DXVECTOR3 *pV2)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pP || !pV1 || !pV2)
|
|
return NULL;
|
|
#endif
|
|
|
|
float d = VB_D3DXPlaneDotNormal(pP, pV1) - VB_D3DXPlaneDotNormal(pP, pV2);
|
|
|
|
if(d == 0.0f)
|
|
return NULL;
|
|
|
|
float f = VB_D3DXPlaneDotCoord(pP, pV1) / d;
|
|
|
|
if(!_finite(f))
|
|
return NULL;
|
|
|
|
VB_D3DXVec3Lerp(pOut, pV1, pV2, f);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXPLANE* WINAPI VB_D3DXPlaneFromPointNormal
|
|
( D3DXPLANE *pOut, const D3DXVECTOR3 *pPoint, const D3DXVECTOR3 *pNormal)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pPoint || !pNormal)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->a = pNormal->x;
|
|
pOut->b = pNormal->y;
|
|
pOut->c = pNormal->z;
|
|
pOut->d = -VB_D3DXVec3Dot(pPoint, pNormal);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXPLANE* WINAPI VB_D3DXPlaneFromPoints
|
|
( D3DXPLANE *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pV2,
|
|
const D3DXVECTOR3 *pV3)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pV1 || !pV2 || !pV3)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXVECTOR3 V12 = *pV1 - *pV2;
|
|
D3DXVECTOR3 V13 = *pV1 - *pV3;
|
|
|
|
VB_D3DXVec3Cross((D3DXVECTOR3 *) pOut, &V12, &V13);
|
|
VB_D3DXVec3Normalize((D3DXVECTOR3 *) pOut, (D3DXVECTOR3 *) pOut);
|
|
|
|
pOut->d = -VB_D3DXPlaneDotNormal(pOut, pV1);
|
|
return pOut;
|
|
}
|
|
|
|
D3DXPLANE* WINAPI VB_D3DXPlaneTransform
|
|
( D3DXPLANE *pOut, const D3DXPLANE *pP, const D3DXMATRIX *pM )
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pP || !pM)
|
|
return NULL;
|
|
#endif
|
|
|
|
D3DXPLANE P;
|
|
VB_D3DXPlaneNormalize(&P, pP);
|
|
|
|
D3DXVECTOR3 V(-P.a * P.d, -P.b * P.d, -P.c * P.d);
|
|
VB_D3DXVec3TransformCoord(&V, &V, pM);
|
|
|
|
VB_D3DXVec3TransformNormal((D3DXVECTOR3 *) pOut, (const D3DXVECTOR3 *) &P, pM);
|
|
VB_D3DXVec3Normalize((D3DXVECTOR3 *) pOut, (const D3DXVECTOR3 *) pOut);
|
|
|
|
pOut->d = -VB_D3DXPlaneDotNormal(pOut, &V);
|
|
return pOut;
|
|
}
|
|
|
|
|
|
//--------------------------
|
|
// Color
|
|
//--------------------------
|
|
|
|
D3DXCOLOR* WINAPI VB_D3DXColorAdjustSaturation
|
|
(D3DXCOLOR *pOut, const D3DXCOLOR *pC, float s)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pC)
|
|
return NULL;
|
|
#endif
|
|
|
|
// Approximate values for each component's contribution to luminance.
|
|
// (Based upon the NTSC standard described in the comp.graphics.algorithms
|
|
// colorspace FAQ)
|
|
float grey = pC->r * 0.2125f + pC->g * 0.7154f + pC->b * 0.0721f;
|
|
|
|
pOut->r = grey + s * (pC->r - grey);
|
|
pOut->g = grey + s * (pC->g - grey);
|
|
pOut->b = grey + s * (pC->b - grey);
|
|
pOut->a = pC->a;
|
|
return pOut;
|
|
}
|
|
|
|
D3DXCOLOR* WINAPI VB_D3DXColorAdjustContrast
|
|
(D3DXCOLOR *pOut, const D3DXCOLOR *pC, float c)
|
|
{
|
|
#if DBG
|
|
if(!pOut || !pC)
|
|
return NULL;
|
|
#endif
|
|
|
|
pOut->r = 0.5f + c * (pC->r - 0.5f);
|
|
pOut->g = 0.5f + c * (pC->g - 0.5f);
|
|
pOut->b = 0.5f + c * (pC->b - 0.5f);
|
|
pOut->a = pC->a;
|
|
return pOut;
|
|
}
|
|
|