#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__