//------------------------------------------------------------------------------------- // SimpleMath.inl -- Simplified C++ Math wrapper for DirectXMath // // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. // // http://go.microsoft.com/fwlink/?LinkId=248929 // http://go.microsoft.com/fwlink/?LinkID=615561 //------------------------------------------------------------------------------------- #pragma once /**************************************************************************** * * Rectangle * ****************************************************************************/ //------------------------------------------------------------------------------ // Rectangle operations //------------------------------------------------------------------------------ inline Vector2 Rectangle::Location() const noexcept { return Vector2(float(x), float(y)); } inline Vector2 Rectangle::Center() const noexcept { return Vector2(float(x) + (float(width) / 2.f), float(y) + (float(height) / 2.f)); } inline bool Rectangle::Contains(const Vector2& point) const noexcept { return (float(x) <= point.x) && (point.x < float(x + width)) && (float(y) <= point.y) && (point.y < float(y + height)); } inline void Rectangle::Inflate(long horizAmount, long vertAmount) noexcept { x -= horizAmount; y -= vertAmount; width += horizAmount; height += vertAmount; } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline Rectangle Rectangle::Intersect(const Rectangle& ra, const Rectangle& rb) noexcept { long righta = ra.x + ra.width; long rightb = rb.x + rb.width; long bottoma = ra.y + ra.height; long bottomb = rb.y + rb.height; long maxX = ra.x > rb.x ? ra.x : rb.x; long maxY = ra.y > rb.y ? ra.y : rb.y; long minRight = righta < rightb ? righta : rightb; long minBottom = bottoma < bottomb ? bottoma : bottomb; Rectangle result; if ((minRight > maxX) && (minBottom > maxY)) { result.x = maxX; result.y = maxY; result.width = minRight - maxX; result.height = minBottom - maxY; } else { result.x = 0; result.y = 0; result.width = 0; result.height = 0; } return result; } inline RECT Rectangle::Intersect(const RECT& rcta, const RECT& rctb) noexcept { long maxX = rcta.left > rctb.left ? rcta.left : rctb.left; long maxY = rcta.top > rctb.top ? rcta.top : rctb.top; long minRight = rcta.right < rctb.right ? rcta.right : rctb.right; long minBottom = rcta.bottom < rctb.bottom ? rcta.bottom : rctb.bottom; RECT result; if ((minRight > maxX) && (minBottom > maxY)) { result.left = maxX; result.top = maxY; result.right = minRight; result.bottom = minBottom; } else { result.left = 0; result.top = 0; result.right = 0; result.bottom = 0; } return result; } inline Rectangle Rectangle::Union(const Rectangle& ra, const Rectangle& rb) noexcept { long righta = ra.x + ra.width; long rightb = rb.x + rb.width; long bottoma = ra.y + ra.height; long bottomb = rb.y + rb.height; int minX = ra.x < rb.x ? ra.x : rb.x; int minY = ra.y < rb.y ? ra.y : rb.y; int maxRight = righta > rightb ? righta : rightb; int maxBottom = bottoma > bottomb ? bottoma : bottomb; Rectangle result; result.x = minX; result.y = minY; result.width = maxRight - minX; result.height = maxBottom - minY; return result; } inline RECT Rectangle::Union(const RECT& rcta, const RECT& rctb) noexcept { RECT result; result.left = rcta.left < rctb.left ? rcta.left : rctb.left; result.top = rcta.top < rctb.top ? rcta.top : rctb.top; result.right = rcta.right > rctb.right ? rcta.right : rctb.right; result.bottom = rcta.bottom > rctb.bottom ? rcta.bottom : rctb.bottom; return result; } /**************************************************************************** * * Vector2 * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Vector2::operator == (const Vector2& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); return XMVector2Equal(v1, v2); } inline bool Vector2::operator != (const Vector2& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); return XMVector2NotEqual(v1, v2); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Vector2& Vector2::operator+= (const Vector2& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR X = XMVectorAdd(v1, v2); XMStoreFloat2(this, X); return *this; } inline Vector2& Vector2::operator-= (const Vector2& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR X = XMVectorSubtract(v1, v2); XMStoreFloat2(this, X); return *this; } inline Vector2& Vector2::operator*= (const Vector2& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR X = XMVectorMultiply(v1, v2); XMStoreFloat2(this, X); return *this; } inline Vector2& Vector2::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVectorScale(v1, S); XMStoreFloat2(this, X); return *this; } inline Vector2& Vector2::operator/= (float S) noexcept { using namespace DirectX; assert(S != 0.0f); XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVectorScale(v1, 1.f / S); XMStoreFloat2(this, X); return *this; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Vector2 operator+ (const Vector2& V1, const Vector2& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V1); XMVECTOR v2 = XMLoadFloat2(&V2); XMVECTOR X = XMVectorAdd(v1, v2); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator- (const Vector2& V1, const Vector2& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V1); XMVECTOR v2 = XMLoadFloat2(&V2); XMVECTOR X = XMVectorSubtract(v1, v2); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator* (const Vector2& V1, const Vector2& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V1); XMVECTOR v2 = XMLoadFloat2(&V2); XMVECTOR X = XMVectorMultiply(v1, v2); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator* (const Vector2& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V); XMVECTOR X = XMVectorScale(v1, S); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator/ (const Vector2& V1, const Vector2& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V1); XMVECTOR v2 = XMLoadFloat2(&V2); XMVECTOR X = XMVectorDivide(v1, v2); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator/ (const Vector2& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V); XMVECTOR X = XMVectorScale(v1, 1.f / S); Vector2 R; XMStoreFloat2(&R, X); return R; } inline Vector2 operator* (float S, const Vector2& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&V); XMVECTOR X = XMVectorScale(v1, S); Vector2 R; XMStoreFloat2(&R, X); return R; } //------------------------------------------------------------------------------ // Vector operations //------------------------------------------------------------------------------ inline bool Vector2::InBounds(const Vector2& Bounds) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&Bounds); return XMVector2InBounds(v1, v2); } inline float Vector2::Length() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVector2Length(v1); return XMVectorGetX(X); } inline float Vector2::LengthSquared() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVector2LengthSq(v1); return XMVectorGetX(X); } inline float Vector2::Dot(const Vector2& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR X = XMVector2Dot(v1, v2); return XMVectorGetX(X); } inline void Vector2::Cross(const Vector2& V, Vector2& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR R = XMVector2Cross(v1, v2); XMStoreFloat2(&result, R); } inline Vector2 Vector2::Cross(const Vector2& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&V); XMVECTOR R = XMVector2Cross(v1, v2); Vector2 result; XMStoreFloat2(&result, R); return result; } inline void Vector2::Normalize() noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVector2Normalize(v1); XMStoreFloat2(this, X); } inline void Vector2::Normalize(Vector2& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR X = XMVector2Normalize(v1); XMStoreFloat2(&result, X); } inline void Vector2::Clamp(const Vector2& vmin, const Vector2& vmax) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&vmin); XMVECTOR v3 = XMLoadFloat2(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat2(this, X); } inline void Vector2::Clamp(const Vector2& vmin, const Vector2& vmax, Vector2& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(this); XMVECTOR v2 = XMLoadFloat2(&vmin); XMVECTOR v3 = XMLoadFloat2(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat2(&result, X); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline float Vector2::Distance(const Vector2& v1, const Vector2& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector2Length(V); return XMVectorGetX(X); } inline float Vector2::DistanceSquared(const Vector2& v1, const Vector2& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector2LengthSq(V); return XMVectorGetX(X); } inline void Vector2::Min(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorMin(x1, x2); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Min(const Vector2& v1, const Vector2& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorMin(x1, x2); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Max(const Vector2& v1, const Vector2& v2, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorMax(x1, x2); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Max(const Vector2& v1, const Vector2& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorMax(x1, x2); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Lerp(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::SmoothStep(const Vector2& v1, const Vector2& v2, float t, Vector2& result) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat2(&result, X); } inline Vector2 Vector2::SmoothStep(const Vector2& v1, const Vector2& v2, float t) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR x3 = XMLoadFloat2(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Barycentric(const Vector2& v1, const Vector2& v2, const Vector2& v3, float f, float g) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR x3 = XMLoadFloat2(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR x3 = XMLoadFloat2(&v3); XMVECTOR x4 = XMLoadFloat2(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); XMStoreFloat2(&result, X); } inline Vector2 Vector2::CatmullRom(const Vector2& v1, const Vector2& v2, const Vector2& v3, const Vector2& v4, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&v2); XMVECTOR x3 = XMLoadFloat2(&v3); XMVECTOR x4 = XMLoadFloat2(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t, Vector2& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&t1); XMVECTOR x3 = XMLoadFloat2(&v2); XMVECTOR x4 = XMLoadFloat2(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Hermite(const Vector2& v1, const Vector2& t1, const Vector2& v2, const Vector2& t2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat2(&v1); XMVECTOR x2 = XMLoadFloat2(&t1); XMVECTOR x3 = XMLoadFloat2(&v2); XMVECTOR x4 = XMLoadFloat2(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Reflect(const Vector2& ivec, const Vector2& nvec, Vector2& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat2(&ivec); XMVECTOR n = XMLoadFloat2(&nvec); XMVECTOR X = XMVector2Reflect(i, n); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Reflect(const Vector2& ivec, const Vector2& nvec) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat2(&ivec); XMVECTOR n = XMLoadFloat2(&nvec); XMVECTOR X = XMVector2Reflect(i, n); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex, Vector2& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat2(&ivec); XMVECTOR n = XMLoadFloat2(&nvec); XMVECTOR X = XMVector2Refract(i, n, refractionIndex); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Refract(const Vector2& ivec, const Vector2& nvec, float refractionIndex) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat2(&ivec); XMVECTOR n = XMLoadFloat2(&nvec); XMVECTOR X = XMVector2Refract(i, n, refractionIndex); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Transform(const Vector2& v, const Quaternion& quat, Vector2& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Transform(const Vector2& v, const Quaternion& quat) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); Vector2 result; XMStoreFloat2(&result, X); return result; } inline void Vector2::Transform(const Vector2& v, const Matrix& m, Vector2& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector2TransformCoord(v1, M); XMStoreFloat2(&result, X); } inline Vector2 Vector2::Transform(const Vector2& v, const Matrix& m) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector2TransformCoord(v1, M); Vector2 result; XMStoreFloat2(&result, X); return result; } _Use_decl_annotations_ inline void Vector2::Transform(const Vector2* varray, size_t count, const Matrix& m, Vector2* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector2TransformCoordStream(resultArray, sizeof(XMFLOAT2), varray, sizeof(XMFLOAT2), count, M); } inline void Vector2::Transform(const Vector2& v, const Matrix& m, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector2Transform(v1, M); XMStoreFloat4(&result, X); } _Use_decl_annotations_ inline void Vector2::Transform(const Vector2* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector2TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT2), count, M); } inline void Vector2::TransformNormal(const Vector2& v, const Matrix& m, Vector2& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector2TransformNormal(v1, M); XMStoreFloat2(&result, X); } inline Vector2 Vector2::TransformNormal(const Vector2& v, const Matrix& m) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector2TransformNormal(v1, M); Vector2 result; XMStoreFloat2(&result, X); return result; } _Use_decl_annotations_ inline void Vector2::TransformNormal(const Vector2* varray, size_t count, const Matrix& m, Vector2* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector2TransformNormalStream(resultArray, sizeof(XMFLOAT2), varray, sizeof(XMFLOAT2), count, M); } /**************************************************************************** * * Vector3 * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Vector3::operator == (const Vector3& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); return XMVector3Equal(v1, v2); } inline bool Vector3::operator != (const Vector3& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); return XMVector3NotEqual(v1, v2); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Vector3& Vector3::operator+= (const Vector3& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR X = XMVectorAdd(v1, v2); XMStoreFloat3(this, X); return *this; } inline Vector3& Vector3::operator-= (const Vector3& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR X = XMVectorSubtract(v1, v2); XMStoreFloat3(this, X); return *this; } inline Vector3& Vector3::operator*= (const Vector3& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR X = XMVectorMultiply(v1, v2); XMStoreFloat3(this, X); return *this; } inline Vector3& Vector3::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVectorScale(v1, S); XMStoreFloat3(this, X); return *this; } inline Vector3& Vector3::operator/= (float S) noexcept { using namespace DirectX; assert(S != 0.0f); XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVectorScale(v1, 1.f / S); XMStoreFloat3(this, X); return *this; } //------------------------------------------------------------------------------ // Urnary operators //------------------------------------------------------------------------------ inline Vector3 Vector3::operator- () const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVectorNegate(v1); Vector3 R; XMStoreFloat3(&R, X); return R; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Vector3 operator+ (const Vector3& V1, const Vector3& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V1); XMVECTOR v2 = XMLoadFloat3(&V2); XMVECTOR X = XMVectorAdd(v1, v2); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator- (const Vector3& V1, const Vector3& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V1); XMVECTOR v2 = XMLoadFloat3(&V2); XMVECTOR X = XMVectorSubtract(v1, v2); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator* (const Vector3& V1, const Vector3& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V1); XMVECTOR v2 = XMLoadFloat3(&V2); XMVECTOR X = XMVectorMultiply(v1, v2); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator* (const Vector3& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V); XMVECTOR X = XMVectorScale(v1, S); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator/ (const Vector3& V1, const Vector3& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V1); XMVECTOR v2 = XMLoadFloat3(&V2); XMVECTOR X = XMVectorDivide(v1, v2); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator/ (const Vector3& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V); XMVECTOR X = XMVectorScale(v1, 1.f / S); Vector3 R; XMStoreFloat3(&R, X); return R; } inline Vector3 operator* (float S, const Vector3& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&V); XMVECTOR X = XMVectorScale(v1, S); Vector3 R; XMStoreFloat3(&R, X); return R; } //------------------------------------------------------------------------------ // Vector operations //------------------------------------------------------------------------------ inline bool Vector3::InBounds(const Vector3& Bounds) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&Bounds); return XMVector3InBounds(v1, v2); } inline float Vector3::Length() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVector3Length(v1); return XMVectorGetX(X); } inline float Vector3::LengthSquared() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVector3LengthSq(v1); return XMVectorGetX(X); } inline float Vector3::Dot(const Vector3& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR X = XMVector3Dot(v1, v2); return XMVectorGetX(X); } inline void Vector3::Cross(const Vector3& V, Vector3& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR R = XMVector3Cross(v1, v2); XMStoreFloat3(&result, R); } inline Vector3 Vector3::Cross(const Vector3& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&V); XMVECTOR R = XMVector3Cross(v1, v2); Vector3 result; XMStoreFloat3(&result, R); return result; } inline void Vector3::Normalize() noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVector3Normalize(v1); XMStoreFloat3(this, X); } inline void Vector3::Normalize(Vector3& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR X = XMVector3Normalize(v1); XMStoreFloat3(&result, X); } inline void Vector3::Clamp(const Vector3& vmin, const Vector3& vmax) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&vmin); XMVECTOR v3 = XMLoadFloat3(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat3(this, X); } inline void Vector3::Clamp(const Vector3& vmin, const Vector3& vmax, Vector3& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(this); XMVECTOR v2 = XMLoadFloat3(&vmin); XMVECTOR v3 = XMLoadFloat3(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat3(&result, X); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline float Vector3::Distance(const Vector3& v1, const Vector3& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector3Length(V); return XMVectorGetX(X); } inline float Vector3::DistanceSquared(const Vector3& v1, const Vector3& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector3LengthSq(V); return XMVectorGetX(X); } inline void Vector3::Min(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorMin(x1, x2); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Min(const Vector3& v1, const Vector3& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorMin(x1, x2); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Max(const Vector3& v1, const Vector3& v2, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorMax(x1, x2); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Max(const Vector3& v1, const Vector3& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorMax(x1, x2); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Lerp(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::SmoothStep(const Vector3& v1, const Vector3& v2, float t, Vector3& result) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat3(&result, X); } inline Vector3 Vector3::SmoothStep(const Vector3& v1, const Vector3& v2, float t) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR x3 = XMLoadFloat3(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Barycentric(const Vector3& v1, const Vector3& v2, const Vector3& v3, float f, float g) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR x3 = XMLoadFloat3(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR x3 = XMLoadFloat3(&v3); XMVECTOR x4 = XMLoadFloat3(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); XMStoreFloat3(&result, X); } inline Vector3 Vector3::CatmullRom(const Vector3& v1, const Vector3& v2, const Vector3& v3, const Vector3& v4, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&v2); XMVECTOR x3 = XMLoadFloat3(&v3); XMVECTOR x4 = XMLoadFloat3(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t, Vector3& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&t1); XMVECTOR x3 = XMLoadFloat3(&v2); XMVECTOR x4 = XMLoadFloat3(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Hermite(const Vector3& v1, const Vector3& t1, const Vector3& v2, const Vector3& t2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat3(&v1); XMVECTOR x2 = XMLoadFloat3(&t1); XMVECTOR x3 = XMLoadFloat3(&v2); XMVECTOR x4 = XMLoadFloat3(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Reflect(const Vector3& ivec, const Vector3& nvec, Vector3& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat3(&ivec); XMVECTOR n = XMLoadFloat3(&nvec); XMVECTOR X = XMVector3Reflect(i, n); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Reflect(const Vector3& ivec, const Vector3& nvec) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat3(&ivec); XMVECTOR n = XMLoadFloat3(&nvec); XMVECTOR X = XMVector3Reflect(i, n); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex, Vector3& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat3(&ivec); XMVECTOR n = XMLoadFloat3(&nvec); XMVECTOR X = XMVector3Refract(i, n, refractionIndex); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Refract(const Vector3& ivec, const Vector3& nvec, float refractionIndex) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat3(&ivec); XMVECTOR n = XMLoadFloat3(&nvec); XMVECTOR X = XMVector3Refract(i, n, refractionIndex); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Transform(const Vector3& v, const Quaternion& quat, Vector3& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Transform(const Vector3& v, const Quaternion& quat) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); Vector3 result; XMStoreFloat3(&result, X); return result; } inline void Vector3::Transform(const Vector3& v, const Matrix& m, Vector3& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector3TransformCoord(v1, M); XMStoreFloat3(&result, X); } inline Vector3 Vector3::Transform(const Vector3& v, const Matrix& m) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector3TransformCoord(v1, M); Vector3 result; XMStoreFloat3(&result, X); return result; } _Use_decl_annotations_ inline void Vector3::Transform(const Vector3* varray, size_t count, const Matrix& m, Vector3* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector3TransformCoordStream(resultArray, sizeof(XMFLOAT3), varray, sizeof(XMFLOAT3), count, M); } inline void Vector3::Transform(const Vector3& v, const Matrix& m, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector3Transform(v1, M); XMStoreFloat4(&result, X); } _Use_decl_annotations_ inline void Vector3::Transform(const Vector3* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector3TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT3), count, M); } inline void Vector3::TransformNormal(const Vector3& v, const Matrix& m, Vector3& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector3TransformNormal(v1, M); XMStoreFloat3(&result, X); } inline Vector3 Vector3::TransformNormal(const Vector3& v, const Matrix& m) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector3TransformNormal(v1, M); Vector3 result; XMStoreFloat3(&result, X); return result; } _Use_decl_annotations_ inline void Vector3::TransformNormal(const Vector3* varray, size_t count, const Matrix& m, Vector3* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector3TransformNormalStream(resultArray, sizeof(XMFLOAT3), varray, sizeof(XMFLOAT3), count, M); } /**************************************************************************** * * Vector4 * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Vector4::operator == (const Vector4& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); return XMVector4Equal(v1, v2); } inline bool Vector4::operator != (const Vector4& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); return XMVector4NotEqual(v1, v2); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Vector4& Vector4::operator+= (const Vector4& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); XMVECTOR X = XMVectorAdd(v1, v2); XMStoreFloat4(this, X); return *this; } inline Vector4& Vector4::operator-= (const Vector4& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); XMVECTOR X = XMVectorSubtract(v1, v2); XMStoreFloat4(this, X); return *this; } inline Vector4& Vector4::operator*= (const Vector4& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); XMVECTOR X = XMVectorMultiply(v1, v2); XMStoreFloat4(this, X); return *this; } inline Vector4& Vector4::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVectorScale(v1, S); XMStoreFloat4(this, X); return *this; } inline Vector4& Vector4::operator/= (float S) noexcept { using namespace DirectX; assert(S != 0.0f); XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVectorScale(v1, 1.f / S); XMStoreFloat4(this, X); return *this; } //------------------------------------------------------------------------------ // Urnary operators //------------------------------------------------------------------------------ inline Vector4 Vector4::operator- () const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVectorNegate(v1); Vector4 R; XMStoreFloat4(&R, X); return R; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Vector4 operator+ (const Vector4& V1, const Vector4& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V1); XMVECTOR v2 = XMLoadFloat4(&V2); XMVECTOR X = XMVectorAdd(v1, v2); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator- (const Vector4& V1, const Vector4& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V1); XMVECTOR v2 = XMLoadFloat4(&V2); XMVECTOR X = XMVectorSubtract(v1, v2); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator* (const Vector4& V1, const Vector4& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V1); XMVECTOR v2 = XMLoadFloat4(&V2); XMVECTOR X = XMVectorMultiply(v1, v2); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator* (const Vector4& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V); XMVECTOR X = XMVectorScale(v1, S); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator/ (const Vector4& V1, const Vector4& V2) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V1); XMVECTOR v2 = XMLoadFloat4(&V2); XMVECTOR X = XMVectorDivide(v1, v2); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator/ (const Vector4& V, float S) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V); XMVECTOR X = XMVectorScale(v1, 1.f / S); Vector4 R; XMStoreFloat4(&R, X); return R; } inline Vector4 operator* (float S, const Vector4& V) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&V); XMVECTOR X = XMVectorScale(v1, S); Vector4 R; XMStoreFloat4(&R, X); return R; } //------------------------------------------------------------------------------ // Vector operations //------------------------------------------------------------------------------ inline bool Vector4::InBounds(const Vector4& Bounds) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&Bounds); return XMVector4InBounds(v1, v2); } inline float Vector4::Length() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVector4Length(v1); return XMVectorGetX(X); } inline float Vector4::LengthSquared() const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVector4LengthSq(v1); return XMVectorGetX(X); } inline float Vector4::Dot(const Vector4& V) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&V); XMVECTOR X = XMVector4Dot(v1, v2); return XMVectorGetX(X); } inline void Vector4::Cross(const Vector4& v1, const Vector4& v2, Vector4& result) const noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(this); XMVECTOR x2 = XMLoadFloat4(&v1); XMVECTOR x3 = XMLoadFloat4(&v2); XMVECTOR R = XMVector4Cross(x1, x2, x3); XMStoreFloat4(&result, R); } inline Vector4 Vector4::Cross(const Vector4& v1, const Vector4& v2) const noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(this); XMVECTOR x2 = XMLoadFloat4(&v1); XMVECTOR x3 = XMLoadFloat4(&v2); XMVECTOR R = XMVector4Cross(x1, x2, x3); Vector4 result; XMStoreFloat4(&result, R); return result; } inline void Vector4::Normalize() noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVector4Normalize(v1); XMStoreFloat4(this, X); } inline void Vector4::Normalize(Vector4& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR X = XMVector4Normalize(v1); XMStoreFloat4(&result, X); } inline void Vector4::Clamp(const Vector4& vmin, const Vector4& vmax) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&vmin); XMVECTOR v3 = XMLoadFloat4(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat4(this, X); } inline void Vector4::Clamp(const Vector4& vmin, const Vector4& vmax, Vector4& result) const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(this); XMVECTOR v2 = XMLoadFloat4(&vmin); XMVECTOR v3 = XMLoadFloat4(&vmax); XMVECTOR X = XMVectorClamp(v1, v2, v3); XMStoreFloat4(&result, X); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline float Vector4::Distance(const Vector4& v1, const Vector4& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector4Length(V); return XMVectorGetX(X); } inline float Vector4::DistanceSquared(const Vector4& v1, const Vector4& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR V = XMVectorSubtract(x2, x1); XMVECTOR X = XMVector4LengthSq(V); return XMVectorGetX(X); } inline void Vector4::Min(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorMin(x1, x2); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Min(const Vector4& v1, const Vector4& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorMin(x1, x2); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Max(const Vector4& v1, const Vector4& v2, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorMax(x1, x2); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Max(const Vector4& v1, const Vector4& v2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorMax(x1, x2); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Lerp(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Lerp(const Vector4& v1, const Vector4& v2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::SmoothStep(const Vector4& v1, const Vector4& v2, float t, Vector4& result) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); XMStoreFloat4(&result, X); } inline Vector4 Vector4::SmoothStep(const Vector4& v1, const Vector4& v2, float t) noexcept { using namespace DirectX; t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t); // Clamp value to 0 to 1 t = t * t*(3.f - 2.f*t); XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR X = XMVectorLerp(x1, x2, t); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR x3 = XMLoadFloat4(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Barycentric(const Vector4& v1, const Vector4& v2, const Vector4& v3, float f, float g) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR x3 = XMLoadFloat4(&v3); XMVECTOR X = XMVectorBaryCentric(x1, x2, x3, f, g); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR x3 = XMLoadFloat4(&v3); XMVECTOR x4 = XMLoadFloat4(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); XMStoreFloat4(&result, X); } inline Vector4 Vector4::CatmullRom(const Vector4& v1, const Vector4& v2, const Vector4& v3, const Vector4& v4, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&v2); XMVECTOR x3 = XMLoadFloat4(&v3); XMVECTOR x4 = XMLoadFloat4(&v4); XMVECTOR X = XMVectorCatmullRom(x1, x2, x3, x4, t); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t, Vector4& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&t1); XMVECTOR x3 = XMLoadFloat4(&v2); XMVECTOR x4 = XMLoadFloat4(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Hermite(const Vector4& v1, const Vector4& t1, const Vector4& v2, const Vector4& t2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(&v1); XMVECTOR x2 = XMLoadFloat4(&t1); XMVECTOR x3 = XMLoadFloat4(&v2); XMVECTOR x4 = XMLoadFloat4(&t2); XMVECTOR X = XMVectorHermite(x1, x2, x3, x4, t); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Reflect(const Vector4& ivec, const Vector4& nvec, Vector4& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat4(&ivec); XMVECTOR n = XMLoadFloat4(&nvec); XMVECTOR X = XMVector4Reflect(i, n); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Reflect(const Vector4& ivec, const Vector4& nvec) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat4(&ivec); XMVECTOR n = XMLoadFloat4(&nvec); XMVECTOR X = XMVector4Reflect(i, n); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex, Vector4& result) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat4(&ivec); XMVECTOR n = XMLoadFloat4(&nvec); XMVECTOR X = XMVector4Refract(i, n, refractionIndex); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Refract(const Vector4& ivec, const Vector4& nvec, float refractionIndex) noexcept { using namespace DirectX; XMVECTOR i = XMLoadFloat4(&ivec); XMVECTOR n = XMLoadFloat4(&nvec); XMVECTOR X = XMVector4Refract(i, n, refractionIndex); Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Transform(const Vector2& v, const Quaternion& quat, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f XMStoreFloat4(&result, X); } inline Vector4 Vector4::Transform(const Vector2& v, const Quaternion& quat) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat2(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Transform(const Vector3& v, const Quaternion& quat, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f XMStoreFloat4(&result, X); } inline Vector4 Vector4::Transform(const Vector3& v, const Quaternion& quat) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat3(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(g_XMIdentityR3, X, g_XMSelect1110); // result.w = 1.f Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Transform(const Vector4& v, const Quaternion& quat, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(v1, X, g_XMSelect1110); // result.w = v.w XMStoreFloat4(&result, X); } inline Vector4 Vector4::Transform(const Vector4& v, const Quaternion& quat) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&v); XMVECTOR q = XMLoadFloat4(&quat); XMVECTOR X = XMVector3Rotate(v1, q); X = XMVectorSelect(v1, X, g_XMSelect1110); // result.w = v.w Vector4 result; XMStoreFloat4(&result, X); return result; } inline void Vector4::Transform(const Vector4& v, const Matrix& m, Vector4& result) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector4Transform(v1, M); XMStoreFloat4(&result, X); } inline Vector4 Vector4::Transform(const Vector4& v, const Matrix& m) noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(&v); XMMATRIX M = XMLoadFloat4x4(&m); XMVECTOR X = XMVector4Transform(v1, M); Vector4 result; XMStoreFloat4(&result, X); return result; } _Use_decl_annotations_ inline void Vector4::Transform(const Vector4* varray, size_t count, const Matrix& m, Vector4* resultArray) noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(&m); XMVector4TransformStream(resultArray, sizeof(XMFLOAT4), varray, sizeof(XMFLOAT4), count, M); } /**************************************************************************** * * Matrix * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Matrix::operator == (const Matrix& M) const noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); return (XMVector4Equal(x1, y1) && XMVector4Equal(x2, y2) && XMVector4Equal(x3, y3) && XMVector4Equal(x4, y4)) != 0; } inline bool Matrix::operator != (const Matrix& M) const noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); return (XMVector4NotEqual(x1, y1) || XMVector4NotEqual(x2, y2) || XMVector4NotEqual(x3, y3) || XMVector4NotEqual(x4, y4)) != 0; } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Matrix::Matrix(const XMFLOAT3X3& M) noexcept { _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; _41 = 0.f; _42 = 0.f; _43 = 0.f; _44 = 1.f; } inline Matrix::Matrix(const XMFLOAT4X3& M) noexcept { _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; _41 = M._41; _42 = M._42; _43 = M._43; _44 = 1.f; } inline Matrix& Matrix::operator= (const XMFLOAT3X3& M) noexcept { _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; _41 = 0.f; _42 = 0.f; _43 = 0.f; _44 = 1.f; return *this; } inline Matrix& Matrix::operator= (const XMFLOAT4X3& M) noexcept { _11 = M._11; _12 = M._12; _13 = M._13; _14 = 0.f; _21 = M._21; _22 = M._22; _23 = M._23; _24 = 0.f; _31 = M._31; _32 = M._32; _33 = M._33; _34 = 0.f; _41 = M._41; _42 = M._42; _43 = M._43; _44 = 1.f; return *this; } inline Matrix& Matrix::operator+= (const Matrix& M) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); x1 = XMVectorAdd(x1, y1); x2 = XMVectorAdd(x2, y2); x3 = XMVectorAdd(x3, y3); x4 = XMVectorAdd(x4, y4); XMStoreFloat4(reinterpret_cast(&_11), x1); XMStoreFloat4(reinterpret_cast(&_21), x2); XMStoreFloat4(reinterpret_cast(&_31), x3); XMStoreFloat4(reinterpret_cast(&_41), x4); return *this; } inline Matrix& Matrix::operator-= (const Matrix& M) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); x1 = XMVectorSubtract(x1, y1); x2 = XMVectorSubtract(x2, y2); x3 = XMVectorSubtract(x3, y3); x4 = XMVectorSubtract(x4, y4); XMStoreFloat4(reinterpret_cast(&_11), x1); XMStoreFloat4(reinterpret_cast(&_21), x2); XMStoreFloat4(reinterpret_cast(&_31), x3); XMStoreFloat4(reinterpret_cast(&_41), x4); return *this; } inline Matrix& Matrix::operator*= (const Matrix& M) noexcept { using namespace DirectX; XMMATRIX M1 = XMLoadFloat4x4(this); XMMATRIX M2 = XMLoadFloat4x4(&M); XMMATRIX X = XMMatrixMultiply(M1, M2); XMStoreFloat4x4(this, X); return *this; } inline Matrix& Matrix::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); x1 = XMVectorScale(x1, S); x2 = XMVectorScale(x2, S); x3 = XMVectorScale(x3, S); x4 = XMVectorScale(x4, S); XMStoreFloat4(reinterpret_cast(&_11), x1); XMStoreFloat4(reinterpret_cast(&_21), x2); XMStoreFloat4(reinterpret_cast(&_31), x3); XMStoreFloat4(reinterpret_cast(&_41), x4); return *this; } inline Matrix& Matrix::operator/= (float S) noexcept { using namespace DirectX; assert(S != 0.f); XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); float rs = 1.f / S; x1 = XMVectorScale(x1, rs); x2 = XMVectorScale(x2, rs); x3 = XMVectorScale(x3, rs); x4 = XMVectorScale(x4, rs); XMStoreFloat4(reinterpret_cast(&_11), x1); XMStoreFloat4(reinterpret_cast(&_21), x2); XMStoreFloat4(reinterpret_cast(&_31), x3); XMStoreFloat4(reinterpret_cast(&_41), x4); return *this; } inline Matrix& Matrix::operator/= (const Matrix& M) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&_41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M._41)); x1 = XMVectorDivide(x1, y1); x2 = XMVectorDivide(x2, y2); x3 = XMVectorDivide(x3, y3); x4 = XMVectorDivide(x4, y4); XMStoreFloat4(reinterpret_cast(&_11), x1); XMStoreFloat4(reinterpret_cast(&_21), x2); XMStoreFloat4(reinterpret_cast(&_31), x3); XMStoreFloat4(reinterpret_cast(&_41), x4); return *this; } //------------------------------------------------------------------------------ // Urnary operators //------------------------------------------------------------------------------ inline Matrix Matrix::operator- () const noexcept { using namespace DirectX; XMVECTOR v1 = XMLoadFloat4(reinterpret_cast(&_11)); XMVECTOR v2 = XMLoadFloat4(reinterpret_cast(&_21)); XMVECTOR v3 = XMLoadFloat4(reinterpret_cast(&_31)); XMVECTOR v4 = XMLoadFloat4(reinterpret_cast(&_41)); v1 = XMVectorNegate(v1); v2 = XMVectorNegate(v2); v3 = XMVectorNegate(v3); v4 = XMVectorNegate(v4); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), v1); XMStoreFloat4(reinterpret_cast(&R._21), v2); XMStoreFloat4(reinterpret_cast(&R._31), v3); XMStoreFloat4(reinterpret_cast(&R._41), v4); return R; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Matrix operator+ (const Matrix& M1, const Matrix& M2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); x1 = XMVectorAdd(x1, y1); x2 = XMVectorAdd(x2, y2); x3 = XMVectorAdd(x3, y3); x4 = XMVectorAdd(x4, y4); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } inline Matrix operator- (const Matrix& M1, const Matrix& M2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); x1 = XMVectorSubtract(x1, y1); x2 = XMVectorSubtract(x2, y2); x3 = XMVectorSubtract(x3, y3); x4 = XMVectorSubtract(x4, y4); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } inline Matrix operator* (const Matrix& M1, const Matrix& M2) noexcept { using namespace DirectX; XMMATRIX m1 = XMLoadFloat4x4(&M1); XMMATRIX m2 = XMLoadFloat4x4(&M2); XMMATRIX X = XMMatrixMultiply(m1, m2); Matrix R; XMStoreFloat4x4(&R, X); return R; } inline Matrix operator* (const Matrix& M, float S) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); x1 = XMVectorScale(x1, S); x2 = XMVectorScale(x2, S); x3 = XMVectorScale(x3, S); x4 = XMVectorScale(x4, S); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } inline Matrix operator/ (const Matrix& M, float S) noexcept { using namespace DirectX; assert(S != 0.f); XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); float rs = 1.f / S; x1 = XMVectorScale(x1, rs); x2 = XMVectorScale(x2, rs); x3 = XMVectorScale(x3, rs); x4 = XMVectorScale(x4, rs); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } inline Matrix operator/ (const Matrix& M1, const Matrix& M2) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); x1 = XMVectorDivide(x1, y1); x2 = XMVectorDivide(x2, y2); x3 = XMVectorDivide(x3, y3); x4 = XMVectorDivide(x4, y4); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } inline Matrix operator* (float S, const Matrix& M) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M._41)); x1 = XMVectorScale(x1, S); x2 = XMVectorScale(x2, S); x3 = XMVectorScale(x3, S); x4 = XMVectorScale(x4, S); Matrix R; XMStoreFloat4(reinterpret_cast(&R._11), x1); XMStoreFloat4(reinterpret_cast(&R._21), x2); XMStoreFloat4(reinterpret_cast(&R._31), x3); XMStoreFloat4(reinterpret_cast(&R._41), x4); return R; } //------------------------------------------------------------------------------ // Matrix operations //------------------------------------------------------------------------------ inline bool Matrix::Decompose(Vector3& scale, Quaternion& rotation, Vector3& translation) noexcept { using namespace DirectX; XMVECTOR s, r, t; if (!XMMatrixDecompose(&s, &r, &t, *this)) return false; XMStoreFloat3(&scale, s); XMStoreFloat4(&rotation, r); XMStoreFloat3(&translation, t); return true; } inline Matrix Matrix::Transpose() const noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(this); Matrix R; XMStoreFloat4x4(&R, XMMatrixTranspose(M)); return R; } inline void Matrix::Transpose(Matrix& result) const noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(this); XMStoreFloat4x4(&result, XMMatrixTranspose(M)); } inline Matrix Matrix::Invert() const noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(this); Matrix R; XMVECTOR det; XMStoreFloat4x4(&R, XMMatrixInverse(&det, M)); return R; } inline void Matrix::Invert(Matrix& result) const noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(this); XMVECTOR det; XMStoreFloat4x4(&result, XMMatrixInverse(&det, M)); } inline float Matrix::Determinant() const noexcept { using namespace DirectX; XMMATRIX M = XMLoadFloat4x4(this); return XMVectorGetX(XMMatrixDeterminant(M)); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ _Use_decl_annotations_ inline Matrix Matrix::CreateBillboard( const Vector3& object, const Vector3& cameraPosition, const Vector3& cameraUp, const Vector3* cameraForward) noexcept { using namespace DirectX; XMVECTOR O = XMLoadFloat3(&object); XMVECTOR C = XMLoadFloat3(&cameraPosition); XMVECTOR Z = XMVectorSubtract(O, C); XMVECTOR N = XMVector3LengthSq(Z); if (XMVector3Less(N, g_XMEpsilon)) { if (cameraForward) { XMVECTOR F = XMLoadFloat3(cameraForward); Z = XMVectorNegate(F); } else Z = g_XMNegIdentityR2; } else { Z = XMVector3Normalize(Z); } XMVECTOR up = XMLoadFloat3(&cameraUp); XMVECTOR X = XMVector3Cross(up, Z); X = XMVector3Normalize(X); XMVECTOR Y = XMVector3Cross(Z, X); XMMATRIX M; M.r[0] = X; M.r[1] = Y; M.r[2] = Z; M.r[3] = XMVectorSetW(O, 1.f); Matrix R; XMStoreFloat4x4(&R, M); return R; } _Use_decl_annotations_ inline Matrix Matrix::CreateConstrainedBillboard( const Vector3& object, const Vector3& cameraPosition, const Vector3& rotateAxis, const Vector3* cameraForward, const Vector3* objectForward) noexcept { using namespace DirectX; static const XMVECTORF32 s_minAngle = { { { 0.99825467075f, 0.99825467075f, 0.99825467075f, 0.99825467075f } } }; // 1.0 - XMConvertToRadians( 0.1f ); XMVECTOR O = XMLoadFloat3(&object); XMVECTOR C = XMLoadFloat3(&cameraPosition); XMVECTOR faceDir = XMVectorSubtract(O, C); XMVECTOR N = XMVector3LengthSq(faceDir); if (XMVector3Less(N, g_XMEpsilon)) { if (cameraForward) { XMVECTOR F = XMLoadFloat3(cameraForward); faceDir = XMVectorNegate(F); } else faceDir = g_XMNegIdentityR2; } else { faceDir = XMVector3Normalize(faceDir); } XMVECTOR Y = XMLoadFloat3(&rotateAxis); XMVECTOR X, Z; XMVECTOR dot = XMVectorAbs(XMVector3Dot(Y, faceDir)); if (XMVector3Greater(dot, s_minAngle)) { if (objectForward) { Z = XMLoadFloat3(objectForward); dot = XMVectorAbs(XMVector3Dot(Y, Z)); if (XMVector3Greater(dot, s_minAngle)) { dot = XMVectorAbs(XMVector3Dot(Y, g_XMNegIdentityR2)); Z = (XMVector3Greater(dot, s_minAngle)) ? g_XMIdentityR0 : g_XMNegIdentityR2; } } else { dot = XMVectorAbs(XMVector3Dot(Y, g_XMNegIdentityR2)); Z = (XMVector3Greater(dot, s_minAngle)) ? g_XMIdentityR0 : g_XMNegIdentityR2; } X = XMVector3Cross(Y, Z); X = XMVector3Normalize(X); Z = XMVector3Cross(X, Y); Z = XMVector3Normalize(Z); } else { X = XMVector3Cross(Y, faceDir); X = XMVector3Normalize(X); Z = XMVector3Cross(X, Y); Z = XMVector3Normalize(Z); } XMMATRIX M; M.r[0] = X; M.r[1] = Y; M.r[2] = Z; M.r[3] = XMVectorSetW(O, 1.f); Matrix R; XMStoreFloat4x4(&R, M); return R; } inline Matrix Matrix::CreateTranslation(const Vector3& position) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixTranslation(position.x, position.y, position.z)); return R; } inline Matrix Matrix::CreateTranslation(float x, float y, float z) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixTranslation(x, y, z)); return R; } inline Matrix Matrix::CreateScale(const Vector3& scales) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixScaling(scales.x, scales.y, scales.z)); return R; } inline Matrix Matrix::CreateScale(float xs, float ys, float zs) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixScaling(xs, ys, zs)); return R; } inline Matrix Matrix::CreateScale(float scale) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixScaling(scale, scale, scale)); return R; } inline Matrix Matrix::CreateRotationX(float radians) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixRotationX(radians)); return R; } inline Matrix Matrix::CreateRotationY(float radians) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixRotationY(radians)); return R; } inline Matrix Matrix::CreateRotationZ(float radians) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixRotationZ(radians)); return R; } inline Matrix Matrix::CreateFromAxisAngle(const Vector3& axis, float angle) noexcept { using namespace DirectX; Matrix R; XMVECTOR a = XMLoadFloat3(&axis); XMStoreFloat4x4(&R, XMMatrixRotationAxis(a, angle)); return R; } inline Matrix Matrix::CreatePerspectiveFieldOfView(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane)); return R; } inline Matrix Matrix::CreatePerspective(float width, float height, float nearPlane, float farPlane) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane)); return R; } inline Matrix Matrix::CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlane, float farPlane) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixPerspectiveOffCenterRH(left, right, bottom, top, nearPlane, farPlane)); return R; } inline Matrix Matrix::CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixOrthographicRH(width, height, zNearPlane, zFarPlane)); return R; } inline Matrix Matrix::CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixOrthographicOffCenterRH(left, right, bottom, top, zNearPlane, zFarPlane)); return R; } inline Matrix Matrix::CreateLookAt(const Vector3& eye, const Vector3& target, const Vector3& up) noexcept { using namespace DirectX; Matrix R; XMVECTOR eyev = XMLoadFloat3(&eye); XMVECTOR targetv = XMLoadFloat3(&target); XMVECTOR upv = XMLoadFloat3(&up); XMStoreFloat4x4(&R, XMMatrixLookAtRH(eyev, targetv, upv)); return R; } inline Matrix Matrix::CreateWorld(const Vector3& position, const Vector3& forward, const Vector3& up) noexcept { using namespace DirectX; XMVECTOR zaxis = XMVector3Normalize(XMVectorNegate(XMLoadFloat3(&forward))); XMVECTOR yaxis = XMLoadFloat3(&up); XMVECTOR xaxis = XMVector3Normalize(XMVector3Cross(yaxis, zaxis)); yaxis = XMVector3Cross(zaxis, xaxis); Matrix R; XMStoreFloat3(reinterpret_cast(&R._11), xaxis); XMStoreFloat3(reinterpret_cast(&R._21), yaxis); XMStoreFloat3(reinterpret_cast(&R._31), zaxis); R._14 = R._24 = R._34 = 0.f; R._41 = position.x; R._42 = position.y; R._43 = position.z; R._44 = 1.f; return R; } inline Matrix Matrix::CreateFromQuaternion(const Quaternion& rotation) noexcept { using namespace DirectX; Matrix R; XMVECTOR quatv = XMLoadFloat4(&rotation); XMStoreFloat4x4(&R, XMMatrixRotationQuaternion(quatv)); return R; } inline Matrix Matrix::CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept { using namespace DirectX; Matrix R; XMStoreFloat4x4(&R, XMMatrixRotationRollPitchYaw(pitch, yaw, roll)); return R; } inline Matrix Matrix::CreateShadow(const Vector3& lightDir, const Plane& plane) noexcept { using namespace DirectX; Matrix R; XMVECTOR light = XMLoadFloat3(&lightDir); XMVECTOR planev = XMLoadFloat4(&plane); XMStoreFloat4x4(&R, XMMatrixShadow(planev, light)); return R; } inline Matrix Matrix::CreateReflection(const Plane& plane) noexcept { using namespace DirectX; Matrix R; XMVECTOR planev = XMLoadFloat4(&plane); XMStoreFloat4x4(&R, XMMatrixReflect(planev)); return R; } inline void Matrix::Lerp(const Matrix& M1, const Matrix& M2, float t, Matrix& result) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); x1 = XMVectorLerp(x1, y1, t); x2 = XMVectorLerp(x2, y2, t); x3 = XMVectorLerp(x3, y3, t); x4 = XMVectorLerp(x4, y4, t); XMStoreFloat4(reinterpret_cast(&result._11), x1); XMStoreFloat4(reinterpret_cast(&result._21), x2); XMStoreFloat4(reinterpret_cast(&result._31), x3); XMStoreFloat4(reinterpret_cast(&result._41), x4); } inline Matrix Matrix::Lerp(const Matrix& M1, const Matrix& M2, float t) noexcept { using namespace DirectX; XMVECTOR x1 = XMLoadFloat4(reinterpret_cast(&M1._11)); XMVECTOR x2 = XMLoadFloat4(reinterpret_cast(&M1._21)); XMVECTOR x3 = XMLoadFloat4(reinterpret_cast(&M1._31)); XMVECTOR x4 = XMLoadFloat4(reinterpret_cast(&M1._41)); XMVECTOR y1 = XMLoadFloat4(reinterpret_cast(&M2._11)); XMVECTOR y2 = XMLoadFloat4(reinterpret_cast(&M2._21)); XMVECTOR y3 = XMLoadFloat4(reinterpret_cast(&M2._31)); XMVECTOR y4 = XMLoadFloat4(reinterpret_cast(&M2._41)); x1 = XMVectorLerp(x1, y1, t); x2 = XMVectorLerp(x2, y2, t); x3 = XMVectorLerp(x3, y3, t); x4 = XMVectorLerp(x4, y4, t); Matrix result; XMStoreFloat4(reinterpret_cast(&result._11), x1); XMStoreFloat4(reinterpret_cast(&result._21), x2); XMStoreFloat4(reinterpret_cast(&result._31), x3); XMStoreFloat4(reinterpret_cast(&result._41), x4); return result; } inline void Matrix::Transform(const Matrix& M, const Quaternion& rotation, Matrix& result) noexcept { using namespace DirectX; XMVECTOR quatv = XMLoadFloat4(&rotation); XMMATRIX M0 = XMLoadFloat4x4(&M); XMMATRIX M1 = XMMatrixRotationQuaternion(quatv); XMStoreFloat4x4(&result, XMMatrixMultiply(M0, M1)); } inline Matrix Matrix::Transform(const Matrix& M, const Quaternion& rotation) noexcept { using namespace DirectX; XMVECTOR quatv = XMLoadFloat4(&rotation); XMMATRIX M0 = XMLoadFloat4x4(&M); XMMATRIX M1 = XMMatrixRotationQuaternion(quatv); Matrix result; XMStoreFloat4x4(&result, XMMatrixMultiply(M0, M1)); return result; } /**************************************************************************** * * Plane * ****************************************************************************/ inline Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) noexcept { using namespace DirectX; XMVECTOR P0 = XMLoadFloat3(&point1); XMVECTOR P1 = XMLoadFloat3(&point2); XMVECTOR P2 = XMLoadFloat3(&point3); XMStoreFloat4(this, XMPlaneFromPoints(P0, P1, P2)); } inline Plane::Plane(const Vector3& point, const Vector3& normal) noexcept { using namespace DirectX; XMVECTOR P = XMLoadFloat3(&point); XMVECTOR N = XMLoadFloat3(&normal); XMStoreFloat4(this, XMPlaneFromPointNormal(P, N)); } //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Plane::operator == (const Plane& p) const noexcept { using namespace DirectX; XMVECTOR p1 = XMLoadFloat4(this); XMVECTOR p2 = XMLoadFloat4(&p); return XMPlaneEqual(p1, p2); } inline bool Plane::operator != (const Plane& p) const noexcept { using namespace DirectX; XMVECTOR p1 = XMLoadFloat4(this); XMVECTOR p2 = XMLoadFloat4(&p); return XMPlaneNotEqual(p1, p2); } //------------------------------------------------------------------------------ // Plane operations //------------------------------------------------------------------------------ inline void Plane::Normalize() noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(this); XMStoreFloat4(this, XMPlaneNormalize(p)); } inline void Plane::Normalize(Plane& result) const noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(this); XMStoreFloat4(&result, XMPlaneNormalize(p)); } inline float Plane::Dot(const Vector4& v) const noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(this); XMVECTOR v0 = XMLoadFloat4(&v); return XMVectorGetX(XMPlaneDot(p, v0)); } inline float Plane::DotCoordinate(const Vector3& position) const noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(this); XMVECTOR v0 = XMLoadFloat3(&position); return XMVectorGetX(XMPlaneDotCoord(p, v0)); } inline float Plane::DotNormal(const Vector3& normal) const noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(this); XMVECTOR n0 = XMLoadFloat3(&normal); return XMVectorGetX(XMPlaneDotNormal(p, n0)); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline void Plane::Transform(const Plane& plane, const Matrix& M, Plane& result) noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(&plane); XMMATRIX m0 = XMLoadFloat4x4(&M); XMStoreFloat4(&result, XMPlaneTransform(p, m0)); } inline Plane Plane::Transform(const Plane& plane, const Matrix& M) noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(&plane); XMMATRIX m0 = XMLoadFloat4x4(&M); Plane result; XMStoreFloat4(&result, XMPlaneTransform(p, m0)); return result; } inline void Plane::Transform(const Plane& plane, const Quaternion& rotation, Plane& result) noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(&plane); XMVECTOR q = XMLoadFloat4(&rotation); XMVECTOR X = XMVector3Rotate(p, q); X = XMVectorSelect(p, X, g_XMSelect1110); // result.d = plane.d XMStoreFloat4(&result, X); } inline Plane Plane::Transform(const Plane& plane, const Quaternion& rotation) noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(&plane); XMVECTOR q = XMLoadFloat4(&rotation); XMVECTOR X = XMVector3Rotate(p, q); X = XMVectorSelect(p, X, g_XMSelect1110); // result.d = plane.d Plane result; XMStoreFloat4(&result, X); return result; } /**************************************************************************** * * Quaternion * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Quaternion::operator == (const Quaternion& q) const noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); return XMQuaternionEqual(q1, q2); } inline bool Quaternion::operator != (const Quaternion& q) const noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); return XMQuaternionNotEqual(q1, q2); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Quaternion& Quaternion::operator+= (const Quaternion& q) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); XMStoreFloat4(this, XMVectorAdd(q1, q2)); return *this; } inline Quaternion& Quaternion::operator-= (const Quaternion& q) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); XMStoreFloat4(this, XMVectorSubtract(q1, q2)); return *this; } inline Quaternion& Quaternion::operator*= (const Quaternion& q) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); XMStoreFloat4(this, XMQuaternionMultiply(q1, q2)); return *this; } inline Quaternion& Quaternion::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(this, XMVectorScale(q, S)); return *this; } inline Quaternion& Quaternion::operator/= (const Quaternion& q) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); q2 = XMQuaternionInverse(q2); XMStoreFloat4(this, XMQuaternionMultiply(q1, q2)); return *this; } //------------------------------------------------------------------------------ // Urnary operators //------------------------------------------------------------------------------ inline Quaternion Quaternion::operator- () const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); Quaternion R; XMStoreFloat4(&R, XMVectorNegate(q)); return R; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Quaternion operator+ (const Quaternion& Q1, const Quaternion& Q2) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(&Q1); XMVECTOR q2 = XMLoadFloat4(&Q2); Quaternion R; XMStoreFloat4(&R, XMVectorAdd(q1, q2)); return R; } inline Quaternion operator- (const Quaternion& Q1, const Quaternion& Q2) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(&Q1); XMVECTOR q2 = XMLoadFloat4(&Q2); Quaternion R; XMStoreFloat4(&R, XMVectorSubtract(q1, q2)); return R; } inline Quaternion operator* (const Quaternion& Q1, const Quaternion& Q2) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(&Q1); XMVECTOR q2 = XMLoadFloat4(&Q2); Quaternion R; XMStoreFloat4(&R, XMQuaternionMultiply(q1, q2)); return R; } inline Quaternion operator* (const Quaternion& Q, float S) noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(&Q); Quaternion R; XMStoreFloat4(&R, XMVectorScale(q, S)); return R; } inline Quaternion operator/ (const Quaternion& Q1, const Quaternion& Q2) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(&Q1); XMVECTOR q2 = XMLoadFloat4(&Q2); q2 = XMQuaternionInverse(q2); Quaternion R; XMStoreFloat4(&R, XMQuaternionMultiply(q1, q2)); return R; } inline Quaternion operator* (float S, const Quaternion& Q) noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(&Q); Quaternion R; XMStoreFloat4(&R, XMVectorScale(q1, S)); return R; } //------------------------------------------------------------------------------ // Quaternion operations //------------------------------------------------------------------------------ inline float Quaternion::Length() const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); return XMVectorGetX(XMQuaternionLength(q)); } inline float Quaternion::LengthSquared() const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); return XMVectorGetX(XMQuaternionLengthSq(q)); } inline void Quaternion::Normalize() noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(this, XMQuaternionNormalize(q)); } inline void Quaternion::Normalize(Quaternion& result) const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(&result, XMQuaternionNormalize(q)); } inline void Quaternion::Conjugate() noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(this, XMQuaternionConjugate(q)); } inline void Quaternion::Conjugate(Quaternion& result) const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(&result, XMQuaternionConjugate(q)); } inline void Quaternion::Inverse(Quaternion& result) const noexcept { using namespace DirectX; XMVECTOR q = XMLoadFloat4(this); XMStoreFloat4(&result, XMQuaternionInverse(q)); } inline float Quaternion::Dot(const Quaternion& q) const noexcept { using namespace DirectX; XMVECTOR q1 = XMLoadFloat4(this); XMVECTOR q2 = XMLoadFloat4(&q); return XMVectorGetX(XMQuaternionDot(q1, q2)); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline Quaternion Quaternion::CreateFromAxisAngle(const Vector3& axis, float angle) noexcept { using namespace DirectX; XMVECTOR a = XMLoadFloat3(&axis); Quaternion R; XMStoreFloat4(&R, XMQuaternionRotationAxis(a, angle)); return R; } inline Quaternion Quaternion::CreateFromYawPitchRoll(float yaw, float pitch, float roll) noexcept { using namespace DirectX; Quaternion R; XMStoreFloat4(&R, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll)); return R; } inline Quaternion Quaternion::CreateFromRotationMatrix(const Matrix& M) noexcept { using namespace DirectX; XMMATRIX M0 = XMLoadFloat4x4(&M); Quaternion R; XMStoreFloat4(&R, XMQuaternionRotationMatrix(M0)); return R; } inline void Quaternion::Lerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); XMVECTOR dot = XMVector4Dot(Q0, Q1); XMVECTOR R; if (XMVector4GreaterOrEqual(dot, XMVectorZero())) { R = XMVectorLerp(Q0, Q1, t); } else { XMVECTOR tv = XMVectorReplicate(t); XMVECTOR t1v = XMVectorReplicate(1.f - t); XMVECTOR X0 = XMVectorMultiply(Q0, t1v); XMVECTOR X1 = XMVectorMultiply(Q1, tv); R = XMVectorSubtract(X0, X1); } XMStoreFloat4(&result, XMQuaternionNormalize(R)); } inline Quaternion Quaternion::Lerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); XMVECTOR dot = XMVector4Dot(Q0, Q1); XMVECTOR R; if (XMVector4GreaterOrEqual(dot, XMVectorZero())) { R = XMVectorLerp(Q0, Q1, t); } else { XMVECTOR tv = XMVectorReplicate(t); XMVECTOR t1v = XMVectorReplicate(1.f - t); XMVECTOR X0 = XMVectorMultiply(Q0, t1v); XMVECTOR X1 = XMVectorMultiply(Q1, tv); R = XMVectorSubtract(X0, X1); } Quaternion result; XMStoreFloat4(&result, XMQuaternionNormalize(R)); return result; } inline void Quaternion::Slerp(const Quaternion& q1, const Quaternion& q2, float t, Quaternion& result) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); XMStoreFloat4(&result, XMQuaternionSlerp(Q0, Q1, t)); } inline Quaternion Quaternion::Slerp(const Quaternion& q1, const Quaternion& q2, float t) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); Quaternion result; XMStoreFloat4(&result, XMQuaternionSlerp(Q0, Q1, t)); return result; } inline void Quaternion::Concatenate(const Quaternion& q1, const Quaternion& q2, Quaternion& result) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q0)); } inline Quaternion Quaternion::Concatenate(const Quaternion& q1, const Quaternion& q2) noexcept { using namespace DirectX; XMVECTOR Q0 = XMLoadFloat4(&q1); XMVECTOR Q1 = XMLoadFloat4(&q2); Quaternion result; XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q0)); return result; } /**************************************************************************** * * Color * ****************************************************************************/ inline Color::Color(const DirectX::PackedVector::XMCOLOR& Packed) noexcept { using namespace DirectX; XMStoreFloat4(this, PackedVector::XMLoadColor(&Packed)); } inline Color::Color(const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept { using namespace DirectX; XMStoreFloat4(this, PackedVector::XMLoadUByteN4(&Packed)); } //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Color::operator == (const Color& c) const noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); return XMColorEqual(c1, c2); } inline bool Color::operator != (const Color& c) const noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); return XMColorNotEqual(c1, c2); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Color& Color::operator= (const DirectX::PackedVector::XMCOLOR& Packed) noexcept { using namespace DirectX; XMStoreFloat4(this, PackedVector::XMLoadColor(&Packed)); return *this; } inline Color& Color::operator= (const DirectX::PackedVector::XMUBYTEN4& Packed) noexcept { using namespace DirectX; XMStoreFloat4(this, PackedVector::XMLoadUByteN4(&Packed)); return *this; } inline Color& Color::operator+= (const Color& c) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); XMStoreFloat4(this, XMVectorAdd(c1, c2)); return *this; } inline Color& Color::operator-= (const Color& c) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); XMStoreFloat4(this, XMVectorSubtract(c1, c2)); return *this; } inline Color& Color::operator*= (const Color& c) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); XMStoreFloat4(this, XMVectorMultiply(c1, c2)); return *this; } inline Color& Color::operator*= (float S) noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(this, XMVectorScale(c, S)); return *this; } inline Color& Color::operator/= (const Color& c) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(this); XMVECTOR c2 = XMLoadFloat4(&c); XMStoreFloat4(this, XMVectorDivide(c1, c2)); return *this; } //------------------------------------------------------------------------------ // Urnary operators //------------------------------------------------------------------------------ inline Color Color::operator- () const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); Color R; XMStoreFloat4(&R, XMVectorNegate(c)); return R; } //------------------------------------------------------------------------------ // Binary operators //------------------------------------------------------------------------------ inline Color operator+ (const Color& C1, const Color& C2) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(&C1); XMVECTOR c2 = XMLoadFloat4(&C2); Color R; XMStoreFloat4(&R, XMVectorAdd(c1, c2)); return R; } inline Color operator- (const Color& C1, const Color& C2) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(&C1); XMVECTOR c2 = XMLoadFloat4(&C2); Color R; XMStoreFloat4(&R, XMVectorSubtract(c1, c2)); return R; } inline Color operator* (const Color& C1, const Color& C2) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(&C1); XMVECTOR c2 = XMLoadFloat4(&C2); Color R; XMStoreFloat4(&R, XMVectorMultiply(c1, c2)); return R; } inline Color operator* (const Color& C, float S) noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(&C); Color R; XMStoreFloat4(&R, XMVectorScale(c, S)); return R; } inline Color operator/ (const Color& C1, const Color& C2) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(&C1); XMVECTOR c2 = XMLoadFloat4(&C2); Color R; XMStoreFloat4(&R, XMVectorDivide(c1, c2)); return R; } inline Color operator* (float S, const Color& C) noexcept { using namespace DirectX; XMVECTOR c1 = XMLoadFloat4(&C); Color R; XMStoreFloat4(&R, XMVectorScale(c1, S)); return R; } //------------------------------------------------------------------------------ // Color operations //------------------------------------------------------------------------------ inline DirectX::PackedVector::XMCOLOR Color::BGRA() const noexcept { using namespace DirectX; XMVECTOR clr = XMLoadFloat4(this); PackedVector::XMCOLOR Packed; PackedVector::XMStoreColor(&Packed, clr); return Packed; } inline DirectX::PackedVector::XMUBYTEN4 Color::RGBA() const noexcept { using namespace DirectX; XMVECTOR clr = XMLoadFloat4(this); PackedVector::XMUBYTEN4 Packed; PackedVector::XMStoreUByteN4(&Packed, clr); return Packed; } inline Vector3 Color::ToVector3() const noexcept { return Vector3(x, y, z); } inline Vector4 Color::ToVector4() const noexcept { return Vector4(x, y, z, w); } inline void Color::Negate() noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(this, XMColorNegative(c)); } inline void Color::Negate(Color& result) const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(&result, XMColorNegative(c)); } inline void Color::Saturate() noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(this, XMVectorSaturate(c)); } inline void Color::Saturate(Color& result) const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(&result, XMVectorSaturate(c)); } inline void Color::Premultiply() noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMVECTOR a = XMVectorSplatW(c); a = XMVectorSelect(g_XMIdentityR3, a, g_XMSelect1110); XMStoreFloat4(this, XMVectorMultiply(c, a)); } inline void Color::Premultiply(Color& result) const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMVECTOR a = XMVectorSplatW(c); a = XMVectorSelect(g_XMIdentityR3, a, g_XMSelect1110); XMStoreFloat4(&result, XMVectorMultiply(c, a)); } inline void Color::AdjustSaturation(float sat) noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(this, XMColorAdjustSaturation(c, sat)); } inline void Color::AdjustSaturation(float sat, Color& result) const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(&result, XMColorAdjustSaturation(c, sat)); } inline void Color::AdjustContrast(float contrast) noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(this, XMColorAdjustContrast(c, contrast)); } inline void Color::AdjustContrast(float contrast, Color& result) const noexcept { using namespace DirectX; XMVECTOR c = XMLoadFloat4(this); XMStoreFloat4(&result, XMColorAdjustContrast(c, contrast)); } //------------------------------------------------------------------------------ // Static functions //------------------------------------------------------------------------------ inline void Color::Modulate(const Color& c1, const Color& c2, Color& result) noexcept { using namespace DirectX; XMVECTOR C0 = XMLoadFloat4(&c1); XMVECTOR C1 = XMLoadFloat4(&c2); XMStoreFloat4(&result, XMColorModulate(C0, C1)); } inline Color Color::Modulate(const Color& c1, const Color& c2) noexcept { using namespace DirectX; XMVECTOR C0 = XMLoadFloat4(&c1); XMVECTOR C1 = XMLoadFloat4(&c2); Color result; XMStoreFloat4(&result, XMColorModulate(C0, C1)); return result; } inline void Color::Lerp(const Color& c1, const Color& c2, float t, Color& result) noexcept { using namespace DirectX; XMVECTOR C0 = XMLoadFloat4(&c1); XMVECTOR C1 = XMLoadFloat4(&c2); XMStoreFloat4(&result, XMVectorLerp(C0, C1, t)); } inline Color Color::Lerp(const Color& c1, const Color& c2, float t) noexcept { using namespace DirectX; XMVECTOR C0 = XMLoadFloat4(&c1); XMVECTOR C1 = XMLoadFloat4(&c2); Color result; XMStoreFloat4(&result, XMVectorLerp(C0, C1, t)); return result; } /**************************************************************************** * * Ray * ****************************************************************************/ //----------------------------------------------------------------------------- // Comparision operators //------------------------------------------------------------------------------ inline bool Ray::operator == (const Ray& r) const noexcept { using namespace DirectX; XMVECTOR r1p = XMLoadFloat3(&position); XMVECTOR r2p = XMLoadFloat3(&r.position); XMVECTOR r1d = XMLoadFloat3(&direction); XMVECTOR r2d = XMLoadFloat3(&r.direction); return XMVector3Equal(r1p, r2p) && XMVector3Equal(r1d, r2d); } inline bool Ray::operator != (const Ray& r) const noexcept { using namespace DirectX; XMVECTOR r1p = XMLoadFloat3(&position); XMVECTOR r2p = XMLoadFloat3(&r.position); XMVECTOR r1d = XMLoadFloat3(&direction); XMVECTOR r2d = XMLoadFloat3(&r.direction); return XMVector3NotEqual(r1p, r2p) && XMVector3NotEqual(r1d, r2d); } //----------------------------------------------------------------------------- // Ray operators //------------------------------------------------------------------------------ inline bool Ray::Intersects(const BoundingSphere& sphere, _Out_ float& Dist) const noexcept { return sphere.Intersects(position, direction, Dist); } inline bool Ray::Intersects(const BoundingBox& box, _Out_ float& Dist) const noexcept { return box.Intersects(position, direction, Dist); } inline bool Ray::Intersects(const Vector3& tri0, const Vector3& tri1, const Vector3& tri2, _Out_ float& Dist) const noexcept { return DirectX::TriangleTests::Intersects(position, direction, tri0, tri1, tri2, Dist); } inline bool Ray::Intersects(const Plane& plane, _Out_ float& Dist) const noexcept { using namespace DirectX; XMVECTOR p = XMLoadFloat4(&plane); XMVECTOR dir = XMLoadFloat3(&direction); XMVECTOR nd = XMPlaneDotNormal(p, dir); if (XMVector3LessOrEqual(XMVectorAbs(nd), g_RayEpsilon)) { Dist = 0.f; return false; } else { // t = -(dot(n,origin) + D) / dot(n,dir) XMVECTOR pos = XMLoadFloat3(&position); XMVECTOR v = XMPlaneDotNormal(p, pos); v = XMVectorAdd(v, XMVectorSplatW(p)); v = XMVectorDivide(v, nd); float dist = -XMVectorGetX(v); if (dist < 0) { Dist = 0.f; return false; } else { Dist = dist; return true; } } } /**************************************************************************** * * Viewport * ****************************************************************************/ //------------------------------------------------------------------------------ // Comparision operators //------------------------------------------------------------------------------ inline bool Viewport::operator == (const Viewport& vp) const noexcept { return (x == vp.x && y == vp.y && width == vp.width && height == vp.height && minDepth == vp.minDepth && maxDepth == vp.maxDepth); } inline bool Viewport::operator != (const Viewport& vp) const noexcept { return (x != vp.x || y != vp.y || width != vp.width || height != vp.height || minDepth != vp.minDepth || maxDepth != vp.maxDepth); } //------------------------------------------------------------------------------ // Assignment operators //------------------------------------------------------------------------------ inline Viewport& Viewport::operator= (const RECT& rct) noexcept { x = float(rct.left); y = float(rct.top); width = float(rct.right - rct.left); height = float(rct.bottom - rct.top); minDepth = 0.f; maxDepth = 1.f; return *this; } #if defined(__d3d11_h__) || defined(__d3d11_x_h__) inline Viewport& Viewport::operator= (const D3D11_VIEWPORT& vp) noexcept { x = vp.TopLeftX; y = vp.TopLeftY; width = vp.Width; height = vp.Height; minDepth = vp.MinDepth; maxDepth = vp.MaxDepth; return *this; } #endif #if defined(__d3d12_h__) || defined(__d3d12_x_h__) || defined(__XBOX_D3D12_X__) inline Viewport& Viewport::operator= (const D3D12_VIEWPORT& vp) noexcept { x = vp.TopLeftX; y = vp.TopLeftY; width = vp.Width; height = vp.Height; minDepth = vp.MinDepth; maxDepth = vp.MaxDepth; return *this; } #endif //------------------------------------------------------------------------------ // Viewport operations //------------------------------------------------------------------------------ inline float Viewport::AspectRatio() const noexcept { if (width == 0.f || height == 0.f) return 0.f; return (width / height); } inline Vector3 Viewport::Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept { using namespace DirectX; XMVECTOR v = XMLoadFloat3(&p); XMMATRIX projection = XMLoadFloat4x4(&proj); v = XMVector3Project(v, x, y, width, height, minDepth, maxDepth, projection, view, world); Vector3 result; XMStoreFloat3(&result, v); return result; } inline void Viewport::Project(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept { using namespace DirectX; XMVECTOR v = XMLoadFloat3(&p); XMMATRIX projection = XMLoadFloat4x4(&proj); v = XMVector3Project(v, x, y, width, height, minDepth, maxDepth, projection, view, world); XMStoreFloat3(&result, v); } inline Vector3 Viewport::Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world) const noexcept { using namespace DirectX; XMVECTOR v = XMLoadFloat3(&p); XMMATRIX projection = XMLoadFloat4x4(&proj); v = XMVector3Unproject(v, x, y, width, height, minDepth, maxDepth, projection, view, world); Vector3 result; XMStoreFloat3(&result, v); return result; } inline void Viewport::Unproject(const Vector3& p, const Matrix& proj, const Matrix& view, const Matrix& world, Vector3& result) const noexcept { using namespace DirectX; XMVECTOR v = XMLoadFloat3(&p); XMMATRIX projection = XMLoadFloat4x4(&proj); v = XMVector3Unproject(v, x, y, width, height, minDepth, maxDepth, projection, view, world); XMStoreFloat3(&result, v); }