From 926ffe18cd08e4b02f9a987642ea14b8c0191874 Mon Sep 17 00:00:00 2001 From: Yggdrasil75 Date: Fri, 27 Feb 2026 08:45:26 -0500 Subject: [PATCH] fixed some rendering --- tests/planet.cpp | 19 +++- util/grid/grid3eigen.hpp | 206 +++++++++++++++++++++++---------------- util/sim/planet.hpp | 8 +- 3 files changed, 145 insertions(+), 88 deletions(-) diff --git a/tests/planet.cpp b/tests/planet.cpp index 1b537bb..c16f46d 100644 --- a/tests/planet.cpp +++ b/tests/planet.cpp @@ -24,8 +24,9 @@ private: int rayCount = 3; int reflectCount = 4; bool slowRender = false; - float lodDist = 4096.0f; + float lodDist = 1024.0f; float lodDropoff = 0.001f; + float maxViewDistance = 4096; bool globalIllumination = false; bool useLod = true; std::map keyStates; @@ -37,6 +38,9 @@ private: bool tectonicGenned = false; bool doFixPlates = true; bool platesUseCellular = false; + std::chrono::steady_clock::time_point lastStatsUpdate; + std::string cachedStats; + bool statsNeedUpdate = true; enum class DebugColorMode { BASE, @@ -271,6 +275,10 @@ public: if (ImGui::Button(orbitEquator ? "Stop Equator" : "Orbit Equator")) orbitEquator = !orbitEquator; } + + updateStatsCache(); + ImGui::TextUnformatted(cachedStats.c_str()); + ImGui::EndChild(); } @@ -487,6 +495,7 @@ public: sim.grid.setLODMinDistance(lodDist); sim.grid.setLODFalloff(lodDropoff); + sim.grid.setMaxDistance(maxViewDistance); if (slowRender) { currentPreviewFrame = sim.grid.renderFrame(cam, outWidth, outHeight, frame::colormap::RGB, rayCount, reflectCount, globalIllumination, useLod); @@ -541,6 +550,14 @@ public: void fillPlanet() { sim.fillPlanet(); } + + void updateStatsCache() { + std::stringstream gridstats; + sim.grid.printStats(gridstats); + cachedStats = gridstats.str(); + lastStatsUpdate = std::chrono::steady_clock::now(); + statsNeedUpdate = false; + } }; #endif \ No newline at end of file diff --git a/util/grid/grid3eigen.hpp b/util/grid/grid3eigen.hpp index a15bfe4..1c9373c 100644 --- a/util/grid/grid3eigen.hpp +++ b/util/grid/grid3eigen.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef SSE #include @@ -134,6 +135,7 @@ private: float lodFalloffRate_ = 0.1f; // Lower = better, higher = worse. 0-1 float lodMinDistance_ = 100.0f; + float maxDistance_ = 4096; struct Ray { PointType origin; @@ -175,6 +177,12 @@ private: return {childMin, childMax}; } + bool boxIntersectsBox(const BoundingBox& a, const BoundingBox& b) const { + return (a.first[0] <= b.second[0] && a.second[0] >= b.first[0] && + a.first[1] <= b.second[1] && a.second[1] >= b.first[1] && + a.first[2] <= b.second[2] && a.second[2] >= b.first[2]); + } + void splitNode(OctreeNode* node, int depth) { if (depth >= maxDepth) return; for (int i = 0; i < 8; ++i) { @@ -182,12 +190,23 @@ private: node->children[i] = std::make_unique(childBounds.first, childBounds.second); } + std::vector> keep; for (const auto& pointData : node->points) { - int octant = getOctant(pointData->position, node->center); - node->children[octant]->points.emplace_back(pointData); + // Keep massive objects in the parent + if (pointData->size >= node->nodeSize) { + keep.emplace_back(pointData); + continue; + } + + BoundingBox cubeBounds = pointData->getCubeBounds(); + for (int i = 0; i < 8; ++i) { + if (boxIntersectsBox(node->children[i]->bounds, cubeBounds)) { + node->children[i]->points.emplace_back(pointData); + } + } } - node->points.clear(); + node->points = std::move(keep); node->isLeaf = false; for (int i = 0; i < 8; ++i) { @@ -203,7 +222,8 @@ private: node->lodData = nullptr; } - if (!node->contains(pointData->position)) return false; + BoundingBox cubeBounds = pointData->getCubeBounds(); + if (!boxIntersectsBox(node->bounds, cubeBounds)) return false; if (node->isLeaf) { node->points.emplace_back(pointData); @@ -212,12 +232,20 @@ private: } return true; } else { - int octant = getOctant(pointData->position, node->center); - if (node->children[octant]) { - return insertRecursive(node->children[octant].get(), pointData, depth + 1); + // Keep in parent if size is larger than or equal to the node size + if (pointData->size >= node->nodeSize) { + node->points.emplace_back(pointData); + return true; } + + bool inserted = false; + for (int i = 0; i < 8; ++i) { + if (node->children[i] && boxIntersectsBox(node->children[i]->bounds, cubeBounds)) { + inserted |= insertRecursive(node->children[i].get(), pointData, depth + 1); + } + } + return inserted; } - return false; } void ensureLOD(const OctreeNode* node) const { @@ -232,10 +260,10 @@ private: bool anyLight = false; int count = 0; - if (node->points.size() == 1) { + if (node->isLeaf && node->points.size() == 1) { node->lodData = node->points[0]; return; - } else if (node->isLeaf && node->points.size() == 0) { + } else if (node->isLeaf && node->points.empty()) { return; } @@ -249,13 +277,13 @@ private: count++; }; + for(const auto& pt : node->points) accumulate(pt); + for (const auto& child : node->children) { if (child) { ensureLOD(child.get()); if (child->lodData) { accumulate(child->lodData); - } else if (child->isLeaf && !child->points.empty()) { - for(const auto& pt : child->points) accumulate(pt); } } } @@ -305,45 +333,44 @@ private: return nullptr; } - bool removeRecursive(OctreeNode* node, const PointType& pos, float tolerance) { + bool removeRecursive(OctreeNode* node, const BoundingBox& bounds, const PointType& pos, float tolerance, bool& sizeDecremented) { { std::lock_guard lock(node->lodMutex); node->lodData = nullptr; } - if (!node->contains(pos)) return false; + if (!boxIntersectsBox(node->bounds, bounds)) return false; - if (node->isLeaf) { - bool found = false; - auto it = std::remove_if(node->points.begin(), node->points.end(), - [&](const std::shared_ptr& pointData) { - if (!pointData->active) return false; - - float distSq = (pointData->position - pos).squaredNorm(); - if (distSq <= tolerance * tolerance) { - found = true; - return true; - } - return false; - }); - - if (found) { - node->points.erase(it, node->points.end()); + bool foundAny = false; + + auto it = std::remove_if(node->points.begin(), node->points.end(), + [&](const std::shared_ptr& pointData) { + if (!pointData->active) return false; + float distSq = (pointData->position - pos).squaredNorm(); + return (distSq <= tolerance * tolerance); + }); + + if (it != node->points.end()) { + node->points.erase(it, node->points.end()); + if (!sizeDecremented) { size--; - return true; + sizeDecremented = true; } - return false; - } else { - int octant = getOctant(pos, node->center); - if (node->children[octant]) { - return removeRecursive(node->children[octant].get(), pos, tolerance); + foundAny = true; + } + + if (!node->isLeaf) { + for (int i = 0; i < 8; ++i) { + if (node->children[i]) { + foundAny |= removeRecursive(node->children[i].get(), bounds, pos, tolerance, sizeDecremented); + } } } - return false; + return foundAny; } - void searchNode(OctreeNode* node, const PointType& center, float radiusSq, int objectid, - std::vector>& results) const { + void searchNodeRecursive(OctreeNode* node, const PointType& center, float radiusSq, int objectid, + std::vector>& results, std::unordered_set>& seen) const { PointType closestPoint; for (int i = 0; i < Dim; ++i) { closestPoint[i] = std::max(node->bounds.first[i], std::min(center[i], node->bounds.second[i])); @@ -354,25 +381,29 @@ private: return; } - if (node->isLeaf) { - for (const auto& pointData : node->points) { - if (!pointData->active) continue; - - float pointDistSq = (pointData->position - center).squaredNorm(); - if (pointDistSq <= radiusSq && (pointData->objectId == objectid || objectid == -1)) { - results.emplace_back(pointData); - } + for (const auto& pointData : node->points) { + if (!pointData->active) continue; + + float pointDistSq = (pointData->position - center).squaredNorm(); + if (pointDistSq <= radiusSq && (pointData->objectId == objectid || objectid == -1)) { + if (seen.insert(pointData).second) results.emplace_back(pointData); } - } else { + } + + if (!node->isLeaf) { for (const auto& child : node->children) { - if (child) { - searchNode(child.get(), center, radiusSq, objectid, results); - } + if (child) searchNodeRecursive(child.get(), center, radiusSq, objectid, results, seen); } } } - void voxelTraverseRecursive(OctreeNode* node, float tMin, float tMax, float maxDist, + void searchNode(OctreeNode* node, const PointType& center, float radiusSq, int objectid, + std::vector>& results) const { + std::unordered_set> seen; + searchNodeRecursive(node, center, radiusSq, objectid, results, seen); + } + + void voxelTraverseRecursive(OctreeNode* node, float tMin, float tMax, float& maxDist, bool enableLOD, const Ray& ray, std::shared_ptr& hit, float invLodf) const { if (enableLOD && !node->isLeaf) { float dist = (node->center - ray.origin).norm(); @@ -383,7 +414,10 @@ private: PointType n; PointType h; if (rayCubeIntersect(ray, node->lodData.get(), t, n, h)) { - if (t >= 0 && t <= maxDist) hit = node->lodData; + if (t >= 0 && t <= maxDist) { + hit = node->lodData; + maxDist = t; + } } return; } @@ -395,9 +429,9 @@ private: float t; PointType normal, hitPoint; if (rayCubeIntersect(ray, pointData.get(), t, normal, hitPoint)) { - if (t <= maxDist) { + if (t >= 0 && t <= maxDist && t <= tMax + 0.001f) { + maxDist = t; hit = pointData; - return; } } } @@ -412,7 +446,7 @@ private: float tNext; - while(tMin < tMax && !hit) { + while(tMin < tMax && tMin <= maxDist) { Eigen::Vector3f next_t; next_t[0] = (currIdx & 1) ? tMax : ttt[0]; next_t[1] = (currIdx & 2) ? tMax : ttt[1]; @@ -609,27 +643,27 @@ private: node->isLeaf = isLeaf; node->lodData = nullptr; - if (isLeaf) { - size_t pointCount; - readVal(in, pointCount); - node->points.reserve(pointCount); - - for (size_t i = 0; i < pointCount; ++i) { - auto pt = std::make_shared(); - readVal(in, pt->data); - readVec3(in, pt->position); - readVal(in, pt->objectId); - readVal(in, pt->active); - readVal(in, pt->visible); - readVal(in, pt->size); - readVec3(in, pt->color); - readVal(in, pt->light); - readVal(in, pt->emittance); - readVal(in, pt->refraction); - readVal(in, pt->reflection); - node->points.push_back(pt); - } - } else { + size_t pointCount; + readVal(in, pointCount); + node->points.reserve(pointCount); + + for (size_t i = 0; i < pointCount; ++i) { + auto pt = std::make_shared(); + readVal(in, pt->data); + readVec3(in, pt->position); + readVal(in, pt->objectId); + readVal(in, pt->active); + readVal(in, pt->visible); + readVal(in, pt->size); + readVec3(in, pt->color); + readVal(in, pt->light); + readVal(in, pt->emittance); + readVal(in, pt->refraction); + readVal(in, pt->reflection); + node->points.push_back(pt); + } + + if (!isLeaf) { uint8_t childMask; readVal(in, childMask); @@ -945,6 +979,7 @@ public: void setLODFalloff(float rate) { lodFalloffRate_ = rate; } void setLODMinDistance(float dist) { lodMinDistance_ = dist; } + void setMaxDistance(float dist) { maxDistance_ = dist; } void generateLODs() { if (!root_) return; @@ -1028,7 +1063,10 @@ public: } bool remove(const PointType& pos, float tolerance = EPSILON) { - return removeRecursive(root_.get(), pos, tolerance); + auto pt = find(pos, tolerance); + if (!pt) return false; + bool sizeDecremented = false; + return removeRecursive(root_.get(), pt->getCubeBounds(), pos, tolerance, sizeDecremented); } std::vector> findInRadius(const PointType& center, float radius, int objectid = -1) const { @@ -1170,7 +1208,8 @@ public: float tMin, tMax; if (rayBoxIntersect(oray, root_->bounds, tMin, tMax)) { tMax = std::min(tMax, maxDist); - voxelTraverseRecursive(root_.get(), tMin, tMax, maxDist, enableLOD, oray, hit, invLodf); + float currentMaxDist = maxDist; + voxelTraverseRecursive(root_.get(), tMin, tMax, currentMaxDist, enableLOD, oray, hit, invLodf); } return hit; } @@ -1234,7 +1273,8 @@ public: float tMin, tMax; if (rayBoxIntersect(ray, root_->bounds, tMin, tMax)) { tMax = std::min(tMax, maxDist); - voxelTraverseRecursive(root_.get(), tMin, tMax, maxDist, enableLOD, ray, hit, lodRatio); + float currentMaxDist = maxDist; + voxelTraverseRecursive(root_.get(), tMin, tMax, currentMaxDist, enableLOD, ray, hit, lodRatio); } return hit; } @@ -1259,7 +1299,6 @@ public: const PointType globalLightDir = (-cam.direction * 0.2f).normalized(); const float fogStart = 1000.0f; - const float fogEnd = 4000.0f; const float minVisibility = 0.2f; #pragma omp parallel for schedule(dynamic, 128) collapse(2) @@ -1276,7 +1315,7 @@ public: Eigen::Vector3f color = backgroundColor_; Ray ray(origin, rayDir); - auto hit = fastVoxelTraverse(ray, std::numeric_limits::max(), true); + auto hit = fastVoxelTraverse(ray, maxDistance_, true); if (hit != nullptr) { auto obj = hit; @@ -1295,7 +1334,7 @@ public: color = color * intensity; } - float fogFactor = std::clamp((fogEnd - t) / (fogEnd - fogStart), minVisibility, 1.0f); + float fogFactor = std::clamp((maxDistance_ - t) / (maxDistance_ - fogStart), minVisibility, 1.0f); color = color * fogFactor + backgroundColor_ * (1.0f - fogFactor); } @@ -1608,6 +1647,7 @@ public: os << " Point Data : " << (dataMem / 1024.0) << " KB\n"; os << "========================================\n" << std::defaultfloat; } + bool empty() const { return size == 0; } void clear() { diff --git a/util/sim/planet.hpp b/util/sim/planet.hpp index e5a0fe2..3ced496 100644 --- a/util/sim/planet.hpp +++ b/util/sim/planet.hpp @@ -128,7 +128,7 @@ public: planetsim() { config = planetConfig(); - grid = Octree({-config.gridSizeCube,-config.gridSizeCube,-config.gridSizeCube,},{config.gridSizeCube,config.gridSizeCube,config.gridSizeCube}); + grid = Octree(v3(-config.gridSizeCube,-config.gridSizeCube,-config.gridSizeCube),v3(config.gridSizeCube,config.gridSizeCube,config.gridSizeCube), 16, 32); } float evaluate2DStack(const Eigen::Vector2f& point, const NoisePreviewState& state, PNoise2& gen) { @@ -352,9 +352,9 @@ public: std::cout << "have " << unassignedCount << " remaining nodes" << std::endl; while (unassignedCount > 0) { - if (unassignedCount % 100 == 0) { - std::cout << "have " << unassignedCount << " remaining nodes" << std::endl; - } + // if (unassignedCount % 100 == 0) { + // std::cout << "have " << unassignedCount << " remaining nodes" << std::endl; + // } int totalWeight = 0; for (int i = 0; i < config.numPlates; i++) {