7uint8_t GreedyMesher::at(
const uint8_t *
v,
int x,
int y,
int z) {
12uint8_t GreedyMesher::neighborAt(
const uint8_t *voxels,
ChunkSampler sampler,
void *userData,
13 int chunkX,
int chunkY,
int chunkZ,
int nx,
int ny,
int nz) {
20uint8_t GreedyMesher::outsideVoxel(
const uint8_t *voxels,
ChunkSampler sampler,
void *userData,
21 int chunkX,
int chunkY,
int chunkZ,
FaceDir dir,
int slice,
23 int x = 0,
y = 0,
z = 0;
31 default:
x = gu;
y = gv;
z = slice - 1;
break;
33 return neighborAt(voxels,
sampler, userData, chunkX, chunkY, chunkZ,
x,
y,
z);
37 int chunkX,
int chunkY,
int chunkZ,
FaceDir dir,
int slice,
int gu,
39 const uint8_t e1 = outsideVoxel(voxels,
sampler, userData, chunkX, chunkY, chunkZ,
dir, slice,
41 const uint8_t e2 = outsideVoxel(voxels,
sampler, userData, chunkX, chunkY, chunkZ,
dir, slice,
43 const uint8_t
d = outsideVoxel(voxels,
sampler, userData, chunkX, chunkY, chunkZ,
dir, slice,
45 if (isSolid(e1) && isSolid(e2))
return 0;
46 return uint8_t(3 - (isSolid(e1) ? 1 : 0) - (isSolid(e2) ? 1 : 0) - (isSolid(
d) ? 1 : 0));
49uint32_t GreedyMesher::rectAOWord(
const uint8_t *voxels,
ChunkSampler sampler,
void *userData,
50 int chunkX,
int chunkY,
int chunkZ,
FaceDir dir,
int slice,
51 int x,
int y,
int z,
int w,
int h) {
56 gu[0] =
z; gv[0] =
y; gu[1] =
z +
w; gv[1] =
y;
57 gu[2] =
z +
w; gv[2] =
y +
h; gu[3] =
z; gv[3] =
y +
h;
60 gu[0] =
z +
w; gv[0] =
y; gu[1] =
z; gv[1] =
y;
61 gu[2] =
z; gv[2] =
y +
h; gu[3] =
z +
w; gv[3] =
y +
h;
64 gu[0] =
x; gv[0] =
z; gu[1] =
x +
w; gv[1] =
z;
65 gu[2] =
x +
w; gv[2] =
z +
h; gu[3] =
x; gv[3] =
z +
h;
68 gu[0] =
x; gv[0] =
z +
h; gu[1] =
x +
w; gv[1] =
z +
h;
69 gu[2] =
x +
w; gv[2] =
z; gu[3] =
x; gv[3] =
z;
72 gu[0] =
x +
w; gv[0] =
y; gu[1] =
x; gv[1] =
y;
73 gu[2] =
x; gv[2] =
y +
h; gu[3] =
x +
w; gv[3] =
y +
h;
77 gu[0] =
x; gv[0] =
y; gu[1] =
x +
w; gv[1] =
y;
78 gu[2] =
x +
w; gv[2] =
y +
h; gu[3] =
x; gv[3] =
y +
h;
82 for (
int i = 0; i < 4; ++i) {
84 uint32_t(vertexAO(voxels,
sampler, userData, chunkX, chunkY, chunkZ,
dir, slice,
86 word |= ao << (2 * i);
92 std::vector<PackedRect> &out, std::vector<uint32_t> *aoOut) {
101 const int tex =
key & 0xFF;
102 const uint32_t cellAO = uint32_t(
key >> 8) & 0xFFu;
103 const uint32_t ao0 = cellAO & 3u;
104 const bool uniformAO = ((cellAO >> 2) & 3u) == ao0 &&
105 ((cellAO >> 4) & 3u) == ao0 &&
106 ((cellAO >> 6) & 3u) == ao0;
118 for (
int k = 0; k <
w; ++k) {
119 if (!uniformAO ||
mask[
v +
h][
u + k] !=
key) {
127 for (
int dv = 0; dv <
h; ++dv)
128 for (
int du = 0; du <
w; ++du)
mask[
v + dv][
u + du] = -1;
130 int x = 0,
y = 0,
z = 0;
160 if (aoOut) aoOut->push_back(cellAO);
168 void *samplerUserData,
int chunkX,
int chunkY,
int chunkZ,
169 std::vector<uint32_t> *aoOut) {
178 int x = 0,
y = 0,
z = 0;
179 int nx = 0,
ny = 0,
nz = 0;
246 const uint8_t
id =
at(voxels,
x,
y,
z);
247 if (!isSolid(
id))
continue;
248 if (isSolid(neighborAt(voxels,
sampler, samplerUserData, chunkX, chunkY, chunkZ,
252 const uint32_t ao = rectAOWord(voxels,
sampler, samplerUserData, chunkX, chunkY,
253 chunkZ,
dir,
s,
x,
y,
z, 1, 1);
254 mask[
v][
u] = tex | int(ao << 8);
264 void *samplerUserData,
int chunkX,
int chunkY,
int chunkZ,
265 std::vector<uint32_t> aoOut[6]) {
268 if (aoOut) aoOut[i].clear();
270 chunkZ, aoOut ? &aoOut[i] :
nullptr);
vk::UniqueSampler sampler
EVENGINE_API_DOMAINS public API.
static void meshFace(const uint8_t *voxels, FaceDir dir, std::vector< PackedRect > &out, const CubeTypeRegistry &types=CubeTypeRegistry::empty(), ChunkSampler sampler=nullptr, void *samplerUserData=nullptr, int chunkX=0, int chunkY=0, int chunkZ=0, std::vector< uint32_t > *aoOut=nullptr)
Mesh a single face direction into out (appended; caller may clear).
static void meshChunk(const uint8_t *voxels, std::vector< PackedRect > outFaces[6], const CubeTypeRegistry &types=CubeTypeRegistry::empty(), ChunkSampler sampler=nullptr, void *samplerUserData=nullptr, int chunkX=0, int chunkY=0, int chunkZ=0, std::vector< uint32_t > aoOut[6]=nullptr)
Mesh all six faces. Clears and fills outFaces[6].
方块类型定义:名字、各面图集纹理、方向性、组合声明。 方向性方块在注册时按 orientation 绕 Y 轴展开成多个"具体类型"变体, 每个变体持有旋转后的各面纹理;渲染端只消费纹理 id,不接触 ...
constexpr int kChunkSize
Chunk edge length in voxels (fixed).
uint8_t resolveFaceTex(const CubeTypeRegistry &types, uint8_t id, FaceDir dir)
求某个体素在某面方向上的实际图集纹理 id。 未注册的 id 退化为“所有面 = 原 id”(向后兼容:体素值即纹理 id)。
constexpr int faceDirCount()
Face dir count.
uint8_t(*)(void *userData, int chunkX, int chunkY, int chunkZ, int localX, int localY, int localZ) ChunkSampler
Optional out-of-chunk neighbor sampler for seam culling. Receives chunk coordinates plus the (possibl...
FaceDir
Six axis-aligned face directions. Each chunk keeps a separate instance buffer per direction so camera...
static PackedRect pack(int x, int y, int z, int width, int height, int tex)
Pack.