mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-04 03:37:59 -04:00
Allow configuring leaf radius and tree height independently.
fixes #519
This commit is contained in:
parent
02fff0fd4c
commit
d2bc6e6428
@ -22,9 +22,11 @@
|
||||
"log" : "cubyz:oak_log",
|
||||
"top" : "cubyz:oak_top",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 4,
|
||||
"height_variation" : 6
|
||||
"type" : "round",
|
||||
"height" : 1,
|
||||
"height_variation" : 1,
|
||||
"leafRadius" : 2,
|
||||
"leafRadius_variation" : 1,
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:ground_patch",
|
||||
|
@ -34,8 +34,10 @@
|
||||
"top" : "cubyz:birch_top",
|
||||
"chance" : 0.01,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3.5,
|
||||
"leafRadius_variation" : 1.5
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:fallen_tree",
|
||||
|
@ -22,8 +22,10 @@
|
||||
"top" : "cubyz:chalk/aqua",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -32,8 +34,10 @@
|
||||
"top" : "cubyz:chalk/black",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -42,8 +46,10 @@
|
||||
"top" : "cubyz:chalk/blue",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -52,8 +58,10 @@
|
||||
"top" : "cubyz:chalk/brown",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -62,8 +70,10 @@
|
||||
"top" : "cubyz:chalk/crimson",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -72,8 +82,10 @@
|
||||
"top" : "cubyz:chalk/cyan",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -82,8 +94,10 @@
|
||||
"top" : "cubyz:chalk/dark_grey",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -92,8 +106,10 @@
|
||||
"top" : "cubyz:chalk/green",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -102,8 +118,10 @@
|
||||
"top" : "cubyz:chalk/grey",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -112,8 +130,10 @@
|
||||
"top" : "cubyz:chalk/indigo",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -122,8 +142,10 @@
|
||||
"top" : "cubyz:chalk/lime",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -132,8 +154,10 @@
|
||||
"top" : "cubyz:chalk/magenta",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -142,8 +166,10 @@
|
||||
"top" : "cubyz:chalk/orange",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -152,8 +178,10 @@
|
||||
"top" : "cubyz:chalk/pink",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -162,8 +190,10 @@
|
||||
"top" : "cubyz:chalk/purple",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -172,8 +202,10 @@
|
||||
"top" : "cubyz:chalk/red",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -182,8 +214,10 @@
|
||||
"top" : "cubyz:chalk/violet",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -192,8 +226,10 @@
|
||||
"top" : "cubyz:chalk/viridian",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -202,8 +238,10 @@
|
||||
"top" : "cubyz:chalk/white",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -212,8 +250,10 @@
|
||||
"top" : "cubyz:chalk/yellow",
|
||||
"chance" : 0.0005,
|
||||
"type" : "round",
|
||||
"height" : 6,
|
||||
"height_variation" : 3
|
||||
"height" : 10,
|
||||
"height_variation" : 5,
|
||||
"leafRadius" : 3,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -23,7 +23,9 @@
|
||||
"chance" : 0.001,
|
||||
"type" : "round",
|
||||
"height" : 12,
|
||||
"height_variation" : 10
|
||||
"height_variation" : 10,
|
||||
"leafRadius" : 5,
|
||||
"leafRadius_variation" : 6
|
||||
}
|
||||
],
|
||||
|
||||
|
@ -35,9 +35,11 @@
|
||||
"log" : "cubyz:fog/red",
|
||||
"top" : "cubyz:fog/red",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -45,9 +47,11 @@
|
||||
"log" : "cubyz:fog/green",
|
||||
"top" : "cubyz:fog/green",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -55,9 +59,11 @@
|
||||
"log" : "cubyz:fog/blue",
|
||||
"top" : "cubyz:fog/blue",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -65,9 +71,11 @@
|
||||
"log" : "cubyz:fog/yellow",
|
||||
"top" : "cubyz:fog/yellow",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -75,9 +83,11 @@
|
||||
"log" : "cubyz:fog/cyan",
|
||||
"top" : "cubyz:fog/cyan",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
{
|
||||
"id" : "cubyz:simple_tree",
|
||||
@ -85,9 +95,11 @@
|
||||
"log" : "cubyz:fog/magenta",
|
||||
"top" : "cubyz:fog/magenta",
|
||||
"chance" : 0.01,
|
||||
"type" : "bush",
|
||||
"height" : 32,
|
||||
"height_variation" : 3
|
||||
"type" : "round",
|
||||
"height" : 0,
|
||||
"height_variation" : 0,
|
||||
"leafRadius" : 16,
|
||||
"leafRadius_variation" : 3
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ const SimpleTreeModel = @This();
|
||||
const Type = enum {
|
||||
pyramid,
|
||||
round,
|
||||
bush,
|
||||
};
|
||||
|
||||
typ: Type,
|
||||
@ -27,17 +26,24 @@ woodBlock: u16,
|
||||
topWoodBlock: u16,
|
||||
height0: i32,
|
||||
deltaHeight: u31,
|
||||
leafRadius: f32,
|
||||
deltaLeafRadius: f32,
|
||||
branched: bool,
|
||||
|
||||
pub fn loadModel(arenaAllocator: NeverFailingAllocator, parameters: JsonElement) *SimpleTreeModel {
|
||||
const self = arenaAllocator.create(SimpleTreeModel);
|
||||
self.* = .{
|
||||
.typ = std.meta.stringToEnum(Type, parameters.get([]const u8, "type", "")) orelse .round,
|
||||
.typ = std.meta.stringToEnum(Type, parameters.get([]const u8, "type", "")) orelse blk: {
|
||||
if(parameters.get(?[]const u8, "type", null)) |typ| std.log.err("Unknown tree type \"{s}\"", .{typ});
|
||||
break :blk .round;
|
||||
},
|
||||
.leavesBlock = main.blocks.getByID(parameters.get([]const u8, "leaves", "cubyz:oak_leaves")),
|
||||
.woodBlock = main.blocks.getByID(parameters.get([]const u8, "log", "cubyz:oak_log")),
|
||||
.topWoodBlock = main.blocks.getByID(parameters.get([]const u8, "top", "cubyz:oak_top")),
|
||||
.height0 = parameters.get(i32, "height", 6),
|
||||
.deltaHeight = parameters.get(u31, "height_variation", 3),
|
||||
.leafRadius = parameters.get(f32, "leafRadius", (1 + parameters.get(f32, "height", 6))/2),
|
||||
.deltaLeafRadius = parameters.get(f32, "leafRadius_variation", parameters.get(f32, "height_variation", 3)/2),
|
||||
.branched = parameters.get(bool, "branched", true),
|
||||
};
|
||||
return self;
|
||||
@ -78,7 +84,9 @@ pub fn generateBranch(self: *SimpleTreeModel, x: i32, y: i32, z: i32, d: u32, ch
|
||||
}
|
||||
|
||||
pub fn generate(self: *SimpleTreeModel, x: i32, y: i32, z: i32, chunk: *main.chunk.ServerChunk, caveMap: terrain.CaveMap.CaveMapView, seed: *u64) void {
|
||||
var height = self.height0 + random.nextIntBounded(u31, seed, self.deltaHeight);
|
||||
const factor = random.nextFloat(seed);
|
||||
var height = self.height0 + @as(i32, @intFromFloat(factor*@as(f32, @floatFromInt(self.deltaHeight))));
|
||||
const leafRadius = self.leafRadius + factor*self.deltaLeafRadius;
|
||||
|
||||
if(z + height >= caveMap.findTerrainChangeAbove(x, y, z)) // Space is too small.Allocator
|
||||
return;
|
||||
@ -116,17 +124,16 @@ pub fn generate(self: *SimpleTreeModel, x: i32, y: i32, z: i32, chunk: *main.chu
|
||||
.round => {
|
||||
self.generateStem(x, y, z, height, chunk, seed);
|
||||
|
||||
const leafRadius = 1 + @divFloor(height, 2);
|
||||
const floatLeafRadius = @as(f32, @floatFromInt(leafRadius)) - random.nextFloat(seed);
|
||||
const radiusSqr: i32 = @intFromFloat(floatLeafRadius*floatLeafRadius);
|
||||
const randomRadiusSqr: i32 = @intFromFloat((floatLeafRadius - 0.25)*(floatLeafRadius - 0.25));
|
||||
const ceilRadius: i32 = @intFromFloat(@ceil(leafRadius));
|
||||
const radiusSqr: i32 = @intFromFloat(leafRadius*leafRadius);
|
||||
const randomRadiusSqr: i32 = @intFromFloat((leafRadius - 0.25)*(leafRadius - 0.25));
|
||||
const center = z + height;
|
||||
var pz = chunk.startIndex(center - leafRadius);
|
||||
while(pz < center + leafRadius) : (pz += chunk.super.pos.voxelSize) {
|
||||
var px = chunk.startIndex(x - leafRadius);
|
||||
while(px < x + leafRadius) : (px += chunk.super.pos.voxelSize) {
|
||||
var py = chunk.startIndex(y - leafRadius);
|
||||
while(py < y + leafRadius) : (py += chunk.super.pos.voxelSize) {
|
||||
var pz = chunk.startIndex(center - ceilRadius);
|
||||
while(pz < center + ceilRadius) : (pz += chunk.super.pos.voxelSize) {
|
||||
var px = chunk.startIndex(x - ceilRadius);
|
||||
while(px < x + ceilRadius) : (px += chunk.super.pos.voxelSize) {
|
||||
var py = chunk.startIndex(y - ceilRadius);
|
||||
while(py < y + ceilRadius) : (py += chunk.super.pos.voxelSize) {
|
||||
const distSqr = (pz - center)*(pz - center) + (px - x)*(px - x) + (py - y)*(py - y);
|
||||
if(chunk.liesInChunk(px, py, pz) and distSqr < radiusSqr and (distSqr < randomRadiusSqr or random.nextInt(u1, seed) != 0)) { // TODO: Use another seed to make this more reliable!
|
||||
chunk.updateBlockIfDegradable(px, py, pz, .{.typ = self.leavesBlock, .data = 0}); // TODO: Natural standard.
|
||||
@ -135,30 +142,5 @@ pub fn generate(self: *SimpleTreeModel, x: i32, y: i32, z: i32, chunk: *main.chu
|
||||
}
|
||||
}
|
||||
},
|
||||
.bush => {
|
||||
const oldHeight = height;
|
||||
height = @min(2, height); // Make sure the stem of the bush stays small.
|
||||
|
||||
self.generateStem(x, y, z, height, chunk, seed);
|
||||
|
||||
const leafRadius = 1 + @divFloor(oldHeight, 2);
|
||||
const floatLeafRadius = @as(f32, @floatFromInt(leafRadius)) - random.nextFloat(seed);
|
||||
const radiusSqr: i32 = @intFromFloat(floatLeafRadius*floatLeafRadius);
|
||||
const randomRadiusSqr: i32 = @intFromFloat((floatLeafRadius - 0.25)*(floatLeafRadius - 0.25));
|
||||
const center = z + height;
|
||||
var pz = chunk.startIndex(center - leafRadius);
|
||||
while(pz < center + leafRadius) : (pz += chunk.super.pos.voxelSize) {
|
||||
var px = chunk.startIndex(x - leafRadius);
|
||||
while(px < x + leafRadius) : (px += chunk.super.pos.voxelSize) {
|
||||
var py = chunk.startIndex(y - leafRadius);
|
||||
while(py < y + leafRadius) : (py += chunk.super.pos.voxelSize) {
|
||||
const distSqr = (pz - center)*(pz - center) + (px - x)*(px - x) + (py - y)*(py - y);
|
||||
if(chunk.liesInChunk(px, py, pz) and distSqr < radiusSqr and (distSqr < randomRadiusSqr or random.nextInt(u1, seed) != 0)) { // TODO: Use another seed to make this more reliable!
|
||||
chunk.updateBlockIfDegradable(px, py, pz, .{.typ = self.leavesBlock, .data = 0}); // TODO: Natural standard.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user