From 99d97b75079debe7b7fd0aae07701651056aa2be Mon Sep 17 00:00:00 2001 From: maelstrom Date: Fri, 10 Oct 2025 21:37:41 +0200 Subject: [PATCH] feat(rendering): added frustum class --- core/CMakeLists.txt | 2 ++ core/src/rendering/frustum.cpp | 44 ++++++++++++++++++++++++++++++++++ core/src/rendering/frustum.h | 29 ++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 core/src/rendering/frustum.cpp create mode 100644 core/src/rendering/frustum.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 7a14c9e..a3c1427 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -57,6 +57,8 @@ set(SOURCES src/rendering/font.h src/rendering/defaultmeshes.h src/rendering/texture3d.cpp + src/rendering/frustum.h + src/rendering/frustum.cpp src/physics/world.h src/physics/world.cpp src/logger.cpp diff --git a/core/src/rendering/frustum.cpp b/core/src/rendering/frustum.cpp new file mode 100644 index 0000000..526dc5f --- /dev/null +++ b/core/src/rendering/frustum.cpp @@ -0,0 +1,44 @@ +#include "frustum.h" +#include "datatypes/vector.h" +#include + +// https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling + +// https://stackoverflow.com/q/66227192/16255372 +FrustumPlane::FrustumPlane(Vector3 point, Vector3 normal) : normal(normal.Unit()), distance(normal.Unit().Dot(point)) {} + +Frustum::Frustum(const Camera cam, float aspect, float fovY, float zNear, float zFar) { + const float halfVSide = zFar * tanf(fovY * 0.5f); + const float halfHSide = halfVSide * aspect; + const glm::vec3 frontMultFar = zFar * cam.cameraFront; + + // Don't forget to normalize!!! + glm::vec3 camRight = glm::normalize(glm::cross(cam.cameraFront, -cam.cameraUp)); // Technically this is left, but whatever + glm::vec3 trueCamUp = glm::cross(cam.cameraFront, camRight); + near = { cam.cameraPos + zNear * cam.cameraFront, cam.cameraFront }; + far = { cam.cameraPos + frontMultFar, -cam.cameraFront }; + right = { cam.cameraPos, + glm::cross(frontMultFar - camRight * halfHSide, trueCamUp) }; + left = { cam.cameraPos, + glm::cross(trueCamUp,frontMultFar + camRight * halfHSide) }; + top = { cam.cameraPos, + glm::cross(camRight, frontMultFar - trueCamUp * halfVSide) }; + bottom = { cam.cameraPos, + glm::cross(frontMultFar + trueCamUp * halfVSide, camRight) }; +} + +bool FrustumPlane::checkPointForward(Vector3 point) { + return (normal.Dot(point) - distance) < 0; +} + +bool Frustum::checkPoint(Vector3 point) { + return true + // TODO: Near and far are broken for some reason + // && near.checkPointForward(point) + // && far.checkPointForward(point) + && left.checkPointForward(point) + && right.checkPointForward(point) + && top.checkPointForward(point) + && bottom.checkPointForward(point) + ; +} \ No newline at end of file diff --git a/core/src/rendering/frustum.h b/core/src/rendering/frustum.h new file mode 100644 index 0000000..01a4cdc --- /dev/null +++ b/core/src/rendering/frustum.h @@ -0,0 +1,29 @@ +#pragma once + +#include "camera.h" +#include "datatypes/vector.h" + +// https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling + +struct FrustumPlane { + Vector3 normal; + float distance; // leastPoint = normal * distance + // leastPoint is the closest point to (0,0) + + FrustumPlane(Vector3 point, Vector3 normal); + FrustumPlane() = default; + + bool checkPointForward(Vector3); +}; + +struct Frustum { + FrustumPlane near; + FrustumPlane far; + FrustumPlane left; + FrustumPlane right; + FrustumPlane top; + FrustumPlane bottom; + + Frustum(const Camera cam, float aspect, float fovY, float zNear, float zFar); + bool checkPoint(Vector3); +}; \ No newline at end of file