116 lines
3.4 KiB
C++
116 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "ZLMath.h"
|
|
#include "Perlin.h"
|
|
#include "Renderer.h" // Äëÿ VertexDataStruct
|
|
#include <vector>
|
|
#include <array>
|
|
#include <string>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
namespace ZL {
|
|
|
|
using VertexID = std::string;
|
|
using V2TMap = std::map<VertexID, std::vector<int>>;
|
|
|
|
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<Vector3f, 3> data;
|
|
std::array<VertexID, 3> ids;
|
|
|
|
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> initialVertexMap;
|
|
|
|
// Âíóòðåííèå ìåòîäû ãåíåðàöèè
|
|
std::vector<Triangle> subdivideTriangles(const std::vector<Triangle>& inputTriangles);
|
|
Vector3f calculateSurfaceNormal(Vector3f p_sphere, float noiseCoeff);
|
|
LodLevel trianglesToVertices(const std::vector<Triangle>& 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& getAtmosphereLod() const;
|
|
int getCurrentLodIndex() const;
|
|
int getMaxLodIndex() const;
|
|
|
|
// Ëîãèêà
|
|
std::pair<float, float> calculateZRange(float distanceToSurface);
|
|
float distanceToPlanetSurface(const Vector3f& viewerPosition);
|
|
|
|
// Âîçâðàùàåò èíäåêñû òðåóãîëüíèêîâ, âèäèìûõ êàìåðîé
|
|
std::vector<int> getTrianglesUnderCamera(const Vector3f& viewerPosition);
|
|
|
|
std::vector<int> findNeighbors(int index, int lod);
|
|
|
|
static std::vector<int> find_sub_triangle_spherical(const Vector3f& a_orig, const Vector3f& b_orig, const Vector3f& c_orig, const Vector3f& px_orig);
|
|
|
|
};
|
|
|
|
} // namespace ZL
|