Clean up & Optimize MeshGenerator class

master
aurailus 2019-06-16 18:35:40 -07:00
parent 5ffd3c6dbb
commit 225862bdd1
7 changed files with 83 additions and 79 deletions

View File

@ -90,7 +90,7 @@ void MeshGenStream::threadFunction(MeshGenStream::Thread *thread) {
u.vertices = new std::vector<Vertex>();
u.indices = new std::vector<unsigned int>();
MeshGenerator().build(u.chunk, thread->atlas, *u.adjacent, *u.vertices, *u.indices);
MeshGenerator(*u.vertices, *u.indices, thread->atlas, *u.chunk, *u.adjacent);
delete u.adjacent;

View File

@ -2,88 +2,60 @@
// Created by aurailus on 01/12/18.
//
#include <thread>
#include "MeshGenerator.h"
MeshGenerator::MeshGenerator() {
indOffset = 0;
}
MeshGenerator::MeshGenerator(std::vector<Vertex> &vertices, std::vector<unsigned int> &indices,
LocalBlockAtlas& atlas, const BlockChunk& chunk, const std::vector<bool>& adj) :
vertices(vertices),
indices(indices),
atlas(atlas),
chunk(chunk) {
LocalBlockDef& blockData(int ind, BlockChunk &chunk, LocalBlockAtlas& atlas) {
return atlas.fromIndex(chunk.getBlock(ind));
}
LocalBlockDef& blockData(glm::vec3 &pos, BlockChunk &chunk, LocalBlockAtlas &atlas) {
return atlas.fromIndex(chunk.getBlock(pos));
}
bool faceOcculudedAt(glm::vec3 &pos, BlockChunk &chunk, LocalBlockAtlas &atlas, std::vector<bool> &bools) {
auto off = TransPos::CHUNK_SIZE*TransPos::CHUNK_SIZE; //CHUNK_SIZE ^ 2
if (pos.x < 0 || pos.x >= TransPos::CHUNK_SIZE || pos.y < 0 || pos.y >= TransPos::CHUNK_SIZE || pos.z < 0 || pos.z >= TransPos::CHUNK_SIZE) {
if (pos.x == -1) return bools[off + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.x == TransPos::CHUNK_SIZE) return bools[ + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.y == -1) return bools[off*3 + (int)pos.x * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.y == TransPos::CHUNK_SIZE) return bools[off*2 + (int)pos.x * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.z == -1) return bools[off*5 + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.x];
if (pos.z == TransPos::CHUNK_SIZE) return bools[off*4 + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.x];
return false;
}
return blockData(pos, chunk, atlas).isCulling();
}
void MeshGenerator::build(const std::shared_ptr<BlockChunk> &chunk, LocalBlockAtlas &atlas, std::vector<bool> &adjacents,
std::vector<Vertex> &vertices, std::vector<unsigned int> &indices) {
vertices.reserve(10000);
indices.reserve(10000);
Timer t("Mesh Generation");
vertices.reserve(300000);
indices.reserve(50000);
glm::vec3 off;
glm::vec3 vis;
glm::vec3 check;
for (int i = 0; i < (int)pow(TransPos::CHUNK_SIZE, 3); i++) {
if (blockData(i, *chunk, atlas).getModel().visible) {
auto end = (int)pow(TransPos::CHUNK_SIZE, 3);
for (int i = 0; i < end; i++) {
if (getDef(i).getModel().visible) {
VecUtils::indAssignVec(i, off);
// Add TallGrass offsets
// TODO: Make this acknowlege MeshMods
vis = off;
// if (chunk->getBlock(i) >= 6 && chunk->fromIndex(i) <= 10) {
// vis += glm::vec3((((double)rand() / RAND_MAX) - 0.5f) / 3.f, 0, (((double)rand() / RAND_MAX) - 0.5f) / 3.f);
// }
if (chunk.getBlock(i) >= 6 && chunk.getBlock(i) <= 10) {
vis += glm::vec3((((double)rand() / RAND_MAX) - 0.5f) / 3.f, 0, (((double)rand() / RAND_MAX) - 0.5f) / 3.f);
}
//TODO: Better way to do this, surely
LocalBlockModel& model = getDef(i).getModel();
if (model.visible) {
LocalBlockModel& model = blockData(i, *chunk, atlas).getModel();
check = off; check.x -= 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[XNEG]);
check.x = off.x - 1; check.y = off.y; check.z = off.z;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[XNEG]);
check = off; check.x += 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[XPOS]);
check.x = off.x + 1; check.y = off.y; check.z = off.z;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[XPOS]);
check = off; check.y -= 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[YNEG]);
check.x = off.x; check.y = off.y - 1; check.z = off.z;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[YNEG]);
check = off; check.y += 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[YPOS]);
check.x = off.x; check.y = off.y + 1; check.z = off.z;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[YPOS]);
check = off; check.z -= 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[ZNEG]);
check.x = off.x; check.y = off.y; check.z = off.z - 1;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[ZNEG]);
check = off; check.z += 1;
if (!faceOcculudedAt(check, adj)) addFaces(vis, model.parts[ZPOS]);
check.x = off.x; check.y = off.y; check.z = off.z + 1;
if (!faceOcculudedAt(check, *chunk, atlas, adjacents))
addFaces(vis, vertices, indices, model.parts[ZPOS]);
addFaces(vis, vertices, indices, model.parts[NO_CULL]);
addFaces(vis, model.parts[NO_CULL]);
}
}
}
@ -91,11 +63,37 @@ void MeshGenerator::build(const std::shared_ptr<BlockChunk> &chunk, LocalBlockAt
indices.shrink_to_fit();
}
void MeshGenerator::addFaces(glm::vec3 &offset, vector<Vertex> &vertices, vector<unsigned int> &indices, vector<LocalMeshPart> &meshParts) {
LocalBlockDef& MeshGenerator::getDef(int ind) {
return atlas.fromIndex(chunk.getBlock(ind));
}
LocalBlockDef& MeshGenerator::getDef(const glm::vec3 &pos) {
return atlas.fromIndex(chunk.getBlock(pos));
}
bool MeshGenerator::faceOcculudedAt(const glm::vec3 &pos, const std::vector<bool> &adj) {
auto off = TransPos::CHUNK_SIZE*TransPos::CHUNK_SIZE; //CHUNK_SIZE ^ 2
if (pos.x < 0 || pos.x >= TransPos::CHUNK_SIZE || pos.y < 0 || pos.y >= TransPos::CHUNK_SIZE || pos.z < 0 || pos.z >= TransPos::CHUNK_SIZE) {
if (pos.x == -1) return adj[off + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.x == TransPos::CHUNK_SIZE) return adj[(int)pos.y * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.y == -1) return adj[off*3 + (int)pos.x * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.y == TransPos::CHUNK_SIZE) return adj[off*2 + (int)pos.x * TransPos::CHUNK_SIZE + (int)pos.z];
if (pos.z == -1) return adj[off*5 + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.x];
if (pos.z == TransPos::CHUNK_SIZE) return adj[off*4 + (int)pos.y * TransPos::CHUNK_SIZE + (int)pos.x];
return false;
}
return getDef(pos).isCulling();
}
void MeshGenerator::addFaces(const glm::vec3 &positon, const vector<LocalMeshPart> &meshParts) {
for (const LocalMeshPart& mp : meshParts) {
for (const MeshVertex &vertex : mp.vertices) {
vertices.push_back({{vertex.pos + offset}, 1, {vertex.tex.x, vertex.tex.y, 0, 0}, vertex.nml});
vertices.push_back({{vertex.pos + positon}, 1, {vertex.tex.x, vertex.tex.y, 0, 0}, vertex.nml});
}
for (unsigned int index : mp.indices) {

View File

@ -24,13 +24,20 @@
class MeshGenerator {
public:
MeshGenerator();
void build(const std::shared_ptr<BlockChunk> &chunk, LocalBlockAtlas &atlas, std::vector<bool> &adjacents,
std::vector<Vertex> &vertices, std::vector<unsigned int> &indices);
MeshGenerator(std::vector<Vertex> &vertices, std::vector<unsigned int> &indices,
LocalBlockAtlas& atlas, const BlockChunk& chunk, const std::vector<bool>& adj);
private:
unsigned int indOffset;
bool faceOcculudedAt(const glm::vec3 &pos, const std::vector<bool> &adj);
void addFaces(const glm::vec3 &positon, const vector<LocalMeshPart> &meshParts);
LocalBlockDef& getDef(int ind);
LocalBlockDef& getDef(const glm::vec3 &pos);
unsigned int indOffset = 0;
const BlockChunk& chunk;
LocalBlockAtlas& atlas;
std::vector<Vertex>& vertices;
std::vector<unsigned int>& indices;
void addFaces(glm::vec3 &offset, vector<Vertex> &vertices, vector<unsigned int> &indices, vector<LocalMeshPart> &meshParts);
};
#endif //GLPROJECT_MESHGENERATOR_H

View File

@ -13,10 +13,8 @@
class ServerPlayer {
public:
// const static int ACTIVE_RANGE_H = 30;
// const static int ACTIVE_RANGE_V = 12;
const static int ACTIVE_RANGE_H = 12;
const static int ACTIVE_RANGE_V = 6;
const static int ACTIVE_RANGE_H = 16;
const static int ACTIVE_RANGE_V = 8;
explicit ServerPlayer(ServerPeer* peer, std::string uuid, std::string username);

View File

@ -58,7 +58,8 @@ void Dimension::update() {
auto diffVec = pos - *playerPos;
float distance = max(abs(diffVec.x), max(abs(diffVec.y), abs(diffVec.z)));
if (distance > 16) {
//TODO: Don't hard code this number
if (distance > 30) {
if (chunk->meshChunk != nullptr) {
meshChunks.erase(chunk->meshChunkIter);
delete chunk->meshChunk;

View File

@ -33,13 +33,13 @@ BlockChunk::BlockChunk(std::vector<int> blocks, glm::vec3 pos) :
renderedEmpty = true;
}
int BlockChunk::getBlock(const glm::vec3& pos) {
int BlockChunk::getBlock(const glm::vec3& pos) const {
auto ind = VecUtils::vecToInd(pos);
if (ind < 0 || ind >= (int)pow(TransPos::CHUNK_SIZE, 3)) return -1;
return blocks[ind];
}
int BlockChunk::getBlock(int ind) {
int BlockChunk::getBlock(int ind) const {
if (ind < 0 || ind >= (int)pow(TransPos::CHUNK_SIZE, 3)) return -1;
return blocks[ind];
}

View File

@ -24,8 +24,8 @@ public:
bool shouldRender();
bool allAdjacentsExist();
int getBlock(int ind);
int getBlock(const glm::vec3& pos);
int getBlock(int ind) const;
int getBlock(const glm::vec3& pos) const;
bool setBlock(const glm::vec3& pos, int ind);