119 lines
2.9 KiB
C++
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
|