#pragma once #include "utils/Perlin.h" #include "render/Renderer.h" #include #include #include #include #include namespace ZL { using VertexID = std::string; using V2TMap = std::map>; struct Vector3fComparator { bool operator()(const Eigen::Vector3f& a, const Eigen::Vector3f& b) const { // Лексикографическое сравнение (x, затем y, затем z) if (a.x() != b.x()) return a.x() < b.x(); if (a.y() != b.y()) return a.y() < b.y(); return a.z() < b.z(); } }; VertexID generateEdgeID(const VertexID& id1, const VertexID& id2); constexpr static int MAX_LOD_LEVELS = 6; struct Triangle { std::array data; std::array ids; Triangle() { } Triangle(Vector3f p1, Vector3f p2, Vector3f p3) : data{ p1, p2, p3 } { } Triangle(std::array idata, std::array iids) : data{ idata } , ids{ iids } { } }; struct LodLevel { std::vector triangles; VertexDataStruct vertexData; std::vector VertexIDs; V2TMap v2tMap; void Scale(float s) { vertexData.Scale(s); for (auto& t : triangles) { for (int i = 0; i < 3; i++) { t.data[i] = t.data[i] * s; } } } void Move(Vector3f pos) { vertexData.Move(pos); for (auto& t : triangles) { for (int i = 0; i < 3; i++) { t.data[i] = t.data[i] + pos; } } } }; class PlanetData { public: static const float PLANET_RADIUS; static const Vector3f PLANET_CENTER_OFFSET; private: PerlinNoise perlin; PerlinNoise colorPerlin; std::array planetMeshLods; LodLevel planetAtmosphereLod; int currentLod; // Логический текущий уровень детализации //std::map initialVertexMap; // Внутренние методы генерации std::vector subdivideTriangles(const std::vector& inputTriangles, float noiseCoeff); LodLevel createLodLevel(const std::vector& triangles); void recalculateMeshAttributes(LodLevel& lod); LodLevel generateSphere(int subdivisions, float noiseCoeff); public: PlanetData(); void init(); // Методы доступа к данным (для рендерера) const LodLevel& getLodLevel(int level) const; const LodLevel& getAtmosphereLod() const; int getCurrentLodIndex() const; int getMaxLodIndex() const; // Логика std::pair calculateZRange(float distanceToSurface); float distanceToPlanetSurfaceFast(const Vector3f& viewerPosition); // Возвращает индексы треугольников, видимых камерой std::vector getBestTriangleUnderCamera(const Vector3f& viewerPosition); std::vector getTrianglesUnderCameraNew2(const Vector3f& viewerPosition); void applySphericalRelaxation(LodLevel& lod, int iterations); }; } // namespace ZL