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:
paramat 2015-03-28 05:14:53 +00:00
parent 9527984dbc
commit 74eb14cc80
2 changed files with 495 additions and 266 deletions

@ -45,11 +45,11 @@ 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++;
} }
@ -63,21 +63,15 @@ void make_tree(MMVManip &vmanip, v3s16 p0,
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),
@ -86,39 +80,40 @@ void make_tree(MMVManip &vmanip, v3s16 p0,
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);
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); v3s16 p(x, y, z);
p += p1; if (vmanip.m_area.contains(p + p1) == true &&
if(vmanip.m_area.contains(p) == false) (vmanip.m_data[vi].getContent() == CONTENT_AIR ||
continue; vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) {
u32 vi = vmanip.m_area.index(p);
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;
u32 i = leaves_a.index(x,y,z);
if (leaves_d[i] == 1) { if (leaves_d[i] == 1) {
bool is_apple = pr.range(0, 99) < 10; bool is_apple = pr.range(0, 99) < 10;
if(is_apple_tree && is_apple) { 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;
@ -143,27 +138,22 @@ treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *nd
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
@ -195,14 +185,11 @@ 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;
@ -240,18 +227,43 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
} }
//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,67 +295,153 @@ 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) {
else if (tree_definition.trunk_type == "crossed" && !tree_definition.thin_branches) tree_trunk_placement(
{ 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-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,position.Y,position.Z-1),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
);
} }
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 '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 = v3f(1, 0, 0);
@ -351,13 +449,22 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
position += 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(
vmanip,
v3f(position.X, position.Y, position.Z),
ps.next(),
tree_definition
);
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 'R': case 'R':
tree_fruit_placement(vmanip,v3f(position.X,position.Y,position.Z),tree_definition); tree_fruit_placement(
vmanip,
v3f(position.X, position.Y, position.Z),
tree_definition
);
dir = v3f(1, 0, 0); dir = v3f(1, 0, 0);
dir = transposeMatrix(rotation, dir); dir = transposeMatrix(rotation, dir);
position += dir; position += dir;
@ -378,32 +485,38 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
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,
angle_in_radians + angleOffset_in_radians, v3f(0, 0, 1));
rotation *= temp_rotation; 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,
angle_in_radians + angleOffset_in_radians, v3f(0, 0, -1));
rotation *= temp_rotation; 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,
angle_in_radians + angleOffset_in_radians, v3f(0, 1, 0));
rotation *= temp_rotation; 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,
angle_in_radians + angleOffset_in_radians, v3f(0, -1, 0));
rotation *= temp_rotation; 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,
angle_in_radians, v3f(1, 0, 0));
rotation *= temp_rotation; 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,
angle_in_radians, v3f(-1, 0, 0));
rotation *= temp_rotation; rotation *= temp_rotation;
break; break;
default: default:
@ -414,8 +527,8 @@ 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)
@ -427,8 +540,8 @@ void tree_node_placement(MMVManip &vmanip, v3f p0,
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)
@ -440,6 +553,7 @@ void tree_trunk_placement(MMVManip &vmanip, v3f p0,
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)
{ {
@ -453,16 +567,16 @@ void tree_leaves_placement(MMVManip &vmanip, v3f p0,
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)
@ -480,8 +594,8 @@ void tree_single_leaves_placement(MMVManip &vmanip, v3f p0,
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)
@ -493,6 +607,7 @@ void tree_fruit_placement(MMVManip &vmanip, v3f p0,
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,6 +635,7 @@ 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;
@ -532,8 +648,8 @@ v3f transposeMatrix(irr::core::matrix4 M, v3f v)
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
@ -552,8 +668,7 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
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);
@ -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++;
@ -592,21 +705,15 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
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),
@ -615,29 +722,148 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
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);
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); v3s16 p(x, y, z);
p += p1; if (vmanip.m_area.contains(p + p1) == true &&
if(vmanip.m_area.contains(p) == false) (vmanip.m_data[vi].getContent() == CONTENT_AIR ||
continue; vmanip.m_data[vi].getContent() == CONTENT_IGNORE)) {
u32 vi = vmanip.m_area.index(p);
if (vmanip.m_data[vi].getContent() != CONTENT_AIR &&
vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
continue;
u32 i = leaves_a.index(x,y,z);
if (leaves_d[i] == 1) 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)