#include "Chunk.h" #include #include const int VERTEX_SIZE = 7; // x, y, z, nx, ny, nz, voxelKind const float topFace[24] = { // x, y, z, nx, ny, nz -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f }; const float bottomFace[24] = { -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f }; const float rightFace[24] = { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f }; const float leftFace[24] = { -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f }; const float frontFace[24] = { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f }; const float backFace[24] = { -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f }; void addFace(glm::ivec3 pos, const float *faceVertices, float voxelKind, std::vector &vbo, std::vector &ebo) { unsigned int vIndex = vbo.size() / VERTEX_SIZE; for (int i = 0; i < 4; i++) { const float* v = &faceVertices[i * 6]; // Face data is still 6 floats per vertex float world_x = v[0] + pos.x; float world_y = v[1] + pos.y; float world_z = v[2] + pos.z; // Debug: Print first vertex of first face // if (vbo.empty() && i == 0) { // std::cout << "[MESH] First vertex - Local pos: (" << pos.x << ", " << pos.y << ", " << pos.z << ")" << std::endl; // std::cout << "[MESH] First vertex - World: (" << world_x << ", " << world_y << ", " << world_z << ")" << std::endl; // } vbo.push_back(world_x); vbo.push_back(world_y); vbo.push_back(world_z); vbo.push_back(v[3]); vbo.push_back(v[4]); vbo.push_back(v[5]); vbo.push_back(voxelKind); // Add voxel kind as 7th component } ebo.push_back(vIndex + 0); ebo.push_back(vIndex + 1); ebo.push_back(vIndex + 2); ebo.push_back(vIndex + 0); ebo.push_back(vIndex + 2); ebo.push_back(vIndex + 3); } Chunk::Chunk() { this->data.fill(VoxelKind::Air); } Mesh* Chunk::getMesh() { // Generate mesh on first access if not already generated, or if dirty if ((!mesh || mesh_dirty) && !this->isEmpty()) { generateMesh(); mesh_dirty = false; } return mesh.get(); } void Chunk::generateMesh() { std::vector vboData; std::vector eboData; // std::cout << "Generating Chunk mesh..." << std::endl; const std::pair neighbors[6] = { std::pair(glm::ivec3(0, 1, 0), topFace), // top std::pair(glm::ivec3(0, -1, 0), bottomFace), // bottom std::pair(glm::ivec3(1, 0, 0), rightFace), // right std::pair(glm::ivec3(-1, 0, 0), leftFace), // left std::pair(glm::ivec3(0, 0, 1), frontFace), // front std::pair(glm::ivec3(0, 0, -1), backFace) // back }; for (int i = 0; i < TOTAL; ++i) { VoxelKind kind = this->data[i]; if (kind == VoxelKind::Air) continue; int x = i % SIZE; int y = (i / SIZE) % SIZE; int z = i / (SIZE * SIZE); glm::ivec3 pos(x, y, z); for (const auto& neighborPair : neighbors) { glm::ivec3 dir = neighborPair.first; const float* face = neighborPair.second; int nx = x + dir.x; int ny = y + dir.y; int nz = z + dir.z; bool neighbour_is_solid = false; // in-bounds neighbor -> check data if (nx >= 0 && nx < SIZE && ny >= 0 && ny < SIZE && nz >= 0 && nz < SIZE) { // std::cout << "Accessing " << nx << ", " << ny << ", " << nz << std::endl; neighbour_is_solid = (data[index(nx, ny, nz)] != VoxelKind::Air); } else { // neighbour out of this chunk: treat as air (exposed face) // or call into World to query adjacent chunk here neighbour_is_solid = false; } if (!neighbour_is_solid) { addFace(pos, face, static_cast(kind), vboData, eboData); } } } // Create and initialize mesh if it doesn't exist if (!mesh) { mesh = std::make_unique(); mesh->init(); } // Now, upload this data to our mesh object mesh->uploadData(vboData, eboData); }