Skip to content

Commit

Permalink
Feature: Enable frustum in camera
Browse files Browse the repository at this point in the history
  • Loading branch information
kimkulling committed Dec 3, 2024
1 parent 32c3ef3 commit 7695c91
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 25 deletions.
1 change: 0 additions & 1 deletion src/Engine/App/AssetRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ void AssetRegistry::destroy() {
sInstance = nullptr;
}


bool AssetRegistry::registerAssetPath(const String &mount, const String &path) {
if (nullptr == sInstance) {
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/Engine/App/CameraComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ bool CameraComponent::onUpdate(Time) {
mProjection = glm::ortho(mLeft, mRight, mBottom, mTop, mNear, mFar);
}
mView = glm::lookAt(mEye, mCenter, mUp);

mViewProjection = mProjection * mView;
mFrustum.extractFrom(mViewProjection);

return true;
}

Expand Down
4 changes: 3 additions & 1 deletion src/Engine/App/CameraComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "App/TransformComponent.h"
#include "App/SceneCommon.h"
#include "Common/TAABB.h"
#include "Common/Frustum.h"

namespace OSRE {
namespace App {
Expand Down Expand Up @@ -161,7 +162,8 @@ class OSRE_EXPORT CameraComponent : public Component {
f32 mAspectRatio;
f32 mLeft, mRight, mTop, mBottom;
glm::vec3 mEye, mCenter, mUp;
glm::mat4 mView, mProjection;
glm::mat4 mView, mProjection, mViewProjection;
Common::Frustum mFrustum;
};

inline CameraModel CameraComponent::getCameraModel() const {
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/App/TransformComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@ inline bool TransformComponent::isActive() const {
return mIsActive;
}

} // Namespace App
} // namespace App
} // namespace OSRE
4 changes: 0 additions & 4 deletions src/Engine/App/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ World::World(const String &worldName) :
// empty
}

World::~World() {
// empty
}

void World::addEntity(Entity *entity) {
if (nullptr == entity) {
osre_debug(Tag, "Pointer to entity are nullptr");
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/App/World.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class OSRE_EXPORT World : public Common::Object {
explicit World(const String &worldName);

/// @brief The class destructor.
~World() override;
~World() override = default;

/// @brief Will add a new entity.
/// @param entity The entity to add.
Expand Down
51 changes: 37 additions & 14 deletions src/Engine/Common/Frustum.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,39 +24,61 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "Common/osre_common.h"
#include "Common/glm_common.h"
#include <cppcore/Container/TStaticArray.h>

namespace OSRE {
namespace Common {

struct Plane {
glm::vec4 param;

bool operator==(const Plane &rhs) const {
return (param == rhs.param);
}

bool operator!=(const Plane &rhs) const {
return (param != rhs.param);
}
};

class Frustum {
public:
enum {

Check notice

Code scanning / CodeQL

Irregular enum initialization Note

In an enumerator list, the = construct should not be used to explicitly initialize members other than the first, unless all items are explicitly initialized.
Invalid = -1,
Top = 0,
Bottom,
Left,
Right,
NearP,
FarP
FarP,
Count
};

Frustum(Plane *planes);
Frustum();
~Frustum() = default;
bool isIn(glm::vec3 &point);
bool isIn(const glm::vec3 &point);
void extractFrom(const glm::mat4 &vp);
void clear();

private:
glm::vec4 mPlanes[6];
cppcore::TStaticArray<Plane, 6> mPlanes;
};

inline Frustum::Frustum(Plane *planes) {
for (ui32 i = 0; i < Count; ++i) {
mPlanes[i] = planes[i];
}
}
inline Frustum::Frustum() {
clear();
}

inline bool Frustum::isIn( glm::vec3 &point ) {
inline bool Frustum::isIn(const glm::vec3 &point ) {
bool in = true;
for (auto & plane : mPlanes) {
const f32 d = plane.x * point.x + plane.y * point.y + plane.z * point.z + plane.w;
for (size_t i = 0; i < mPlanes.size(); ++i) {
const Plane &plane = mPlanes[i];
const f32 d = plane.param.x * point.x + plane.param.y * point.y + plane.param.z * point.z + plane.param.w;
if (d < 0.0f) {
in = false;
break;
Expand All @@ -72,17 +94,18 @@ inline void Frustum::extractFrom(const glm::mat4 &vp) {
glm::vec4 rowZ = glm::row(vp, 2);
glm::vec4 rowW = glm::row(vp, 3);

mPlanes[0] = normalize(rowW + rowX);
mPlanes[1] = normalize(rowW - rowX);
mPlanes[2] = normalize(rowW + rowY);
mPlanes[3] = normalize(rowW - rowY);
mPlanes[4] = normalize(rowW + rowZ);
mPlanes[5] = normalize(rowW - rowZ);
mPlanes[0].param = normalize(rowW + rowX);
mPlanes[1].param = normalize(rowW - rowX);
mPlanes[2].param = normalize(rowW + rowY);
mPlanes[3].param = normalize(rowW - rowY);
mPlanes[4].param = normalize(rowW + rowZ);
mPlanes[5].param = normalize(rowW - rowZ);
}

inline void Frustum::clear() {
for (auto &plane : mPlanes) {
plane.x = plane.y = plane.z = plane.w = 0.0f;
for (size_t i = 0; i < mPlanes.size(); ++i) {
Plane &plane = mPlanes[i];
plane.param.x = plane.param.y = plane.param.z = plane.param.w = 0.0f;
}
}

Expand Down
19 changes: 17 additions & 2 deletions test/UnitTests/src/Common/FrustumTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class FrustumTest : public ::testing::Test {
// empty
};

TEST_F( FrustumTest, createTest ) {
TEST_F(FrustumTest, createTest) {
bool ok = true;
try {
Frustum f;
Expand All @@ -42,7 +42,22 @@ TEST_F( FrustumTest, createTest ) {
EXPECT_TRUE(ok);
}

TEST_F( FrustumTest, extractFromTest ) {
TEST_F(FrustumTest, isInTest) {
Frustum f;
glm::mat4 p = glm::perspective(1.2f, 1.f, 0.1f, 100.0f);
glm::mat4 v = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 20), glm::vec3(0, 1, 0));
glm::mat4 vp = p * v;
f.extractFrom(vp);
glm::vec3 pt1(0, 0, 10.5);
bool in = f.isIn(pt1);
EXPECT_TRUE(in);

glm::vec3 pt2(0, 0, -10.5);
bool out = f.isIn(pt2);
EXPECT_FALSE(out);
}

TEST_F(FrustumTest, extractFromTest) {
glm::vec3 pos(-10, 10, 0), center(0, 0, 0), up(0, 0, 1);
glm::mat4 v = glm::lookAt(pos, center, up);
glm::mat4 p = glm::perspective(1.2f, 1.f, 0.1f, 100.0f);
Expand Down

0 comments on commit 7695c91

Please sign in to comment.