mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-04 03:37:59 -04:00
Merge branch 'master' into bolette-mushroom-caves
This commit is contained in:
commit
23db06f7ed
@ -54,6 +54,15 @@ pub fn onClose() void {
|
|||||||
main.globalAllocator.free(searchString);
|
main.globalAllocator.free(searchString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn hasMatchingTag(tags: []const main.Tag, target: []const u8) bool {
|
||||||
|
for(tags) |tag| {
|
||||||
|
if(std.mem.containsAtLeast(u8, tag.getName(), 1, target)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fn initContent() void {
|
fn initContent() void {
|
||||||
const root = VerticalList.init(.{padding, padding}, 300, 0);
|
const root = VerticalList.init(.{padding, padding}, 300, 0);
|
||||||
{
|
{
|
||||||
@ -73,10 +82,19 @@ fn initContent() void {
|
|||||||
const list = VerticalList.init(.{0, padding}, 144, 0);
|
const list = VerticalList.init(.{0, padding}, 144, 0);
|
||||||
items = .init(main.globalAllocator);
|
items = .init(main.globalAllocator);
|
||||||
var itemIterator = main.items.iterator();
|
var itemIterator = main.items.iterator();
|
||||||
|
if(searchString.len > 1 and searchString[0] == '.') {
|
||||||
|
const tag = searchString[1..];
|
||||||
|
while(itemIterator.next()) |item| {
|
||||||
|
if(hasMatchingTag(item.tags(), tag) or (item.block() != null and hasMatchingTag((main.blocks.Block{.typ = item.block().?, .data = undefined}).blockTags(), tag))) {
|
||||||
|
items.append(Item{.baseItem = item.*});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while(itemIterator.next()) |item| {
|
while(itemIterator.next()) |item| {
|
||||||
if(searchString.len != 0 and !std.mem.containsAtLeast(u8, item.id(), 1, searchString)) continue;
|
if(searchString.len != 0 and !std.mem.containsAtLeast(u8, item.id(), 1, searchString)) continue;
|
||||||
items.append(Item{.baseItem = item.*});
|
items.append(Item{.baseItem = item.*});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std.mem.sort(Item, items.items, {}, lessThan);
|
std.mem.sort(Item, items.items, {}, lessThan);
|
||||||
const slotCount = items.items.len + (slotsPerRow - items.items.len%slotsPerRow);
|
const slotCount = items.items.len + (slotsPerRow - items.items.len%slotsPerRow);
|
||||||
|
@ -1215,7 +1215,6 @@ pub const Protocols = struct {
|
|||||||
var ligthMapReader = utils.BinaryReader.init(_inflatedData);
|
var ligthMapReader = utils.BinaryReader.init(_inflatedData);
|
||||||
const map = main.globalAllocator.create(main.server.terrain.LightMap.LightMapFragment);
|
const map = main.globalAllocator.create(main.server.terrain.LightMap.LightMapFragment);
|
||||||
map.init(pos.wx, pos.wy, pos.voxelSize);
|
map.init(pos.wx, pos.wy, pos.voxelSize);
|
||||||
_ = map.refCount.fetchAdd(1, .monotonic);
|
|
||||||
for(&map.startHeight) |*val| {
|
for(&map.startHeight) |*val| {
|
||||||
val.* = try ligthMapReader.readInt(i16);
|
val.* = try ligthMapReader.readInt(i16);
|
||||||
}
|
}
|
||||||
|
@ -807,8 +807,7 @@ pub const ChunkMesh = struct { // MARK: ChunkMesh
|
|||||||
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
var allSun: bool = self.chunk.data.paletteLength == 1 and self.chunk.data.palette[0].typ == 0;
|
||||||
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
var sunStarters: [chunk.chunkSize*chunk.chunkSize][3]u8 = undefined;
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
const lightStartMap = mesh_storage.getLightMapPieceAndIncreaseRefCount(self.pos.wx, self.pos.wy, self.pos.voxelSize) orelse break :sunLight;
|
const lightStartMap = mesh_storage.getLightMapPiece(self.pos.wx, self.pos.wy, self.pos.voxelSize) orelse break :sunLight;
|
||||||
defer lightStartMap.decreaseRefCount();
|
|
||||||
x = 0;
|
x = 0;
|
||||||
while(x < chunk.chunkSize) : (x += 1) {
|
while(x < chunk.chunkSize) : (x += 1) {
|
||||||
var y: u8 = 0;
|
var y: u8 = 0;
|
||||||
|
@ -33,7 +33,7 @@ const ChunkMeshNode = struct {
|
|||||||
const storageSize = 64;
|
const storageSize = 64;
|
||||||
const storageMask = storageSize - 1;
|
const storageMask = storageSize - 1;
|
||||||
var storageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize*storageSize]ChunkMeshNode = undefined;
|
var storageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize*storageSize]ChunkMeshNode = undefined;
|
||||||
var mapStorageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize]?*LightMap.LightMapFragment = undefined;
|
var mapStorageLists: [settings.highestSupportedLod + 1]*[storageSize*storageSize]Atomic(?*LightMap.LightMapFragment) = undefined;
|
||||||
var meshList = main.List(*chunk_meshing.ChunkMesh).init(main.globalAllocator);
|
var meshList = main.List(*chunk_meshing.ChunkMesh).init(main.globalAllocator);
|
||||||
var priorityMeshUpdateList: main.utils.ConcurrentQueue(chunk.ChunkPosition) = undefined;
|
var priorityMeshUpdateList: main.utils.ConcurrentQueue(chunk.ChunkPosition) = undefined;
|
||||||
pub var updatableList = main.List(chunk.ChunkPosition).init(main.globalAllocator);
|
pub var updatableList = main.List(chunk.ChunkPosition).init(main.globalAllocator);
|
||||||
@ -85,8 +85,8 @@ pub fn init() void { // MARK: init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(&mapStorageLists) |*mapStorageList| {
|
for(&mapStorageLists) |*mapStorageList| {
|
||||||
mapStorageList.* = main.globalAllocator.create([storageSize*storageSize]?*LightMap.LightMapFragment);
|
mapStorageList.* = main.globalAllocator.create([storageSize*storageSize]Atomic(?*LightMap.LightMapFragment));
|
||||||
@memset(mapStorageList.*, null);
|
@memset(mapStorageList.*, .init(null));
|
||||||
}
|
}
|
||||||
priorityMeshUpdateList = .init(main.globalAllocator, 16);
|
priorityMeshUpdateList = .init(main.globalAllocator, 16);
|
||||||
mapUpdatableList = .init(main.globalAllocator, 16);
|
mapUpdatableList = .init(main.globalAllocator, 16);
|
||||||
@ -102,7 +102,6 @@ pub fn deinit() void {
|
|||||||
lastPz = 0;
|
lastPz = 0;
|
||||||
lastRD = 0;
|
lastRD = 0;
|
||||||
freeOldMeshes(olderPx, olderPy, olderPz, olderRD);
|
freeOldMeshes(olderPx, olderPy, olderPz, olderRD);
|
||||||
main.heap.GarbageCollection.waitForFreeCompletion();
|
|
||||||
for(storageLists) |storageList| {
|
for(storageLists) |storageList| {
|
||||||
main.globalAllocator.destroy(storageList);
|
main.globalAllocator.destroy(storageList);
|
||||||
}
|
}
|
||||||
@ -112,7 +111,7 @@ pub fn deinit() void {
|
|||||||
|
|
||||||
updatableList.clearAndFree();
|
updatableList.clearAndFree();
|
||||||
while(mapUpdatableList.dequeue()) |map| {
|
while(mapUpdatableList.dequeue()) |map| {
|
||||||
map.decreaseRefCount();
|
map.deferredDeinit();
|
||||||
}
|
}
|
||||||
mapUpdatableList.deinit();
|
mapUpdatableList.deinit();
|
||||||
priorityMeshUpdateList.deinit();
|
priorityMeshUpdateList.deinit();
|
||||||
@ -121,6 +120,7 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
blockUpdateList.deinit();
|
blockUpdateList.deinit();
|
||||||
meshList.clearAndFree();
|
meshList.clearAndFree();
|
||||||
|
main.heap.GarbageCollection.waitForFreeCompletion();
|
||||||
meshMemoryPool.deinit();
|
meshMemoryPool.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ fn updateHigherLodNodeFinishedMeshing(pos_: chunk.ChunkPosition, finishedMeshing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *?*LightMap.LightMapFragment {
|
fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *Atomic(?*LightMap.LightMapFragment) {
|
||||||
const lod = std.math.log2_int(u31, voxelSize);
|
const lod = std.math.log2_int(u31, voxelSize);
|
||||||
var xIndex = x >> lod + LightMap.LightMapFragment.mapShift;
|
var xIndex = x >> lod + LightMap.LightMapFragment.mapShift;
|
||||||
var yIndex = y >> lod + LightMap.LightMapFragment.mapShift;
|
var yIndex = y >> lod + LightMap.LightMapFragment.mapShift;
|
||||||
@ -169,14 +169,8 @@ fn getMapPiecePointer(x: i32, y: i32, voxelSize: u31) *?*LightMap.LightMapFragme
|
|||||||
return &(&mapStorageLists)[lod][@intCast(index)];
|
return &(&mapStorageLists)[lod][@intCast(index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getLightMapPieceAndIncreaseRefCount(x: i32, y: i32, voxelSize: u31) ?*LightMap.LightMapFragment {
|
pub fn getLightMapPiece(x: i32, y: i32, voxelSize: u31) ?*LightMap.LightMapFragment {
|
||||||
mutex.lock();
|
return getMapPiecePointer(x, y, voxelSize).load(.acquire);
|
||||||
defer mutex.unlock();
|
|
||||||
const result: *LightMap.LightMapFragment = getMapPiecePointer(x, y, voxelSize).* orelse {
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
result.increaseRefCount();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getBlockFromRenderThread(x: i32, y: i32, z: i32) ?blocks.Block {
|
pub fn getBlockFromRenderThread(x: i32, y: i32, z: i32) ?blocks.Block {
|
||||||
@ -212,7 +206,7 @@ pub fn getLight(wx: i32, wy: i32, wz: i32) ?[6]u8 {
|
|||||||
|
|
||||||
pub fn getBlockFromAnyLodFromRenderThread(x: i32, y: i32, z: i32) blocks.Block {
|
pub fn getBlockFromAnyLodFromRenderThread(x: i32, y: i32, z: i32) blocks.Block {
|
||||||
var lod: u5 = 0;
|
var lod: u5 = 0;
|
||||||
while(lod < settings.highestLod) : (lod += 1) {
|
while(lod <= settings.highestLod) : (lod += 1) {
|
||||||
const node = getNodePointer(.{.wx = x, .wy = y, .wz = z, .voxelSize = @as(u31, 1) << lod});
|
const node = getNodePointer(.{.wx = x, .wy = y, .wz = z, .voxelSize = @as(u31, 1) << lod});
|
||||||
const mesh = node.mesh.load(.acquire) orelse continue;
|
const mesh = node.mesh.load(.acquire) orelse continue;
|
||||||
const block = mesh.chunk.getBlock(x & chunk.chunkMask << lod, y & chunk.chunkMask << lod, z & chunk.chunkMask << lod);
|
const block = mesh.chunk.getBlock(x & chunk.chunkMask << lod, y & chunk.chunkMask << lod, z & chunk.chunkMask << lod);
|
||||||
@ -437,13 +431,9 @@ fn freeOldMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: u16) void {
|
|||||||
const yIndex = @divExact(y, size) & storageMask;
|
const yIndex = @divExact(y, size) & storageMask;
|
||||||
const index = xIndex*storageSize + yIndex;
|
const index = xIndex*storageSize + yIndex;
|
||||||
|
|
||||||
const mapPointer = &mapStorageLists[_lod][@intCast(index)];
|
const oldMap = mapStorageLists[_lod][@intCast(index)].swap(null, .monotonic);
|
||||||
mutex.lock();
|
|
||||||
const oldMap = mapPointer.*;
|
|
||||||
mapPointer.* = null;
|
|
||||||
mutex.unlock();
|
|
||||||
if(oldMap) |map| {
|
if(oldMap) |map| {
|
||||||
map.decreaseRefCount();
|
map.deferredDeinit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -576,14 +566,12 @@ fn createNewMeshes(olderPx: i32, olderPy: i32, olderPz: i32, olderRD: u16, meshR
|
|||||||
const index = xIndex*storageSize + yIndex;
|
const index = xIndex*storageSize + yIndex;
|
||||||
const pos = LightMap.MapFragmentPosition{.wx = x, .wy = y, .voxelSize = @as(u31, 1) << lod, .voxelSizeShift = lod};
|
const pos = LightMap.MapFragmentPosition{.wx = x, .wy = y, .voxelSize = @as(u31, 1) << lod, .voxelSizeShift = lod};
|
||||||
|
|
||||||
const node = &mapStorageLists[_lod][@intCast(index)];
|
const map = mapStorageLists[_lod][@intCast(index)].load(.unordered);
|
||||||
mutex.lock();
|
if(map) |_map| {
|
||||||
if(node.*) |map| {
|
std.debug.assert(std.meta.eql(pos, _map.pos));
|
||||||
std.debug.assert(std.meta.eql(pos, map.pos));
|
|
||||||
} else {
|
} else {
|
||||||
mapRequests.append(pos);
|
mapRequests.append(pos);
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,13 +758,12 @@ pub fn updateMeshes(targetTime: i64) void { // MARK: updateMeshes()=
|
|||||||
}
|
}
|
||||||
while(mapUpdatableList.dequeue()) |map| {
|
while(mapUpdatableList.dequeue()) |map| {
|
||||||
if(!isMapInRenderDistance(map.pos)) {
|
if(!isMapInRenderDistance(map.pos)) {
|
||||||
map.decreaseRefCount();
|
map.deferredDeinit();
|
||||||
} else {
|
} else {
|
||||||
const mapPointer = getMapPiecePointer(map.pos.wx, map.pos.wy, map.pos.voxelSize);
|
const mapPointer = getMapPiecePointer(map.pos.wx, map.pos.wy, map.pos.voxelSize).swap(map, .release);
|
||||||
if(mapPointer.*) |old| {
|
if(mapPointer) |old| {
|
||||||
old.decreaseRefCount();
|
old.deferredDeinit();
|
||||||
}
|
}
|
||||||
mapPointer.* = map;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(updatableList.items.len != 0) {
|
while(updatableList.items.len != 0) {
|
||||||
|
@ -20,25 +20,18 @@ pub const LightMapFragment = struct {
|
|||||||
startHeight: [mapSize*mapSize]i16 = undefined,
|
startHeight: [mapSize*mapSize]i16 = undefined,
|
||||||
pos: MapFragmentPosition,
|
pos: MapFragmentPosition,
|
||||||
|
|
||||||
refCount: Atomic(u16) = .init(0),
|
|
||||||
|
|
||||||
pub fn init(self: *LightMapFragment, wx: i32, wy: i32, voxelSize: u31) void {
|
pub fn init(self: *LightMapFragment, wx: i32, wy: i32, voxelSize: u31) void {
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.pos = MapFragmentPosition.init(wx, wy, voxelSize),
|
.pos = MapFragmentPosition.init(wx, wy, voxelSize),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increaseRefCount(self: *LightMapFragment) void {
|
fn deinit(self: *const LightMapFragment, _: usize) void {
|
||||||
const prevVal = self.refCount.fetchAdd(1, .monotonic);
|
|
||||||
std.debug.assert(prevVal != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decreaseRefCount(self: *LightMapFragment) void {
|
|
||||||
const prevVal = self.refCount.fetchSub(1, .monotonic);
|
|
||||||
std.debug.assert(prevVal != 0);
|
|
||||||
if(prevVal == 1) {
|
|
||||||
main.globalAllocator.destroy(self);
|
main.globalAllocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deferredDeinit(self: *LightMapFragment) void {
|
||||||
|
main.heap.GarbageCollection.deferredFree(.{.ptr = self, .freeFunction = main.utils.castFunctionSelfToAnyopaque(LightMapFragment.deinit)});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHeight(self: *LightMapFragment, wx: i32, wy: i32) i32 {
|
pub fn getHeight(self: *LightMapFragment, wx: i32, wy: i32) i32 {
|
||||||
@ -51,7 +44,7 @@ pub const LightMapFragment = struct {
|
|||||||
const cacheSize = 1 << 6; // Must be a power of 2!
|
const cacheSize = 1 << 6; // Must be a power of 2!
|
||||||
const cacheMask = cacheSize - 1;
|
const cacheMask = cacheSize - 1;
|
||||||
const associativity = 8; // 64MiB MiB Cache size
|
const associativity = 8; // 64MiB MiB Cache size
|
||||||
var cache: Cache(LightMapFragment, cacheSize, associativity, LightMapFragment.decreaseRefCount) = .{};
|
var cache: Cache(LightMapFragment, cacheSize, associativity, LightMapFragment.deferredDeinit) = .{};
|
||||||
|
|
||||||
fn cacheInit(pos: MapFragmentPosition) *LightMapFragment {
|
fn cacheInit(pos: MapFragmentPosition) *LightMapFragment {
|
||||||
const mapFragment = main.globalAllocator.create(LightMapFragment);
|
const mapFragment = main.globalAllocator.create(LightMapFragment);
|
||||||
@ -65,7 +58,6 @@ fn cacheInit(pos: MapFragmentPosition) *LightMapFragment {
|
|||||||
mapFragment.startHeight[x << LightMapFragment.mapShift | y] = @max(0, baseHeight +| 16); // Simple heuristic. TODO: Update this value once chunks get generated in the region.
|
mapFragment.startHeight[x << LightMapFragment.mapShift | y] = @max(0, baseHeight +| 16); // Simple heuristic. TODO: Update this value once chunks get generated in the region.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = @atomicRmw(u16, &mapFragment.refCount.raw, .Add, 1, .monotonic);
|
|
||||||
return mapFragment;
|
return mapFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,12 +65,12 @@ pub fn deinit() void {
|
|||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32, voxelSize: u31) *LightMapFragment {
|
pub fn getOrGenerateFragment(wx: i32, wy: i32, voxelSize: u31) *LightMapFragment {
|
||||||
const compare = MapFragmentPosition.init(
|
const compare = MapFragmentPosition.init(
|
||||||
wx & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
wx & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
||||||
wy & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
wy & ~@as(i32, LightMapFragment.mapMask*voxelSize | voxelSize - 1),
|
||||||
voxelSize,
|
voxelSize,
|
||||||
);
|
);
|
||||||
const result = cache.findOrCreate(compare, cacheInit, LightMapFragment.increaseRefCount);
|
const result = cache.findOrCreate(compare, cacheInit, null);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -226,8 +226,7 @@ const ChunkManager = struct { // MARK: ChunkManager
|
|||||||
|
|
||||||
pub fn run(self: *LightMapLoadTask) void {
|
pub fn run(self: *LightMapLoadTask) void {
|
||||||
defer self.clean();
|
defer self.clean();
|
||||||
const map = terrain.LightMap.getOrGenerateFragmentAndIncreaseRefCount(self.pos.wx, self.pos.wy, self.pos.voxelSize);
|
const map = terrain.LightMap.getOrGenerateFragment(self.pos.wx, self.pos.wy, self.pos.voxelSize);
|
||||||
defer map.decreaseRefCount();
|
|
||||||
if(self.source) |source| {
|
if(self.source) |source| {
|
||||||
if(source.connected.load(.unordered)) main.network.Protocols.lightMapTransmission.sendLightMap(source.conn, map);
|
if(source.connected.load(.unordered)) main.network.Protocols.lightMapTransmission.sendLightMap(source.conn, map);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user