121 lines
3.3 KiB
C++
121 lines
3.3 KiB
C++
#pragma once
|
|
|
|
#include "utils/Perlin.h"
|
|
#include "render/Renderer.h"
|
|
#include <vector>
|
|
#include <array>
|
|
#include <string>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
namespace ZL {
|
|
|
|
|
|
using VertexID = std::string;
|
|
using V2TMap = std::map<VertexID, std::vector<int>>;
|
|
|
|
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<Vector3f, 3> data;
|
|
std::array<VertexID, 3> ids;
|
|
|
|
Triangle()
|
|
{
|
|
}
|
|
|
|
Triangle(Vector3f p1, Vector3f p2, Vector3f p3)
|
|
: data{ p1, p2, p3 }
|
|
{
|
|
}
|
|
|
|
Triangle(std::array<Vector3f, 3> idata, std::array<VertexID, 3> iids)
|
|
: data{ idata }
|
|
, ids{ iids }
|
|
{
|
|
}
|
|
};
|
|
|
|
struct LodLevel
|
|
{
|
|
std::vector<Triangle> triangles;
|
|
VertexDataStruct vertexData;
|
|
std::vector<VertexID> 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<LodLevel, MAX_LOD_LEVELS> planetMeshLods;
|
|
LodLevel planetAtmosphereLod;
|
|
|
|
int currentLod; // Ëîãè÷åñêèé òåêóùèé óðîâåíü äåòàëèçàöèè
|
|
|
|
//std::map<Vector3f, VertexID, Vector3fComparator> initialVertexMap;
|
|
|
|
// Âíóòðåííèå ìåòîäû ãåíåðàöèè
|
|
std::vector<Triangle> subdivideTriangles(const std::vector<Triangle>& inputTriangles, float noiseCoeff);
|
|
LodLevel createLodLevel(const std::vector<Triangle>& 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<float, float> calculateZRange(float distanceToSurface);
|
|
float distanceToPlanetSurfaceFast(const Vector3f& viewerPosition);
|
|
|
|
// Âîçâðàùàåò èíäåêñû òðåóãîëüíèêîâ, âèäèìûõ êàìåðîé
|
|
std::vector<int> getBestTriangleUnderCamera(const Vector3f& viewerPosition);
|
|
std::vector<int> getTrianglesUnderCameraNew2(const Vector3f& viewerPosition);
|
|
|
|
void applySphericalRelaxation(LodLevel& lod, int iterations);
|
|
};
|
|
|
|
} // namespace ZL
|