get rid of the chunk shit, broken sphere..
This commit is contained in:
parent
736e7a19b1
commit
cfbcc73549
|
@ -31,6 +31,7 @@ endif()
|
||||||
add_executable(${VOXSPATIUM_EXECUTABLE} ${SOURCES})
|
add_executable(${VOXSPATIUM_EXECUTABLE} ${SOURCES})
|
||||||
|
|
||||||
# Include GL
|
# Include GL
|
||||||
|
set(OpenGL_GL_PREFERENCE "LEGACY")
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
include_directories(${OPENGL_INCLUDE_DIR})
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
target_link_libraries(${VOXSPATIUM_EXECUTABLE} ${OPENGL_LIBRARIES})
|
target_link_libraries(${VOXSPATIUM_EXECUTABLE} ${OPENGL_LIBRARIES})
|
||||||
|
@ -38,7 +39,7 @@ target_link_libraries(${VOXSPATIUM_EXECUTABLE} ${OPENGL_LIBRARIES})
|
||||||
# Include GLEW
|
# Include GLEW
|
||||||
find_package(GLEW REQUIRED)
|
find_package(GLEW REQUIRED)
|
||||||
include_directories(${GLEW_INCLUDE_PATH})
|
include_directories(${GLEW_INCLUDE_PATH})
|
||||||
target_link_libraries(${VOXSPATIUM_EXECUTABLE} ${GLEW_LIBRARY})
|
target_link_libraries(${VOXSPATIUM_EXECUTABLE} ${GLEW_LIBRARIES})
|
||||||
|
|
||||||
# Include SDL
|
# Include SDL
|
||||||
INCLUDE(FindPkgConfig)
|
INCLUDE(FindPkgConfig)
|
||||||
|
|
|
@ -160,7 +160,7 @@ void Application::run()
|
||||||
Input::getInstance().setMouseCoords(m_width/2, m_height/2);
|
Input::getInstance().setMouseCoords(m_width/2, m_height/2);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 4);
|
Planet* pl = new Planet(glm::vec3(0.0f,0.0f,0.0f), 128.0f);
|
||||||
// Create the shader and link them together
|
// Create the shader and link them together
|
||||||
Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag");
|
Shader& chunkShader = Shader::createShader("data/shaders/chunk.vert", "data/shaders/chunk.frag");
|
||||||
chunkShader.linkShaders();
|
chunkShader.linkShaders();
|
||||||
|
|
|
@ -226,7 +226,7 @@ void Camera::updateProjection(void)
|
||||||
{
|
{
|
||||||
// Recalculate the projection matrix
|
// Recalculate the projection matrix
|
||||||
glm::vec2 screenDims = Application::getInstance().getScreenDimensions();
|
glm::vec2 screenDims = Application::getInstance().getScreenDimensions();
|
||||||
m_projection = glm::perspective(getFOV(), (GLfloat)screenDims.x/(GLfloat)screenDims.y, 0.1f, 100.0f);
|
m_projection = glm::perspective(getFOV(), (GLfloat)screenDims.x/(GLfloat)screenDims.y, 0.1f, 1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::updateCameraVectors(void)
|
void Camera::updateCameraVectors(void)
|
||||||
|
|
|
@ -1,266 +0,0 @@
|
||||||
#include "Chunk.h"
|
|
||||||
#include "planet/PlanetFace.h"
|
|
||||||
|
|
||||||
const glm::vec3 FACE_VERTEX[6][4] = {
|
|
||||||
// Bottom
|
|
||||||
{
|
|
||||||
glm::vec3(1.0, 0.0, 0.0),
|
|
||||||
glm::vec3(1.0, 0.0, 1.0),
|
|
||||||
glm::vec3(0.0, 0.0, 1.0),
|
|
||||||
glm::vec3(0.0, 0.0, 0.0)
|
|
||||||
},
|
|
||||||
// Top
|
|
||||||
{
|
|
||||||
glm::vec3(0.0, 1.0, 0.0),
|
|
||||||
glm::vec3(0.0, 1.0, 1.0),
|
|
||||||
glm::vec3(1.0, 1.0, 1.0),
|
|
||||||
glm::vec3(1.0, 1.0, 0.0)
|
|
||||||
},
|
|
||||||
// Left
|
|
||||||
{
|
|
||||||
glm::vec3(0.0, 0.0, 1.0),
|
|
||||||
glm::vec3(0.0, 1.0, 1.0),
|
|
||||||
glm::vec3(0.0, 1.0, 0.0),
|
|
||||||
glm::vec3(0.0, 0.0, 0.0)
|
|
||||||
},
|
|
||||||
// Right
|
|
||||||
{
|
|
||||||
glm::vec3(1.0, 0.0, 0.0),
|
|
||||||
glm::vec3(1.0, 1.0, 0.0),
|
|
||||||
glm::vec3(1.0, 1.0, 1.0),
|
|
||||||
glm::vec3(1.0, 0.0, 1.0)
|
|
||||||
},
|
|
||||||
// Back
|
|
||||||
{
|
|
||||||
glm::vec3(1.0, 0.0, 1.0),
|
|
||||||
glm::vec3(1.0, 1.0, 1.0),
|
|
||||||
glm::vec3(0.0, 1.0, 1.0),
|
|
||||||
glm::vec3(0.0, 0.0, 1.0)
|
|
||||||
},
|
|
||||||
// Front
|
|
||||||
{
|
|
||||||
glm::vec3(0.0, 0.0,0.0),
|
|
||||||
glm::vec3(0.0, 1.0,0.0),
|
|
||||||
glm::vec3(1.0, 1.0,0.0),
|
|
||||||
glm::vec3(1.0, 0.0,0.0)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Chunk::Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z) :
|
|
||||||
m_planet(planet),
|
|
||||||
m_planetFace(face),
|
|
||||||
m_cx(x),
|
|
||||||
m_cy(y),
|
|
||||||
m_cz(z),
|
|
||||||
m_dirty(false),
|
|
||||||
m_active(true)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Chunk::~Chunk()
|
|
||||||
{
|
|
||||||
// Delete the buffers
|
|
||||||
deleteBuffers();
|
|
||||||
|
|
||||||
// Delete the cells
|
|
||||||
for (int i = 0; i < CHUNK_SIZE; ++i)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < CHUNK_SIZE; ++j)
|
|
||||||
{
|
|
||||||
delete [] m_cells[i][j];
|
|
||||||
}
|
|
||||||
|
|
||||||
delete [] m_cells[i];
|
|
||||||
}
|
|
||||||
delete [] m_cells;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::unload()
|
|
||||||
{
|
|
||||||
m_active = false;
|
|
||||||
|
|
||||||
// Make space in memory
|
|
||||||
m_vertices.clear();
|
|
||||||
deleteBuffers();
|
|
||||||
|
|
||||||
// Next time the chunk loads, we'll have to regenerate it.
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::load()
|
|
||||||
{
|
|
||||||
m_active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::generate()
|
|
||||||
{
|
|
||||||
// Populate cells with dummy data
|
|
||||||
m_cells = new Cell**[CHUNK_SIZE];
|
|
||||||
for(int i = 0; i < CHUNK_SIZE; i++)
|
|
||||||
{
|
|
||||||
m_cells[i] = new Cell*[CHUNK_SIZE];
|
|
||||||
|
|
||||||
for(int j = 0; j < CHUNK_SIZE; j++)
|
|
||||||
{
|
|
||||||
m_cells[i][j] = new Cell[CHUNK_SIZE];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_generated = true;
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::updateFlags()
|
|
||||||
{
|
|
||||||
// Figure out if we are a completely empty chunk
|
|
||||||
|
|
||||||
//if(numVerts == 0 && numTriangles == 0)
|
|
||||||
//{
|
|
||||||
// m_emptyChunk = true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//m_emptyChunk = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::draw(Camera* camera, Shader* shader)
|
|
||||||
{
|
|
||||||
if (!m_active || !m_vao || !m_vbo)
|
|
||||||
return;
|
|
||||||
|
|
||||||
shader->setBuffers(m_vao, m_vbo, 0);
|
|
||||||
shader->use();
|
|
||||||
|
|
||||||
m_model = glm::translate(glm::mat4(1.0f), this->getAbsolutePosition()) * m_planetFace->getOrientation();
|
|
||||||
|
|
||||||
camera->shaderViewProjection(*shader);
|
|
||||||
shader->setUniform("modelMatrix", m_model);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::formFace(std::vector<Vertex> &vertices, const glm::vec3 &position, CellFace face)
|
|
||||||
{
|
|
||||||
// Calculate positions in mesh
|
|
||||||
auto P = [&](const glm::vec3& p) {
|
|
||||||
const glm::vec3 pp = (position + p);
|
|
||||||
return pp;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get the vertices of the selected face
|
|
||||||
const glm::vec3 pos[4] = {
|
|
||||||
P(FACE_VERTEX[face][0]), P(FACE_VERTEX[face][1]),
|
|
||||||
P(FACE_VERTEX[face][2]), P(FACE_VERTEX[face][3]),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Calculate normals
|
|
||||||
glm::vec3 normal = glm::cross(pos[2] - pos[0], pos[3] - pos[1]);
|
|
||||||
|
|
||||||
// Construct face from triangles
|
|
||||||
vertices.push_back({pos[0], normal, {0.0, 1.0}});
|
|
||||||
vertices.push_back({pos[1], normal, {0.0, 0.0}});
|
|
||||||
vertices.push_back({pos[2], normal, {1.0, 0.0}});
|
|
||||||
vertices.push_back({pos[0], normal, {0.0, 1.0}});
|
|
||||||
vertices.push_back({pos[2], normal, {1.0, 0.0}});
|
|
||||||
vertices.push_back({pos[3], normal, {1.0, 1.0}});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::rebuildMesh()
|
|
||||||
{
|
|
||||||
// Default visibility of a face
|
|
||||||
const bool faceDefault = true;
|
|
||||||
|
|
||||||
// Don't update the chunk again until a change has occured
|
|
||||||
m_dirty = false;
|
|
||||||
|
|
||||||
// Clear previous vertices
|
|
||||||
m_vertices.clear();
|
|
||||||
|
|
||||||
// Determine which cells should have which faces drawn
|
|
||||||
for (int x = 0; x < CHUNK_SIZE; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < CHUNK_SIZE; y++)
|
|
||||||
{
|
|
||||||
for (int z = 0; z < CHUNK_SIZE; z++)
|
|
||||||
{
|
|
||||||
if(m_cells[x][y][z].isSolid() == false)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool faceLeft = faceDefault;
|
|
||||||
if(x > 0)
|
|
||||||
faceLeft = !m_cells[x-1][y][z].isSolid();
|
|
||||||
|
|
||||||
bool faceRight = faceDefault;
|
|
||||||
if(x < CHUNK_SIZE - 1)
|
|
||||||
faceRight = !m_cells[x+1][y][z].isSolid();
|
|
||||||
|
|
||||||
bool faceBottom = faceDefault;
|
|
||||||
if(y > 0)
|
|
||||||
faceBottom = !m_cells[x][y-1][z].isSolid();
|
|
||||||
|
|
||||||
bool faceTop = faceDefault;
|
|
||||||
if(y < CHUNK_SIZE - 1)
|
|
||||||
faceTop = !m_cells[x][y+1][z].isSolid();
|
|
||||||
|
|
||||||
bool faceBack = faceDefault;
|
|
||||||
if(z > 0)
|
|
||||||
faceBack = !m_cells[x][y][z-1].isSolid();
|
|
||||||
|
|
||||||
bool faceFront = faceDefault;
|
|
||||||
if(z < CHUNK_SIZE - 1)
|
|
||||||
faceFront = !m_cells[x][y][z+1].isSolid();
|
|
||||||
|
|
||||||
glm::vec3 cellPos = glm::vec3(x, y, z);
|
|
||||||
|
|
||||||
if (faceBottom)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_BOTTOM);
|
|
||||||
if (faceTop)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_TOP);
|
|
||||||
if (faceLeft)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_LEFT);
|
|
||||||
if (faceRight)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_RIGHT);
|
|
||||||
if (faceFront)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_FRONT);
|
|
||||||
if (faceBack)
|
|
||||||
formFace(m_vertices, cellPos, CELL_FACE_BACK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete previous buffers
|
|
||||||
deleteBuffers();
|
|
||||||
|
|
||||||
m_emptyChunk = m_vertices.size() == 0;
|
|
||||||
|
|
||||||
if (m_emptyChunk)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Generate buffers
|
|
||||||
glGenVertexArrays(1, &m_vao);
|
|
||||||
glBindVertexArray(m_vao);
|
|
||||||
|
|
||||||
glGenBuffers(1, &m_vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * m_vertices.size(), &(m_vertices[0]), GL_STATIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Chunk::isDetailedEnough(Camera* camera)
|
|
||||||
{
|
|
||||||
// TODO: Level of detail on mesh
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Chunk::deleteBuffers()
|
|
||||||
{
|
|
||||||
if (m_vbo)
|
|
||||||
glDeleteBuffers(1, &m_vbo);
|
|
||||||
if (m_vao)
|
|
||||||
glDeleteBuffers(1, &m_vao);
|
|
||||||
}
|
|
||||||
|
|
||||||
const glm::vec3 Chunk::getAbsolutePosition()
|
|
||||||
{
|
|
||||||
return getPosition() + m_planetFace->getPosition();
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
#ifndef __CHUNK_H__
|
|
||||||
#define __CHUNK_H__
|
|
||||||
|
|
||||||
#include "util/Common.h"
|
|
||||||
#include "planet/Planet.h"
|
|
||||||
#include "Camera.h"
|
|
||||||
|
|
||||||
#define CHUNK_SIZE 16
|
|
||||||
|
|
||||||
struct Vertex
|
|
||||||
{
|
|
||||||
glm::vec3 position;
|
|
||||||
glm::vec3 normal;
|
|
||||||
glm::vec2 uv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Cell
|
|
||||||
{
|
|
||||||
GLuint internalId;
|
|
||||||
bool isSolid()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CellFace {
|
|
||||||
CELL_FACE_BOTTOM, CELL_FACE_TOP,
|
|
||||||
CELL_FACE_LEFT, CELL_FACE_RIGHT,
|
|
||||||
CELL_FACE_FRONT, CELL_FACE_BACK
|
|
||||||
};
|
|
||||||
|
|
||||||
class Chunk
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Chunk(Planet* planet, class PlanetFace* face, int x, int y, int z);
|
|
||||||
~Chunk();
|
|
||||||
|
|
||||||
void unload();
|
|
||||||
void load();
|
|
||||||
void generate();
|
|
||||||
|
|
||||||
void rebuildMesh();
|
|
||||||
|
|
||||||
inline const glm::vec3 getPosition() const { return glm::vec3(m_cx, m_cy, m_cz); }
|
|
||||||
const glm::vec3 getAbsolutePosition();
|
|
||||||
inline int getX() const { return m_cx; }
|
|
||||||
inline int getY() const { return m_cy; }
|
|
||||||
inline int getZ() const { return m_cz; }
|
|
||||||
|
|
||||||
inline bool isLoaded() const { return m_active; }
|
|
||||||
inline bool isRedrawRequired() const { return m_dirty; }
|
|
||||||
inline bool isGenerated() const { return m_generated; }
|
|
||||||
|
|
||||||
inline bool shouldRender() const { return !m_emptyChunk && m_active && m_generated; }
|
|
||||||
|
|
||||||
inline glm::mat4 getModelMatrix() const { return m_model; }
|
|
||||||
|
|
||||||
bool isDetailedEnough(Camera* camera);
|
|
||||||
|
|
||||||
void draw(Camera* camera, Shader* shader);
|
|
||||||
void updateFlags();
|
|
||||||
private:
|
|
||||||
void formFace(std::vector<Vertex> &vertices, const glm::vec3 &position, CellFace face);
|
|
||||||
void deleteBuffers();
|
|
||||||
|
|
||||||
Planet* m_planet;
|
|
||||||
class PlanetFace* m_planetFace;
|
|
||||||
glm::mat4 m_model;
|
|
||||||
|
|
||||||
bool m_dirty;
|
|
||||||
bool m_active;
|
|
||||||
bool m_generated;
|
|
||||||
bool m_emptyChunk;
|
|
||||||
|
|
||||||
int m_cx, m_cy, m_cz;
|
|
||||||
|
|
||||||
GLuint m_vao, m_vbo;
|
|
||||||
|
|
||||||
Cell*** m_cells;
|
|
||||||
std::vector<Vertex> m_vertices;
|
|
||||||
};
|
|
||||||
#endif // __CHUNK_H__
|
|
|
@ -19,16 +19,16 @@ Planet::~Planet()
|
||||||
|
|
||||||
void Planet::draw(Camera* camera, Shader* shader)
|
void Planet::draw(Camera* camera, Shader* shader)
|
||||||
{
|
{
|
||||||
//for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
//{
|
{
|
||||||
m_faces[FACE_TOP]->draw(camera, shader);
|
m_faces[i]->draw(camera, shader);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Planet::tick(Camera* camera, GLfloat dtime)
|
void Planet::tick(Camera* camera, GLfloat dtime)
|
||||||
{
|
{
|
||||||
//for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
//{
|
{
|
||||||
m_faces[FACE_TOP]->tick(camera, dtime);
|
m_faces[i]->tick(camera, dtime);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,344 +1,196 @@
|
||||||
#include "planet/PlanetFace.h"
|
#include "planet/PlanetFace.h"
|
||||||
#include "planet/Planet.h"
|
|
||||||
|
const glm::vec3 FACE_NORMALS[6] = {
|
||||||
|
glm::vec3(0.0f, -1.0f, 0.0f),
|
||||||
|
glm::vec3(0.0f, 1.0f, 0.0f),
|
||||||
|
glm::vec3(-1.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec3(1.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec3(0.0f, 0.0f, -1.0f),
|
||||||
|
glm::vec3(0.0f, 0.0f, 1.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
PlanetFaceNode::PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level) :
|
||||||
|
m_planet(planet), m_planetFace(face), m_pos(position), m_level(level), m_generated(false), m_dirty(true)
|
||||||
|
{
|
||||||
|
glm::vec3 normal = face->getNormal();
|
||||||
|
m_left = glm::vec3(normal.y, normal.z, normal.x);
|
||||||
|
m_forward = glm::cross(normal, m_left);
|
||||||
|
|
||||||
|
if (level == 0)
|
||||||
|
{
|
||||||
|
float radius = m_planet->getRadius() / 2.0f;
|
||||||
|
m_pos = m_pos - (m_left * radius);
|
||||||
|
m_pos = m_pos - (m_forward * radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlanetFaceNode::~PlanetFaceNode()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
delete m_children[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteBuffers(1, &m_vao);
|
||||||
|
glDeleteBuffers(1, &m_vbo);
|
||||||
|
glDeleteBuffers(1, &m_ebo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::tick(Camera* camera, GLfloat dtime)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::draw(Camera* camera, Shader* shader)
|
||||||
|
{
|
||||||
|
if (!m_generated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shader->setBuffers(m_vao, m_vbo, m_ebo);
|
||||||
|
shader->use();
|
||||||
|
|
||||||
|
camera->shaderViewProjection(*shader);
|
||||||
|
shader->setUniform("modelMatrix", glm::translate(glm::mat4(1.0f), this->getAbsolutePosition()));
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, m_indices, GL_UNSIGNED_INT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::generate()
|
||||||
|
{
|
||||||
|
if (m_generated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
|
||||||
|
float divisionLevel = (float)pow(2.0, m_level);
|
||||||
|
float radius = m_planet->getRadius();
|
||||||
|
for (int i = 0; i < RESOLUTION; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < RESOLUTION; j++)
|
||||||
|
{
|
||||||
|
float iindex = i / (RESOLUTION - 1.0);
|
||||||
|
float jindex = j / (RESOLUTION - 1.0);
|
||||||
|
|
||||||
|
// From the left and forward vectors, we can calculate an oriented vertex
|
||||||
|
glm::vec3 iv = ((m_left * iindex) * radius) / divisionLevel;
|
||||||
|
glm::vec3 jv = ((m_forward * jindex) * radius) / divisionLevel;
|
||||||
|
|
||||||
|
// Add the scaled left and forward to the centered origin
|
||||||
|
glm::vec3 vertex = m_pos + (iv + jv);
|
||||||
|
|
||||||
|
// Normalize and multiply by radius to create a spherical mesh
|
||||||
|
glm::vec3 vertNormal = glm::normalize(vertex);
|
||||||
|
glm::vec3 pos = vertNormal * radius;
|
||||||
|
|
||||||
|
// Add
|
||||||
|
vertices.push_back({ pos, vertNormal, glm::vec2(j * (1.0 / RESOLUTION), i * (1.0 / RESOLUTION)) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int gz = 0; gz < RESOLUTION - 1; gz++)
|
||||||
|
{
|
||||||
|
for (int gx = 0; gx < RESOLUTION - 1; gx++)
|
||||||
|
{
|
||||||
|
int topLeft = (gz * RESOLUTION) + gx;
|
||||||
|
int topRight = topLeft + 1;
|
||||||
|
int bottomLeft = ((gz + 1) * RESOLUTION) + gx;
|
||||||
|
int bottomRight = bottomLeft + 1;
|
||||||
|
|
||||||
|
indices.push_back(topLeft);
|
||||||
|
indices.push_back(topRight);
|
||||||
|
indices.push_back(bottomLeft);
|
||||||
|
indices.push_back(bottomLeft);
|
||||||
|
indices.push_back(topRight);
|
||||||
|
indices.push_back(bottomRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_indices = indices.size();
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &m_vao);
|
||||||
|
glBindVertexArray(m_vao);
|
||||||
|
|
||||||
|
glGenBuffers(1, &m_vbo);
|
||||||
|
glGenBuffers(1, &m_ebo);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * m_indices, &(indices[0]), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), &(vertices[0]), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
m_generated = true;
|
||||||
|
m_leaf = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::subdivide()
|
||||||
|
{
|
||||||
|
if (m_level == 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int lv = m_level + 1;
|
||||||
|
float radius = m_planet->getRadius();
|
||||||
|
|
||||||
|
glm::vec3 stepLeft = m_left * (radius / (float)pow(2, lv));
|
||||||
|
glm::vec3 stepForward = m_forward * (radius / (float)pow(2, lv));
|
||||||
|
|
||||||
|
m_children[0] = new PlanetFaceNode(m_planet, m_planetFace, m_pos + stepForward, lv);
|
||||||
|
m_children[1] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft) + stepForward, lv);
|
||||||
|
m_children[2] = new PlanetFaceNode(m_planet, m_planetFace, m_pos, lv);
|
||||||
|
m_children[3] = new PlanetFaceNode(m_planet, m_planetFace, (m_pos + stepLeft), lv);
|
||||||
|
|
||||||
|
m_leaf = false;
|
||||||
|
this->dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::merge()
|
||||||
|
{
|
||||||
|
if (m_level == 0 && m_leaf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
m_children[i]->merge();
|
||||||
|
m_children[i]->dispose();
|
||||||
|
delete m_children[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_leaf = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlanetFaceNode::dispose()
|
||||||
|
{
|
||||||
|
m_generated = false;
|
||||||
|
glDeleteBuffers(1, &m_vao);
|
||||||
|
glDeleteBuffers(1, &m_vbo);
|
||||||
|
glDeleteBuffers(1, &m_ebo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlanetFaceNode::isLeaf()
|
||||||
|
{
|
||||||
|
return m_leaf;
|
||||||
|
}
|
||||||
|
|
||||||
PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
|
PlanetFace::PlanetFace(Planet* planet, const unsigned int face) :
|
||||||
m_planet(planet), m_face(face), m_pos(glm::vec3(0.0f, 0.0f, 0.0f))
|
m_planet(planet), m_face(face)
|
||||||
{
|
{
|
||||||
// Set face normal depending on face
|
m_normal = FACE_NORMALS[m_face];
|
||||||
switch (m_face)
|
m_planetFace = new PlanetFaceNode(planet, this, m_normal * (m_planet->getRadius() / 2.0f), 0);
|
||||||
{
|
m_planetFace->generate();
|
||||||
case Face::FACE_BOTTOM:
|
|
||||||
m_normal = glm::vec3(0.0f, -1.0f, 0.0f);
|
|
||||||
break;
|
|
||||||
case Face::FACE_TOP:
|
|
||||||
m_normal = glm::vec3(0.0f, 1.0f, 0.0f);
|
|
||||||
break;
|
|
||||||
case Face::FACE_LEFT:
|
|
||||||
m_normal = glm::vec3(-1.0f, 0.0f, 0.0f);
|
|
||||||
break;
|
|
||||||
case Face::FACE_RIGHT:
|
|
||||||
m_normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
|
||||||
break;
|
|
||||||
case Face::FACE_FRONT:
|
|
||||||
m_normal = glm::vec3(0.0f, 0.0f, -1.0f);
|
|
||||||
break;
|
|
||||||
case Face::FACE_BACK:
|
|
||||||
m_normal = glm::vec3(0.0f, 0.0f, 1.0f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_chunks = new ChunkManager(this, planet->getRadius());
|
|
||||||
|
|
||||||
if (m_face < 2)
|
|
||||||
m_orientation = glm::rotate(glm::mat4(1.0f), (float)((face == FACE_BOTTOM ? 0.5 : -0.5) * M_PI),
|
|
||||||
glm::vec3(0.0f, 1.0f, 0.0f));
|
|
||||||
else
|
|
||||||
m_orientation = glm::rotate(glm::mat4(1.0f), (float)(face * -0.5 * M_PI), glm::vec3(1.0f, 0.0f, 0.0f));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlanetFace::~PlanetFace()
|
PlanetFace::~PlanetFace()
|
||||||
{
|
{
|
||||||
|
delete m_planetFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetFace::draw(Camera* camera, Shader* shader)
|
void PlanetFace::draw(Camera* camera, Shader* shader)
|
||||||
{
|
{
|
||||||
if (m_chunks)
|
m_planetFace->draw(camera, shader);
|
||||||
{
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
glCullFace(GL_BACK);
|
|
||||||
|
|
||||||
m_chunks->render(camera, shader);
|
|
||||||
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlanetFace::tick(Camera* camera, GLfloat dtime)
|
void PlanetFace::tick(Camera* camera, GLfloat dtime)
|
||||||
{
|
{
|
||||||
if (m_chunks)
|
m_planetFace->tick(camera, dtime);
|
||||||
{
|
|
||||||
m_chunks->update(camera, dtime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ******** //
|
|
||||||
// CHUNKS //
|
|
||||||
// ******** //
|
|
||||||
|
|
||||||
ChunkManager::ChunkManager(PlanetFace* face, GLuint chunkCount) : m_face(face)
|
|
||||||
{
|
|
||||||
m_forceVisibilityUpdate = true;
|
|
||||||
for (int x = 0; x < (int)chunkCount; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < (int)chunkCount; y++)
|
|
||||||
{
|
|
||||||
for (int z = 0; z < (int)chunkCount; z++)
|
|
||||||
{
|
|
||||||
m_chunks.push_back(new Chunk(m_face->getPlanet(), m_face, x * CHUNK_SIZE, y * CHUNK_SIZE, z * CHUNK_SIZE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChunkManager::~ChunkManager()
|
|
||||||
{
|
|
||||||
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
delete pChunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::update(Camera* camera, GLfloat dtime)
|
|
||||||
{
|
|
||||||
updateUnload();
|
|
||||||
|
|
||||||
updateLoad();
|
|
||||||
|
|
||||||
updateRebuild();
|
|
||||||
|
|
||||||
updateGenerate();
|
|
||||||
|
|
||||||
updateFlags();
|
|
||||||
|
|
||||||
updateVisibility(camera);
|
|
||||||
|
|
||||||
updateRender(camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
Chunk* ChunkManager::getChunk(int x, int y, int z)
|
|
||||||
{
|
|
||||||
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if (pChunk->getX() == x && pChunk->getY() == y && pChunk->getZ() == z)
|
|
||||||
return pChunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateUnload()
|
|
||||||
{
|
|
||||||
// Unload any chunks
|
|
||||||
for(auto iterator = m_chunkUnloadQueue.begin(); iterator != m_chunkUnloadQueue.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if(pChunk->isLoaded())
|
|
||||||
{
|
|
||||||
pChunk->unload();
|
|
||||||
|
|
||||||
m_forceVisibilityUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the unload list (every frame)
|
|
||||||
m_chunkUnloadQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateLoad()
|
|
||||||
{
|
|
||||||
int lNumOfChunksLoaded = 0;
|
|
||||||
|
|
||||||
for(auto iterator = m_chunkLoadQueue.begin(); iterator != m_chunkLoadQueue.end() &&
|
|
||||||
(lNumOfChunksLoaded != ASYNC_NUM_CHUNKS_PER_FRAME); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if(pChunk->isLoaded() == false)
|
|
||||||
{
|
|
||||||
if(lNumOfChunksLoaded != ASYNC_NUM_CHUNKS_PER_FRAME)
|
|
||||||
{
|
|
||||||
pChunk->load();
|
|
||||||
|
|
||||||
// Increase the chunks loaded count
|
|
||||||
lNumOfChunksLoaded++;
|
|
||||||
|
|
||||||
m_forceVisibilityUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the load list (every frame)
|
|
||||||
m_chunkLoadQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateRebuild()
|
|
||||||
{
|
|
||||||
// Rebuild any chunks that are in the rebuild chunk list
|
|
||||||
int lNumRebuiltChunkThisFrame = 0;
|
|
||||||
for(auto iterator = m_chunkRebuildQueue.begin(); iterator != m_chunkRebuildQueue.end() &&
|
|
||||||
(lNumRebuiltChunkThisFrame != ASYNC_NUM_CHUNKS_PER_FRAME); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if(pChunk->isLoaded() && pChunk->isGenerated())
|
|
||||||
{
|
|
||||||
if(lNumRebuiltChunkThisFrame != ASYNC_NUM_CHUNKS_PER_FRAME)
|
|
||||||
{
|
|
||||||
pChunk->rebuildMesh();
|
|
||||||
|
|
||||||
// If we rebuild a chunk, add it to the list of chunks that need their render flags updated
|
|
||||||
// since we might now be empty or surrounded
|
|
||||||
m_chunkFlagsQueue.push_back(pChunk);
|
|
||||||
|
|
||||||
// Also add our neighbours since they might now be surrounded too (If we have neighbours)
|
|
||||||
Chunk* pChunkXMinus = getChunk(pChunk->getX()-1, pChunk->getY(), pChunk->getZ());
|
|
||||||
Chunk* pChunkXPlus = getChunk(pChunk->getX()+1, pChunk->getY(), pChunk->getZ());
|
|
||||||
Chunk* pChunkYMinus = getChunk(pChunk->getX(), pChunk->getY()-1, pChunk->getZ());
|
|
||||||
Chunk* pChunkYPlus = getChunk(pChunk->getX(), pChunk->getY()+1, pChunk->getZ());
|
|
||||||
Chunk* pChunkZMinus = getChunk(pChunk->getX(), pChunk->getY(), pChunk->getZ()-1);
|
|
||||||
Chunk* pChunkZPlus = getChunk(pChunk->getX(), pChunk->getY(), pChunk->getZ()+1);
|
|
||||||
|
|
||||||
if(pChunkXMinus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkXMinus);
|
|
||||||
|
|
||||||
if(pChunkXPlus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkXPlus);
|
|
||||||
|
|
||||||
if(pChunkYMinus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkYMinus);
|
|
||||||
|
|
||||||
if(pChunkYPlus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkYPlus);
|
|
||||||
|
|
||||||
if(pChunkZMinus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkZMinus);
|
|
||||||
|
|
||||||
if(pChunkZPlus != NULL)
|
|
||||||
m_chunkFlagsQueue.push_back(pChunkZPlus);
|
|
||||||
|
|
||||||
// Only rebuild a certain number of chunks per frame
|
|
||||||
lNumRebuiltChunkThisFrame++;
|
|
||||||
|
|
||||||
m_forceVisibilityUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the rebuild list
|
|
||||||
m_chunkRebuildQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateFlags()
|
|
||||||
{
|
|
||||||
for(auto iterator = m_chunkFlagsQueue.begin(); iterator != m_chunkFlagsQueue.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
pChunk->updateFlags();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
m_chunkFlagsQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateGenerate()
|
|
||||||
{
|
|
||||||
// Generate any chunks that have not already been generated
|
|
||||||
for(auto iterator = m_chunkGenerateQueue.begin(); iterator != m_chunkGenerateQueue.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if(pChunk->isLoaded() && pChunk->isGenerated() == false)
|
|
||||||
{
|
|
||||||
pChunk->generate();
|
|
||||||
|
|
||||||
if(pChunk->isGenerated())
|
|
||||||
{
|
|
||||||
// Only force the visibility update if we actually generate the chunk, some chunks wait in the pre-generate stage...
|
|
||||||
m_forceVisibilityUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the generate list (every frame)
|
|
||||||
m_chunkGenerateQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateVisibility(Camera* camera)
|
|
||||||
{
|
|
||||||
m_forceVisibilityUpdate = false;
|
|
||||||
|
|
||||||
m_chunksVisible.clear();
|
|
||||||
|
|
||||||
for(auto iterator = m_chunks.begin(); iterator != m_chunks.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
// TODO: Temporary distance limit
|
|
||||||
if (glm::abs(glm::length(camera->getPosition() - pChunk->getAbsolutePosition())) > 64.0f)
|
|
||||||
{
|
|
||||||
if (pChunk->isLoaded())
|
|
||||||
{
|
|
||||||
m_chunkUnloadQueue.push_back(pChunk);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!pChunk->isLoaded())
|
|
||||||
{
|
|
||||||
m_chunkLoadQueue.push_back(pChunk);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate chunk
|
|
||||||
if (!pChunk->isGenerated())
|
|
||||||
{
|
|
||||||
m_chunkGenerateQueue.push_back(pChunk);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pChunk->isRedrawRequired() || !pChunk->isDetailedEnough(camera))
|
|
||||||
{
|
|
||||||
m_chunkRebuildQueue.push_back(pChunk);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_chunksVisible.push_back(pChunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::updateRender(Camera* camera)
|
|
||||||
{
|
|
||||||
// Clear the render list each frame BEFORE we do our tests to see what chunks should be rendered
|
|
||||||
m_chunkRenderQueue.clear();
|
|
||||||
|
|
||||||
for(auto iterator = m_chunksVisible.begin(); iterator != m_chunksVisible.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
|
|
||||||
if(pChunk != NULL)
|
|
||||||
{
|
|
||||||
if(pChunk->isLoaded() && pChunk->isGenerated())
|
|
||||||
{
|
|
||||||
if(pChunk->shouldRender()) // Early flags check so we don't always have to do the frustum check...
|
|
||||||
{
|
|
||||||
// TODO: fix frustum culling
|
|
||||||
//glm::vec3 pos = pChunk->getAbsolutePosition();
|
|
||||||
//glm::mat4 model = glm::translate(glm::mat4(1.0f), pos);
|
|
||||||
|
|
||||||
//camera->updateFrustum(model);
|
|
||||||
//if(camera->frustumContainsBox(glm::vec3(0.0f), glm::vec3((float)CHUNK_SIZE / 2)) > 0)
|
|
||||||
//{
|
|
||||||
m_chunkRenderQueue.push_back(pChunk);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChunkManager::render(Camera* camera, Shader* shader)
|
|
||||||
{
|
|
||||||
// Render only the chunks that should be rendered
|
|
||||||
for(auto iterator = m_chunkRenderQueue.begin(); iterator != m_chunkRenderQueue.end(); ++iterator)
|
|
||||||
{
|
|
||||||
Chunk* pChunk = (*iterator);
|
|
||||||
pChunk->draw(camera, shader);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,56 +2,66 @@
|
||||||
#define __PLANETFACE_H__
|
#define __PLANETFACE_H__
|
||||||
|
|
||||||
#include "util/Common.h"
|
#include "util/Common.h"
|
||||||
#include "planet/Chunk.h"
|
#include "planet/Planet.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
|
||||||
#define ASYNC_NUM_CHUNKS_PER_FRAME 8
|
#define RESOLUTION 128
|
||||||
|
|
||||||
enum Face {
|
enum Face
|
||||||
|
{
|
||||||
FACE_BOTTOM, FACE_TOP,
|
FACE_BOTTOM, FACE_TOP,
|
||||||
FACE_LEFT, FACE_RIGHT,
|
FACE_LEFT, FACE_RIGHT,
|
||||||
FACE_FRONT, FACE_BACK
|
FACE_FRONT, FACE_BACK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec2 uv;
|
||||||
|
};
|
||||||
|
|
||||||
class Planet;
|
class Planet;
|
||||||
class PlanetFace;
|
class PlanetFace;
|
||||||
|
|
||||||
// PlanetFace Chunk Manager
|
class PlanetFaceNode
|
||||||
class ChunkManager
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChunkManager(PlanetFace* face, GLuint chunkCount);
|
PlanetFaceNode(Planet* planet, PlanetFace* face, glm::vec3 position, const unsigned int level);
|
||||||
~ChunkManager();
|
~PlanetFaceNode();
|
||||||
|
|
||||||
void update(Camera* camera, GLfloat dtime);
|
void tick(Camera* camera, GLfloat dtime);
|
||||||
Chunk* getChunk(int x, int y, int z);
|
void draw(Camera* camera, Shader* shader);
|
||||||
|
|
||||||
void render(Camera* camera, Shader* shader);
|
void generate();
|
||||||
|
void subdivide();
|
||||||
|
void merge();
|
||||||
|
void dispose();
|
||||||
|
bool isLeaf();
|
||||||
|
|
||||||
|
inline Planet* getPlanet() const { return m_planet; }
|
||||||
|
inline PlanetFace* getPlanetFace() const { return m_planetFace; }
|
||||||
|
|
||||||
|
inline glm::vec3 getAbsolutePosition() const { return m_planet->getPosition() + m_pos; }
|
||||||
private:
|
private:
|
||||||
void updateUnload();
|
Planet* m_planet;
|
||||||
void updateLoad();
|
PlanetFace* m_planetFace;
|
||||||
void updateGenerate();
|
|
||||||
void updateRebuild();
|
|
||||||
void updateFlags();
|
|
||||||
void updateVisibility(Camera* camera);
|
|
||||||
void updateRender(Camera* camera);
|
|
||||||
|
|
||||||
std::vector<Chunk*> m_chunks;
|
PlanetFaceNode* m_parent;
|
||||||
std::vector<Chunk*> m_chunksVisible;
|
PlanetFaceNode* m_children[4];
|
||||||
|
|
||||||
// Queues
|
unsigned int m_level;
|
||||||
std::vector<Chunk*> m_chunkUnloadQueue;
|
bool m_dirty;
|
||||||
std::vector<Chunk*> m_chunkLoadQueue;
|
bool m_generated;
|
||||||
std::vector<Chunk*> m_chunkGenerateQueue;
|
bool m_leaf;
|
||||||
std::vector<Chunk*> m_chunkRebuildQueue;
|
|
||||||
std::vector<Chunk*> m_chunkRenderQueue;
|
|
||||||
std::vector<Chunk*> m_chunkFlagsQueue;
|
|
||||||
|
|
||||||
PlanetFace* m_face;
|
GLuint m_ebo, m_vao, m_vbo;
|
||||||
|
int m_indices;
|
||||||
|
|
||||||
int m_chunksLoaded = 0;
|
glm::vec3 m_pos;
|
||||||
bool m_forceVisibilityUpdate;
|
glm::vec3 m_left;
|
||||||
|
glm::vec3 m_forward;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlanetFace
|
class PlanetFace
|
||||||
|
@ -65,17 +75,13 @@ class PlanetFace
|
||||||
|
|
||||||
inline Planet* getPlanet() const { return m_planet; }
|
inline Planet* getPlanet() const { return m_planet; }
|
||||||
|
|
||||||
inline const glm::vec3 getPosition() const { return m_planet->getPosition() + m_pos; }
|
inline const glm::vec3 getNormal() const { return m_normal; }
|
||||||
inline const glm::mat4 getOrientation() const { return m_orientation; }
|
|
||||||
private:
|
private:
|
||||||
Planet* m_planet;
|
Planet* m_planet;
|
||||||
unsigned int m_face;
|
unsigned int m_face;
|
||||||
|
|
||||||
glm::vec3 m_normal;
|
glm::vec3 m_normal;
|
||||||
glm::vec3 m_pos;
|
|
||||||
|
|
||||||
ChunkManager* m_chunks;
|
PlanetFaceNode* m_planetFace;
|
||||||
|
|
||||||
glm::mat4 m_orientation;
|
|
||||||
};
|
};
|
||||||
#endif // __PLANETFACE_H__
|
#endif // __PLANETFACE_H__
|
||||||
|
|
Loading…
Reference in New Issue