mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
parent
824840a776
commit
54ab3fc8ed
@ -5,6 +5,7 @@ pub const log = @import("log.zig");
|
||||
pub const no_rotation = @import("no_rotation.zig");
|
||||
pub const ore = @import("ore.zig");
|
||||
pub const planar = @import("planar.zig");
|
||||
pub const sign = @import("sign.zig");
|
||||
pub const stairs = @import("stairs.zig");
|
||||
pub const texture_pile = @import("texture_pile.zig");
|
||||
pub const torch = @import("torch.zig");
|
||||
|
162
src/rotation/sign.zig
Normal file
162
src/rotation/sign.zig
Normal file
@ -0,0 +1,162 @@
|
||||
const std = @import("std");
|
||||
|
||||
const main = @import("main");
|
||||
const blocks = main.blocks;
|
||||
const Block = blocks.Block;
|
||||
const Neighbor = main.chunk.Neighbor;
|
||||
const ModelIndex = main.models.ModelIndex;
|
||||
const rotation = main.rotation;
|
||||
const Degrees = rotation.Degrees;
|
||||
const RayIntersectionResult = rotation.RayIntersectionResult;
|
||||
const RotationMode = rotation.RotationMode;
|
||||
const vec = main.vec;
|
||||
const Mat4f = vec.Mat4f;
|
||||
const Vec3f = vec.Vec3f;
|
||||
const Vec3i = vec.Vec3i;
|
||||
const ZonElement = main.ZonElement;
|
||||
|
||||
pub const naturalStandard: u16 = 0;
|
||||
pub const dependsOnNeighbors = true;
|
||||
var rotatedModels: std.StringHashMap(ModelIndex) = undefined;
|
||||
|
||||
pub fn init() void {
|
||||
rotatedModels = .init(main.globalAllocator.allocator);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
rotatedModels.deinit();
|
||||
}
|
||||
|
||||
pub fn reset() void {
|
||||
rotatedModels.clearRetainingCapacity();
|
||||
}
|
||||
|
||||
const centerRotations = 8;
|
||||
const sideRotations = 4;
|
||||
|
||||
pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex {
|
||||
const floorModelId: []const u8 = zon.get([]const u8, "floor", "cubyz:cube");
|
||||
const sideModelId: []const u8 = zon.get([]const u8, "side", "cubyz:cube");
|
||||
const ceilingModelId: []const u8 = zon.get([]const u8, "ceiling", "cubyz:cube");
|
||||
const key: []const u8 = std.mem.concat(main.stackAllocator.allocator, u8, &.{floorModelId, sideModelId, ceilingModelId}) catch unreachable;
|
||||
defer main.stackAllocator.free(key);
|
||||
|
||||
if(rotatedModels.get(key)) |modelIndex| return modelIndex;
|
||||
|
||||
const floorModel = main.models.getModelIndex(floorModelId).model();
|
||||
const sideModel = main.models.getModelIndex(sideModelId).model();
|
||||
const ceilingModel = main.models.getModelIndex(ceilingModelId).model();
|
||||
var modelIndex: ModelIndex = undefined;
|
||||
// Rotate the model:
|
||||
for(0..centerRotations) |i| {
|
||||
const index = floorModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(@as(f32, @floatFromInt(i))*2.0*std.math.pi/centerRotations)});
|
||||
if(i == 0) modelIndex = index;
|
||||
}
|
||||
for(0..centerRotations) |i| {
|
||||
_ = ceilingModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(@as(f32, @floatFromInt(i))*2.0*std.math.pi/centerRotations)});
|
||||
}
|
||||
for(0..sideRotations) |i| {
|
||||
_ = sideModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(@as(f32, @floatFromInt(i))*2.0*std.math.pi/sideRotations)});
|
||||
}
|
||||
rotatedModels.put(key, modelIndex) catch unreachable;
|
||||
return modelIndex;
|
||||
}
|
||||
|
||||
pub fn model(block: Block) ModelIndex {
|
||||
return .{.index = blocks.meshes.modelIndexStart(block).index + @min(centerRotations*2 + sideRotations, block.data)};
|
||||
}
|
||||
|
||||
pub fn rotateZ(data: u16, angle: Degrees) u16 {
|
||||
const rotationTable: [4][2*centerRotations + sideRotations]u8 = .{
|
||||
.{
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19,
|
||||
},
|
||||
.{
|
||||
2, 3, 4, 5, 6, 7, 0, 1,
|
||||
10, 11, 12, 13, 14, 15, 8, 9,
|
||||
17, 18, 19, 16,
|
||||
},
|
||||
.{
|
||||
4, 5, 6, 7, 0, 1, 2, 3,
|
||||
12, 13, 14, 15, 8, 9, 10, 11,
|
||||
18, 19, 16, 17,
|
||||
},
|
||||
.{
|
||||
6, 7, 0, 1, 2, 3, 4, 5,
|
||||
14, 15, 8, 9, 10, 11, 12, 13,
|
||||
19, 16, 17, 18,
|
||||
},
|
||||
};
|
||||
if(data >= 2*centerRotations + sideRotations) return 0;
|
||||
return rotationTable[@intFromEnum(angle)][data];
|
||||
}
|
||||
|
||||
fn getRotationFromDir(dir: Vec3f) u16 {
|
||||
const x = dir[0];
|
||||
const y = dir[1];
|
||||
var data: u3 = 0;
|
||||
if(@abs(x) > @abs(y)) {
|
||||
if(x < 0) {
|
||||
data = 0;
|
||||
} else {
|
||||
data = 4;
|
||||
}
|
||||
if(@abs(x) < 2*@abs(y)) {
|
||||
if((x < 0) == (y < 0)) {
|
||||
data +%= 1;
|
||||
} else {
|
||||
data -%= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(y < 0) {
|
||||
data = 2;
|
||||
} else {
|
||||
data = 6;
|
||||
}
|
||||
if(@abs(y) < 2*@abs(x)) {
|
||||
if((x < 0) == (y < 0)) {
|
||||
data -%= 1;
|
||||
} else {
|
||||
data +%= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, neighbor: ?Neighbor, currentData: *Block, neighborBlock: Block, blockPlacing: bool) bool {
|
||||
if(neighbor == null) return false;
|
||||
const neighborModel = blocks.meshes.model(neighborBlock).model();
|
||||
const neighborSupport = !neighborBlock.replacable() and neighborModel.neighborFacingQuads[neighbor.?.reverse().toInt()].len != 0;
|
||||
if(!neighborSupport) return false;
|
||||
if(!blockPlacing) return false;
|
||||
currentData.data = switch(Neighbor.fromRelPos(relativeDir) orelse unreachable) {
|
||||
.dirNegX => 2*centerRotations,
|
||||
.dirNegY => 2*centerRotations + 1,
|
||||
.dirPosX => 2*centerRotations + 2,
|
||||
.dirPosY => 2*centerRotations + 3,
|
||||
.dirUp => centerRotations + getRotationFromDir(playerDir),
|
||||
.dirDown => getRotationFromDir(playerDir),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool {
|
||||
const neighborModel = blocks.meshes.model(neighborBlock).model();
|
||||
const neighborSupport = !neighborBlock.replacable() and neighborModel.neighborFacingQuads[neighbor.reverse().toInt()].len != 0;
|
||||
if(neighborSupport) return false;
|
||||
const shouldBeBroken = switch(neighbor) {
|
||||
.dirNegX => block.data == 2*centerRotations,
|
||||
.dirNegY => block.data == 2*centerRotations + 1,
|
||||
.dirPosX => block.data == 2*centerRotations + 2,
|
||||
.dirPosY => block.data == 2*centerRotations + 3,
|
||||
.dirDown => block.data < centerRotations,
|
||||
.dirUp => block.data >= centerRotations and block.data < 2*centerRotations,
|
||||
};
|
||||
if(!shouldBeBroken) return false;
|
||||
block.* = .{.typ = 0, .data = 0};
|
||||
return true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user