From dea5735c870b82e05b52d525d72d07d0b21c4e4a Mon Sep 17 00:00:00 2001 From: josh Date: Wed, 10 Jan 2024 14:46:12 -0500 Subject: [PATCH] Implement CreateFrustumFromCamera --- CMakeLists.txt | 3 +- include/J3ML/Geometry.h | 62 +++++++++++++++++---- include/J3ML/LinearAlgebra/Matrix4x4.h | 36 ++++++++++++- include/J3ML/LinearAlgebra/Vector.h | 13 +++++ main.cpp | 2 +- src/J3ML/LinearAlgebra/Matrix4x4.cpp | 75 ++++++++++++++++++++++++++ tests/LinearAlgebra/Vector3Tests.cpp | 2 +- 7 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 include/J3ML/LinearAlgebra/Vector.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 893e0f8..c3af1a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,8 @@ file(GLOB_RECURSE J3ML_SRC "src/J3ML/*.c" "src/J3ML/*.cpp") include_directories("include") add_library(J3ML SHARED ${J3ML_SRC} - src/J3ML/LinearAlgebra/AxisAngle.cpp) + src/J3ML/LinearAlgebra/AxisAngle.cpp + include/J3ML/LinearAlgebra/Vector.h) set_target_properties(J3ML PROPERTIES LINKER_LANGUAGE CXX) install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME}) diff --git a/include/J3ML/Geometry.h b/include/J3ML/Geometry.h index ec73859..8400e29 100644 --- a/include/J3ML/Geometry.h +++ b/include/J3ML/Geometry.h @@ -3,12 +3,13 @@ #pragma once namespace Geometry { - using Point2D = LinearAlgebra::Vector2; + using Vector2 = LinearAlgebra::Vector2; + using Vector3 = LinearAlgebra::Vector3; class LineSegment2D { - Point2D A; - Point2D B; + Vector2 A; + Vector2 B; }; class Rectangle; //AABB2D; @@ -29,7 +30,7 @@ namespace Geometry { - using Point3D = LinearAlgebra::Vector3; + // A 3D axis-aligned bounding box // This data structure can be used to represent coarse bounds of objects, in situations where detailed triangle-level @@ -44,18 +45,59 @@ namespace Geometry { class Line; class LineSegment { - Point3D A; - Point3D B; + Vector3 A; + Vector3 B; }; class Ray { - Point3D Origin; - Point3D Direction; + Vector3 Origin; + Vector3 Direction; }; class OBB; - class Frustum; - class Plane; + class Plane + { + public: + Vector3 Position; + Vector3 Normal; + float distance = 0.f; + + }; + class Frustum { + public: + Plane TopFace; + Plane BottomFace; + Plane RightFace; + Plane LeftFace; + Plane FarFace; + Plane NearFace; + }; + + class Camera { + public: + Vector3 Position; + Vector3 Front; + Vector3 Right; + Vector3 Up; + }; + + static Frustum CreateFrustumFromCamera(const Camera& cam, float aspect, float fovY, float zNear, float zFar) + { + Frustum frustum; + const float halfVSide = zFar * tanf(fovY * 0.5f); + const float halfHSide = halfVSide * aspect; + + const Vector3 frontMultFar = cam.Front * zFar; + + frustum.NearFace = Plane{cam.Position + cam.Front * zNear, cam.Front}; + frustum.FarFace = Plane{cam.Position + frontMultFar, -cam.Front}; + frustum.RightFace = Plane{cam.Position, Vector3::Cross(frontMultFar - cam.Right * halfHSide, cam.Up)}; + frustum.LeftFace = Plane{cam.Position, Vector3::Cross(cam.Up, frontMultFar+cam.Right*halfHSide)}; + frustum.TopFace = Plane{cam.Position, Vector3::Cross(cam.Right, frontMultFar - cam.Up * halfVSide)}; + frustum.BottomFace = Plane{cam.Position, Vector3::Cross(frontMultFar + cam.Up * halfVSide, cam.Right)}; + return frustum; + } + class Polygon; class Polyhedron; class QuadTree; diff --git a/include/J3ML/LinearAlgebra/Matrix4x4.h b/include/J3ML/LinearAlgebra/Matrix4x4.h index 58d7660..8d38b47 100644 --- a/include/J3ML/LinearAlgebra/Matrix4x4.h +++ b/include/J3ML/LinearAlgebra/Matrix4x4.h @@ -10,7 +10,7 @@ namespace LinearAlgebra { * The elements of this matrix are * m_00, m_01, m_02, m_03 * m_10, m_11, m_12, m_13 - * m_20, m_21, m_22, m_23, + * m_20, m_21, m_22, xm_23, * m_30, m_31, m_32, m_33 * * The element m_yx is the value on the row y and column x. @@ -18,8 +18,42 @@ namespace LinearAlgebra { */ class Matrix4x4 { public: + enum { Rows = 4 }; + enum { Cols = 4 }; + static const Matrix4x4 Zero; static const Matrix4x4 Identity; + static const Matrix4x4 NaN; + + Matrix4x4() {} + Matrix4x4(float val); + Matrix4x4(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33); + Matrix4x4(const Vector4& r1, const Vector4& r2, const Vector4& r3, const Vector4& r4); + explicit Matrix4x4(const Quaternion& orientation); + + Vector4 GetRow(int index) const; + Vector4 GetColumn(int index) const; + float At(int x, int y) const; + + Vector4 Diagonal() const; + Vector4 WorldX() const; + Vector4 WorldY() const; + Vector4 WorldZ() const; + + /// Computes the determinant of this matrix. + // If the determinant is nonzero, this matrix is invertible. + float Determinant() const; + + Matrix4x4 Inverse() const; + + Matrix4x4 Transpose() const; + + Vector2 Transform(const Vector2& rhs) const; + Vector3 Transform(const Vector3& rhs) const; + Vector4 Transform(const Vector4& rhs) const; Vector3 GetTranslationComponent() const; Matrix3x3 GetRotationComponent() const; diff --git a/include/J3ML/LinearAlgebra/Vector.h b/include/J3ML/LinearAlgebra/Vector.h new file mode 100644 index 0000000..f25a6d5 --- /dev/null +++ b/include/J3ML/LinearAlgebra/Vector.h @@ -0,0 +1,13 @@ +#pragma once + + +template +class templated_vector +{ + +}; + + +using v2f = templated_vector; +using v3f = templated_vector; +using v4f = templated_vector; \ No newline at end of file diff --git a/main.cpp b/main.cpp index a9db1dc..eb78919 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ #include - +#include int main(int argc, char** argv) { diff --git a/src/J3ML/LinearAlgebra/Matrix4x4.cpp b/src/J3ML/LinearAlgebra/Matrix4x4.cpp index 3be5e12..6088c72 100644 --- a/src/J3ML/LinearAlgebra/Matrix4x4.cpp +++ b/src/J3ML/LinearAlgebra/Matrix4x4.cpp @@ -1,5 +1,80 @@ #include +#include namespace LinearAlgebra { + const Matrix4x4 Matrix4x4::Zero = Matrix4x4(0); + const Matrix4x4 Matrix4x4::Identity = Matrix4x4({1,0,0,0}, {0,1,0,0}, {0,0,1,0}, {0,0,0,1}); + const Matrix4x4 Matrix4x4::NaN = Matrix4x4(NAN); + Matrix4x4::Matrix4x4(const Vector4 &r1, const Vector4 &r2, const Vector4 &r3, const Vector4 &r4) { + this->elems[0][0] = r1.x; + this->elems[0][1] = r1.y; + this->elems[0][2] = r1.z; + this->elems[0][3] = r1.w; + + this->elems[1][0] = r2.x; + this->elems[1][1] = r2.y; + this->elems[1][2] = r2.z; + this->elems[1][3] = r2.w; + + this->elems[2][0] = r3.x; + this->elems[2][1] = r3.y; + this->elems[2][2] = r3.z; + this->elems[2][3] = r3.w; + + this->elems[3][0] = r4.x; + this->elems[3][1] = r4.y; + this->elems[3][2] = r4.z; + this->elems[3][3] = r4.w; + } + + Matrix4x4::Matrix4x4(float val) { + this->elems[0][0] = val; + this->elems[0][1] = val; + this->elems[0][2] = val; + this->elems[0][3] = val; + + this->elems[1][0] = val; + this->elems[1][1] = val; + this->elems[1][2] = val; + this->elems[1][3] = val; + + this->elems[2][0] = val; + this->elems[2][1] = val; + this->elems[2][2] = val; + this->elems[2][3] = val; + + this->elems[3][0] = val; + this->elems[3][1] = val; + this->elems[3][2] = val; + this->elems[3][3] = val; + } + + Matrix4x4::Matrix4x4(float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33) { + this->elems[0][0] = m00; + this->elems[0][1] = m01; + this->elems[0][2] = m02; + this->elems[0][3] = m03; + + this->elems[1][0] = m10; + this->elems[1][1] = m11; + this->elems[1][2] = m12; + this->elems[1][3] = m13; + + this->elems[2][0] = m20; + this->elems[2][1] = m21; + this->elems[2][2] = m22; + this->elems[2][3] = m23; + + this->elems[3][0] = m30; + this->elems[3][1] = m31; + this->elems[3][2] = m32; + this->elems[3][3] = m33; + + } + + Matrix4x4::Matrix4x4(const Quaternion &orientation) { + + } } \ No newline at end of file diff --git a/tests/LinearAlgebra/Vector3Tests.cpp b/tests/LinearAlgebra/Vector3Tests.cpp index 510117e..11e5974 100644 --- a/tests/LinearAlgebra/Vector3Tests.cpp +++ b/tests/LinearAlgebra/Vector3Tests.cpp @@ -189,7 +189,7 @@ TEST(Vector3Test, V3_AngleBetween) { Vector3 B {.25f, .75f, .25f}; A = A.Normalize(); B = B.Normalize(); - LinearAlgebra::Angle2D ExpectedResult {-0.697914, -2.35619}; + LinearAlgebra::Angle2D ExpectedResult {-0.69791365, -2.3561945}; std::cout << A.AngleBetween(B).x << ", " << A.AngleBetween(B).y << ""; auto angle = A.AngleBetween(B); EXPECT_FLOAT_EQ(angle.x, ExpectedResult.x);