Skip to content

Commit 8e87689

Browse files
some nice optimizations
1 parent 892405a commit 8e87689

7 files changed

Lines changed: 80 additions & 33 deletions

File tree

ICE/Components/include/TransformComponent.h

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct TransformComponent : public Component {
2121
setRotationEulerDeg(rot);
2222
}
2323

24-
TransformComponent(const Eigen::Matrix4f& matrix) {
24+
TransformComponent(const Eigen::Matrix4f& matrix) {
2525
m_position = matrix.block<3, 1>(0, 3);
2626

2727
Eigen::Vector3f vX = matrix.block<3, 1>(0, 0);
@@ -79,46 +79,54 @@ struct TransformComponent : public Component {
7979
void updateParentMatrix(const Eigen::Matrix4f& parent_matrix) {
8080
m_parent_matrix = parent_matrix;
8181
m_world_matrix = parent_matrix * getModelMatrix();
82+
m_version++;
8283
}
8384

8485
Eigen::Vector3f& position() {
85-
m_dirty = true;
86+
markDirty();
8687
return m_position;
8788
}
8889

8990
Eigen::Quaternionf& rotation() {
90-
m_dirty = true;
91+
markDirty();
9192
return m_rotation;
9293
}
9394

9495
Eigen::Vector3f& scale() {
95-
m_dirty = true;
96+
markDirty();
9697
return m_scale;
9798
}
9899

99100
void setPosition(const Eigen::Vector3f& position) {
100-
m_dirty = true;
101+
markDirty();
101102
m_position = position;
102103
}
103104

104105
void setRotation(const Eigen::Quaternionf& rotation) {
105-
m_dirty = true;
106+
markDirty();
106107
m_rotation = rotation.normalized();
107108
}
108109

109110
void setRotationEulerDeg(const Eigen::Vector3f& eulerDeg) {
110-
m_dirty = true;
111+
markDirty();
111112
Eigen::Vector3f rad = eulerDeg * M_PI / 180.0;
112113
m_rotation = Eigen::AngleAxisf(rad.x(), Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(rad.y(), Eigen::Vector3f::UnitY())
113114
* Eigen::AngleAxisf(rad.z(), Eigen::Vector3f::UnitZ());
114115
}
115116

116117
void setScale(const Eigen::Vector3f& scale) {
117-
m_dirty = true;
118+
markDirty();
118119
m_scale = scale;
119120
}
120121

122+
uint32_t getVersion() { return m_version; }
123+
121124
private:
125+
void markDirty() {
126+
m_dirty = true;
127+
m_version++;
128+
}
129+
122130
Eigen::Vector3f m_position;
123131
Eigen::Quaternionf m_rotation;
124132
Eigen::Vector3f m_scale;
@@ -127,6 +135,7 @@ struct TransformComponent : public Component {
127135
mutable Eigen::Matrix4f m_parent_matrix = Eigen::Matrix4f::Identity();
128136
mutable Eigen::Matrix4f m_world_matrix = Eigen::Matrix4f::Identity();
129137
mutable bool m_dirty = true;
138+
mutable uint32_t m_version = 0;
130139
};
131140

132141
} // namespace ICE

ICE/Math/include/AABB.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class AABB {
2828
const Eigen::Vector3f& getMax() const;
2929

3030
private:
31+
void precomputeCenterAndExtent();
32+
3133
Eigen::Vector3f min, max;
34+
Eigen::Vector3f center, extent;
3235
};
3336
} // namespace ICE

ICE/Math/src/AABB.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
namespace ICE {
88

99
AABB::AABB(const Eigen::Vector3f &min, const Eigen::Vector3f &max) : min(min), max(max) {
10+
precomputeCenterAndExtent();
1011
}
1112
AABB::AABB(const std::vector<Eigen::Vector3f> &points) : AABB(points[0], points[0]) {
1213
for (const auto &v : points) {
1314
min = min.cwiseMin(v);
1415
max = max.cwiseMax(v);
1516
}
17+
precomputeCenterAndExtent();
1618
}
1719

1820
AABB AABB::scaledBy(const Eigen::Vector3f &scale) const {
@@ -44,11 +46,11 @@ AABB AABB::unionWith(const AABB &other) const {
4446
}
4547

4648
Eigen::Vector3f AABB::getCenter() const {
47-
return (min + max) / 2;
49+
return center;
4850
}
4951

5052
Eigen::Vector3f AABB::getExtent() const {
51-
return (max - min) / 2;
53+
return extent;
5254
}
5355

5456
const Eigen::Vector3f &AABB::getMin() const {
@@ -58,4 +60,9 @@ const Eigen::Vector3f &AABB::getMin() const {
5860
const Eigen::Vector3f &AABB::getMax() const {
5961
return max;
6062
}
63+
64+
void AABB::precomputeCenterAndExtent() {
65+
center = (min + max) * 0.5f;
66+
extent = (max - min) * 0.5f;
67+
}
6168
} // namespace ICE

ICE/System/include/RenderSystem.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ namespace ICE {
1717
class Scene;
1818
class Registry;
1919

20+
struct CullingData {
21+
uint32_t lastTransformVersion = 0xFFFFFFFF;
22+
AssetUID lastMesh = 0;
23+
24+
Eigen::Vector3f worldCenter;
25+
Eigen::Vector3f worldExtents;
26+
};
27+
2028
class RenderSystem : public System {
2129
public:
2230
RenderSystem(const std::shared_ptr<RendererAPI> &api, const std::shared_ptr<GraphicsFactory> &factory, const std::shared_ptr<Registry> &reg,
@@ -63,5 +71,7 @@ class RenderSystem : public System {
6371
std::shared_ptr<GPURegistry> m_gpu_bank;
6472

6573
std::shared_ptr<VertexArray> m_quad_vao;
74+
75+
std::unordered_map<Entity, CullingData> m_culling_cache;
6676
};
6777
} // namespace ICE

ICE/System/include/SceneGraphSystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ class SceneGraphSystem : public System {
2222

2323
private:
2424
std::shared_ptr<Scene> m_scene;
25+
std::unordered_map<Entity, uint32_t> m_transformVersions;
2526
};
2627
} // namespace ICE

ICE/System/src/RenderSystem.cpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,40 @@ void RenderSystem::update(double delta) {
4646
auto frustum = extractFrustumPlanes(proj_mat * view_mat);
4747
Logger::Log(ICE::Logger::DEBUG, "Graphics", "Render Queue Size: %d", m_render_queue.size());
4848
for (const auto &e : m_render_queue) {
49-
auto rc = m_registry->getComponent<RenderComponent>(e);
5049
auto tc = m_registry->getComponent<TransformComponent>(e);
51-
auto mesh = m_gpu_bank->getMesh(rc->mesh);
52-
auto material = m_gpu_bank->getMaterial(rc->material);
53-
auto shader = m_gpu_bank->getShader(material->getShader());
54-
if (!mesh || !material || !shader)
55-
continue;
50+
auto rc = m_registry->getComponent<RenderComponent>(e);
5651

5752
auto model_mat = tc->getWorldMatrix();
58-
59-
auto local_aabb = m_gpu_bank->getMeshAABB(rc->mesh);
60-
Eigen::Vector3f localCenter = local_aabb.getCenter();
61-
Eigen::Vector3f localExtents = local_aabb.getExtent();
6253

63-
Eigen::Matrix3f R = model_mat.block<3, 3>(0, 0);
64-
Eigen::Vector3f T = model_mat.block<3, 1>(0, 3);
54+
if (!m_culling_cache.contains(e) || m_culling_cache[e].lastTransformVersion != tc->getVersion() || m_culling_cache[e].lastMesh != rc->mesh) {
55+
auto local_aabb = m_gpu_bank->getMeshAABB(rc->mesh);
56+
Eigen::Vector3f localCenter = local_aabb.getCenter();
57+
Eigen::Vector3f localExtents = local_aabb.getExtent();
58+
59+
Eigen::Matrix3f R = model_mat.block<3, 3>(0, 0);
60+
Eigen::Vector3f T = model_mat.block<3, 1>(0, 3);
6561

66-
Eigen::Vector3f worldCenter = R * localCenter + T;
62+
Eigen::Vector3f worldCenter = R * localCenter + T;
6763

68-
Eigen::Matrix3f absR = R.cwiseAbs();
69-
Eigen::Vector3f worldExtents = absR * localExtents;
64+
Eigen::Matrix3f absR = R.cwiseAbs();
65+
Eigen::Vector3f worldExtents = absR * localExtents;
7066

71-
if (!isAABBInFrustum(frustum, worldCenter, worldExtents))
67+
m_culling_cache[e] = CullingData{
68+
.lastTransformVersion = tc->getVersion(),
69+
.lastMesh = rc->mesh,
70+
.worldCenter = worldCenter,
71+
.worldExtents = worldExtents,
72+
};
73+
}
74+
if (!isAABBInFrustum(frustum, m_culling_cache[e].worldCenter, m_culling_cache[e].worldExtents))
75+
continue;
76+
77+
auto mesh = m_gpu_bank->getMesh(rc->mesh);
78+
auto material = m_gpu_bank->getMaterial(rc->material);
79+
auto shader = m_gpu_bank->getShader(material->getShader());
80+
if (!mesh || !material || !shader)
7281
continue;
73-
82+
7483
std::unordered_map<int, Eigen::Matrix4f> bone_matrices;
7584
if (m_registry->entityHasComponent<SkinningComponent>(e)) {
7685
const auto &skinning = m_gpu_bank->getMeshSkinningData(rc->mesh);

ICE/System/src/SceneGraphSystem.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace ICE {
44
SceneGraphSystem::SceneGraphSystem(const std::shared_ptr<Scene> &scene) : m_scene(scene) {
5-
65
}
76

87
void SceneGraphSystem::onEntityAdded(Entity e) {
@@ -11,19 +10,28 @@ void SceneGraphSystem::onEntityRemoved(Entity e) {
1110
}
1211
void SceneGraphSystem::update(double delta) {
1312
auto root = m_scene->getGraph()->getRoot();
14-
std::function<void(const std::shared_ptr<SceneGraph::SceneNode> &, const Eigen::Matrix4f &)> updateNode;
15-
updateNode = [this, &updateNode](const std::shared_ptr<SceneGraph::SceneNode> &node, const Eigen::Matrix4f &parentMatrix) {
13+
std::function<void(const std::shared_ptr<SceneGraph::SceneNode> &, const Eigen::Matrix4f &, bool)> updateNode;
14+
updateNode = [this, &updateNode](const std::shared_ptr<SceneGraph::SceneNode> &node, const Eigen::Matrix4f &parentMatrix, bool parent_changed) {
1615
Eigen::Matrix4f newParentMatrix = parentMatrix;
1716
if (node->entity != 0 && m_scene->getRegistry()->entityHasComponent<TransformComponent>(node->entity)) {
1817
auto tc = m_scene->getRegistry()->getComponent<TransformComponent>(node->entity);
19-
tc->updateParentMatrix(parentMatrix);
18+
19+
if (parent_changed) {
20+
tc->updateParentMatrix(parentMatrix);
21+
}
22+
23+
if (!m_transformVersions.contains(node->entity) || m_transformVersions[node->entity] != tc->getVersion()) {
24+
parent_changed = true;
25+
m_transformVersions[node->entity] = tc->getVersion();
26+
}
2027
newParentMatrix = tc->getWorldMatrix();
28+
2129
}
2230
for (const auto &child : node->children) {
23-
updateNode(child, newParentMatrix);
31+
updateNode(child, newParentMatrix, parent_changed);
2432
}
2533
};
26-
updateNode(root, Eigen::Matrix4f::Identity());
34+
updateNode(root, Eigen::Matrix4f::Identity(), false);
2735
}
2836

2937
} // namespace ICE

0 commit comments

Comments
 (0)