Code: Select all
#pragma once
static const float SZero = 0;
__declspec(align(16)) struct Vector3D
{
#pragma region Constructor
public: Vector3D()
{
X = 0;
Y = 0;
Z = 0;
W = 0;
}
public: Vector3D(float x, float y, float z)
{
X = x;
Y = y;
Z = z;
W = 0;
}
#pragma endregion
#pragma region Destructor
public: ~Vector3D(void)
{
}
#pragma endregion
#pragma region Fields
public: float X;
public: float Y;
public: float Z;
private: float W;
#pragma endregion
#pragma region Properties
#pragma endregion
#pragma region Operator Overloads
#pragma endregion
#pragma region Methods
public: void NormalizePrecise()
{
_asm
{
//get length
mov eax, this
movd xmm0, dword ptr ds:[eax]
movd xmm1, dword ptr ds:[eax + 4]
movd xmm2, dword ptr ds:[eax + 8]
mulss xmm0, xmm0
mulss xmm1, xmm1
mulss xmm2, xmm2
addss xmm0, xmm1
addss xmm0, xmm2
sqrtss xmm0, xmm0
ucomiss xmm0, SZero
je Done
//duplicate length across register
pshufd xmm0, xmm0, 0
//divide by length
movdqa xmm1, xmmword ptr ds:[eax]
divps xmm1, xmm0
//store result
movdqa xmmword ptr ds:[eax], xmm1
Done:
}
}
public: void Normalize()
{
_asm
{
//get recipricol length
mov eax, this
movd xmm0, dword ptr ds:[eax]
movd xmm1, dword ptr ds:[eax + 4]
movd xmm2, dword ptr ds:[eax + 8]
mulss xmm0, xmm0
mulss xmm1, xmm1
mulss xmm2, xmm2
addss xmm0, xmm1
addss xmm0, xmm2
ucomiss xmm0, SZero
je Done
rsqrtss xmm0, xmm0
//duplicate length across register
pshufd xmm0, xmm0, 0
//multiply by recipricol length (divide by length)
movdqa xmm1, xmmword ptr ds:[eax]
mulps xmm1, xmm0
//store result
movdqa xmmword ptr ds:[eax], xmm1
Done:
}
}
public: void Absolute()
{
_asm
{
mov eax, this
and dword ptr ds:[eax], 07FFFFFFFh
and dword ptr ds:[eax + 4], 07FFFFFFFh
and dword ptr ds:[eax + 8], 07FFFFFFFh
}
}
public: void Maximize(const Vector3D &v1)
{
_asm
{
//get parameter information
mov eax, v1
movdqa xmm0, xmmword ptr ds:[eax]
mov eax, this
//compute maximum
maxps xmm0, xmmword ptr ds:[eax]
//store result
movdqa xmmword ptr ds:[eax], xmm0
}
}
public: void Minimize(const Vector3D &v1)
{
_asm
{
//get parameter information
mov eax, v1
movdqa xmm0, xmmword ptr ds:[eax]
mov eax, this
//compute minimum
minps xmm0, xmmword ptr ds:[eax]
//store result
movdqa xmmword ptr ds:[eax], xmm0
}
}
public: void Cross(const Vector3D &v1)
{
_asm
{
//get parameter information
mov eax, v1
movdqa xmm0, xmmword ptr ds:[eax]
mov eax, this
movdqa xmm1, xmmword ptr ds:[eax]
//align vectors to be multiplied
pshufd xmm2, xmm0, 11001001b //(v1.Y, v1.Z, v1.X)
pshufd xmm4, xmm1, 11001001b //(Y, Z, X)
pshufd xmm3, xmm0, 11010010b //(v1.Z, v1.X, v1.Y)
pshufd xmm5, xmm1, 11010010b //(Z, X, Y)
//perform cross-product
mulps xmm4, xmm3
mulps xmm5, xmm2
subps xmm4, xmm5
//store result
movdqa xmmword ptr ds:[eax], xmm4
}
}
public: void Lerp(const Vector3D &v1, float interpolator)
{
_asm
{
//get parameter information
mov eax, v1
movdqa xmm0, xmmword ptr ds:[eax]
mov eax, this
movdqa xmm1, xmmword ptr ds:[eax]
//duplicate interpolator across register
pshufd xmm2, interpolator, 0
//interpolate
subps xmm0, xmm1
mulps xmm0, xmm2
addps xmm0, xmm1
//store result
movdqa xmmword ptr ds:[eax], xmm0
}
}
#pragma endregion
};