Implement D3DOrtho

This commit is contained in:
2024-01-12 10:27:36 -05:00
parent 32046d88cd
commit 1eae732718
4 changed files with 109 additions and 18 deletions

View File

@@ -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;

View File

@@ -6,18 +6,7 @@
namespace LinearAlgebra {
template<typename Matrix>
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);
};
}

View File

@@ -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;

View File

@@ -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;
}
}