mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-10 04:41:32 -04:00
Various performance improvements:
The NoiseCaveGenerator now produces all (noise + interpolateValue) values at once instead of recalculating them 7 times on average. The TerrainGenerator no longer uses integer division. The chunk meshing doesn't calculate the giant switch case in the middle of `cenBeSeenThroughOtherBlock()` if the block as the simple cube model. And some smaller things.
This commit is contained in:
parent
83f4503390
commit
f15d1adc56
@ -25,7 +25,7 @@ pub const BlockClass = enum(u8) {
|
|||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
var allocator = arena.allocator();
|
var allocator = arena.allocator();
|
||||||
|
|
||||||
pub const MaxBLockCount: usize = 65536; // 16 bit limit
|
pub const maxBlockCount: usize = 65536; // 16 bit limit
|
||||||
|
|
||||||
pub const BlockDrop = struct {
|
pub const BlockDrop = struct {
|
||||||
item: items.Item,
|
item: items.Item,
|
||||||
@ -56,26 +56,26 @@ pub const Ore = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var _lightingTransparent: [MaxBLockCount]bool = undefined;
|
var _lightingTransparent: [maxBlockCount]bool = undefined;
|
||||||
var _transparent: [MaxBLockCount]bool = undefined;
|
var _transparent: [maxBlockCount]bool = undefined;
|
||||||
var _id: [MaxBLockCount][]u8 = undefined;
|
var _id: [maxBlockCount][]u8 = undefined;
|
||||||
/// Time in seconds to break this block by hand.
|
/// Time in seconds to break this block by hand.
|
||||||
var _hardness: [MaxBLockCount]f32 = undefined;
|
var _hardness: [maxBlockCount]f32 = undefined;
|
||||||
/// Minimum pickaxe/axe/shovel power required.
|
/// Minimum pickaxe/axe/shovel power required.
|
||||||
var _breakingPower: [MaxBLockCount]f32 = undefined;
|
var _breakingPower: [maxBlockCount]f32 = undefined;
|
||||||
var _solid: [MaxBLockCount]bool = undefined;
|
var _solid: [maxBlockCount]bool = undefined;
|
||||||
var _selectable: [MaxBLockCount]bool = undefined;
|
var _selectable: [maxBlockCount]bool = undefined;
|
||||||
var _blockDrops: [MaxBLockCount][]BlockDrop = undefined;
|
var _blockDrops: [maxBlockCount][]BlockDrop = undefined;
|
||||||
/// Meaning undegradable parts of trees or other structures can grow through this block.
|
/// Meaning undegradable parts of trees or other structures can grow through this block.
|
||||||
var _degradable: [MaxBLockCount]bool = undefined;
|
var _degradable: [maxBlockCount]bool = undefined;
|
||||||
var _viewThrough: [MaxBLockCount]bool = undefined;
|
var _viewThrough: [maxBlockCount]bool = undefined;
|
||||||
var _blockClass: [MaxBLockCount]BlockClass = undefined;
|
var _blockClass: [maxBlockCount]BlockClass = undefined;
|
||||||
var _light: [MaxBLockCount]u32 = undefined;
|
var _light: [maxBlockCount]u32 = undefined;
|
||||||
/// How much light this block absorbs if it is transparent
|
/// How much light this block absorbs if it is transparent
|
||||||
var _absorption: [MaxBLockCount]u32 = undefined;
|
var _absorption: [maxBlockCount]u32 = undefined;
|
||||||
/// GUI that is opened on click.
|
/// GUI that is opened on click.
|
||||||
var _gui: [MaxBLockCount][]u8 = undefined;
|
var _gui: [maxBlockCount][]u8 = undefined;
|
||||||
var _mode: [MaxBLockCount]*RotationMode = undefined;
|
var _mode: [maxBlockCount]*RotationMode = undefined;
|
||||||
|
|
||||||
var reverseIndices = std.StringHashMap(u16).init(arena.allocator());
|
var reverseIndices = std.StringHashMap(u16).init(arena.allocator());
|
||||||
|
|
||||||
@ -310,10 +310,10 @@ pub const meshes = struct {
|
|||||||
time: i32,
|
time: i32,
|
||||||
};
|
};
|
||||||
var size: u32 = 0;
|
var size: u32 = 0;
|
||||||
var _modelIndex: [MaxBLockCount]u16 = undefined;
|
var _modelIndex: [maxBlockCount]u16 = undefined;
|
||||||
var _textureIndices: [MaxBLockCount][6]u32 = undefined;
|
var _textureIndices: [maxBlockCount][6]u32 = undefined;
|
||||||
/// Stores the number of textures after each block was added. Used to clean additional textures when the world is switched.
|
/// Stores the number of textures after each block was added. Used to clean additional textures when the world is switched.
|
||||||
var maxTextureCount: [MaxBLockCount]u32 = undefined;
|
var maxTextureCount: [maxBlockCount]u32 = undefined;
|
||||||
/// Number of loaded meshes. Used to determine if an update is needed.
|
/// Number of loaded meshes. Used to determine if an update is needed.
|
||||||
var loadedMeshes: u32 = 0;
|
var loadedMeshes: u32 = 0;
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ pub const meshing = struct {
|
|||||||
fn canBeSeenThroughOtherBlock(block: Block, other: Block, neighbor: u3) bool {
|
fn canBeSeenThroughOtherBlock(block: Block, other: Block, neighbor: u3) bool {
|
||||||
const rotatedModel = blocks.meshes.model(block);
|
const rotatedModel = blocks.meshes.model(block);
|
||||||
const model = &models.voxelModels.items[rotatedModel.modelIndex];
|
const model = &models.voxelModels.items[rotatedModel.modelIndex];
|
||||||
const freestandingModel = switch(rotatedModel.permutation.permuteNeighborIndex(neighbor)) {
|
const freestandingModel = rotatedModel.modelIndex != models.fullCube and switch(rotatedModel.permutation.permuteNeighborIndex(neighbor)) {
|
||||||
Neighbors.dirNegX => model.min[0] != 0,
|
Neighbors.dirNegX => model.min[0] != 0,
|
||||||
Neighbors.dirPosX => model.max[0] != 16,
|
Neighbors.dirPosX => model.max[0] != 16,
|
||||||
Neighbors.dirDown => model.min[1] != 0,
|
Neighbors.dirDown => model.min[1] != 0,
|
||||||
|
@ -208,6 +208,7 @@ pub fn getModelIndex(string: []const u8) u16 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub var voxelModels: std.ArrayList(VoxelModel) = undefined;
|
pub var voxelModels: std.ArrayList(VoxelModel) = undefined;
|
||||||
|
pub var fullCube: u16 = 0;
|
||||||
|
|
||||||
// TODO: Allow loading from world assets.
|
// TODO: Allow loading from world assets.
|
||||||
// TODO: Editable player models.
|
// TODO: Editable player models.
|
||||||
@ -220,6 +221,7 @@ pub fn init() !void {
|
|||||||
nameToIndex = std.StringHashMap(u16).init(main.threadAllocator);
|
nameToIndex = std.StringHashMap(u16).init(main.threadAllocator);
|
||||||
|
|
||||||
try nameToIndex.put("cube", @intCast(u16, voxelModels.items.len));
|
try nameToIndex.put("cube", @intCast(u16, voxelModels.items.len));
|
||||||
|
fullCube = @intCast(u16, voxelModels.items.len);
|
||||||
(try voxelModels.addOne()).init(cube);
|
(try voxelModels.addOne()).init(cube);
|
||||||
|
|
||||||
try nameToIndex.put("log", @intCast(u16, voxelModels.items.len));
|
try nameToIndex.put("log", @intCast(u16, voxelModels.items.len));
|
||||||
|
@ -2,6 +2,7 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
const main = @import("root");
|
const main = @import("root");
|
||||||
|
const Array3D = main.utils.Array3D;
|
||||||
const Cache = main.utils.Cache;
|
const Cache = main.utils.Cache;
|
||||||
const Chunk = main.chunk.Chunk;
|
const Chunk = main.chunk.Chunk;
|
||||||
const ChunkPosition = main.chunk.ChunkPosition;
|
const ChunkPosition = main.chunk.ChunkPosition;
|
||||||
@ -25,8 +26,7 @@ pub const CaveBiomeMapFragment = struct {
|
|||||||
pub const caveBiomeMapMask = caveBiomeMapSize - 1;
|
pub const caveBiomeMapMask = caveBiomeMapSize - 1;
|
||||||
|
|
||||||
pos: main.chunk.ChunkPosition,
|
pos: main.chunk.ChunkPosition,
|
||||||
biomeMap0: [1 << 3*(caveBiomeMapShift - caveBiomeShift)]*const Biome = undefined,
|
biomeMap: [1 << 3*(caveBiomeMapShift - caveBiomeShift)][2]*const Biome = undefined,
|
||||||
biomeMap1: [1 << 3*(caveBiomeMapShift - caveBiomeShift)]*const Biome = undefined,
|
|
||||||
refCount: std.atomic.Atomic(u16) = std.atomic.Atomic(u16).init(0),
|
refCount: std.atomic.Atomic(u16) = std.atomic.Atomic(u16).init(0),
|
||||||
|
|
||||||
pub fn init(self: *CaveBiomeMapFragment, wx: i32, wy: i32, wz: i32) !void {
|
pub fn init(self: *CaveBiomeMapFragment, wx: i32, wy: i32, wz: i32) !void {
|
||||||
@ -178,6 +178,24 @@ pub const InterpolatableCaveBiomeMapView = struct {
|
|||||||
return @select(i32, in >= Vec3i{0, 0, 0}, Vec3i{1, 1, 1}, Vec3i{-1, -1, -1});
|
return @select(i32, in >= Vec3i{0, 0, 0}, Vec3i{1, 1, 1}, Vec3i{-1, -1, -1});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bulkInterpolateValue(self: InterpolatableCaveBiomeMapView, comptime field: []const u8, wx: i32, wy: i32, wz: i32, voxelSize: u31, map: Array3D(f32), comptime mode: enum{addToMap}, comptime scale: f32) void {
|
||||||
|
var x: u31 = 0;
|
||||||
|
while(x < map.width) : (x += 1) {
|
||||||
|
var y: u31 = 0;
|
||||||
|
while(y < map.height) : (y += 1) {
|
||||||
|
var z: u31 = 0;
|
||||||
|
while(z < map.depth) : (z += 1) {
|
||||||
|
switch (mode) {
|
||||||
|
.addToMap => {
|
||||||
|
// TODO: Do a tetrahedron voxelization here, so parts of the tetrahedral barycentric coordinates can be precomputed.
|
||||||
|
map.ptr(x, y, z).* += scale*interpolateValue(self, wx + x*voxelSize, wy + y*voxelSize, wz + z*voxelSize, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub noinline fn interpolateValue(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, comptime field: []const u8) f32 {
|
pub noinline fn interpolateValue(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, comptime field: []const u8) f32 {
|
||||||
const worldPos = Vec3i{wx, wy, wz};
|
const worldPos = Vec3i{wx, wy, wz};
|
||||||
const closestGridpoint0 = (worldPos + @splat(3, @as(i32, CaveBiomeMapFragment.caveBiomeSize/2))) & @splat(3, ~@as(i32, CaveBiomeMapFragment.caveBiomeMask));
|
const closestGridpoint0 = (worldPos + @splat(3, @as(i32, CaveBiomeMapFragment.caveBiomeSize/2))) & @splat(3, ~@as(i32, CaveBiomeMapFragment.caveBiomeMask));
|
||||||
@ -283,7 +301,7 @@ pub const InterpolatableCaveBiomeMapView = struct {
|
|||||||
return self.surfaceFragments[index].getBiome(wx, wz);
|
return self.surfaceFragments[index].getBiome(wx, wz);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _getBiome(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, map: u1) *const Biome {
|
noinline fn _getBiome(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, map: u1) *const Biome {
|
||||||
var index: u8 = 0;
|
var index: u8 = 0;
|
||||||
if(wx - self.fragments[0].pos.wx >= CaveBiomeMapFragment.caveBiomeMapSize) {
|
if(wx - self.fragments[0].pos.wx >= CaveBiomeMapFragment.caveBiomeMapSize) {
|
||||||
index += 4;
|
index += 4;
|
||||||
@ -298,15 +316,11 @@ pub const InterpolatableCaveBiomeMapView = struct {
|
|||||||
const relY = @intCast(u31, wy - self.fragments[index].pos.wy);
|
const relY = @intCast(u31, wy - self.fragments[index].pos.wy);
|
||||||
const relZ = @intCast(u31, wz - self.fragments[index].pos.wz);
|
const relZ = @intCast(u31, wz - self.fragments[index].pos.wz);
|
||||||
const indexInArray = CaveBiomeMapFragment.getIndex(relX, relY, relZ);
|
const indexInArray = CaveBiomeMapFragment.getIndex(relX, relY, relZ);
|
||||||
if(map == 0) {
|
return self.fragments[index].biomeMap[indexInArray][map];
|
||||||
return self.fragments[index].biomeMap0[indexInArray];
|
|
||||||
} else {
|
|
||||||
return self.fragments[index].biomeMap1[indexInArray];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Useful when the rough biome location is enough, for example for music.
|
/// Useful when the rough biome location is enough, for example for music.
|
||||||
pub fn getRoughBiome(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, nullSeed: ?*u64, comptime _checkSurfaceBiome: bool) *const Biome {
|
pub noinline fn getRoughBiome(self: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32, comptime getSeed: bool, seed: *u64, comptime _checkSurfaceBiome: bool) *const Biome {
|
||||||
if(_checkSurfaceBiome) {
|
if(_checkSurfaceBiome) {
|
||||||
if(self.checkSurfaceBiome(wx, wy, wz)) |surfaceBiome| {
|
if(self.checkSurfaceBiome(wx, wy, wz)) |surfaceBiome| {
|
||||||
return surfaceBiome;
|
return surfaceBiome;
|
||||||
@ -328,7 +342,7 @@ pub const InterpolatableCaveBiomeMapView = struct {
|
|||||||
map = 1;
|
map = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nullSeed) |seed| {
|
if(getSeed) {
|
||||||
// A good old "I don't know what I'm doing" hash:
|
// A good old "I don't know what I'm doing" hash:
|
||||||
seed.* = @bitCast(u64, @as(i64, gridPointX) << 48 ^ @as(i64, gridPointY) << 23 ^ @as(i64, gridPointZ) << 11 ^ @as(i64, gridPointX) >> 5 ^ @as(i64, gridPointY) << 3 ^ @as(i64, gridPointZ) ^ @as(i64, map)*5427642781) ^ main.server.world.?.seed;
|
seed.* = @bitCast(u64, @as(i64, gridPointX) << 48 ^ @as(i64, gridPointY) << 23 ^ @as(i64, gridPointZ) << 11 ^ @as(i64, gridPointX) >> 5 ^ @as(i64, gridPointY) << 3 ^ @as(i64, gridPointZ) ^ @as(i64, map)*5427642781) ^ main.server.world.?.seed;
|
||||||
}
|
}
|
||||||
@ -383,11 +397,11 @@ pub const CaveBiomeMapView = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getBiome(self: CaveBiomeMapView, relX: i32, relY: i32, relZ: i32) *const Biome {
|
pub fn getBiome(self: CaveBiomeMapView, relX: i32, relY: i32, relZ: i32) *const Biome {
|
||||||
return self.getBiomeAndSeed(relX, relY, relZ, null);
|
return self.getBiomeAndSeed(relX, relY, relZ, false, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Also returns a seed that is unique for the corresponding biome position.
|
/// Also returns a seed that is unique for the corresponding biome position.
|
||||||
pub fn getBiomeAndSeed(self: CaveBiomeMapView, relX: i32, relY: i32, relZ: i32, seed: ?*u64) *const Biome {
|
pub noinline fn getBiomeAndSeed(self: CaveBiomeMapView, relX: i32, relY: i32, relZ: i32, comptime getSeed: bool, seed: *u64) *const Biome {
|
||||||
std.debug.assert(relX >= -32 and relX < self.super.width + 32); // coordinate out of bounds
|
std.debug.assert(relX >= -32 and relX < self.super.width + 32); // coordinate out of bounds
|
||||||
std.debug.assert(relY >= -32 and relY < self.super.width + 32); // coordinate out of bounds
|
std.debug.assert(relY >= -32 and relY < self.super.width + 32); // coordinate out of bounds
|
||||||
std.debug.assert(relZ >= -32 and relZ < self.super.width + 32); // coordinate out of bounds
|
std.debug.assert(relZ >= -32 and relZ < self.super.width + 32); // coordinate out of bounds
|
||||||
@ -407,7 +421,7 @@ pub const CaveBiomeMapView = struct {
|
|||||||
wz += @floatToInt(i32, valueZ);
|
wz += @floatToInt(i32, valueZ);
|
||||||
};
|
};
|
||||||
|
|
||||||
return self.super.getRoughBiome(wx, wy, wz, seed, false);
|
return self.super.getRoughBiome(wx, wy, wz, getSeed, seed, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,11 +83,7 @@ pub fn generate(map: *CaveBiomeMapFragment, worldSeed: u64) Allocator.Error!void
|
|||||||
if(randomValue < 0) break;
|
if(randomValue < 0) break;
|
||||||
}
|
}
|
||||||
var index = CaveBiomeMapFragment.getIndex(x, y, z);
|
var index = CaveBiomeMapFragment.getIndex(x, y, z);
|
||||||
if(_map == 0) {
|
map.biomeMap[index][_map] = biome;
|
||||||
map.biomeMap0[index] = biome;
|
|
||||||
} else {
|
|
||||||
map.biomeMap1[index] = biome;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,9 @@ pub fn deinit() void {
|
|||||||
const scale = 64;
|
const scale = 64;
|
||||||
const interpolatedPart = 4;
|
const interpolatedPart = 4;
|
||||||
|
|
||||||
fn getValue(noise: Array3D(f32), map: *CaveMapFragment, biomeMap: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32) f32 {
|
fn getValue(noise: Array3D(f32), map: *CaveMapFragment, outerSize: u31, biomeMap: InterpolatableCaveBiomeMapView, wx: i32, wy: i32, wz: i32) f32 {
|
||||||
return noise.get(@intCast(u31, wx - map.pos.wx) >> map.voxelShift, @intCast(u31, wy - map.pos.wy) >> map.voxelShift, @intCast(u31, wz - map.pos.wz) >> map.voxelShift) + biomeMap.interpolateValue(wx, wy, wz, "caves")*scale;
|
_ = biomeMap; // TODO: clean this up at some point.
|
||||||
|
return noise.get(@intCast(u31, wx - map.pos.wx)/outerSize, @intCast(u31, wy - map.pos.wy)/outerSize, @intCast(u31, wz - map.pos.wz)/outerSize);// + biomeMap.interpolateValue(wx, wy, wz, "caves")*scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void {
|
pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void {
|
||||||
@ -47,22 +48,23 @@ pub fn generate(map: *CaveMapFragment, worldSeed: u64) Allocator.Error!void {
|
|||||||
const biomeMap = try InterpolatableCaveBiomeMapView.init(map.pos, CaveMapFragment.width*map.pos.voxelSize);
|
const biomeMap = try InterpolatableCaveBiomeMapView.init(map.pos, CaveMapFragment.width*map.pos.voxelSize);
|
||||||
defer biomeMap.deinit();
|
defer biomeMap.deinit();
|
||||||
const outerSize = @max(map.pos.voxelSize, interpolatedPart);
|
const outerSize = @max(map.pos.voxelSize, interpolatedPart);
|
||||||
var noise = try FractalNoise3D.generateAligned(main.threadAllocator, map.pos.wx, map.pos.wy, map.pos.wz, map.pos.voxelSize, CaveMapFragment.width + 1, CaveMapFragment.height + 1, CaveMapFragment.width + 1, worldSeed, scale);//try Cached3DFractalNoise.init(map.pos.wx, map.pos.wy & ~@as(i32, CaveMapFragment.width*map.pos.voxelSize - 1), map.pos.wz, outerSize, map.pos.voxelSize*CaveMapFragment.width, worldSeed, scale);
|
var noise = try FractalNoise3D.generateAligned(main.threadAllocator, map.pos.wx, map.pos.wy, map.pos.wz, outerSize, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, CaveMapFragment.height*map.pos.voxelSize/outerSize + 1, CaveMapFragment.width*map.pos.voxelSize/outerSize + 1, worldSeed, scale);//try Cached3DFractalNoise.init(map.pos.wx, map.pos.wy & ~@as(i32, CaveMapFragment.width*map.pos.voxelSize - 1), map.pos.wz, outerSize, map.pos.voxelSize*CaveMapFragment.width, worldSeed, scale);
|
||||||
defer noise.deinit(main.threadAllocator);
|
defer noise.deinit(main.threadAllocator);
|
||||||
|
biomeMap.bulkInterpolateValue("caves", map.pos.wx, map.pos.wy, map.pos.wz, outerSize, noise, .addToMap, scale);
|
||||||
var x: u31 = 0;
|
var x: u31 = 0;
|
||||||
while(x < map.pos.voxelSize*CaveMapFragment.width) : (x += outerSize) {
|
while(x < map.pos.voxelSize*CaveMapFragment.width) : (x += outerSize) {
|
||||||
var y: u31 = 0;
|
var y: u31 = 0;
|
||||||
while(y < map.pos.voxelSize*CaveMapFragment.height) : (y += outerSize) {
|
while(y < map.pos.voxelSize*CaveMapFragment.height) : (y += outerSize) {
|
||||||
var z: u31 = 0;
|
var z: u31 = 0;
|
||||||
while(z < map.pos.voxelSize*CaveMapFragment.width) : (z += outerSize) {
|
while(z < map.pos.voxelSize*CaveMapFragment.width) : (z += outerSize) {
|
||||||
const val000 = getValue(noise, map, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz);
|
const val000 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz);
|
||||||
const val001 = getValue(noise, map, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz + outerSize);
|
const val001 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy, z + map.pos.wz + outerSize);
|
||||||
const val010 = getValue(noise, map, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz);
|
const val010 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz);
|
||||||
const val011 = getValue(noise, map, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize);
|
const val011 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize);
|
||||||
const val100 = getValue(noise, map, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz);
|
const val100 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz);
|
||||||
const val101 = getValue(noise, map, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz + outerSize);
|
const val101 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy, z + map.pos.wz + outerSize);
|
||||||
const val110 = getValue(noise, map, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz);
|
const val110 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz);
|
||||||
const val111 = getValue(noise, map, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize);
|
const val111 = getValue(noise, map, outerSize, biomeMap, x + map.pos.wx + outerSize, y + map.pos.wy + outerSize, z + map.pos.wz + outerSize);
|
||||||
// Test if they are all inside or all outside the cave to skip these cases:
|
// Test if they are all inside or all outside the cave to skip these cases:
|
||||||
const measureForEquality = sign(val000) + sign(val001) + sign(val010) + sign(val011) + sign(val100) + sign(val101) + sign(val110) + sign(val111);
|
const measureForEquality = sign(val000) + sign(val001) + sign(val010) + sign(val011) + sign(val100) + sign(val101) + sign(val110) + sign(val111);
|
||||||
if(measureForEquality == -8) {
|
if(measureForEquality == -8) {
|
||||||
|
@ -129,7 +129,7 @@ fn considerCrystal(x: i32, y: i32, z: i32, chunk: *main.chunk.Chunk, seed: *u64,
|
|||||||
|
|
||||||
fn considerCoordinates(x: i32, y: i32, z: i32, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView, seed: *u64) void {
|
fn considerCoordinates(x: i32, y: i32, z: i32, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView, seed: *u64) void {
|
||||||
var oldSeed = seed.*;
|
var oldSeed = seed.*;
|
||||||
const crystalSpawns = biomeMap.getBiomeAndSeed(x + main.chunk.chunkSize/2 - chunk.pos.wx, y + main.chunk.chunkSize/2 - chunk.pos.wy, z + main.chunk.chunkSize/2 - chunk.pos.wz, seed).crystals;
|
const crystalSpawns = biomeMap.getBiomeAndSeed(x + main.chunk.chunkSize/2 - chunk.pos.wx, y + main.chunk.chunkSize/2 - chunk.pos.wy, z + main.chunk.chunkSize/2 - chunk.pos.wz, true, seed).crystals;
|
||||||
random.scrambleSeed(seed);
|
random.scrambleSeed(seed);
|
||||||
var differendColors: u32 = 1;
|
var differendColors: u32 = 1;
|
||||||
if(random.nextInt(u1, seed) != 0) {
|
if(random.nextInt(u1, seed) != 0) {
|
||||||
|
@ -38,6 +38,7 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(worldSeed: u64, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView) Allocator.Error!void {
|
pub fn generate(worldSeed: u64, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveMapView, biomeMap: CaveBiomeMap.CaveBiomeMapView) Allocator.Error!void {
|
||||||
|
const voxelSizeShift = @ctz(chunk.pos.voxelSize);
|
||||||
var x: u31 = 0;
|
var x: u31 = 0;
|
||||||
while(x < chunk.width) : (x += chunk.pos.voxelSize) {
|
while(x < chunk.width) : (x += chunk.pos.voxelSize) {
|
||||||
var z: u31 = 0;
|
var z: u31 = 0;
|
||||||
@ -46,7 +47,7 @@ pub fn generate(worldSeed: u64, chunk: *main.chunk.Chunk, caveMap: CaveMap.CaveM
|
|||||||
var makeSurfaceStructure = true;
|
var makeSurfaceStructure = true;
|
||||||
var y: i32 = chunk.width - chunk.pos.voxelSize;
|
var y: i32 = chunk.width - chunk.pos.voxelSize;
|
||||||
while(y >= 0) : (y -= chunk.pos.voxelSize) {
|
while(y >= 0) : (y -= chunk.pos.voxelSize) {
|
||||||
const mask = @as(u64, 1) << @intCast(u6, @divExact(y, chunk.pos.voxelSize));
|
const mask = @as(u64, 1) << @intCast(u6, y >> voxelSizeShift);
|
||||||
if(heightData & mask != 0) {
|
if(heightData & mask != 0) {
|
||||||
const biome = biomeMap.getBiome(x, y, z);
|
const biome = biomeMap.getBiome(x, y, z);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user