-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathChunkMesher.h
131 lines (99 loc) · 4.33 KB
/
ChunkMesher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#pragma once
#include "Vertex.h"
#include "BlockData.h"
#include "Chunk.h"
#include "ChunkMesh.h"
#include "ChunkMeshTask.h"
class BlockPack;
class BlockTextureLayer;
class ChunkMeshData;
struct BlockTexture;
struct PlanetHeightData;
struct FloraQuadData;
// Sizes For A Padded Chunk
const int PADDED_CHUNK_WIDTH = (CHUNK_WIDTH + 2);
const int PADDED_CHUNK_LAYER = (PADDED_CHUNK_WIDTH * PADDED_CHUNK_WIDTH);
const int PADDED_CHUNK_SIZE = (PADDED_CHUNK_LAYER * PADDED_CHUNK_WIDTH);
// !!! IMPORTANT !!!
// TODO(BEN): Make a class for complex Chunk Mesh Splicing. Store plenty of metadata in RAM about the regions in each mesh and just do a CPU copy to align them all and mix them around. Then meshes can be remeshed, rendered, recombined, at will.
// Requirements: Each chunk is only meshed when it needs to, as they do now.
// Rather than remeshing when combining and splitting, we just download the data from the GPU (or cache it compressed in RAM on 64 bit systems?)
// Copy it around, and re-upload.
// glBufferSubData and maybe even re-use buffers to minimize bandwidth???
// each worker thread gets one of these
// This class is too big to statically allocate
class ChunkMesher {
public:
ChunkMesher():blocks(nullptr), m_chunkMeshData(nullptr){}
void init(const BlockPack* blocks);
// Easily creates chunk mesh synchronously.
CALLER_DELETE ChunkMesh* easyCreateChunkMesh(const Chunk* chunk, MeshTaskType type) {
prepareData(chunk);
ChunkMesh* mesh = new ChunkMesh;
mesh->position = chunk->getVoxelPosition().pos;
uploadMeshData(*mesh, createChunkMeshData(type));
return mesh;
}
// Call one of these before createChunkMesh
void prepareData(const Chunk* chunk);
// For use with threadpool
void prepareDataAsync(ChunkHandle& chunk, ChunkHandle neighbors[NUM_NEIGHBOR_HANDLES]);
// TODO(Ben): Unique ptr?
// Must call prepareData or prepareDataAsync first
CALLER_DELETE ChunkMeshData* createChunkMeshData(MeshTaskType type);
// Returns true if the mesh is renderable
static bool uploadMeshData(ChunkMesh& mesh, ChunkMeshData* meshData);
// Frees buffers AND deletes memory. mesh Pointer is invalid after calling.
static void freeChunkMesh(CALLEE_DELETE ChunkMesh* mesh);
void freeBuffers();
int bx, by, bz; // Block iterators
int blockIndex;
ui16 blockID;
const Block* block;
const PlanetHeightData* heightData;
ui8v3 voxelPosOffset;
// Heightmap data
PlanetHeightData heightDataBuffer[CHUNK_LAYER];
// Voxel data arrays
ui16 blockData[PADDED_CHUNK_SIZE];
ui16 tertiaryData[PADDED_CHUNK_SIZE];
const BlockPack* blocks;
VoxelPosition3D chunkVoxelPos;
private:
void addBlock();
void addQuad(int face, int rightAxis, int frontAxis, int leftOffset, int backOffset, int rightStretchIndex, const ui8v2& texOffset, f32 ambientOcclusion[]);
void computeAmbientOcclusion(int upOffset, int frontOffset, int rightOffset, f32 ambientOcclusion[]);
void addFlora();
void addFloraQuad(const ui8v3* positions, FloraQuadData& data);
int tryMergeQuad(VoxelQuad* quad, std::vector<VoxelQuad>& quads, int face, int rightAxis, int frontAxis, int leftOffset, int backOffset, int rightStretchIndex, const ui8v2& texOffset);
void addLiquid();
int getLiquidLevel(int blockIndex, const Block& block);
bool shouldRenderFace(int offset);
int getOcclusion(const Block& block);
ui8 getBlendMode(const BlendType& blendType);
static void buildTransparentVao(ChunkMesh& cm);
static void buildCutoutVao(ChunkMesh& cm);
static void buildVao(ChunkMesh& cm);
static void buildWaterVao(ChunkMesh& cm);
ui16 m_quadIndices[PADDED_CHUNK_SIZE][6];
ui16 m_wvec[CHUNK_SIZE];
std::vector<BlockVertex> m_finalVerts[6];
std::vector<VoxelQuad> m_floraQuads;
std::vector<VoxelQuad> m_quads[6];
ui32 m_numQuads;
BlockTextureMethodParams m_textureMethodParams[6][2];
// TODO(Ben): Change this up a bit
std::vector<LiquidVertex> _waterVboVerts;
ChunkMeshData* m_chunkMeshData;
int m_highestY;
int m_lowestY;
int m_highestX;
int m_lowestX;
int m_highestZ;
int m_lowestZ;
const PlanetHeightData* m_chunkHeightData;
static PlanetHeightData defaultChunkHeightData[CHUNK_LAYER];
int wSize;
// ui32 m_finalQuads[7000];
BlockVertex m_topVerts[4100];
};