From 1eae732718380c6da03ce1540f6fca193b5ff551 Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 12 Jan 2024 10:27:36 -0500 Subject: [PATCH] Implement D3DOrtho --- include/J3ML/LinearAlgebra/Matrix3x3.h | 1 - include/J3ML/LinearAlgebra/Matrix4x4.h | 45 +++++++++++++-------- include/J3ML/LinearAlgebra/Vector3.h | 27 +++++++++++++ src/J3ML/LinearAlgebra/Matrix4x4.cpp | 54 ++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 18 deletions(-) diff --git a/include/J3ML/LinearAlgebra/Matrix3x3.h b/include/J3ML/LinearAlgebra/Matrix3x3.h index 1f8dc14..c18d4d2 100644 --- a/include/J3ML/LinearAlgebra/Matrix3x3.h +++ b/include/J3ML/LinearAlgebra/Matrix3x3.h @@ -43,7 +43,6 @@ namespace LinearAlgebra { Vector3 GetRow(int index) const; Vector3 GetColumn(int index) const; - Vector3 Diagonal() const; float At(int x, int y) const; diff --git a/include/J3ML/LinearAlgebra/Matrix4x4.h b/include/J3ML/LinearAlgebra/Matrix4x4.h index c97542b..b776573 100644 --- a/include/J3ML/LinearAlgebra/Matrix4x4.h +++ b/include/J3ML/LinearAlgebra/Matrix4x4.h @@ -6,18 +6,7 @@ namespace LinearAlgebra { - template - void SetMatrixRotatePart(Matrix &m, const Quaternion& q) - { - // See e.g. http://www.geometrictools.com/Documentation/LinearAlgebraicQuaternions.pdf . - const float x = q.x; - const float y = q.y; - const float z = q.z; - const float w = q.w; - m[0][0] = 1 - 2*(y*y + z*z); m[0][1] = 2*(x*y - z*w); m[0][2] = 2*(x*z + y*w); - m[1][0] = 2*(x*y + z*w); m[1][1] = 1 - 2*(x*x + z*z); m[1][2] = 2*(y*z - x*w); - m[2][0] = 2*(x*z - y*w); m[2][1] = 2*(y*z + x*w); m[2][2] = 1 - 2*(x*x + y*y); - } + @@ -64,10 +53,17 @@ namespace LinearAlgebra { explicit Matrix4x4(const Quaternion& orientation); + Vector3 GetTranslatePart() const; + Matrix3x3 GetRotatePart() const + { + return Matrix3x3 { + At(0, 0), At(0, 1), At(0, 2), + At(1, 0), At(1, 1), At(1, 2), + At(2, 0), At(2, 1), At(2, 2) + }; + } void SetTranslatePart(float translateX, float translateY, float translateZ); - void SetTranslatePart(const Vector3& offset); - void SetRotatePart(const Quaternion& q); @@ -104,17 +100,32 @@ namespace LinearAlgebra { Vector2 Transform(const Vector2& rhs) const; Vector3 Transform(const Vector3& rhs) const; Vector4 Transform(const Vector4& rhs) const; - Matrix4x4 D3DOrthoProjLH(float n, float f, float h, float v) - { - } + + static Matrix4x4 D3DOrthoProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 D3DOrthoProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 D3DPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 D3DPerspProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + + static Matrix4x4 OpenGLOrthoProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 OpenGLOrthoProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 OpenGLPerspProjLH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); + static Matrix4x4 OpenGLPerspProjRH(float nearPlane, float farPlane, float hViewportSize, float vViewportSize); Vector3 GetTranslationComponent() const; Matrix3x3 GetRotationComponent() const; Vector4 GetRow() const; Vector4 GetColumn() const; + + Vector4 operator[](int row) + { + return Vector4{elems[row][0], elems[row][1], elems[row][2], elems[row][3]}; + } + protected: float elems[4][4]; + + void SetMatrixRotatePart(Matrix4x4 &m, const Quaternion &q); }; } \ No newline at end of file diff --git a/include/J3ML/LinearAlgebra/Vector3.h b/include/J3ML/LinearAlgebra/Vector3.h index 46707d9..a1bc92b 100644 --- a/include/J3ML/LinearAlgebra/Vector3.h +++ b/include/J3ML/LinearAlgebra/Vector3.h @@ -30,6 +30,33 @@ public: static const Vector3 Backward; static const Vector3 NaN; + static void Orthonormalize(Vector3& a, Vector3& b) + { + a = a.Normalize(); + b = b - b.ProjectToNorm(a); + b = b.Normalize(); + } + + static void Orthonormalize(Vector3& a, Vector3& b, Vector3& c) + { + a = a.Normalize(); + b = b - b.ProjectToNorm(a); + b = b.Normalize(); + c = c - c.ProjectToNorm(a); + c = c - c.ProjectToNorm(b); + c = c.Normalize(); + } + + bool AreOrthonormal(const Vector3& a, const Vector3& b, float epsilon) + { + + } + + Vector3 ProjectToNorm(const Vector3& direction) + { + return direction * this->Dot(direction); + } + float GetX() const; float GetY() const; float GetZ() const; diff --git a/src/J3ML/LinearAlgebra/Matrix4x4.cpp b/src/J3ML/LinearAlgebra/Matrix4x4.cpp index 4d1e014..221d5fb 100644 --- a/src/J3ML/LinearAlgebra/Matrix4x4.cpp +++ b/src/J3ML/LinearAlgebra/Matrix4x4.cpp @@ -94,6 +94,18 @@ namespace LinearAlgebra { SetMatrixRotatePart(*this, q); } + void Matrix4x4::SetMatrixRotatePart(Matrix4x4 &m, const Quaternion& q) + { + // See e.g. http://www.geometrictools.com/Documentation/LinearAlgebraicQuaternions.pdf . + const float x = q.x; + const float y = q.y; + const float z = q.z; + const float w = q.w; + elems[0][0] = 1 - 2*(y*y + z*z); elems[0][1] = 2*(x*y - z*w); elems[0][2] = 2*(x*z + y*w); + elems[1][0] = 2*(x*y + z*w); elems[1][1] = 1 - 2*(x*x + z*z); elems[1][2] = 2*(y*z - x*w); + elems[2][0] = 2*(x*z - y*w); elems[2][1] = 2*(y*z + x*w); elems[2][2] = 1 - 2*(x*x + y*y); + } + void Matrix4x4::SetRow(int row, const Vector3 &rowVector, float m_r3) { SetRow(row, rowVector.x, rowVector.y, rowVector.z, m_r3); } @@ -114,4 +126,46 @@ namespace LinearAlgebra { SetTranslatePart(translation); SetRow(3, 0, 0, 0, 1); } + + Matrix4x4 Matrix4x4::D3DOrthoProjLH(float n, float f, float h, float v) { + float p00 = 2.f / h; float p01 = 0; float p02 = 0; float p03 = 0.f; + float p10 = 0; float p11 = 2.f / v; float p12 = 0; float p13 = 0.f; + float p20 = 0; float p21 = 0; float p22 = 1.f / (f-n); float p23 = n / (n-f); + float p30 = 0; float p31 = 0; float p32 = 0.f; float p33 = 1.f; + + return {p00, p01, p02, p03, p10, p11, p12, p13, p20, p21, p22, p23, p30, p31, p32, p33}; + } + + /** This function generates an orthographic projection matrix that maps from + the Direct3D view space to the Direct3D normalized viewport space as follows: + + In Direct3D view space, we assume that the camera is positioned at the origin (0,0,0). + The camera looks directly towards the positive Z axis (0,0,1). + The -X axis spans to the left of the screen, +X goes to the right. + -Y goes to the bottom of the screen, +Y goes to the top. + + After the transformation, we're in the Direct3D normalized viewport space as follows: + + (-1,-1,0) is the bottom-left corner of the viewport at the near plane. + (1,1,0) is the top-right corner of the viewport at the near plane. + (0,0,0) is the center point at the near plane. + Coordinates with z=1 are at the far plane. + + Examples: + (0,0,n) maps to (0,0,0). + (0,0,f) maps to (0,0,1). + (-h/2, -v/2, n) maps to (-1, -1, 0). + (h/2, v/2, f) maps to (1, 1, 1). + */ + Matrix4x4 Matrix4x4::D3DOrthoProjRH(float n, float f, float h, float v) + { + // D3DOrthoProjLH and D3DOrthoProjRH differ from each other in that the third column is negated. + // This corresponds to LH = RH * In, where In is a diagonal matrix with elements [1 1 -1 1]. + float p00 = 2.f / h; float p01 = 0; float p02 = 0; float p03 = 0.f; + float p10 = 0; float p11 = 2.f / v; float p12 = 0; float p13 = 0.f; + float p20 = 0; float p21 = 0; float p22 = 1.f / (n-f); float p23 = n / (n-f); + float p30 = 0; float p31 = 0; float p32 = 0.f; float p33 = 1.f; + } + + } \ No newline at end of file