mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-12 05:53:51 -04:00
Handle backfaces when placing blocks.
This commit is contained in:
parent
876fb77b1c
commit
345e36c030
@ -4,6 +4,7 @@ in vec3 mvVertexPos;
|
|||||||
flat in int blockType;
|
flat in int blockType;
|
||||||
flat in int faceNormal;
|
flat in int faceNormal;
|
||||||
flat in int modelIndex;
|
flat in int modelIndex;
|
||||||
|
flat in int isBackFace;
|
||||||
// For raymarching:
|
// For raymarching:
|
||||||
in vec3 startPosition;
|
in vec3 startPosition;
|
||||||
in vec3 direction;
|
in vec3 direction;
|
||||||
|
106
src/chunk.zig
106
src/chunk.zig
@ -594,23 +594,6 @@ pub const meshing = struct {
|
|||||||
}
|
}
|
||||||
@panic("Couldn't find the face to remove. This case is not handled.");
|
@panic("Couldn't find the face to remove. This case is not handled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn changeFace(self: *PrimitiveMesh, oldFaceData: FaceData, newFaceData: FaceData, fromNeighborChunk: ?u3) void {
|
|
||||||
var searchRange: []FaceData = undefined;
|
|
||||||
if(fromNeighborChunk) |neighbor| {
|
|
||||||
searchRange = self.faces.items[self.neighborStart[neighbor]..self.neighborStart[neighbor+1]];
|
|
||||||
} else {
|
|
||||||
searchRange = self.faces.items[0..self.coreCount];
|
|
||||||
}
|
|
||||||
var i: u32 = 0;
|
|
||||||
while(i < searchRange.len): (i += 2) {
|
|
||||||
if(std.meta.eql(self.faces.items[i], oldFaceData)) {
|
|
||||||
searchRange[i] = newFaceData;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@panic("Couldn't find the face to replace.");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ChunkMesh = struct {
|
pub const ChunkMesh = struct {
|
||||||
@ -787,25 +770,6 @@ pub const meshing = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn changeFace(self: *ChunkMesh, oldFaceData: FaceData, newFaceData: FaceData, fromNeighborChunk: ?u3, oldTransparent: bool, newTransparent: bool) !void {
|
|
||||||
std.debug.assert(!self.mutex.tryLock()); // The mutex should be locked when calling this function.
|
|
||||||
if(oldTransparent) {
|
|
||||||
if(newTransparent) {
|
|
||||||
self.transparentMesh.changeFace(oldFaceData, newFaceData, fromNeighborChunk);
|
|
||||||
} else {
|
|
||||||
self.transparentMesh.removeFace(oldFaceData, fromNeighborChunk);
|
|
||||||
try self.opaqueMesh.addFace(newFaceData, fromNeighborChunk);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(newTransparent) {
|
|
||||||
self.opaqueMesh.removeFace(oldFaceData, fromNeighborChunk);
|
|
||||||
try self.transparentMesh.addFace(newFaceData, fromNeighborChunk);
|
|
||||||
} else {
|
|
||||||
self.opaqueMesh.changeFace(oldFaceData, newFaceData, fromNeighborChunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn updateBlock(self: *ChunkMesh, _x: i32, _y: i32, _z: i32, newBlock: Block) !void {
|
pub fn updateBlock(self: *ChunkMesh, _x: i32, _y: i32, _z: i32, newBlock: Block) !void {
|
||||||
const x = _x & chunkMask;
|
const x = _x & chunkMask;
|
||||||
const y = _y & chunkMask;
|
const y = _y & chunkMask;
|
||||||
@ -829,49 +793,75 @@ pub const meshing = struct {
|
|||||||
ny &= chunkMask;
|
ny &= chunkMask;
|
||||||
nz &= chunkMask;
|
nz &= chunkMask;
|
||||||
const neighborBlock = neighborMesh.chunk.load(.Monotonic).?.blocks[getIndex(nx, ny, nz)];
|
const neighborBlock = neighborMesh.chunk.load(.Monotonic).?.blocks[getIndex(nx, ny, nz)];
|
||||||
{ // TODO: Update blocks with transparent backfaces correctly.
|
{ // TODO: Batch all the changes and apply them in one go for more efficiency.
|
||||||
{ // The face of the changed block
|
{ // The face of the changed block
|
||||||
const newVisibility = canBeSeenThroughOtherBlock(newBlock, neighborBlock, neighbor);
|
const newVisibility = canBeSeenThroughOtherBlock(newBlock, neighborBlock, neighbor);
|
||||||
const newFaceData = constructFaceData(newBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), false);
|
const oldVisibility = canBeSeenThroughOtherBlock(oldBlock, neighborBlock, neighbor);
|
||||||
const oldFaceData = constructFaceData(oldBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), false);
|
if(oldVisibility) { // Removing the face
|
||||||
if(canBeSeenThroughOtherBlock(oldBlock, neighborBlock, neighbor) != newVisibility) {
|
const faceData = constructFaceData(oldBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), false);
|
||||||
if(newVisibility) { // Adding the face
|
if(neighborMesh == self) {
|
||||||
|
self.removeFace(faceData, null, oldBlock.transparent());
|
||||||
|
} else {
|
||||||
|
neighborMesh.removeFace(faceData, neighbor ^ 1, oldBlock.transparent());
|
||||||
|
}
|
||||||
|
if(oldBlock.hasBackFace()) {
|
||||||
|
const backFaceData = constructFaceData(oldBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), true);
|
||||||
if(neighborMesh == self) {
|
if(neighborMesh == self) {
|
||||||
try self.addFace(newFaceData, null, newBlock.transparent());
|
self.removeFace(backFaceData, null, true);
|
||||||
} else {
|
} else {
|
||||||
try neighborMesh.addFace(newFaceData, neighbor ^ 1, newBlock.transparent());
|
self.removeFace(backFaceData, neighbor, true);
|
||||||
}
|
|
||||||
} else { // Removing the face
|
|
||||||
if(neighborMesh == self) {
|
|
||||||
self.removeFace(oldFaceData, null, oldBlock.transparent());
|
|
||||||
} else {
|
|
||||||
neighborMesh.removeFace(oldFaceData, neighbor ^ 1, oldBlock.transparent());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(newVisibility) { // Changing the face
|
}
|
||||||
|
if(newVisibility) { // Adding the face
|
||||||
|
const faceData = constructFaceData(newBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), false);
|
||||||
if(neighborMesh == self) {
|
if(neighborMesh == self) {
|
||||||
try self.changeFace(oldFaceData, newFaceData, null, oldBlock.transparent(), newBlock.transparent());
|
try self.addFace(faceData, null, newBlock.transparent());
|
||||||
} else {
|
} else {
|
||||||
try neighborMesh.changeFace(oldFaceData, newFaceData, neighbor ^ 1, oldBlock.transparent(), newBlock.transparent());
|
try neighborMesh.addFace(faceData, neighbor ^ 1, newBlock.transparent());
|
||||||
|
}
|
||||||
|
if(newBlock.hasBackFace()) {
|
||||||
|
const backFaceData = constructFaceData(newBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), true);
|
||||||
|
if(neighborMesh == self) {
|
||||||
|
try self.addFace(backFaceData, null, true);
|
||||||
|
} else {
|
||||||
|
try self.addFace(backFaceData, neighbor, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ // The face of the neighbor block
|
{ // The face of the neighbor block
|
||||||
const newVisibility = canBeSeenThroughOtherBlock(neighborBlock, newBlock, neighbor ^ 1);
|
const newVisibility = canBeSeenThroughOtherBlock(neighborBlock, newBlock, neighbor ^ 1);
|
||||||
const newFaceData = constructFaceData(neighborBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), false);
|
|
||||||
const oldFaceData = constructFaceData(neighborBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), false);
|
|
||||||
if(canBeSeenThroughOtherBlock(neighborBlock, oldBlock, neighbor ^ 1) != newVisibility) {
|
if(canBeSeenThroughOtherBlock(neighborBlock, oldBlock, neighbor ^ 1) != newVisibility) {
|
||||||
if(newVisibility) { // Adding the face
|
if(newVisibility) { // Adding the face
|
||||||
|
const faceData = constructFaceData(neighborBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), false);
|
||||||
if(neighborMesh == self) {
|
if(neighborMesh == self) {
|
||||||
try self.addFace(newFaceData, null, neighborBlock.transparent());
|
try self.addFace(faceData, null, neighborBlock.transparent());
|
||||||
} else {
|
} else {
|
||||||
try self.addFace(newFaceData, neighbor, neighborBlock.transparent());
|
try self.addFace(faceData, neighbor, neighborBlock.transparent());
|
||||||
|
}
|
||||||
|
if(neighborBlock.hasBackFace()) {
|
||||||
|
const backFaceData = constructFaceData(neighborBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), true);
|
||||||
|
if(neighborMesh == self) {
|
||||||
|
try self.addFace(backFaceData, null, true);
|
||||||
|
} else {
|
||||||
|
try neighborMesh.addFace(backFaceData, neighbor ^ 1, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { // Removing the face
|
} else { // Removing the face
|
||||||
|
const faceData = constructFaceData(neighborBlock, neighbor ^ 1, @intCast(x), @intCast(y), @intCast(z), false);
|
||||||
if(neighborMesh == self) {
|
if(neighborMesh == self) {
|
||||||
self.removeFace(oldFaceData, null, neighborBlock.transparent());
|
self.removeFace(faceData, null, neighborBlock.transparent());
|
||||||
} else {
|
} else {
|
||||||
self.removeFace(oldFaceData, neighbor, neighborBlock.transparent());
|
self.removeFace(faceData, neighbor, neighborBlock.transparent());
|
||||||
|
}
|
||||||
|
if(neighborBlock.hasBackFace()) {
|
||||||
|
const backFaceData = constructFaceData(neighborBlock, neighbor, @intCast(nx), @intCast(ny), @intCast(nz), true);
|
||||||
|
if(neighborMesh == self) {
|
||||||
|
self.removeFace(backFaceData, null, true);
|
||||||
|
} else {
|
||||||
|
neighborMesh.removeFace(backFaceData, neighbor ^ 1, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user