voxspatium/src/planet/PlanetFace.h

128 lines
2.9 KiB
C++

#ifndef __PLANETFACE_H__
#define __PLANETFACE_H__
#include "util/Common.h"
#include "planet/Planet.h"
#include "Shader.h"
#include "Camera.h"
#define RESOLUTION 17
enum Face
{
FACE_FRONT,
FACE_LEFT,
FACE_BACK,
FACE_RIGHT,
FACE_TOP,
FACE_BOTTOM,
};
enum Quadrant
{
TOP_LEFT, TOP_RIGHT,
BOTTOM_RIGHT, BOTTOM_LEFT
};
const unsigned int MAX_SPLITS_PER_UPDATE = 2;
#define MIRROR(s) (((s) + 2) % 4)
#define ADJACENT(s, q) ((4 + (q) - (s)) % 4 <= 1)
#define REFLECT(s, q) ((s) % 2 ? ((q) % 2 ? (q) - 1 : (q) + 1) : 3 - (q))
struct Vertex
{
glm::vec3 position;
glm::vec3 normal;
glm::vec2 uv;
};
class Planet;
class PlanetFace;
class PlanetFaceNode
{
public:
PlanetFaceNode(PlanetFace* face, PlanetFaceNode* parent, glm::vec3 position, const unsigned int index);
~PlanetFaceNode();
void tick(Camera* camera, GLfloat dtime);
void draw(Camera* camera, Shader* shader);
bool isLeaf();
inline PlanetFace* getPlanetFace() const { return m_planetFace; }
glm::vec3 getAbsolutePosition();
inline PlanetFaceNode* getNeighborAt(Direction dir) const { return m_neighbors[dir]; }
inline PlanetFaceNode* getChildAt(Quadrant quad) const { return m_children[quad]; }
void setNeighbor(const unsigned int side, PlanetFaceNode *neighbor);
unsigned int mirrorSide(const unsigned int side) const;
const PlanetFaceNode* getEqualOrHigherNeighbor(const unsigned int side) const;
unsigned int getNeighborDetailDifference(const unsigned int side) const;
private:
void generate();
bool subdivide();
bool merge();
void dispose();
void findNeighbor(const unsigned int side);
void getNeighbor(const unsigned int side);
void updateNeighborDetailDifferences(const unsigned int side);
unsigned int mirrorQuadrant(const unsigned int side, const unsigned int quadrant) const;
PlanetFace* m_planetFace;
PlanetFaceNode* m_parent;
PlanetFaceNode* m_children[4];
PlanetFaceNode* m_neighbors[4];
unsigned int neighborDetailDifferences[4];
unsigned int m_index;
unsigned int m_level;
bool m_dirty;
bool m_generated;
bool m_leaf;
GLuint m_ebo, m_vao, m_vbo;
int m_indices;
glm::vec3 m_pos;
glm::vec3 m_center;
glm::vec3 m_left;
glm::vec3 m_forward;
float m_radius;
};
class PlanetFace
{
public:
PlanetFace(Planet* planet, const unsigned int face = Face::FACE_BOTTOM);
~PlanetFace();
void tick(Camera* camera, GLfloat dtime);
void draw(Camera* camera, Shader* shader);
inline Planet* getPlanet() const { return m_planet; }
inline const glm::vec3 getNormal() const { return m_normal; }
inline PlanetFaceNode* getLODRoot() { return m_lod; }
inline unsigned int getFace() const { return m_face; }
void connect(const unsigned int side, PlanetFace* face);
bool hasSplitsLeft();
private:
Planet* m_planet;
unsigned int m_face;
unsigned int m_splits;
glm::vec3 m_normal;
PlanetFaceNode* m_lod;
};
#endif // __PLANETFACE_H__