mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Add a carpet rotation mode for placing carpets on walls and ceiling.
fixes #775
This commit is contained in:
parent
30669f5284
commit
f53811ae95
129
src/rotation.zig
129
src/rotation.zig
@ -663,6 +663,135 @@ pub const RotationModes = struct {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
pub const Carpet = struct { // MARK: Carpet
|
||||
pub const id: []const u8 = "carpet";
|
||||
pub const dependsOnNeighbors = true;
|
||||
var rotatedModels: std.StringHashMap(u16) = undefined;
|
||||
const CarpetData = packed struct(u6) {
|
||||
negX: bool,
|
||||
posX: bool,
|
||||
negY: bool,
|
||||
posY: bool,
|
||||
negZ: bool,
|
||||
posZ: bool,
|
||||
};
|
||||
|
||||
fn init() void {
|
||||
rotatedModels = .init(main.globalAllocator.allocator);
|
||||
}
|
||||
|
||||
fn deinit() void {
|
||||
rotatedModels.deinit();
|
||||
}
|
||||
|
||||
pub fn createBlockModel(modelId: []const u8) u16 {
|
||||
if(rotatedModels.get(modelId)) |modelIndex| return modelIndex;
|
||||
|
||||
const baseModelIndex = main.models.getModelIndex(modelId);
|
||||
const baseModel = main.models.models.items[baseModelIndex];
|
||||
// Rotate the model:
|
||||
var negXModel: u16 = undefined;
|
||||
var posXModel: u16 = undefined;
|
||||
var negYModel: u16 = undefined;
|
||||
var posYModel: u16 = undefined;
|
||||
var negZModel: u16 = undefined;
|
||||
var posZModel: u16 = undefined;
|
||||
for(1..64) |i| {
|
||||
const carpetData: CarpetData = @bitCast(@as(u6, @intCast(i)));
|
||||
if(i & i-1 == 0) {
|
||||
if(carpetData.negX) negXModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.rotationY(std.math.pi/2.0)});
|
||||
if(carpetData.posX) posXModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.rotationY(-std.math.pi/2.0)});
|
||||
if(carpetData.negY) negYModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.rotationX(-std.math.pi/2.0)});
|
||||
if(carpetData.posY) posYModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.rotationX(std.math.pi/2.0)});
|
||||
if(carpetData.negZ) negZModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.identity()});
|
||||
if(carpetData.posZ) posZModel = baseModel.transformModel(rotationMatrixTransform, .{Mat4f.rotationY(std.math.pi)});
|
||||
} else {
|
||||
var models: [6]u16 = undefined;
|
||||
var amount: usize = 0;
|
||||
if(carpetData.negX) {
|
||||
models[amount] = negXModel;
|
||||
amount += 1;
|
||||
}
|
||||
if(carpetData.posX) {
|
||||
models[amount] = posXModel;
|
||||
amount += 1;
|
||||
}
|
||||
if(carpetData.negY) {
|
||||
models[amount] = negYModel;
|
||||
amount += 1;
|
||||
}
|
||||
if(carpetData.posY) {
|
||||
models[amount] = posYModel;
|
||||
amount += 1;
|
||||
}
|
||||
if(carpetData.negZ) {
|
||||
models[amount] = negZModel;
|
||||
amount += 1;
|
||||
}
|
||||
if(carpetData.posZ) {
|
||||
models[amount] = posZModel;
|
||||
amount += 1;
|
||||
}
|
||||
_ = main.models.Model.mergeModels(models[0..amount]);
|
||||
}
|
||||
}
|
||||
const modelIndex = negXModel;
|
||||
rotatedModels.put(modelId, modelIndex) catch unreachable;
|
||||
return modelIndex;
|
||||
}
|
||||
|
||||
pub fn model(block: Block) u16 {
|
||||
return blocks.meshes.modelIndexStart(block) + (@as(u6, @truncate(block.data)) -| 1);
|
||||
}
|
||||
|
||||
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, relativeDir: Vec3i, currentData: *Block, _: bool) bool {
|
||||
var data: CarpetData = @bitCast(@as(u6, @truncate(currentData.data)));
|
||||
if(relativeDir[0] == 1) data.posX = true;
|
||||
if(relativeDir[0] == -1) data.negX = true;
|
||||
if(relativeDir[1] == 1) data.posY = true;
|
||||
if(relativeDir[1] == -1) data.negY = true;
|
||||
if(relativeDir[2] == 1) data.posZ = true;
|
||||
if(relativeDir[2] == -1) data.negZ = true;
|
||||
if(@as(u6, @bitCast(data)) != currentData.data) {
|
||||
currentData.data = @as(u6, @bitCast(data));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool {
|
||||
const blockModel = blocks.meshes.modelIndexStart(block.*);
|
||||
const neighborModel = blocks.meshes.model(neighborBlock);
|
||||
const targetVal = neighborBlock.solid() and (blockModel == neighborModel or main.models.models.items[neighborModel].neighborFacingQuads[neighbor.reverse().toInt()].len != 0);
|
||||
var currentData: CarpetData = @bitCast(@as(u6, @truncate(block.data)));
|
||||
switch(neighbor) {
|
||||
.dirNegX => {
|
||||
currentData.negX = currentData.negX and targetVal;
|
||||
},
|
||||
.dirPosX => {
|
||||
currentData.posX = currentData.posX and targetVal;
|
||||
},
|
||||
.dirNegY => {
|
||||
currentData.negY = currentData.negY and targetVal;
|
||||
},
|
||||
.dirPosY => {
|
||||
currentData.posY = currentData.posY and targetVal;
|
||||
},
|
||||
.dirDown => {
|
||||
currentData.negZ = currentData.negZ and targetVal;
|
||||
},
|
||||
.dirUp => {
|
||||
currentData.posZ = currentData.posZ and targetVal;
|
||||
},
|
||||
}
|
||||
const result: u16 = @as(u6, @bitCast(currentData));
|
||||
if(result == block.data) return false;
|
||||
if(result == 0) block.* = .{.typ = 0, .data = 0}
|
||||
else block.data = result;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// MARK: init/register
|
||||
|
Loading…
x
Reference in New Issue
Block a user