mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-11 21:37:46 -04:00
Store height map as an integer, which makes it more compressible, reducing file size by ~5×.
fixes #479
This commit is contained in:
parent
4ffd51217b
commit
d56db52835
@ -309,12 +309,12 @@ pub const InterpolatableCaveBiomeMapView = struct {
|
|||||||
if(wy -% self.surfaceFragments[0].pos.wy >= MapFragment.mapSize*self.pos.voxelSize) {
|
if(wy -% self.surfaceFragments[0].pos.wy >= MapFragment.mapSize*self.pos.voxelSize) {
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
const height: i32 = @intFromFloat(self.surfaceFragments[index].getHeight(wx, wy));
|
const height: i32 = self.surfaceFragments[index].getHeight(wx, wy);
|
||||||
if(wz < height - 32*self.pos.voxelSize or wz > height + 128 + self.pos.voxelSize) return null;
|
if(wz < height - 32*self.pos.voxelSize or wz > height + 128 + self.pos.voxelSize) return null;
|
||||||
return self.surfaceFragments[index].getBiome(wx, wy);
|
return self.surfaceFragments[index].getBiome(wx, wy);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSurfaceHeight(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32) f32 {
|
pub fn getSurfaceHeight(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32) i32 {
|
||||||
var index: u8 = 0;
|
var index: u8 = 0;
|
||||||
if(wx -% self.surfaceFragments[0].pos.wx >= MapFragment.mapSize*self.pos.voxelSize) {
|
if(wx -% self.surfaceFragments[0].pos.wx >= MapFragment.mapSize*self.pos.voxelSize) {
|
||||||
index += 2;
|
index += 2;
|
||||||
@ -413,7 +413,7 @@ pub const CaveBiomeMapView = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSurfaceHeight(self: CaveBiomeMapView, wx: i32, wy: i32) f32 {
|
pub fn getSurfaceHeight(self: CaveBiomeMapView, wx: i32, wy: i32) i32 {
|
||||||
return self.super.getSurfaceHeight(wx, wy);
|
return self.super.getSurfaceHeight(wx, wy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +64,10 @@ pub const MapFragment = struct {
|
|||||||
pub const mapSize = 1 << mapShift;
|
pub const mapSize = 1 << mapShift;
|
||||||
pub const mapMask = mapSize - 1;
|
pub const mapMask = mapSize - 1;
|
||||||
|
|
||||||
heightMap: [mapSize][mapSize]f32 = undefined,
|
heightMap: [mapSize][mapSize]i32 = undefined,
|
||||||
biomeMap: [mapSize][mapSize]*const Biome = undefined,
|
biomeMap: [mapSize][mapSize]*const Biome = undefined,
|
||||||
minHeight: f32 = std.math.floatMax(f32),
|
minHeight: i32 = std.math.maxInt(i32),
|
||||||
maxHeight: f32 = 0,
|
maxHeight: i32 = 0,
|
||||||
pos: MapFragmentPosition,
|
pos: MapFragmentPosition,
|
||||||
|
|
||||||
wasStored: Atomic(bool) = .{.raw = false},
|
wasStored: Atomic(bool) = .{.raw = false},
|
||||||
@ -99,14 +99,15 @@ pub const MapFragment = struct {
|
|||||||
return self.biomeMap[@intCast(xIndex)][@intCast(yIndex)];
|
return self.biomeMap[@intCast(xIndex)][@intCast(yIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getHeight(self: *MapFragment, wx: i32, wy: i32) f32 {
|
pub fn getHeight(self: *MapFragment, wx: i32, wy: i32) i32 {
|
||||||
const xIndex = wx>>self.pos.voxelSizeShift & mapMask;
|
const xIndex = wx>>self.pos.voxelSizeShift & mapMask;
|
||||||
const yIndex = wy>>self.pos.voxelSizeShift & mapMask;
|
const yIndex = wy>>self.pos.voxelSizeShift & mapMask;
|
||||||
return self.heightMap[@intCast(xIndex)][@intCast(yIndex)];
|
return self.heightMap[@intCast(xIndex)][@intCast(yIndex)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const StorageHeader = struct {
|
const StorageHeader = struct {
|
||||||
const activeVersion: u8 = 0;
|
const minSupportedVersion: u8 = 0;
|
||||||
|
const activeVersion: u8 = 1;
|
||||||
version: u8 = activeVersion,
|
version: u8 = activeVersion,
|
||||||
neighborInfo: NeighborInfo,
|
neighborInfo: NeighborInfo,
|
||||||
};
|
};
|
||||||
@ -121,7 +122,7 @@ pub const MapFragment = struct {
|
|||||||
@"++": bool = false,
|
@"++": bool = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn load(self: *MapFragment, biomePalette: *main.assets.Palette, originalHeightMap: ?*[mapSize][mapSize]f32) !NeighborInfo {
|
pub fn load(self: *MapFragment, biomePalette: *main.assets.Palette, originalHeightMap: ?*[mapSize][mapSize]i32) !NeighborInfo {
|
||||||
const saveFolder: []const u8 = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/maps", .{main.server.world.?.name}) catch unreachable;
|
const saveFolder: []const u8 = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/maps", .{main.server.world.?.name}) catch unreachable;
|
||||||
defer main.stackAllocator.free(saveFolder);
|
defer main.stackAllocator.free(saveFolder);
|
||||||
|
|
||||||
@ -135,14 +136,30 @@ pub const MapFragment = struct {
|
|||||||
.version = fullData[0],
|
.version = fullData[0],
|
||||||
.neighborInfo = @bitCast(fullData[1]),
|
.neighborInfo = @bitCast(fullData[1]),
|
||||||
};
|
};
|
||||||
if(header.version != StorageHeader.activeVersion) return error.OutdatedFileVersion;
|
|
||||||
const compressedData = fullData[@sizeOf(StorageHeader)..];
|
const compressedData = fullData[@sizeOf(StorageHeader)..];
|
||||||
|
switch(header.version) {
|
||||||
|
0 => { // TODO: Remove after next breaking change
|
||||||
const rawData: []u8 = main.stackAllocator.alloc(u8, mapSize*mapSize*(@sizeOf(u32) + 2*@sizeOf(f32)));
|
const rawData: []u8 = main.stackAllocator.alloc(u8, mapSize*mapSize*(@sizeOf(u32) + 2*@sizeOf(f32)));
|
||||||
defer main.stackAllocator.free(rawData);
|
defer main.stackAllocator.free(rawData);
|
||||||
if(try main.utils.Compression.inflateTo(rawData, compressedData) != rawData.len) return error.CorruptedFile;
|
if(try main.utils.Compression.inflateTo(rawData, compressedData) != rawData.len) return error.CorruptedFile;
|
||||||
const biomeData = rawData[0..mapSize*mapSize*@sizeOf(u32)];
|
const biomeData = rawData[0..mapSize*mapSize*@sizeOf(u32)];
|
||||||
const heightData = rawData[mapSize*mapSize*@sizeOf(u32)..][0..mapSize*mapSize*@sizeOf(f32)];
|
const heightData = rawData[mapSize*mapSize*@sizeOf(u32)..][0..mapSize*mapSize*@sizeOf(f32)];
|
||||||
const originalHeightData = rawData[mapSize*mapSize*(@sizeOf(u32) + @sizeOf(f32))..][0..mapSize*mapSize*@sizeOf(f32)];
|
const originalHeightData = rawData[mapSize*mapSize*(@sizeOf(u32) + @sizeOf(f32))..][0..mapSize*mapSize*@sizeOf(f32)];
|
||||||
|
for(0..mapSize) |x| {
|
||||||
|
for(0..mapSize) |y| {
|
||||||
|
self.biomeMap[x][y] = main.server.terrain.biomes.getById(biomePalette.palette.items[std.mem.readInt(u32, biomeData[4*(x*mapSize + y)..][0..4], .big)]);
|
||||||
|
self.heightMap[x][y] = @intFromFloat(@as(f32, @bitCast(std.mem.readInt(u32, heightData[4*(x*mapSize + y)..][0..4], .big))));
|
||||||
|
if(originalHeightMap) |map| map[x][y] = @intFromFloat(@as(f32, @bitCast(std.mem.readInt(u32, originalHeightData[4*(x*mapSize + y)..][0..4], .big))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1 => {
|
||||||
|
const rawData: []u8 = main.stackAllocator.alloc(u8, mapSize*mapSize*(@sizeOf(u32) + 2*@sizeOf(i32)));
|
||||||
|
defer main.stackAllocator.free(rawData);
|
||||||
|
if(try main.utils.Compression.inflateTo(rawData, compressedData) != rawData.len) return error.CorruptedFile;
|
||||||
|
const biomeData = rawData[0..mapSize*mapSize*@sizeOf(u32)];
|
||||||
|
const heightData = rawData[mapSize*mapSize*@sizeOf(u32)..][0..mapSize*mapSize*@sizeOf(i32)];
|
||||||
|
const originalHeightData = rawData[mapSize*mapSize*(@sizeOf(u32) + @sizeOf(i32))..][0..mapSize*mapSize*@sizeOf(i32)];
|
||||||
for(0..mapSize) |x| {
|
for(0..mapSize) |x| {
|
||||||
for(0..mapSize) |y| {
|
for(0..mapSize) |y| {
|
||||||
self.biomeMap[x][y] = main.server.terrain.biomes.getById(biomePalette.palette.items[std.mem.readInt(u32, biomeData[4*(x*mapSize + y)..][0..4], .big)]);
|
self.biomeMap[x][y] = main.server.terrain.biomes.getById(biomePalette.palette.items[std.mem.readInt(u32, biomeData[4*(x*mapSize + y)..][0..4], .big)]);
|
||||||
@ -150,11 +167,14 @@ pub const MapFragment = struct {
|
|||||||
if(originalHeightMap) |map| map[x][y] = @bitCast(std.mem.readInt(u32, originalHeightData[4*(x*mapSize + y)..][0..4], .big));
|
if(originalHeightMap) |map| map[x][y] = @bitCast(std.mem.readInt(u32, originalHeightData[4*(x*mapSize + y)..][0..4], .big));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
else => return error.OutdatedFileVersion,
|
||||||
|
}
|
||||||
self.wasStored.store(true, .monotonic);
|
self.wasStored.store(true, .monotonic);
|
||||||
return header.neighborInfo;
|
return header.neighborInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(self: *MapFragment, originalData: ?*[mapSize][mapSize]f32, neighborInfo: NeighborInfo) void {
|
pub fn save(self: *MapFragment, originalData: ?*[mapSize][mapSize]i32, neighborInfo: NeighborInfo) void {
|
||||||
const rawData: []u8 = main.stackAllocator.alloc(u8, mapSize*mapSize*(@sizeOf(u32) + 2*@sizeOf(f32)));
|
const rawData: []u8 = main.stackAllocator.alloc(u8, mapSize*mapSize*(@sizeOf(u32) + 2*@sizeOf(f32)));
|
||||||
defer main.stackAllocator.free(rawData);
|
defer main.stackAllocator.free(rawData);
|
||||||
const biomeData = rawData[0..mapSize*mapSize*@sizeOf(u32)];
|
const biomeData = rawData[0..mapSize*mapSize*@sizeOf(u32)];
|
||||||
@ -308,7 +328,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
const mapFragment = main.globalAllocator.create(MapFragment);
|
const mapFragment = main.globalAllocator.create(MapFragment);
|
||||||
defer main.stackAllocator.destroy(mapFragment);
|
defer main.stackAllocator.destroy(mapFragment);
|
||||||
mapFragment.init(pos.wx, pos.wy, pos.voxelSize);
|
mapFragment.init(pos.wx, pos.wy, pos.voxelSize);
|
||||||
var originalHeightMap: [MapFragment.mapSize][MapFragment.mapSize]f32 = undefined;
|
var originalHeightMap: [MapFragment.mapSize][MapFragment.mapSize]i32 = undefined;
|
||||||
const oldNeighborInfo = mapFragment.load(main.server.world.?.biomePalette, &originalHeightMap) catch |err| {
|
const oldNeighborInfo = mapFragment.load(main.server.world.?.biomePalette, &originalHeightMap) catch |err| {
|
||||||
std.log.err("Error loading map at position {}: {s}", .{pos, @errorName(err)});
|
std.log.err("Error loading map at position {}: {s}", .{pos, @errorName(err)});
|
||||||
continue;
|
continue;
|
||||||
@ -370,7 +390,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(neighborInfo.@"+o" and neighborInfo.@"o+" and neighborInfo.@"++") factor = 1;
|
if(neighborInfo.@"+o" and neighborInfo.@"o+" and neighborInfo.@"++") factor = 1;
|
||||||
const x = MapFragment.mapSize - 1 - a;
|
const x = MapFragment.mapSize - 1 - a;
|
||||||
const y = MapFragment.mapSize - 1 - b;
|
const y = MapFragment.mapSize - 1 - b;
|
||||||
originalHeightMap[x][y] = mapFragment.heightMap[x][y]*factor + originalHeightMap[x][y]*(1 - factor);
|
originalHeightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(originalHeightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(neighborInfo.@"+o" or neighborInfo.@"o-") {
|
if(neighborInfo.@"+o" or neighborInfo.@"o-") {
|
||||||
var factor: f32 = 1;
|
var factor: f32 = 1;
|
||||||
@ -380,7 +400,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(neighborInfo.@"+o" and neighborInfo.@"o-" and neighborInfo.@"+-") factor = 1;
|
if(neighborInfo.@"+o" and neighborInfo.@"o-" and neighborInfo.@"+-") factor = 1;
|
||||||
const x = MapFragment.mapSize - 1 - a;
|
const x = MapFragment.mapSize - 1 - a;
|
||||||
const y = b;
|
const y = b;
|
||||||
originalHeightMap[x][y] = mapFragment.heightMap[x][y]*factor + originalHeightMap[x][y]*(1 - factor);
|
originalHeightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(originalHeightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(neighborInfo.@"-o" or neighborInfo.@"o+") {
|
if(neighborInfo.@"-o" or neighborInfo.@"o+") {
|
||||||
var factor: f32 = 1;
|
var factor: f32 = 1;
|
||||||
@ -390,7 +410,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(neighborInfo.@"-o" and neighborInfo.@"o+" and neighborInfo.@"-+") factor = 1;
|
if(neighborInfo.@"-o" and neighborInfo.@"o+" and neighborInfo.@"-+") factor = 1;
|
||||||
const x = a;
|
const x = a;
|
||||||
const y = MapFragment.mapSize - 1 - b;
|
const y = MapFragment.mapSize - 1 - b;
|
||||||
originalHeightMap[x][y] = mapFragment.heightMap[x][y]*factor + originalHeightMap[x][y]*(1 - factor);
|
originalHeightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(originalHeightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(neighborInfo.@"-o" or neighborInfo.@"o-") {
|
if(neighborInfo.@"-o" or neighborInfo.@"o-") {
|
||||||
var factor: f32 = 1;
|
var factor: f32 = 1;
|
||||||
@ -400,7 +420,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(neighborInfo.@"-o" and neighborInfo.@"o-" and neighborInfo.@"--") factor = 1;
|
if(neighborInfo.@"-o" and neighborInfo.@"o-" and neighborInfo.@"--") factor = 1;
|
||||||
const x = a;
|
const x = a;
|
||||||
const y = b;
|
const y = b;
|
||||||
originalHeightMap[x][y] = mapFragment.heightMap[x][y]*factor + originalHeightMap[x][y]*(1 - factor);
|
originalHeightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(originalHeightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,22 +440,22 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(!neighborInfo.@"+o") {
|
if(!neighborInfo.@"+o") {
|
||||||
const x = MapFragment.mapSize - 1 - a;
|
const x = MapFragment.mapSize - 1 - a;
|
||||||
const y = b;
|
const y = b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"-o") {
|
if(!neighborInfo.@"-o") {
|
||||||
const x = a;
|
const x = a;
|
||||||
const y = b;
|
const y = b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"o+") {
|
if(!neighborInfo.@"o+") {
|
||||||
const x = b;
|
const x = b;
|
||||||
const y = MapFragment.mapSize - 1 - a;
|
const y = MapFragment.mapSize - 1 - a;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"o-") {
|
if(!neighborInfo.@"o-") {
|
||||||
const x = b;
|
const x = b;
|
||||||
const y = a;
|
const y = a;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -449,22 +469,22 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
if(!neighborInfo.@"++" and neighborInfo.@"+o" and neighborInfo.@"o+") {
|
if(!neighborInfo.@"++" and neighborInfo.@"+o" and neighborInfo.@"o+") {
|
||||||
const x = MapFragment.mapSize - 1 - a;
|
const x = MapFragment.mapSize - 1 - a;
|
||||||
const y = MapFragment.mapSize - 1 - b;
|
const y = MapFragment.mapSize - 1 - b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"+-" and neighborInfo.@"+o" and neighborInfo.@"o-") {
|
if(!neighborInfo.@"+-" and neighborInfo.@"+o" and neighborInfo.@"o-") {
|
||||||
const x = MapFragment.mapSize - 1 - a;
|
const x = MapFragment.mapSize - 1 - a;
|
||||||
const y = b;
|
const y = b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"-+" and neighborInfo.@"-o" and neighborInfo.@"o+") {
|
if(!neighborInfo.@"-+" and neighborInfo.@"-o" and neighborInfo.@"o+") {
|
||||||
const x = a;
|
const x = a;
|
||||||
const y = MapFragment.mapSize - 1 - b;
|
const y = MapFragment.mapSize - 1 - b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
if(!neighborInfo.@"--" and neighborInfo.@"-o" and neighborInfo.@"o-") {
|
if(!neighborInfo.@"--" and neighborInfo.@"-o" and neighborInfo.@"o-") {
|
||||||
const x = a;
|
const x = a;
|
||||||
const y = b;
|
const y = b;
|
||||||
mapFragment.heightMap[x][y] = mapFragment.heightMap[x][y]*factor + generatedMap.heightMap[x][y]*(1 - factor);
|
mapFragment.heightMap[x][y] = @intFromFloat(@as(f32, @floatFromInt(mapFragment.heightMap[x][y]))*factor + @as(f32, @floatFromInt(generatedMap.heightMap[x][y]))*(1 - factor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,12 +507,12 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
for(0..MapFragment.mapSize/2) |y| {
|
for(0..MapFragment.mapSize/2) |y| {
|
||||||
var biomes: [4]?*const Biome = .{null} ** 4;
|
var biomes: [4]?*const Biome = .{null} ** 4;
|
||||||
var biomeCounts: [4]u8 = .{0} ** 4;
|
var biomeCounts: [4]u8 = .{0} ** 4;
|
||||||
var height: f32 = 0;
|
var height: i32 = 0;
|
||||||
for(0..2) |dx| {
|
for(0..2) |dx| {
|
||||||
for(0..2) |dy| {
|
for(0..2) |dy| {
|
||||||
const curX = x*2 + dx;
|
const curX = x*2 + dx;
|
||||||
const curY = y*2 + dy;
|
const curY = y*2 + dy;
|
||||||
height += cur.heightMap[curX][curY]/4;
|
height += cur.heightMap[curX][curY];
|
||||||
const biome = cur.biomeMap[curX][curY];
|
const biome = cur.biomeMap[curX][curY];
|
||||||
for(0..4) |i| {
|
for(0..4) |i| {
|
||||||
if(biomes[i] == biome) {
|
if(biomes[i] == biome) {
|
||||||
@ -516,7 +536,7 @@ pub fn regenerateLOD(worldName: []const u8) !void {
|
|||||||
}
|
}
|
||||||
const nextX = offSetX + x;
|
const nextX = offSetX + x;
|
||||||
const nextY = offSetY + y;
|
const nextY = offSetY + y;
|
||||||
next.heightMap[nextX][nextY] = height;
|
next.heightMap[nextX][nextY] = @divFloor(height, 4);
|
||||||
next.biomeMap[nextX][nextY] = bestBiome;
|
next.biomeMap[nextX][nextY] = bestBiome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,14 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) void {
|
|||||||
var y: u31 = 0;
|
var y: u31 = 0;
|
||||||
while(y < width) : (y += map.pos.voxelSize) {
|
while(y < width) : (y += map.pos.voxelSize) {
|
||||||
const height = biomeMap.getSurfaceHeight(map.pos.wx + x, map.pos.wy + y);
|
const height = biomeMap.getSurfaceHeight(map.pos.wx + x, map.pos.wy + y);
|
||||||
const smallestHeight: i32 = @intFromFloat(@floor(@min(
|
const smallestHeight: i32 = @min(
|
||||||
biomeMap.getSurfaceHeight(map.pos.wx +% x +% 1, map.pos.wy +% y),
|
biomeMap.getSurfaceHeight(map.pos.wx +% x +% 1, map.pos.wy +% y),
|
||||||
biomeMap.getSurfaceHeight(map.pos.wx +% x, map.pos.wy +% y +% 1),
|
biomeMap.getSurfaceHeight(map.pos.wx +% x, map.pos.wy +% y +% 1),
|
||||||
biomeMap.getSurfaceHeight(map.pos.wx +% x -% 1, map.pos.wy +% y),
|
biomeMap.getSurfaceHeight(map.pos.wx +% x -% 1, map.pos.wy +% y),
|
||||||
biomeMap.getSurfaceHeight(map.pos.wx +% x, map.pos.wy +% y -% 1),
|
biomeMap.getSurfaceHeight(map.pos.wx +% x, map.pos.wy +% y -% 1),
|
||||||
height,
|
height,
|
||||||
) - 0.5));
|
);
|
||||||
const relativeHeight: i32 = @as(i32, @intFromFloat(height)) -% map.pos.wz;
|
const relativeHeight: i32 = height -% map.pos.wz;
|
||||||
map.removeRange(x, y, relativeHeight, CaveMapFragment.height*map.pos.voxelSize);
|
map.removeRange(x, y, relativeHeight, CaveMapFragment.height*map.pos.voxelSize);
|
||||||
if(smallestHeight < 1) { // Seal off caves that intersect the ocean floor.
|
if(smallestHeight < 1) { // Seal off caves that intersect the ocean floor.
|
||||||
map.addRange(x, y, smallestHeight -% 1 -% map.pos.wz, relativeHeight);
|
map.addRange(x, y, smallestHeight -% 1 -% map.pos.wz, relativeHeight);
|
||||||
|
@ -71,7 +71,7 @@ pub fn generate(worldSeed: u64, chunk: *main.chunk.ServerChunk, caveMap: CaveMap
|
|||||||
const wpx = px -% 16 +% chunk.super.pos.wx;
|
const wpx = px -% 16 +% chunk.super.pos.wx;
|
||||||
const wpy = py -% 16 +% chunk.super.pos.wy;
|
const wpy = py -% 16 +% chunk.super.pos.wy;
|
||||||
|
|
||||||
const relZ = @as(i32, @intFromFloat(biomeMap.getSurfaceHeight(wpx, wpy))) -% chunk.super.pos.wz;
|
const relZ = biomeMap.getSurfaceHeight(wpx, wpy) -% chunk.super.pos.wz;
|
||||||
if(relZ < -32 or relZ >= chunk.super.width + 32) continue;
|
if(relZ < -32 or relZ >= chunk.super.width + 32) continue;
|
||||||
|
|
||||||
var seed = random.initSeed3D(worldSeed, .{wpx, wpy, relZ});
|
var seed = random.initSeed3D(worldSeed, .{wpx, wpy, relZ});
|
||||||
|
@ -83,7 +83,7 @@ pub fn generate(worldSeed: u64, chunk: *main.chunk.ServerChunk, caveMap: CaveMap
|
|||||||
chunk.updateBlockInGeneration(x, y, z, .{.typ = typ, .data = 0}); // TODO: Natural standard.
|
chunk.updateBlockInGeneration(x, y, z, .{.typ = typ, .data = 0}); // TODO: Natural standard.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(z + chunk.super.pos.wz < 0 and z + chunk.super.pos.wz >= @as(i32, @intFromFloat(biomeMap.getSurfaceHeight(x + chunk.super.pos.wx, y + chunk.super.pos.wy))) - (chunk.super.pos.voxelSize - 1)) {
|
if(z + chunk.super.pos.wz < 0 and z + chunk.super.pos.wz >= biomeMap.getSurfaceHeight(x + chunk.super.pos.wx, y + chunk.super.pos.wy) - (chunk.super.pos.voxelSize - 1)) {
|
||||||
chunk.updateBlockInGeneration(x, y, z, .{.typ = water, .data = 0}); // TODO: Natural standard.
|
chunk.updateBlockInGeneration(x, y, z, .{.typ = water, .data = 0}); // TODO: Natural standard.
|
||||||
} else {
|
} else {
|
||||||
chunk.updateBlockInGeneration(x, y, z, .{.typ = 0, .data = 0});
|
chunk.updateBlockInGeneration(x, y, z, .{.typ = 0, .data = 0});
|
||||||
|
@ -130,10 +130,10 @@ pub fn generateMapFragment(map: *MapFragment, worldSeed: u64) void {
|
|||||||
height += (roughMap.get(x, y) - 0.5)*2*roughness;
|
height += (roughMap.get(x, y) - 0.5)*2*roughness;
|
||||||
height += (hillMap.get(x, y) - 0.5)*2*hills;
|
height += (hillMap.get(x, y) - 0.5)*2*hills;
|
||||||
height += (mountainMap.get(x, y) - 0.5)*2*mountains;
|
height += (mountainMap.get(x, y) - 0.5)*2*mountains;
|
||||||
map.heightMap[x][y] = height;
|
map.heightMap[x][y] = @intFromFloat(height);
|
||||||
map.minHeight = @min(map.minHeight, height);
|
map.minHeight = @min(map.minHeight, @as(i32, @intFromFloat(height)));
|
||||||
map.minHeight = @max(map.minHeight, 0);
|
map.minHeight = @max(map.minHeight, 0);
|
||||||
map.maxHeight = @max(map.maxHeight, height);
|
map.maxHeight = @max(map.maxHeight, @as(i32, @intFromFloat(height)));
|
||||||
|
|
||||||
|
|
||||||
// Select a biome. Also adding some white noise to make a smoother transition.
|
// Select a biome. Also adding some white noise to make a smoother transition.
|
||||||
|
@ -609,7 +609,7 @@ pub const ServerWorld = struct {
|
|||||||
}
|
}
|
||||||
const map = terrain.SurfaceMap.getOrGenerateFragmentAndIncreaseRefCount(self.spawn[0], self.spawn[1], 1);
|
const map = terrain.SurfaceMap.getOrGenerateFragmentAndIncreaseRefCount(self.spawn[0], self.spawn[1], 1);
|
||||||
defer map.decreaseRefCount();
|
defer map.decreaseRefCount();
|
||||||
self.spawn[2] = @intFromFloat(map.getHeight(self.spawn[0], self.spawn[1]) + 1);
|
self.spawn[2] = map.getHeight(self.spawn[0], self.spawn[1]) + 1;
|
||||||
}
|
}
|
||||||
self.generated = true;
|
self.generated = true;
|
||||||
const newBiomeCheckSum: i64 = @bitCast(terrain.biomes.getBiomeCheckSum(self.seed));
|
const newBiomeCheckSum: i64 = @bitCast(terrain.biomes.getBiomeCheckSum(self.seed));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user