summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/terrain.cpp54
-rw-r--r--game/terrain.h9
-rw-r--r--lib/collections.h8
3 files changed, 49 insertions, 22 deletions
diff --git a/game/terrain.cpp b/game/terrain.cpp
index d3c1d1a..f10aac6 100644
--- a/game/terrain.cpp
+++ b/game/terrain.cpp
@@ -30,19 +30,26 @@ Terrain::SurfaceKey::operator<(const SurfaceKey & other) const
< std::tie(other.surface, other.basePosition.x, other.basePosition.y);
}
-void
-Terrain::generateMeshes()
+inline void
+Terrain::copyVerticesToBuffer() const
{
std::ranges::transform(all_vertices(), glMappedBufferWriter<Vertex> {GL_ARRAY_BUFFER, verticesBuffer, n_vertices()},
[this](const auto & vertex) {
return Vertex {point(vertex), normal(vertex)};
});
+}
- std::map<SurfaceKey, std::vector<GLuint>> surfaceIndices;
- const auto getTile = [this](FaceHandle face) {
- return point(*fv_begin(face)).xy() / TILE_SIZE;
- };
- const auto indexBySurfaceAndTile = std::views::transform([this, &getTile](const auto & faceItr) {
+inline GlobalPosition2D
+Terrain::getTile(const FaceHandle & face) const
+{
+ return point(*cfv_begin(face)).xy() / TILE_SIZE;
+};
+
+Terrain::SurfaceIndices
+Terrain::mapSurfaceFacesToIndices() const
+{
+ SurfaceIndices surfaceIndices;
+ const auto indexBySurfaceAndTile = std::views::transform([this](const auto & faceItr) {
return std::pair<SurfaceKey, FaceHandle> {{getSurface(*faceItr), getTile(*faceItr)}, *faceItr};
});
const auto chunkBySurfaceAndTile = std::views::chunk_by([](const auto & face1, const auto & face2) {
@@ -61,7 +68,12 @@ Terrain::generateMeshes()
std::ranges::transform(fv_range(face), push, &OpenMesh::VertexHandle::idx);
}
}
+ return surfaceIndices;
+}
+void
+Terrain::copyIndicesToBuffers(const SurfaceIndices & surfaceIndices)
+{
for (const auto & [surfaceKey, indices] : surfaceIndices) {
auto meshItr = meshes.find(surfaceKey);
if (meshItr == meshes.end()) {
@@ -77,17 +89,16 @@ Terrain::generateMeshes()
.data(verticesBuffer, GL_ARRAY_BUFFER);
}
meshItr->second.count = static_cast<GLsizei>(indices.size());
- if (!surfaceKey.surface) {
- meshItr->second.aabb = {{surfaceKey.basePosition * TILE_SIZE || getExtents().min.z},
- {(surfaceKey.basePosition + 1) * TILE_SIZE || getExtents().max.z}};
- }
- else {
- meshItr->second.aabb = AxisAlignedBoundingBox<GlobalDistance>::fromPoints(
- indices | std::views::transform([this](const auto vertex) -> GlobalPosition3D {
- return this->point(VertexHandle {static_cast<int>(vertex)});
- }));
- }
+ meshItr->second.aabb = AxisAlignedBoundingBox<GlobalDistance>::fromPoints(
+ indices | std::views::transform([this](const auto vertex) {
+ return this->point(VertexHandle {static_cast<int>(vertex)});
+ }));
}
+}
+
+void
+Terrain::pruneOrphanMeshes(const SurfaceIndices & surfaceIndices)
+{
if (meshes.size() > surfaceIndices.size()) {
std::erase_if(meshes, [&surfaceIndices](const auto & mesh) {
return !surfaceIndices.contains(mesh.first);
@@ -96,6 +107,15 @@ Terrain::generateMeshes()
}
void
+Terrain::generateMeshes()
+{
+ copyVerticesToBuffer();
+ const auto surfaceIndices = mapSurfaceFacesToIndices();
+ copyIndicesToBuffers(surfaceIndices);
+ pruneOrphanMeshes(surfaceIndices);
+}
+
+void
Terrain::tick(TickDuration)
{
}
diff --git a/game/terrain.h b/game/terrain.h
index eaec01d..1a63296 100644
--- a/game/terrain.h
+++ b/game/terrain.h
@@ -41,9 +41,16 @@ private:
struct SurfaceKey {
const Surface * surface;
GlobalPosition2D basePosition;
- bool operator<(const SurfaceKey &) const;
+ inline bool operator<(const SurfaceKey &) const;
};
+ using SurfaceIndices = std::map<SurfaceKey, std::vector<GLuint>>;
+ void copyVerticesToBuffer() const;
+ [[nodiscard]] SurfaceIndices mapSurfaceFacesToIndices() const;
+ void copyIndicesToBuffers(const SurfaceIndices &);
+ void pruneOrphanMeshes(const SurfaceIndices &);
+ [[nodiscard]] inline GlobalPosition2D getTile(const FaceHandle &) const;
+
glBuffer verticesBuffer;
std::map<SurfaceKey, SurfaceArrayBuffer> meshes;
Texture::Ptr grass = std::make_shared<Texture>("grass.png");
diff --git a/lib/collections.h b/lib/collections.h
index b921424..e182af5 100644
--- a/lib/collections.h
+++ b/lib/collections.h
@@ -140,16 +140,16 @@ vectorOfN(std::integral auto N, T start = {}, T step = 1)
template<template<typename...> typename Rtn = std::vector, typename In>
[[nodiscard]] auto
-materializeRange(const In begin, const In end)
+materializeRange(In && begin, In && end)
{
- return Rtn(begin, end);
+ return Rtn(std::forward<In>(begin), std::forward<In>(end));
}
template<template<typename...> typename Rtn = std::vector, IterableCollection In>
[[nodiscard]] auto
-materializeRange(const In & in)
+materializeRange(In && in)
{
- return materializeRange<Rtn>(in.begin(), in.end());
+ return materializeRange<Rtn>(std::forward<In>(in).begin(), std::forward<In>(in).end());
}
template<template<typename...> typename Rtn = std::vector, typename In>