CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
TerrainStorage.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2023 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
12
19
21
22namespace CeresEngine {
23
24 template<typename T> class MemoryMappedTerrainOctree {
25 template<typename U> using Ptr = OffsetPtr<U, std::ptrdiff_t, Int32>;
26
27 struct Node {
30 this, this, this, this, //
31 this, this, this, this, //
32 };
33 };
34
35 struct FreeNode {
37 explicit FreeNode(const Ptr<FreeNode>& next) : next(next) {}
38 };
39
40 struct Header {
42
43 Ptr<Node> root = nullptr;
45
46 AABox aabb{Vector3(-7000 * 1000), Vector3(7000 * 1000)};
48
49 size_t capacity = 0;
51 };
52
55
56 public:
57 explicit MemoryMappedTerrainOctree(const FilePath& path) : mSharedMemory(path, SharedMemory::AccessMode::Write) {
58 if(mSharedMemory.empty()) {
62 } else {
63 mHeader = reinterpret_cast<Header*>(mSharedMemory.data());
64 }
65 }
66
68
69 public:
70 void reserve(size_t newCapacity) {
72 return;
73 }
74
75 const size_t newSize = sizeof(Node) * newCapacity + sizeof(Header);
77
78 mHeader = reinterpret_cast<Header*>(mSharedMemory.data());
79
80 const size_t oldCapacity = mHeader->capacity;
82
83 for(const size_t nodeIndex : range(oldCapacity, newCapacity)) {
84 FreeNode* const nodeMemory = reinterpret_cast<FreeNode*>(nodeAt(nodeIndex));
86 }
87 }
88
89 bool insert(Vector3 position, T value) {
90 insert(mHeader->root.get(), position, T(value), mHeader->aabb, mHeader->aabb.getSize().x);
91 return true;
92 }
93
94 bool insert(const AABox& area, T value) {}
95
96 bool insert(const Sphere& sphere, T value) {
97 insert(mHeader->root.get(), sphere, T(value), mHeader->aabb, mHeader->aabb.getSize().x);
98 return true;
99 }
100
102 if(!mHeader->freeList) {
103 reserve(mHeader->capacity * 2 + 1);
104 }
105
106 CE_ASSERT(mHeader->freeList != nullptr);
107
108 FreeNode* const freeNode = mHeader->freeList.get();
109 mHeader->freeList = freeNode->next;
110
111 freeNode->~FreeNode();
112 return new(freeNode) Node();
113 }
114
115 private:
116 void insert(Node* node, Vector3 position, T&& value, AABox aabb, double resolution) {
117 info("resolution = {}", resolution);
118 if(resolution <= mHeader->maximumResolution) {
119 node->value = value;
120 return;
121 }
122
123 const size_t octant = getOctantFor(position, aabb);
125
126 aabb.minimum = aabb.getCenter() + aabb.getHalfSize() * octantDelta(octant) / 2.0;
127 aabb.maximum = aabb.getCenter() - aabb.getHalfSize() * octantDelta(octant) / 2.0;
128 return insert(node->children[octant].get(), position, std::forward<T>(value), aabb, resolution / 2.0);
129 }
130
131 template<typename Primitive> void insert(Node* node, const Primitive& primitive, const T& value, const AABox& aabb, double resolution) {
132 // If the AABB is fully contained inside the primitive or we have
133 // reached our maximum resolution, stop recursion and write the
134 // value to the node.
135 //
136 if(primitive.contains(aabb) || resolution <= mHeader->maximumResolution) {
137 node->value = value;
138 return;
139 }
140
141 // Else, we might be partially contained, so we iterate over the
142 // 8 octants and find which ones we overlap with.
143 //
144 const Vector3 center = aabb.getCenter();
145 const Vector3 halfSize = aabb.getHalfSize();
146 for(const size_t octant : range(0, 8)) {
147 AABox octantAABB = aabb;
148 {
149 const Vector3 size = halfSize;
150 octantAABB.minimum = center + halfSize / 2.0 * octantDelta(octant) - size / 2.0;
151 octantAABB.maximum = octantAABB.minimum + size;
152 }
153
154 if(!octantAABB.intersects(primitive)) {
155 continue;
156 }
157
159 insert(node->children[octant].get(), primitive, value, octantAABB, resolution / 2.0);
160 }
161 }
162
164 for(const size_t childIndex : range(0, 8)) {
165 if(node->children[childIndex] != node) {
166 continue;
167 }
168
169 node->children[childIndex] = allocateNode();
170 node->children[childIndex]->value = node->value;
171 }
172 }
173
174 void subdivide(Node* node, size_t octant) {
175 if(node->children[octant] != node) {
176 return;
177 }
178
179 node->children[octant] = allocateNode();
180 node->children[octant]->value = node->value;
181 }
182
183 bool shouldCollapse(Node* const node, const T& firstValue) {
184 // if any of the nodes has a different value, we cannot collapse
185 // this.
186 //
187 for(const Ptr<Node>& child : node->children) {
188 if(child == nullptr || child == node) {
189 return false;
190 }
191
192 if(child->value == firstValue) {
193 continue;
194 }
195 }
196 return true;
197 }
198
199 Node* findOrCreateNode(Node* node, Vector2 position, T value, const UInt64 depth, const UInt64 maxDepth) {
200 if(depth == maxDepth) {
201 return node;
202 }
203 }
204
205 void* nodeAt(size_t index) {
206 Node* const firstNode = reinterpret_cast<Node*>(mHeader + 1);
207 return firstNode + index;
208 }
209
214 static size_t getOctantFor(const Vector3& position, const AABox& aabb) {
215 const Vector3 center = aabb.getCenter();
216 return (position.x > center.x ? 0 : (1 << 0)) + //
217 (position.y > center.y ? 0 : (1 << 1)) + //
218 (position.z > center.z ? 0 : (1 << 2));
219 }
220
224 static Vector3 octantDelta(const size_t octant) {
225 return Vector3( //
226 (octant & (1 << 0)) ? -1.0 : 1.0, //
227 (octant & (1 << 1)) ? -1.0 : 1.0, //
228 (octant & (1 << 2)) ? -1.0 : 1.0);
229 }
230 };
231
232} // namespace CeresEngine
#define CE_ASSERT(...)
Definition Macros.hpp:323
Path to file or directory.
Definition FilePath.hpp:37
Definition TerrainStorage.hpp:24
SharedMemory mSharedMemory
Definition TerrainStorage.hpp:53
bool insert(const AABox &area, T value)
Definition TerrainStorage.hpp:94
void reserve(size_t newCapacity)
Definition TerrainStorage.hpp:70
void insert(Node *node, Vector3 position, T &&value, AABox aabb, double resolution)
Definition TerrainStorage.hpp:116
~MemoryMappedTerrainOctree()
Definition TerrainStorage.hpp:67
Header * mHeader
Definition TerrainStorage.hpp:54
bool shouldCollapse(Node *const node, const T &firstValue)
Definition TerrainStorage.hpp:183
MemoryMappedTerrainOctree(const FilePath &path)
Definition TerrainStorage.hpp:57
bool insert(const Sphere &sphere, T value)
Definition TerrainStorage.hpp:96
void subdivide(Node *node)
Definition TerrainStorage.hpp:163
void subdivide(Node *node, size_t octant)
Definition TerrainStorage.hpp:174
void * nodeAt(size_t index)
Definition TerrainStorage.hpp:205
Node * allocateNode()
Definition TerrainStorage.hpp:101
Node * findOrCreateNode(Node *node, Vector2 position, T value, const UInt64 depth, const UInt64 maxDepth)
Definition TerrainStorage.hpp:199
static size_t getOctantFor(const Vector3 &position, const AABox &aabb)
Computes the octant of a position vector within the given aabb.
Definition TerrainStorage.hpp:214
static Vector3 octantDelta(const size_t octant)
Computes the delta position for a given octant.
Definition TerrainStorage.hpp:224
bool insert(Vector3 position, T value)
Definition TerrainStorage.hpp:89
void insert(Node *node, const Primitive &primitive, const T &value, const AABox &aabb, double resolution)
Definition TerrainStorage.hpp:131
A special pointer that stores the pointer as an offset of the pointee to the OffsetPtr instance itsel...
Definition OffsetPtr.hpp:65
Definition SharedMemory.hpp:17
Pointer data() noexcept
void resize(SizeType newSize)
Resizes the array to fit at least newSize elements.
void sync()
Synchronizes any dirty data not synchronized with the file.
bool empty() const noexcept
Definition Application.hpp:19
std::uint64_t UInt64
Definition DataTypes.hpp:26
auto range()
Returns an iterator that increases it's value from 0 to end by 1 for each step.
Definition Iterator.hpp:350
@ Write
Requests writing support from the protocool.
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition TerrainStorage.hpp:35
Ptr< FreeNode > next
Definition TerrainStorage.hpp:36
FreeNode(const Ptr< FreeNode > &next)
Definition TerrainStorage.hpp:37
Definition TerrainStorage.hpp:40
size_t capacity
Definition TerrainStorage.hpp:49
uint8_t reserved[8 *16]
Definition TerrainStorage.hpp:50
Ptr< FreeNode > freeList
Definition TerrainStorage.hpp:44
float maximumResolution
Definition TerrainStorage.hpp:47
Ptr< Node > root
Definition TerrainStorage.hpp:43
uint32_t version
Definition TerrainStorage.hpp:41
AABox aabb
Definition TerrainStorage.hpp:46
Definition TerrainStorage.hpp:27
Ptr< Node > children[8]
Definition TerrainStorage.hpp:29
T value
Definition TerrainStorage.hpp:28