#pragma once #include "ZLMath.h" #include "Perlin.h" #include "Renderer.h" // Для VertexDataStruct #include #include #include #include #include namespace ZL { using VertexID = std::string; using V2TMap = std::map>; VertexID generateEdgeID(const VertexID& id1, const VertexID& id2); constexpr static int MAX_LOD_LEVELS = 6; //constexpr static int MAX_LOD_LEVELS = 3; struct Triangle { std::array data; std::array ids; 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; std::array planetMeshLodsNoDist; LodLevel planetAtmosphereLod; int currentLod; // Логический текущий уровень детализации std::map initialVertexMap; // Внутренние методы генерации std::vector subdivideTriangles(const std::vector& inputTriangles, float noiseCoeff); LodLevel trianglesToVertices(const std::vector& triangles); LodLevel generateSphere(int subdivisions, float noiseCoeff); // Вспомогательные методы математики static float check_spherical_side(const Vector3f& V1, const Vector3f& V2, const Vector3f& P, const Vector3f& V3, float epsilon = 1e-6f); static bool is_inside_spherical_triangle(const Vector3f& P, const Vector3f& V1, const Vector3f& V2, const Vector3f& V3, float epsilon); public: PlanetData(); void init(); // Методы доступа к данным (для рендерера) const LodLevel& getLodLevel(int level) const; const LodLevel& getLodLevelNoDist(int level) const; const LodLevel& getAtmosphereLod() const; int getCurrentLodIndex() const; int getMaxLodIndex() const; // Логика std::pair calculateZRange(float distanceToSurface); float distanceToPlanetSurface(const Vector3f& viewerPosition); // Возвращает индексы треугольников, видимых камерой std::vector getTrianglesUnderCamera(const Vector3f& viewerPosition); std::vector findNeighbors(int index, int lod); static std::vector find_sub_triangle_spherical(const Vector3f& a_orig, const Vector3f& b_orig, const Vector3f& c_orig, const Vector3f& px_orig); }; } // namespace ZL