mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Treegen: Add pine tree. Force place trunks
Speed-optimise leaves blits Use MMVManip for make_jungletree Use correct code style
This commit is contained in:
parent
9527984dbc
commit
74eb14cc80
2 changed files with 495 additions and 266 deletions
730
src/treegen.cpp
730
src/treegen.cpp
|
@ -45,80 +45,75 @@ void make_tree(MMVManip &vmanip, v3s16 p0,
|
||||||
PseudoRandom pr(seed);
|
PseudoRandom pr(seed);
|
||||||
s16 trunk_h = pr.range(4, 5);
|
s16 trunk_h = pr.range(4, 5);
|
||||||
v3s16 p1 = p0;
|
v3s16 p1 = p0;
|
||||||
for(s16 ii=0; ii<trunk_h; ii++)
|
for (s16 ii = 0; ii < trunk_h; ii++) {
|
||||||
{
|
if (vmanip.m_area.contains(p1)) {
|
||||||
if(vmanip.m_area.contains(p1))
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(ii == 0 || vmanip.getNodeNoExNoEmerge(p1).getContent() == CONTENT_AIR)
|
vmanip.m_data[vi] = treenode;
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
}
|
||||||
p1.Y++;
|
p1.Y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// p1 is now the last piece of the trunk
|
// p1 is now the last piece of the trunk
|
||||||
p1.Y -= 1;
|
p1.Y -= 1;
|
||||||
|
|
||||||
VoxelArea leaves_a(v3s16(-2,-1,-2), v3s16(2,2,2));
|
VoxelArea leaves_a(v3s16(-2, -1, -2), v3s16(2, 2, 2));
|
||||||
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
||||||
Buffer<u8> leaves_d(leaves_a.getVolume());
|
Buffer<u8> leaves_d(leaves_a.getVolume());
|
||||||
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
for (s32 i = 0; i < leaves_a.getVolume(); i++)
|
||||||
leaves_d[i] = 0;
|
leaves_d[i] = 0;
|
||||||
|
|
||||||
// Force leaves at near the end of the trunk
|
// Force leaves at near the end of the trunk
|
||||||
{
|
|
||||||
s16 d = 1;
|
s16 d = 1;
|
||||||
for(s16 z=-d; z<=d; z++)
|
for (s16 z = -d; z <= d; z++)
|
||||||
for(s16 y=-d; y<=d; y++)
|
for (s16 y = -d; y <= d; y++)
|
||||||
for(s16 x=-d; x<=d; x++)
|
for (s16 x = -d; x <= d; x++) {
|
||||||
{
|
leaves_d[leaves_a.index(v3s16(x, y, z))] = 1;
|
||||||
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add leaves randomly
|
// Add leaves randomly
|
||||||
for(u32 iii=0; iii<7; iii++)
|
for (u32 iii = 0; iii < 7; iii++) {
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
|
|
||||||
v3s16 p(
|
v3s16 p(
|
||||||
pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X - d),
|
||||||
pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y - d),
|
||||||
pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z - d)
|
||||||
);
|
);
|
||||||
|
|
||||||
for(s16 z=0; z<=d; z++)
|
for (s16 z = 0; z <= d; z++)
|
||||||
for(s16 y=0; y<=d; y++)
|
for (s16 y = 0; y <= d; y++)
|
||||||
for(s16 x=0; x<=d; x++)
|
for (s16 x = 0; x <= d; x++) {
|
||||||
{
|
leaves_d[leaves_a.index(p + v3s16(x, y, z))] = 1;
|
||||||
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blit leaves to vmanip
|
// Blit leaves to vmanip
|
||||||
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++)
|
||||||
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) {
|
||||||
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
v3s16 pmin(leaves_a.MinEdge.X, y, z);
|
||||||
{
|
u32 i = leaves_a.index(pmin);
|
||||||
v3s16 p(x,y,z);
|
u32 vi = vmanip.m_area.index(pmin + p1);
|
||||||
p += p1;
|
for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) {
|
||||||
if(vmanip.m_area.contains(p) == false)
|
v3s16 p(x, y, z);
|
||||||
continue;
|
if (vmanip.m_area.contains(p + p1) == true &&
|
||||||
u32 vi = vmanip.m_area.index(p);
|
(vmanip.m_data[vi].getContent() == CONTENT_AIR ||
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) {
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
if (leaves_d[i] == 1) {
|
||||||
continue;
|
bool is_apple = pr.range(0, 99) < 10;
|
||||||
u32 i = leaves_a.index(x,y,z);
|
if (is_apple_tree && is_apple)
|
||||||
if(leaves_d[i] == 1) {
|
|
||||||
bool is_apple = pr.range(0,99) < 10;
|
|
||||||
if(is_apple_tree && is_apple) {
|
|
||||||
vmanip.m_data[vi] = applenode;
|
vmanip.m_data[vi] = applenode;
|
||||||
} else {
|
else
|
||||||
vmanip.m_data[vi] = leavesnode;
|
vmanip.m_data[vi] = leavesnode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vi++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// L-System tree LUA spawner
|
// L-System tree LUA spawner
|
||||||
treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition)
|
treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0,
|
||||||
|
INodeDefManager *ndef, TreeDef tree_definition)
|
||||||
{
|
{
|
||||||
ServerMap *map = &env->getServerMap();
|
ServerMap *map = &env->getServerMap();
|
||||||
std::map<v3s16, MapBlock*> modified_blocks;
|
std::map<v3s16, MapBlock*> modified_blocks;
|
||||||
|
@ -126,8 +121,8 @@ treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *nd
|
||||||
v3s16 tree_blockp = getNodeBlockPos(p0);
|
v3s16 tree_blockp = getNodeBlockPos(p0);
|
||||||
treegen::error e;
|
treegen::error e;
|
||||||
|
|
||||||
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,3,1));
|
vmanip.initialEmerge(tree_blockp - v3s16(1, 1, 1), tree_blockp + v3s16(1, 3, 1));
|
||||||
e = make_ltree (vmanip, p0, ndef, tree_definition);
|
e = make_ltree(vmanip, p0, ndef, tree_definition);
|
||||||
if (e != SUCCESS)
|
if (e != SUCCESS)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
|
@ -140,30 +135,25 @@ treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *nd
|
||||||
// Send a MEET_OTHER event
|
// Send a MEET_OTHER event
|
||||||
MapEditEvent event;
|
MapEditEvent event;
|
||||||
event.type = MEET_OTHER;
|
event.type = MEET_OTHER;
|
||||||
for(std::map<v3s16, MapBlock*>::iterator
|
for (std::map<v3s16, MapBlock*>::iterator
|
||||||
i = modified_blocks.begin();
|
i = modified_blocks.begin();
|
||||||
i != modified_blocks.end(); ++i)
|
i != modified_blocks.end(); ++i)
|
||||||
{
|
|
||||||
event.modified_blocks.insert(i->first);
|
event.modified_blocks.insert(i->first);
|
||||||
}
|
|
||||||
map->dispatchEvent(&event);
|
map->dispatchEvent(&event);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//L-System tree generator
|
//L-System tree generator
|
||||||
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0,
|
||||||
TreeDef tree_definition)
|
INodeDefManager *ndef, TreeDef tree_definition)
|
||||||
{
|
{
|
||||||
MapNode dirtnode(ndef->getId("mapgen_dirt"));
|
MapNode dirtnode(ndef->getId("mapgen_dirt"));
|
||||||
int seed;
|
int seed;
|
||||||
if (tree_definition.explicit_seed)
|
if (tree_definition.explicit_seed)
|
||||||
{
|
seed = tree_definition.seed + 14002;
|
||||||
seed = tree_definition.seed+14002;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
seed = p0.X * 2 + p0.Y * 4 + p0.Z; // use the tree position to seed PRNG
|
||||||
seed = p0.X*2 + p0.Y*4 + p0.Z; // use the tree position to seed PRNG
|
|
||||||
}
|
|
||||||
PseudoRandom ps(seed);
|
PseudoRandom ps(seed);
|
||||||
|
|
||||||
// chance of inserting abcd rules
|
// chance of inserting abcd rules
|
||||||
|
@ -174,18 +164,18 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
|
|
||||||
//randomize tree growth level, minimum=2
|
//randomize tree growth level, minimum=2
|
||||||
s16 iterations = tree_definition.iterations;
|
s16 iterations = tree_definition.iterations;
|
||||||
if (tree_definition.iterations_random_level>0)
|
if (tree_definition.iterations_random_level > 0)
|
||||||
iterations -= ps.range(0,tree_definition.iterations_random_level);
|
iterations -= ps.range(0, tree_definition.iterations_random_level);
|
||||||
if (iterations<2)
|
if (iterations < 2)
|
||||||
iterations=2;
|
iterations = 2;
|
||||||
|
|
||||||
s16 MAX_ANGLE_OFFSET = 5;
|
s16 MAX_ANGLE_OFFSET = 5;
|
||||||
double angle_in_radians = (double)tree_definition.angle*M_PI/180;
|
double angle_in_radians = (double)tree_definition.angle * M_PI / 180;
|
||||||
double angleOffset_in_radians = (s16)(ps.range(0,1)%MAX_ANGLE_OFFSET)*M_PI/180;
|
double angleOffset_in_radians = (s16)(ps.range(0, 1) % MAX_ANGLE_OFFSET) * M_PI / 180;
|
||||||
|
|
||||||
//initialize rotation matrix, position and stacks for branches
|
//initialize rotation matrix, position and stacks for branches
|
||||||
core::matrix4 rotation;
|
core::matrix4 rotation;
|
||||||
rotation = setRotationAxisRadians(rotation, M_PI/2,v3f(0,0,1));
|
rotation = setRotationAxisRadians(rotation, M_PI / 2, v3f(0, 0, 1));
|
||||||
v3f position;
|
v3f position;
|
||||||
position.X = p0.X;
|
position.X = p0.X;
|
||||||
position.Y = p0.Y;
|
position.Y = p0.Y;
|
||||||
|
@ -195,63 +185,85 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
|
|
||||||
//generate axiom
|
//generate axiom
|
||||||
std::string axiom = tree_definition.initial_axiom;
|
std::string axiom = tree_definition.initial_axiom;
|
||||||
for(s16 i=0; i<iterations; i++)
|
for (s16 i = 0; i < iterations; i++) {
|
||||||
{
|
|
||||||
std::string temp = "";
|
std::string temp = "";
|
||||||
for(s16 j=0; j<(s16)axiom.size(); j++)
|
for (s16 j = 0; j < (s16)axiom.size(); j++) {
|
||||||
{
|
|
||||||
char axiom_char = axiom.at(j);
|
char axiom_char = axiom.at(j);
|
||||||
switch (axiom_char)
|
switch (axiom_char) {
|
||||||
{
|
|
||||||
case 'A':
|
case 'A':
|
||||||
temp+=tree_definition.rules_a;
|
temp += tree_definition.rules_a;
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
temp+=tree_definition.rules_b;
|
temp += tree_definition.rules_b;
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
temp+=tree_definition.rules_c;
|
temp += tree_definition.rules_c;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
temp+=tree_definition.rules_d;
|
temp += tree_definition.rules_d;
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
if (prop_a >= ps.range(1,10))
|
if (prop_a >= ps.range(1, 10))
|
||||||
temp+=tree_definition.rules_a;
|
temp += tree_definition.rules_a;
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if (prop_b >= ps.range(1,10))
|
if (prop_b >= ps.range(1, 10))
|
||||||
temp+=tree_definition.rules_b;
|
temp += tree_definition.rules_b;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (prop_c >= ps.range(1,10))
|
if (prop_c >= ps.range(1, 10))
|
||||||
temp+=tree_definition.rules_c;
|
temp += tree_definition.rules_c;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
if (prop_d >= ps.range(1,10))
|
if (prop_d >= ps.range(1, 10))
|
||||||
temp+=tree_definition.rules_d;
|
temp += tree_definition.rules_d;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
temp+=axiom_char;
|
temp += axiom_char;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
axiom=temp;
|
axiom = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//make sure tree is not floating in the air
|
//make sure tree is not floating in the air
|
||||||
if (tree_definition.trunk_type == "double")
|
if (tree_definition.trunk_type == "double") {
|
||||||
{
|
tree_node_placement(
|
||||||
tree_node_placement(vmanip,v3f(position.X+1,position.Y-1,position.Z),dirtnode);
|
vmanip,
|
||||||
tree_node_placement(vmanip,v3f(position.X,position.Y-1,position.Z+1),dirtnode);
|
v3f(position.X + 1, position.Y - 1, position.Z),
|
||||||
tree_node_placement(vmanip,v3f(position.X+1,position.Y-1,position.Z+1),dirtnode);
|
dirtnode
|
||||||
}
|
);
|
||||||
else if (tree_definition.trunk_type == "crossed")
|
tree_node_placement(
|
||||||
{
|
vmanip,
|
||||||
tree_node_placement(vmanip,v3f(position.X+1,position.Y-1,position.Z),dirtnode);
|
v3f(position.X, position.Y - 1, position.Z + 1),
|
||||||
tree_node_placement(vmanip,v3f(position.X-1,position.Y-1,position.Z),dirtnode);
|
dirtnode
|
||||||
tree_node_placement(vmanip,v3f(position.X,position.Y-1,position.Z+1),dirtnode);
|
);
|
||||||
tree_node_placement(vmanip,v3f(position.X,position.Y-1,position.Z-1),dirtnode);
|
tree_node_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y - 1, position.Z + 1),
|
||||||
|
dirtnode
|
||||||
|
);
|
||||||
|
} else if (tree_definition.trunk_type == "crossed") {
|
||||||
|
tree_node_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y - 1, position.Z),
|
||||||
|
dirtnode
|
||||||
|
);
|
||||||
|
tree_node_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X - 1, position.Y - 1, position.Z),
|
||||||
|
dirtnode
|
||||||
|
);
|
||||||
|
tree_node_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y - 1, position.Z + 1),
|
||||||
|
dirtnode
|
||||||
|
);
|
||||||
|
tree_node_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y - 1, position.Z - 1),
|
||||||
|
dirtnode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build tree out of generated axiom
|
/* build tree out of generated axiom
|
||||||
|
@ -283,84 +295,179 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
s16 x,y,z;
|
s16 x,y,z;
|
||||||
for(s16 i=0; i<(s16)axiom.size(); i++)
|
for (s16 i = 0; i < (s16)axiom.size(); i++) {
|
||||||
{
|
|
||||||
char axiom_char = axiom.at(i);
|
char axiom_char = axiom.at(i);
|
||||||
core::matrix4 temp_rotation;
|
core::matrix4 temp_rotation;
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
v3f dir;
|
v3f dir;
|
||||||
switch (axiom_char)
|
switch (axiom_char) {
|
||||||
{
|
|
||||||
case 'G':
|
case 'G':
|
||||||
dir = v3f(1,0,0);
|
dir = v3f(1, 0, 0);
|
||||||
dir = transposeMatrix(rotation,dir);
|
dir = transposeMatrix(rotation, dir);
|
||||||
position+=dir;
|
position += dir;
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z),tree_definition);
|
tree_trunk_placement(
|
||||||
if (tree_definition.trunk_type == "double" && !tree_definition.thin_branches)
|
vmanip,
|
||||||
{
|
v3f(position.X, position.Y, position.Z),
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z),tree_definition);
|
tree_definition
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z+1),tree_definition);
|
);
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z+1),tree_definition);
|
if (tree_definition.trunk_type == "double" &&
|
||||||
|
!tree_definition.thin_branches) {
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y, position.Z),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
} else if (tree_definition.trunk_type == "crossed" &&
|
||||||
|
!tree_definition.thin_branches) {
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y, position.Z),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X - 1, position.Y, position.Z),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y, position.Z - 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (tree_definition.trunk_type == "crossed" && !tree_definition.thin_branches)
|
dir = v3f(1, 0, 0);
|
||||||
{
|
dir = transposeMatrix(rotation, dir);
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z),tree_definition);
|
position += dir;
|
||||||
tree_trunk_placement(vmanip,v3f(position.X-1,position.Y,position.Z),tree_definition);
|
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z+1),tree_definition);
|
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z-1),tree_definition);
|
|
||||||
}
|
|
||||||
dir = v3f(1,0,0);
|
|
||||||
dir = transposeMatrix(rotation,dir);
|
|
||||||
position+=dir;
|
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z),tree_definition);
|
tree_trunk_placement(
|
||||||
if ((stack_orientation.empty() && tree_definition.trunk_type == "double") ||
|
vmanip,
|
||||||
(!stack_orientation.empty() && tree_definition.trunk_type == "double" && !tree_definition.thin_branches))
|
v3f(position.X, position.Y, position.Z),
|
||||||
{
|
tree_definition
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z),tree_definition);
|
);
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z+1),tree_definition);
|
if ((stack_orientation.empty() &&
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z+1),tree_definition);
|
tree_definition.trunk_type == "double") ||
|
||||||
}
|
(!stack_orientation.empty() &&
|
||||||
else if ((stack_orientation.empty() && tree_definition.trunk_type == "crossed") ||
|
tree_definition.trunk_type == "double" &&
|
||||||
(!stack_orientation.empty() && tree_definition.trunk_type == "crossed" && !tree_definition.thin_branches))
|
!tree_definition.thin_branches)) {
|
||||||
{
|
tree_trunk_placement(
|
||||||
tree_trunk_placement(vmanip,v3f(position.X+1,position.Y,position.Z),tree_definition);
|
vmanip,
|
||||||
tree_trunk_placement(vmanip,v3f(position.X-1,position.Y,position.Z),tree_definition);
|
v3f(position.X +1 , position.Y, position.Z),
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z+1),tree_definition);
|
tree_definition
|
||||||
tree_trunk_placement(vmanip,v3f(position.X,position.Y,position.Z-1),tree_definition);
|
);
|
||||||
}
|
tree_trunk_placement(
|
||||||
if (stack_orientation.empty() == false)
|
vmanip,
|
||||||
{
|
v3f(position.X, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
} else if ((stack_orientation.empty() &&
|
||||||
|
tree_definition.trunk_type == "crossed") ||
|
||||||
|
(!stack_orientation.empty() &&
|
||||||
|
tree_definition.trunk_type == "crossed" &&
|
||||||
|
!tree_definition.thin_branches)) {
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + 1, position.Y, position.Z),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X - 1, position.Y, position.Z),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y, position.Z + 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_trunk_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X, position.Y, position.Z - 1),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
} if (stack_orientation.empty() == false) {
|
||||||
s16 size = 1;
|
s16 size = 1;
|
||||||
for(x=-size; x<=size; x++)
|
for (x = -size; x <= size; x++)
|
||||||
for(y=-size; y<=size; y++)
|
for (y = -size; y <= size; y++)
|
||||||
for(z=-size; z<=size; z++)
|
for (z = -size; z <= size; z++) {
|
||||||
if (abs(x) == size && abs(y) == size && abs(z) == size)
|
if (abs(x) == size &&
|
||||||
{
|
abs(y) == size &&
|
||||||
tree_leaves_placement(vmanip,v3f(position.X+x+1,position.Y+y,position.Z+z),ps.next(), tree_definition);
|
abs(z) == size) {
|
||||||
tree_leaves_placement(vmanip,v3f(position.X+x-1,position.Y+y,position.Z+z),ps.next(), tree_definition);
|
tree_leaves_placement(
|
||||||
tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z+1),ps.next(), tree_definition);
|
vmanip,
|
||||||
tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z-1),ps.next(), tree_definition);
|
v3f(position.X + x + 1, position.Y + y,
|
||||||
|
position.Z + z),
|
||||||
|
ps.next(),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_leaves_placement(
|
||||||
|
vmanip,
|
||||||
|
v3f(position.X + x - 1, position.Y + y,
|
||||||
|
position.Z + z),
|
||||||
|
ps.next(),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_leaves_placement(
|
||||||
|
vmanip,v3f(position.X + x, position.Y + y,
|
||||||
|
position.Z + z + 1),
|
||||||
|
ps.next(),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
tree_leaves_placement(
|
||||||
|
vmanip,v3f(position.X + x, position.Y + y,
|
||||||
|
position.Z + z - 1),
|
||||||
|
ps.next(),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dir = v3f(1,0,0);
|
}
|
||||||
dir = transposeMatrix(rotation,dir);
|
dir = v3f(1, 0, 0);
|
||||||
position+=dir;
|
dir = transposeMatrix(rotation, dir);
|
||||||
|
position += dir;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
tree_single_leaves_placement(vmanip,v3f(position.X,position.Y,position.Z),ps.next() ,tree_definition);
|
tree_single_leaves_placement(
|
||||||
dir = v3f(1,0,0);
|
vmanip,
|
||||||
dir = transposeMatrix(rotation,dir);
|
v3f(position.X, position.Y, position.Z),
|
||||||
position+=dir;
|
ps.next(),
|
||||||
|
tree_definition
|
||||||
|
);
|
||||||
|
dir = v3f(1, 0, 0);
|
||||||
|
dir = transposeMatrix(rotation, dir);
|
||||||
|
position += dir;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
tree_fruit_placement(vmanip,v3f(position.X,position.Y,position.Z),tree_definition);
|
tree_fruit_placement(
|
||||||
dir = v3f(1,0,0);
|
vmanip,
|
||||||
dir = transposeMatrix(rotation,dir);
|
v3f(position.X, position.Y, position.Z),
|
||||||
position+=dir;
|
tree_definition
|
||||||
|
);
|
||||||
|
dir = v3f(1, 0, 0);
|
||||||
|
dir = transposeMatrix(rotation, dir);
|
||||||
|
position += dir;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// turtle orientation commands
|
// turtle orientation commands
|
||||||
|
@ -371,40 +478,46 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
case ']':
|
case ']':
|
||||||
if (stack_orientation.empty())
|
if (stack_orientation.empty())
|
||||||
return UNBALANCED_BRACKETS;
|
return UNBALANCED_BRACKETS;
|
||||||
rotation=stack_orientation.top();
|
rotation = stack_orientation.top();
|
||||||
stack_orientation.pop();
|
stack_orientation.pop();
|
||||||
position=stack_position.top();
|
position = stack_position.top();
|
||||||
stack_position.pop();
|
stack_position.pop();
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,0,1));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians + angleOffset_in_radians, v3f(0, 0, 1));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,0,-1));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians + angleOffset_in_radians, v3f(0, 0, -1));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,1,0));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians + angleOffset_in_radians, v3f(0, 1, 0));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '^':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,-1,0));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians + angleOffset_in_radians, v3f(0, -1, 0));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians,v3f(1,0,0));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians, v3f(1, 0, 0));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
temp_rotation.makeIdentity();
|
temp_rotation.makeIdentity();
|
||||||
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians,v3f(-1,0,0));
|
temp_rotation = setRotationAxisRadians(temp_rotation,
|
||||||
rotation*=temp_rotation;
|
angle_in_radians, v3f(-1, 0, 0));
|
||||||
|
rotation *= temp_rotation;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -414,85 +527,87 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tree_node_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
MapNode node)
|
void tree_node_placement(MMVManip &vmanip, v3f p0, MapNode node)
|
||||||
{
|
{
|
||||||
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if(vmanip.m_area.contains(p1) == false)
|
if (vmanip.m_area.contains(p1) == false)
|
||||||
return;
|
return;
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
if (vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
return;
|
return;
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = node;
|
vmanip.m_data[vmanip.m_area.index(p1)] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tree_trunk_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
TreeDef &tree_definition)
|
void tree_trunk_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if(vmanip.m_area.contains(p1) == false)
|
if (vmanip.m_area.contains(p1) == false)
|
||||||
return;
|
return;
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
if (vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
return;
|
return;
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.trunknode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.trunknode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
void tree_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
PseudoRandom ps ,TreeDef &tree_definition)
|
PseudoRandom ps, TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
MapNode leavesnode=tree_definition.leavesnode;
|
MapNode leavesnode = tree_definition.leavesnode;
|
||||||
if (ps.range(1,100) > 100-tree_definition.leaves2_chance)
|
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
||||||
leavesnode=tree_definition.leaves2node;
|
leavesnode = tree_definition.leaves2node;
|
||||||
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if(vmanip.m_area.contains(p1) == false)
|
if (vmanip.m_area.contains(p1) == false)
|
||||||
return;
|
return;
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
if (vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
return;
|
return;
|
||||||
if (tree_definition.fruit_chance>0)
|
if (tree_definition.fruit_chance > 0) {
|
||||||
{
|
if (ps.range(1, 100) > 100 - tree_definition.fruit_chance)
|
||||||
if (ps.range(1,100) > 100-tree_definition.fruit_chance)
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
|
||||||
else
|
else
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
||||||
}
|
} else if (ps.range(1, 100) > 20) {
|
||||||
else if (ps.range(1,100) > 20)
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
|
||||||
PseudoRandom ps, TreeDef &tree_definition)
|
PseudoRandom ps, TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
MapNode leavesnode=tree_definition.leavesnode;
|
MapNode leavesnode = tree_definition.leavesnode;
|
||||||
if (ps.range(1,100) > 100-tree_definition.leaves2_chance)
|
if (ps.range(1, 100) > 100 - tree_definition.leaves2_chance)
|
||||||
leavesnode=tree_definition.leaves2node;
|
leavesnode = tree_definition.leaves2node;
|
||||||
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if(vmanip.m_area.contains(p1) == false)
|
if (vmanip.m_area.contains(p1) == false)
|
||||||
return;
|
return;
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
if (vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
return;
|
return;
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tree_fruit_placement(MMVManip &vmanip, v3f p0,
|
|
||||||
TreeDef &tree_definition)
|
void tree_fruit_placement(MMVManip &vmanip, v3f p0, TreeDef &tree_definition)
|
||||||
{
|
{
|
||||||
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
v3s16 p1 = v3s16(myround(p0.X), myround(p0.Y), myround(p0.Z));
|
||||||
if(vmanip.m_area.contains(p1) == false)
|
if (vmanip.m_area.contains(p1) == false)
|
||||||
return;
|
return;
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
if (vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
return;
|
return;
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis)
|
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis)
|
||||||
{
|
{
|
||||||
double c = cos(angle);
|
double c = cos(angle);
|
||||||
|
@ -520,20 +635,21 @@ irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3
|
||||||
return M;
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
v3f transposeMatrix(irr::core::matrix4 M, v3f v)
|
v3f transposeMatrix(irr::core::matrix4 M, v3f v)
|
||||||
{
|
{
|
||||||
v3f translated;
|
v3f translated;
|
||||||
double x = M[0] * v.X + M[4] * v.Y + M[8] * v.Z +M[12];
|
double x = M[0] * v.X + M[4] * v.Y + M[8] * v.Z +M[12];
|
||||||
double y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z +M[13];
|
double y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z +M[13];
|
||||||
double z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z +M[14];
|
double z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z +M[14];
|
||||||
translated.X=x;
|
translated.X = x;
|
||||||
translated.Y=y;
|
translated.Y = y;
|
||||||
translated.Z=z;
|
translated.Z = z;
|
||||||
return translated;
|
return translated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
|
||||||
INodeDefManager *ndef, int seed)
|
void make_jungletree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, int seed)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
NOTE: Tree-placing code is currently duplicated in the engine
|
NOTE: Tree-placing code is currently duplicated in the engine
|
||||||
|
@ -551,13 +667,12 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
||||||
MapNode leavesnode(c_leaves);
|
MapNode leavesnode(c_leaves);
|
||||||
|
|
||||||
PseudoRandom pr(seed);
|
PseudoRandom pr(seed);
|
||||||
for(s16 x=-1; x<=1; x++)
|
for (s16 x= -1; x <= 1; x++)
|
||||||
for(s16 z=-1; z<=1; z++)
|
for (s16 z= -1; z <= 1; z++) {
|
||||||
{
|
if (pr.range(0, 2) == 0)
|
||||||
if(pr.range(0, 2) == 0)
|
|
||||||
continue;
|
continue;
|
||||||
v3s16 p1 = p0 + v3s16(x,0,z);
|
v3s16 p1 = p0 + v3s16(x, 0, z);
|
||||||
v3s16 p2 = p0 + v3s16(x,-1,z);
|
v3s16 p2 = p0 + v3s16(x, -1, z);
|
||||||
u32 vi1 = vmanip.m_area.index(p1);
|
u32 vi1 = vmanip.m_area.index(p1);
|
||||||
u32 vi2 = vmanip.m_area.index(p2);
|
u32 vi2 = vmanip.m_area.index(p2);
|
||||||
|
|
||||||
|
@ -572,11 +687,9 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
||||||
|
|
||||||
s16 trunk_h = pr.range(8, 12);
|
s16 trunk_h = pr.range(8, 12);
|
||||||
v3s16 p1 = p0;
|
v3s16 p1 = p0;
|
||||||
for (s16 ii=0; ii<trunk_h; ii++)
|
for (s16 ii = 0; ii < trunk_h; ii++) {
|
||||||
{
|
|
||||||
if (vmanip.m_area.contains(p1)) {
|
if (vmanip.m_area.contains(p1)) {
|
||||||
u32 vi = vmanip.m_area.index(p1);
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
if (vmanip.m_data[vi].getContent() == CONTENT_AIR)
|
|
||||||
vmanip.m_data[vi] = treenode;
|
vmanip.m_data[vi] = treenode;
|
||||||
}
|
}
|
||||||
p1.Y++;
|
p1.Y++;
|
||||||
|
@ -585,59 +698,172 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
||||||
// p1 is now the last piece of the trunk
|
// p1 is now the last piece of the trunk
|
||||||
p1.Y -= 1;
|
p1.Y -= 1;
|
||||||
|
|
||||||
VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3));
|
VoxelArea leaves_a(v3s16(-3, -2, -3), v3s16(3, 2, 3));
|
||||||
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
||||||
Buffer<u8> leaves_d(leaves_a.getVolume());
|
Buffer<u8> leaves_d(leaves_a.getVolume());
|
||||||
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
for (s32 i = 0; i < leaves_a.getVolume(); i++)
|
||||||
leaves_d[i] = 0;
|
leaves_d[i] = 0;
|
||||||
|
|
||||||
// Force leaves at near the end of the trunk
|
// Force leaves at near the end of the trunk
|
||||||
{
|
|
||||||
s16 d = 1;
|
s16 d = 1;
|
||||||
for(s16 z=-d; z<=d; z++)
|
for (s16 z = -d; z <= d; z++)
|
||||||
for(s16 y=-d; y<=d; y++)
|
for (s16 y = -d; y <= d; y++)
|
||||||
for(s16 x=-d; x<=d; x++)
|
for (s16 x = -d; x <= d; x++) {
|
||||||
{
|
|
||||||
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Add leaves randomly
|
// Add leaves randomly
|
||||||
for(u32 iii=0; iii<30; iii++)
|
for (u32 iii = 0; iii < 30; iii++) {
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
|
|
||||||
v3s16 p(
|
v3s16 p(
|
||||||
pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
pr.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X - d),
|
||||||
pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
pr.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y - d),
|
||||||
pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
pr.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z - d)
|
||||||
);
|
);
|
||||||
|
|
||||||
for(s16 z=0; z<=d; z++)
|
for (s16 z = 0; z <= d; z++)
|
||||||
for(s16 y=0; y<=d; y++)
|
for (s16 y = 0; y <= d; y++)
|
||||||
for(s16 x=0; x<=d; x++)
|
for (s16 x = 0; x <= d; x++) {
|
||||||
{
|
leaves_d[leaves_a.index(p + v3s16(x, y, z))] = 1;
|
||||||
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blit leaves to vmanip
|
// Blit leaves to vmanip
|
||||||
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++)
|
||||||
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) {
|
||||||
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
v3s16 pmin(leaves_a.MinEdge.X, y, z);
|
||||||
{
|
u32 i = leaves_a.index(pmin);
|
||||||
v3s16 p(x,y,z);
|
u32 vi = vmanip.m_area.index(pmin + p1);
|
||||||
p += p1;
|
for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) {
|
||||||
if(vmanip.m_area.contains(p) == false)
|
v3s16 p(x, y, z);
|
||||||
continue;
|
if (vmanip.m_area.contains(p + p1) == true &&
|
||||||
u32 vi = vmanip.m_area.index(p);
|
(vmanip.m_data[vi].getContent() == CONTENT_AIR ||
|
||||||
if (vmanip.m_data[vi].getContent() != CONTENT_AIR &&
|
vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) {
|
||||||
vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
if (leaves_d[i] == 1)
|
||||||
continue;
|
|
||||||
u32 i = leaves_a.index(x,y,z);
|
|
||||||
if(leaves_d[i] == 1)
|
|
||||||
vmanip.m_data[vi] = leavesnode;
|
vmanip.m_data[vi] = leavesnode;
|
||||||
}
|
}
|
||||||
|
vi++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void make_pine_tree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef, int seed)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
NOTE: Tree-placing code is currently duplicated in the engine
|
||||||
|
and in games that have saplings; both are deprecated but not
|
||||||
|
replaced yet
|
||||||
|
*/
|
||||||
|
MapNode treenode(ndef->getId("mapgen_pinetree"));
|
||||||
|
MapNode leavesnode(ndef->getId("mapgen_pine_needles"));
|
||||||
|
MapNode snownode(ndef->getId("mapgen_snow"));
|
||||||
|
|
||||||
|
PseudoRandom pr(seed);
|
||||||
|
s16 trunk_h = pr.range(9, 13);
|
||||||
|
v3s16 p1 = p0;
|
||||||
|
for (s16 ii = 0; ii < trunk_h; ii++) {
|
||||||
|
if (vmanip.m_area.contains(p1)) {
|
||||||
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
|
vmanip.m_data[vi] = treenode;
|
||||||
|
}
|
||||||
|
p1.Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make p1 the top node of the trunk
|
||||||
|
p1.Y -= 1;
|
||||||
|
|
||||||
|
VoxelArea leaves_a(v3s16(-3, -6, -3), v3s16(3, 3, 3));
|
||||||
|
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
||||||
|
Buffer<u8> leaves_d(leaves_a.getVolume());
|
||||||
|
for (s32 i = 0; i < leaves_a.getVolume(); i++)
|
||||||
|
leaves_d[i] = 0;
|
||||||
|
|
||||||
|
// Upper branches
|
||||||
|
s16 dev = 3;
|
||||||
|
for (s16 yy = -1; yy <= 1; yy++) {
|
||||||
|
for (s16 zz = -dev; zz <= dev; zz++) {
|
||||||
|
u32 i = leaves_a.index(v3s16(-dev, yy, zz));
|
||||||
|
u32 ia = leaves_a.index(v3s16(-dev, yy+1, zz));
|
||||||
|
for (s16 xx = -dev; xx <= dev; xx++) {
|
||||||
|
if (pr.range(0, 20) <= 19 - dev) {
|
||||||
|
leaves_d[i] = 1;
|
||||||
|
leaves_d[ia] = 2;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
ia++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Centre top nodes
|
||||||
|
u32 i = leaves_a.index(v3s16(0, 1, 0));
|
||||||
|
leaves_d[i] = 1;
|
||||||
|
i = leaves_a.index(v3s16(0, 2, 0));
|
||||||
|
leaves_d[i] = 1;
|
||||||
|
i = leaves_a.index(v3s16(0, 3, 0));
|
||||||
|
leaves_d[i] = 2;
|
||||||
|
|
||||||
|
// Lower branches
|
||||||
|
s16 my = -6;
|
||||||
|
for (u32 iii = 0; iii < 20; iii++) {
|
||||||
|
s16 xi = pr.range(-3, 2);
|
||||||
|
s16 yy = pr.range(-6, -5);
|
||||||
|
s16 zi = pr.range(-3, 2);
|
||||||
|
if (yy > my)
|
||||||
|
my = yy;
|
||||||
|
for (s16 zz = zi; zz <= zi + 1; zz++) {
|
||||||
|
u32 i = leaves_a.index(v3s16(xi, yy, zz));
|
||||||
|
u32 ia = leaves_a.index(v3s16(xi, yy + 1, zz));
|
||||||
|
for (s16 xx = xi; xx <= xi + 1; xx++) {
|
||||||
|
leaves_d[i] = 1;
|
||||||
|
if (leaves_d[ia] == 0)
|
||||||
|
leaves_d[ia] = 2;
|
||||||
|
i++;
|
||||||
|
ia++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = 2;
|
||||||
|
for (s16 yy = my + 1; yy <= my + 2; yy++) {
|
||||||
|
for (s16 zz = -dev; zz <= dev; zz++) {
|
||||||
|
u32 i = leaves_a.index(v3s16(-dev, yy, zz));
|
||||||
|
u32 ia = leaves_a.index(v3s16(-dev, yy + 1, zz));
|
||||||
|
for (s16 xx = -dev; xx <= dev; xx++) {
|
||||||
|
if (pr.range(0, 20) <= 19 - dev) {
|
||||||
|
leaves_d[i] = 1;
|
||||||
|
leaves_d[ia] = 2;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
ia++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blit leaves to vmanip
|
||||||
|
for (s16 z = leaves_a.MinEdge.Z; z <= leaves_a.MaxEdge.Z; z++)
|
||||||
|
for (s16 y = leaves_a.MinEdge.Y; y <= leaves_a.MaxEdge.Y; y++) {
|
||||||
|
v3s16 pmin(leaves_a.MinEdge.X, y, z);
|
||||||
|
u32 i = leaves_a.index(pmin);
|
||||||
|
u32 vi = vmanip.m_area.index(pmin + p1);
|
||||||
|
for (s16 x = leaves_a.MinEdge.X; x <= leaves_a.MaxEdge.X; x++) {
|
||||||
|
v3s16 p(x, y, z);
|
||||||
|
if (vmanip.m_area.contains(p + p1) == true &&
|
||||||
|
(vmanip.m_data[vi].getContent() == CONTENT_AIR ||
|
||||||
|
vmanip.m_data[vi].getContent() == CONTENT_IGNORE ||
|
||||||
|
vmanip.m_data[vi] == snownode)) {
|
||||||
|
if (leaves_d[i] == 1)
|
||||||
|
vmanip.m_data[vi] = leavesnode;
|
||||||
|
else if (leaves_d[i] == 2)
|
||||||
|
vmanip.m_data[vi] = snownode;
|
||||||
|
}
|
||||||
|
vi++;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace treegen
|
}; // namespace treegen
|
||||||
|
|
|
@ -62,7 +62,10 @@ namespace treegen {
|
||||||
void make_tree(MMVManip &vmanip, v3s16 p0,
|
void make_tree(MMVManip &vmanip, v3s16 p0,
|
||||||
bool is_apple_tree, INodeDefManager *ndef, int seed);
|
bool is_apple_tree, INodeDefManager *ndef, int seed);
|
||||||
// Add jungle tree
|
// Add jungle tree
|
||||||
void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
void make_jungletree(MMVManip &vmanip, v3s16 p0,
|
||||||
|
INodeDefManager *ndef, int seed);
|
||||||
|
// Add pine tree
|
||||||
|
void make_pine_tree(MMVManip &vmanip, v3s16 p0,
|
||||||
INodeDefManager *ndef, int seed);
|
INodeDefManager *ndef, int seed);
|
||||||
|
|
||||||
// Add L-Systems tree (used by engine)
|
// Add L-Systems tree (used by engine)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue