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