space-game001/PlanetObject.h
2025-12-14 19:52:55 +03:00

119 lines
2.9 KiB
C++

#pragma once
#include "ZLMath.h"
#include "Renderer.h"
#include "TextureManager.h"
#include <vector>
#include <chrono>
#include <iostream>
#include <string>
#include <array>
#include <numeric>
#include <random>
#include <algorithm>
#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);
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
{
VertexDataStruct vertexData;
std::vector<VertexID> VertexIDs;
V2TMap v2tMap;
};
class PerlinNoise {
std::vector<int> p;
public:
PerlinNoise();
PerlinNoise(uint64_t seed);
float fade(float t);
float lerp(float t, float a, float b);
float grad(int hash, float x, float y, float z);
float noise(float x, float y, float z);
float getSurfaceHeight(Vector3f pos, float noiseCoeff);
};
class PlanetObject {
private:
PerlinNoise perlin;
PerlinNoise colorPerlin;
void prepareDrawData();
std::array<LodLevel, 6> planetMeshLods;
VertexRenderStruct planetRenderStruct;
VertexRenderStruct planetRenderRedStruct;
VertexRenderStruct planetRenderYellowStruct;
LodLevel planetAtmosphereLod;
VertexRenderStruct planetAtmosphere;
std::shared_ptr<Texture> sandTexture;
std::map<Vector3f, VertexID> initialVertexMap = {
{{ 0.0f, 1.0f, 0.0f}, "A"},
{{ 0.0f, -1.0f, 0.0f}, "B"},
{{ 1.0f, 0.0f, 0.0f}, "C"},
{{-1.0f, 0.0f, 0.0f}, "D"},
{{ 0.0f, 0.0f, 1.0f}, "E"},
{{ 0.0f, 0.0f, -1.0f}, "F"}
};
public:
PlanetObject();
void init();
void update(float deltaTimeMs);
void draw(Renderer& renderer);
void drawAtmosphere(Renderer& renderer);
bool planetIsFar();
float distanceToPlanetSurface();
private:
bool drawDataDirty = true;
int currentLod = planetMeshLods.size()-1;
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);
std::pair<float, float> calculateZRange(const Vector3f& shipPosition);
std::vector<int> triangleUnderCamera(int lod);
std::vector<int> findNeighbors(int index, int lod);
};
} // namespace ZL