add variants (WIP)

This commit is contained in:
MihailRis
2025-07-13 21:28:57 +03:00
parent 01181b6403
commit 5478d121f0
16 changed files with 275 additions and 177 deletions
+52 -34
View File
@@ -292,21 +292,22 @@ static bool is_aligned(const glm::vec3& v, float e = 1e-6f) {
}
void BlocksRenderer::blockCustomModel(
const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao
const glm::ivec3& icoord, const Block& block, blockstate states, bool lights, bool ao
) {
const auto& variant = block.getVariant(states.userbits);
glm::vec3 X(1, 0, 0);
glm::vec3 Y(0, 1, 0);
glm::vec3 Z(0, 0, 1);
glm::vec3 coord(icoord);
if (block->rotatable) {
auto& rotations = block->rotations;
CoordSystem orient = rotations.variants[rotation];
if (block.rotatable) {
auto& rotations = block.rotations;
CoordSystem orient = rotations.variants[states.rotation];
X = orient.axes[0];
Y = orient.axes[1];
Z = orient.axes[2];
}
const auto& model = cache.getModel(block->rt.id);
const auto& model = cache.getModel(block.rt.id);
for (const auto& mesh : model.meshes) {
if (vertexCount + mesh.vertices.size() >= capacity) {
overflow = true;
@@ -328,7 +329,7 @@ void BlocksRenderer::blockCustomModel(
0.5f;
vp = vp.x * X + vp.y * Y + vp.z * Z;
if (!isOpen(glm::floor(coord + vp + 0.5f + n * 1e-3f), *block) && is_aligned(n)) {
if (!isOpen(glm::floor(coord + vp + 0.5f + n * 1e-3f), block, variant) && is_aligned(n)) {
continue;
}
@@ -369,6 +370,7 @@ void BlocksRenderer::blockCube(
bool lights,
bool ao
) {
const auto& variant = block.getVariant(states.userbits);
glm::ivec3 X(1, 0, 0);
glm::ivec3 Y(0, 1, 0);
glm::ivec3 Z(0, 0, 1);
@@ -382,41 +384,41 @@ void BlocksRenderer::blockCube(
}
if (ao) {
if (isOpen(coord + Z, block)) {
if (isOpen(coord + Z, block, variant)) {
faceAO(coord, X, Y, Z, texfaces[5], lights);
}
if (isOpen(coord - Z, block)) {
if (isOpen(coord - Z, block, variant)) {
faceAO(coord, -X, Y, -Z, texfaces[4], lights);
}
if (isOpen(coord + Y, block)) {
if (isOpen(coord + Y, block, variant)) {
faceAO(coord, X, -Z, Y, texfaces[3], lights);
}
if (isOpen(coord - Y, block)) {
if (isOpen(coord - Y, block, variant)) {
faceAO(coord, X, Z, -Y, texfaces[2], lights);
}
if (isOpen(coord + X, block)) {
if (isOpen(coord + X, block, variant)) {
faceAO(coord, -Z, Y, X, texfaces[1], lights);
}
if (isOpen(coord - X, block)) {
if (isOpen(coord - X, block, variant)) {
faceAO(coord, Z, Y, -X, texfaces[0], lights);
}
} else {
if (isOpen(coord + Z, block)) {
if (isOpen(coord + Z, block, variant)) {
face(coord, X, Y, Z, texfaces[5], pickLight(coord + Z), lights);
}
if (isOpen(coord - Z, block)) {
if (isOpen(coord - Z, block, variant)) {
face(coord, -X, Y, -Z, texfaces[4], pickLight(coord - Z), lights);
}
if (isOpen(coord + Y, block)) {
if (isOpen(coord + Y, block, variant)) {
face(coord, X, -Z, Y, texfaces[3], pickLight(coord + Y), lights);
}
if (isOpen(coord - Y, block)) {
if (isOpen(coord - Y, block, variant)) {
face(coord, X, Z, -Y, texfaces[2], pickLight(coord - Y), lights);
}
if (isOpen(coord + X, block)) {
if (isOpen(coord + X, block, variant)) {
face(coord, -Z, Y, X, texfaces[1], pickLight(coord + X), lights);
}
if (isOpen(coord - X, block)) {
if (isOpen(coord - X, block, variant)) {
face(coord, Z, Y, -X, texfaces[0], pickLight(coord - X), lights);
}
}
@@ -486,21 +488,26 @@ void BlocksRenderer::render(
blockid_t id = vox.id;
blockstate state = vox.state;
const auto& def = *blockDefsCache[id];
if (id == 0 || def.drawGroup != drawGroup || state.segment) {
const auto& variant = def.getVariant(state.userbits);
uint8_t variantId = state.userbits;
if (id == 0 || variant.drawGroup != drawGroup || state.segment) {
continue;
}
if (def.translucent) {
continue;
}
const UVRegion texfaces[6] {
cache.getRegion(id, 0), cache.getRegion(id, 1),
cache.getRegion(id, 2), cache.getRegion(id, 3),
cache.getRegion(id, 4), cache.getRegion(id, 5)
cache.getRegion(id, variantId, 0),
cache.getRegion(id, variantId, 1),
cache.getRegion(id, variantId, 2),
cache.getRegion(id, variantId, 3),
cache.getRegion(id, variantId, 4),
cache.getRegion(id, variantId, 5)
};
int x = i % CHUNK_W;
int y = i / (CHUNK_D * CHUNK_W);
int z = (i / CHUNK_D) % CHUNK_W;
switch (def.model.type) {
switch (def.getModel(state.userbits).type) {
case BlockModelType::BLOCK:
blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless,
def.ambientOcclusion);
@@ -516,8 +523,13 @@ void BlocksRenderer::render(
break;
}
case BlockModelType::CUSTOM: {
blockCustomModel({x, y, z}, &def, vox.state.rotation,
!def.shadeless, def.ambientOcclusion);
blockCustomModel(
{x, y, z},
def,
vox.state,
!def.shadeless,
def.ambientOcclusion
);
break;
}
default:
@@ -549,21 +561,26 @@ SortingMeshData BlocksRenderer::renderTranslucent(
blockid_t id = vox.id;
blockstate state = vox.state;
const auto& def = *blockDefsCache[id];
if (id == 0 || def.drawGroup != drawGroup || state.segment) {
uint8_t variantId = state.userbits;
const auto& variant = def.getVariant(variantId);
if (id == 0 || variant.drawGroup != drawGroup || state.segment) {
continue;
}
if (!def.translucent) {
continue;
}
const UVRegion texfaces[6] {
cache.getRegion(id, 0), cache.getRegion(id, 1),
cache.getRegion(id, 2), cache.getRegion(id, 3),
cache.getRegion(id, 4), cache.getRegion(id, 5)
cache.getRegion(id, variantId, 0),
cache.getRegion(id, variantId, 1),
cache.getRegion(id, variantId, 2),
cache.getRegion(id, variantId, 3),
cache.getRegion(id, variantId, 4),
cache.getRegion(id, variantId, 5)
};
int x = i % CHUNK_W;
int y = i / (CHUNK_D * CHUNK_W);
int z = (i / CHUNK_D) % CHUNK_W;
switch (def.model.type) {
switch (def.getModel(state.userbits).type) {
case BlockModelType::BLOCK:
blockCube({x, y, z}, texfaces, def, vox.state, !def.shadeless,
def.ambientOcclusion);
@@ -579,7 +596,7 @@ SortingMeshData BlocksRenderer::renderTranslucent(
break;
}
case BlockModelType::CUSTOM: {
blockCustomModel({x, y, z}, &def, vox.state.rotation,
blockCustomModel({x, y, z}, def, vox.state,
!def.shadeless, def.ambientOcclusion);
break;
}
@@ -670,11 +687,12 @@ void BlocksRenderer::build(const Chunk* chunk, const Chunks* chunks) {
const voxel& vox = voxels[i];
blockid_t id = vox.id;
const auto& def = *blockDefsCache[id];
const auto& variant = def.getVariant(vox.state.userbits);
if (beginEnds[def.drawGroup][0] == 0) {
beginEnds[def.drawGroup][0] = i+1;
if (beginEnds[variant.drawGroup][0] == 0) {
beginEnds[variant.drawGroup][0] = i+1;
}
beginEnds[def.drawGroup][1] = i;
beginEnds[variant.drawGroup][1] = i;
}
cancelled = false;