VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
frustumUtils.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3//
4// Created by Arnis Lektauers on 09.02.2026.
5//
6#include "frustumUtils.h"
7
8#include <cmath>
9
10#include "camera.h"
11#include "graphNode.h"
13
14namespace visutwin::canvas
15{
16 bool isVisibleInCameraFrustum(Camera* camera, GraphNode* cameraNode, const BoundingBox& bounds)
17 {
18 if (!camera || !cameraNode) {
19 return true;
20 }
21
22 const auto view = cameraNode->worldTransform().inverse();
23 const auto viewProjection = camera->projectionMatrix() * view;
24
25 Frustum frustum;
26 frustum.create(viewProjection);
27
28 const auto center = bounds.center();
29 const auto extents = bounds.halfExtents();
30 const float extentLen = extents.length();
31 const float baseSlop = std::max(0.01f, extentLen * 0.05f);
32
33 constexpr size_t PLANE_COUNT = 6;
34 for (size_t i = 0; i < PLANE_COUNT; ++i) {
35 const auto& plane = frustum.planes[i];
36 const float px = plane.getX();
37 const float py = plane.getY();
38 const float pz = plane.getZ();
39 const float pw = plane.getW();
40 const float distanceToCenter =
41 px * center.getX() +
42 py * center.getY() +
43 pz * center.getZ() +
44 pw;
45
46 const float projectedRadius =
47 std::abs(px) * extents.getX() +
48 std::abs(py) * extents.getY() +
49 std::abs(pz) * extents.getZ();
50
51 // Be conservative near frustum boundaries to avoid visible popping / over-cull.
52 // Near plane is most sensitive when camera/projection conventions differ slightly.
53 const float slop = (i == 0) ? (baseSlop * 4.0f) : baseSlop;
54 if (distanceToCenter + projectedRadius < -slop) {
55 return false;
56 }
57 }
58
59 return true;
60 }
61}
Axis-Aligned Bounding Box defined by center and half-extents.
Definition boundingBox.h:21
const Vector3 & center() const
Definition boundingBox.h:27
const Vector3 & halfExtents() const
Definition boundingBox.h:35
Perspective or orthographic camera with projection matrix, jitter (TAA), and render target binding.
Definition camera.h:40
const Matrix4 & projectionMatrix()
Definition camera.h:65
Hierarchical scene graph node with local/world transforms and parent-child relationships.
Definition graphNode.h:28
const Matrix4 & worldTransform()
Definition graphNode.cpp:86
bool isVisibleInCameraFrustum(Camera *camera, GraphNode *cameraNode, const BoundingBox &bounds)
void create(const Matrix4 &viewProjection)
Matrix4 inverse() const
float length() const
Definition vector3.h:224
float getX() const
Definition vector4.h:85