Expand Up
@@ -45,89 +45,84 @@ void make_tree(MMVManip &vmanip, v3s16 p0,
PseudoRandom pr (seed);
s16 trunk_h = pr.range (4 , 5 );
v3s16 p1 = p0;
for (s16 ii= 0 ; ii< trunk_h; ii++)
{
if ( vmanip.m_area .contains (p1))
if (ii == 0 || vmanip.getNodeNoExNoEmerge (p1). getContent () == CONTENT_AIR)
vmanip. m_data [vmanip. m_area . index (p1)] = treenode;
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 ++;
}
// p1 is now the last piece of the trunk
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()]);
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 ;
// Force leaves at near the end of the trunk
{
s16 d = 1 ;
for (s16 z=-d; z<=d; z++)
for (s16 y=-d; y<=d; y++)
for (s16 x=-d; x<=d; x++)
{
leaves_d[leaves_a.index (v3s16 (x,y,z))] = 1 ;
}
s16 d = 1 ;
for (s16 z = -d; z <= d; z++)
for (s16 y = -d; y <= d; y++)
for (s16 x = -d; x <= d; x++) {
leaves_d[leaves_a.index (v3s16 (x, y, z))] = 1 ;
}
// Add leaves randomly
for (u32 iii=0 ; iii<7 ; iii++)
{
s16 d = 1 ;
for (u32 iii = 0 ; iii < 7 ; iii++) {
v3s16 p (
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 .Z , leaves_a.MaxEdge .Z - 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 .Z , leaves_a.MaxEdge .Z - d)
);
for (s16 z=0 ; z<=d; z++)
for (s16 y=0 ; y<=d; y++)
for (s16 x=0 ; x<=d; x++)
{
leaves_d[leaves_a.index (p+v3s16 (x,y,z))] = 1 ;
for (s16 z = 0 ; z <= d; z++)
for (s16 y = 0 ; y <= d; y++)
for (s16 x = 0 ; x <= d; x++) {
leaves_d[leaves_a.index (p + v3s16 (x, y, z))] = 1 ;
}
}
// 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++)
for (s16 x=leaves_a.MinEdge .X ; x<=leaves_a.MaxEdge .X ; x++)
{
v3s16 p (x,y,z);
p += p1;
if (vmanip.m_area .contains (p) == false )
continue ;
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 ) {
bool is_apple = pr.range (0 ,99 ) < 10 ;
if (is_apple_tree && is_apple) {
vmanip.m_data [vi] = applenode;
} else {
vmanip.m_data [vi] = leavesnode;
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)) {
if (leaves_d[i] == 1 ) {
bool is_apple = pr.range (0 , 99 ) < 10 ;
if (is_apple_tree && is_apple)
vmanip.m_data [vi] = applenode;
else
vmanip.m_data [vi] = leavesnode;
}
}
vi++;
i++;
}
}
}
// 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 ();
std::map<v3s16, MapBlock*> modified_blocks;
MMVManip vmanip (map);
v3s16 tree_blockp = getNodeBlockPos (p0);
treegen::error e;
vmanip.initialEmerge (tree_blockp - v3s16 (1 ,1 , 1 ), tree_blockp + v3s16 (1 ,3 , 1 ));
e = make_ltree (vmanip, p0, ndef, tree_definition);
vmanip.initialEmerge (tree_blockp - v3s16 (1 , 1 , 1 ), tree_blockp + v3s16 (1 , 3 , 1 ));
e = make_ltree (vmanip, p0, ndef, tree_definition);
if (e != SUCCESS)
return e;
Expand All
@@ -140,30 +135,25 @@ treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *nd
// Send a MEET_OTHER event
MapEditEvent event;
event.type = MEET_OTHER;
for (std::map<v3s16, MapBlock*>::iterator
i = modified_blocks.begin ();
i != modified_blocks.end (); ++i)
{
for (std::map<v3s16, MapBlock*>::iterator
i = modified_blocks.begin ();
i != modified_blocks.end (); ++i)
event.modified_blocks .insert (i->first );
}
map->dispatchEvent (&event);
return SUCCESS;
}
// L-System tree generator
treegen::error make_ltree (MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
TreeDef tree_definition)
treegen::error make_ltree (MMVManip &vmanip, v3s16 p0,
INodeDefManager *ndef, TreeDef tree_definition)
{
MapNode dirtnode (ndef->getId (" mapgen_dirt" ));
int seed;
if (tree_definition.explicit_seed )
{
seed = tree_definition.seed +14002 ;
}
seed = tree_definition.seed + 14002 ;
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);
// chance of inserting abcd rules
Expand All
@@ -174,18 +164,18 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
// randomize tree growth level, minimum=2
s16 iterations = tree_definition.iterations ;
if (tree_definition.iterations_random_level > 0 )
iterations -= ps.range (0 ,tree_definition.iterations_random_level );
if (iterations< 2 )
iterations= 2 ;
if (tree_definition.iterations_random_level > 0 )
iterations -= ps.range (0 , tree_definition.iterations_random_level );
if (iterations < 2 )
iterations = 2 ;
s16 MAX_ANGLE_OFFSET = 5 ;
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 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 ;
// initialize rotation matrix, position and stacks for branches
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;
position.X = p0.X ;
position.Y = p0.Y ;
Expand All
@@ -195,63 +185,85 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
// generate 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 = " " ;
for (s16 j=0 ; j<(s16)axiom.size (); j++)
{
for (s16 j = 0 ; j < (s16)axiom.size (); j++) {
char axiom_char = axiom.at (j);
switch (axiom_char)
{
switch (axiom_char) {
case ' A' :
temp+= tree_definition.rules_a ;
temp += tree_definition.rules_a ;
break ;
case ' B' :
temp+= tree_definition.rules_b ;
temp += tree_definition.rules_b ;
break ;
case ' C' :
temp+= tree_definition.rules_c ;
temp += tree_definition.rules_c ;
break ;
case ' D' :
temp+= tree_definition.rules_d ;
temp += tree_definition.rules_d ;
break ;
case ' a' :
if (prop_a >= ps.range (1 ,10 ))
temp+= tree_definition.rules_a ;
if (prop_a >= ps.range (1 , 10 ))
temp += tree_definition.rules_a ;
break ;
case ' b' :
if (prop_b >= ps.range (1 ,10 ))
temp+= tree_definition.rules_b ;
if (prop_b >= ps.range (1 , 10 ))
temp += tree_definition.rules_b ;
break ;
case ' c' :
if (prop_c >= ps.range (1 ,10 ))
temp+= tree_definition.rules_c ;
if (prop_c >= ps.range (1 , 10 ))
temp += tree_definition.rules_c ;
break ;
case ' d' :
if (prop_d >= ps.range (1 ,10 ))
temp+= tree_definition.rules_d ;
if (prop_d >= ps.range (1 , 10 ))
temp += tree_definition.rules_d ;
break ;
default :
temp+= axiom_char;
temp += axiom_char;
break ;
}
}
axiom= temp;
axiom = temp;
}
// make sure tree is not floating in the air
if (tree_definition.trunk_type == " double" )
{
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 +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);
if (tree_definition.trunk_type == " double" ) {
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 + 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
Expand Down
Expand Up
@@ -283,84 +295,179 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
*/
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);
core::matrix4 temp_rotation;
temp_rotation.makeIdentity ();
v3f dir;
switch (axiom_char)
{
switch (axiom_char) {
case ' G' :
dir = v3f (1 ,0 , 0 );
dir = transposeMatrix (rotation,dir);
position+= dir;
dir = v3f (1 , 0 , 0 );
dir = transposeMatrix (rotation, dir);
position += dir;
break ;
case ' T' :
tree_trunk_placement (vmanip,v3f (position.X ,position.Y ,position.Z ),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);
tree_trunk_placement (
vmanip,
v3f (position.X , position.Y , position.Z ),
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
);
}
dir = v3f (1 ,0 , 0 );
dir = transposeMatrix (rotation,dir);
position+= dir;
dir = v3f (1 , 0 , 0 );
dir = transposeMatrix (rotation, dir);
position += dir;
break ;
case ' F' :
tree_trunk_placement (vmanip,v3f (position.X ,position.Y ,position.Z ),tree_definition);
if ((stack_orientation.empty () && tree_definition.trunk_type == " double" ) ||
(!stack_orientation.empty () && 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 ((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 )
{
tree_trunk_placement (
vmanip,
v3f (position.X , position.Y , position.Z ),
tree_definition
);
if ((stack_orientation.empty () &&
tree_definition.trunk_type == " double" ) ||
(!stack_orientation.empty () &&
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 ((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 ;
for (x=-size; x<=size; x++)
for (y=-size; y<=size; y++)
for (z=-size; z<=size; z++)
if (abs (x) == size && abs (y) == size && 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 (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);
}
for (x = -size; x <= size; x++)
for (y = -size; y <= size; y++)
for (z = -size; z <= size; z++) {
if (abs (x) == size &&
abs (y) == size &&
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 (
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);
position+= dir;
dir = v3f (1 , 0 , 0 );
dir = transposeMatrix (rotation, dir);
position += dir;
break ;
case ' f' :
tree_single_leaves_placement (vmanip,v3f (position.X ,position.Y ,position.Z ),ps.next () ,tree_definition);
dir = v3f (1 ,0 ,0 );
dir = transposeMatrix (rotation,dir);
position+=dir;
tree_single_leaves_placement (
vmanip,
v3f (position.X , position.Y , position.Z ),
ps.next (),
tree_definition
);
dir = v3f (1 , 0 , 0 );
dir = transposeMatrix (rotation, dir);
position += dir;
break ;
case ' R' :
tree_fruit_placement (vmanip,v3f (position.X ,position.Y ,position.Z ),tree_definition);
dir = v3f (1 ,0 ,0 );
dir = transposeMatrix (rotation,dir);
position+=dir;
tree_fruit_placement (
vmanip,
v3f (position.X , position.Y , position.Z ),
tree_definition
);
dir = v3f (1 , 0 , 0 );
dir = transposeMatrix (rotation, dir);
position += dir;
break ;
// turtle orientation commands
Expand All
@@ -371,40 +478,46 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
case ' ]' :
if (stack_orientation.empty ())
return UNBALANCED_BRACKETS;
rotation= stack_orientation.top ();
rotation = stack_orientation.top ();
stack_orientation.pop ();
position= stack_position.top ();
position = stack_position.top ();
stack_position.pop ();
break ;
case ' +' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians+angleOffset_in_radians,v3f (0 ,0 ,1 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians + angleOffset_in_radians, v3f (0 , 0 , 1 ));
rotation *= temp_rotation;
break ;
case ' -' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians+angleOffset_in_radians,v3f (0 ,0 ,-1 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians + angleOffset_in_radians, v3f (0 , 0 , -1 ));
rotation *= temp_rotation;
break ;
case ' &' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians+angleOffset_in_radians,v3f (0 ,1 ,0 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians + angleOffset_in_radians, v3f (0 , 1 , 0 ));
rotation *= temp_rotation;
break ;
case ' ^' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians+angleOffset_in_radians,v3f (0 ,-1 ,0 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians + angleOffset_in_radians, v3f (0 , -1 , 0 ));
rotation *= temp_rotation;
break ;
case ' *' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians,v3f (1 ,0 ,0 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians, v3f (1 , 0 , 0 ));
rotation *= temp_rotation;
break ;
case ' /' :
temp_rotation.makeIdentity ();
temp_rotation=setRotationAxisRadians (temp_rotation, angle_in_radians,v3f (-1 ,0 ,0 ));
rotation*=temp_rotation;
temp_rotation = setRotationAxisRadians (temp_rotation,
angle_in_radians, v3f (-1 , 0 , 0 ));
rotation *= temp_rotation;
break ;
default :
break ;
Expand All
@@ -414,85 +527,87 @@ treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, INodeDefManager *ndef,
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 ));
if (vmanip.m_area .contains (p1) == false )
v3s16 p1 = v3s16 (myround (p0.X ), myround (p0.Y ), myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
return ;
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)
return ;
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 ));
if (vmanip.m_area .contains (p1) == false )
v3s16 p1 = v3s16 (myround (p0.X ), myround (p0.Y ), myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
return ;
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)
return ;
vmanip.m_data [vmanip.m_area .index (p1)] = tree_definition.trunknode ;
}
void tree_leaves_placement (MMVManip &vmanip, v3f p0,
PseudoRandom ps , TreeDef &tree_definition)
PseudoRandom ps, TreeDef &tree_definition)
{
MapNode leavesnode= tree_definition.leavesnode ;
if (ps.range (1 ,100 ) > 100 - tree_definition.leaves2_chance )
leavesnode= tree_definition.leaves2node ;
v3s16 p1 = v3s16 (myround (p0.X ),myround (p0.Y ),myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
MapNode leavesnode = tree_definition.leavesnode ;
if (ps.range (1 , 100 ) > 100 - tree_definition.leaves2_chance )
leavesnode = tree_definition.leaves2node ;
v3s16 p1 = v3s16 (myround (p0.X ), myround (p0.Y ), myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
return ;
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)
return ;
if (tree_definition.fruit_chance >0 )
{
if (ps.range (1 ,100 ) > 100 -tree_definition.fruit_chance )
if (tree_definition.fruit_chance > 0 ) {
if (ps.range (1 , 100 ) > 100 - tree_definition.fruit_chance )
vmanip.m_data [vmanip.m_area .index (p1)] = tree_definition.fruitnode ;
else
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;
}
}
void tree_single_leaves_placement (MMVManip &vmanip, v3f p0,
PseudoRandom ps, TreeDef &tree_definition)
{
MapNode leavesnode= tree_definition.leavesnode ;
if (ps.range (1 ,100 ) > 100 - tree_definition.leaves2_chance )
leavesnode= tree_definition.leaves2node ;
v3s16 p1 = v3s16 (myround (p0.X ),myround (p0.Y ),myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
MapNode leavesnode = tree_definition.leavesnode ;
if (ps.range (1 , 100 ) > 100 - tree_definition.leaves2_chance )
leavesnode = tree_definition.leaves2node ;
v3s16 p1 = v3s16 (myround (p0.X ), myround (p0.Y ), myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
return ;
u32 vi = vmanip.m_area .index (p1);
if (vmanip.m_data [vi].getContent () != CONTENT_AIR
&& vmanip.m_data [vi].getContent () != CONTENT_IGNORE)
if (vmanip.m_data [vi].getContent () != CONTENT_AIR
&& vmanip.m_data [vi].getContent () != CONTENT_IGNORE)
return ;
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 ));
if (vmanip.m_area .contains (p1) == false )
v3s16 p1 = v3s16 (myround (p0.X ), myround (p0.Y ), myround (p0.Z ));
if (vmanip.m_area .contains (p1) == false )
return ;
u32 vi = vmanip.m_area .index (p1);
if (vmanip.m_data [vi].getContent () != CONTENT_AIR
&& vmanip.m_data [vi].getContent () != CONTENT_IGNORE)
if (vmanip.m_data [vi].getContent () != CONTENT_AIR
&& vmanip.m_data [vi].getContent () != CONTENT_IGNORE)
return ;
vmanip.m_data [vmanip.m_area .index (p1)] = tree_definition.fruitnode ;
}
irr::core::matrix4 setRotationAxisRadians (irr::core::matrix4 M, double angle, v3f axis)
{
double c = cos (angle);
Expand Down
Expand Up
@@ -520,20 +635,21 @@ irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3
return M;
}
v3f transposeMatrix (irr::core::matrix4 M, v3f v)
{
v3f translated;
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 z = M[2 ] * v.X + M[6 ] * v.Y + M[10 ] * v.Z +M[14 ];
translated.X = x;
translated.Y = y;
translated.Z = z;
translated.X = x;
translated.Y = y;
translated.Z = z;
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
Expand All
@@ -551,18 +667,17 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
MapNode leavesnode (c_leaves);
PseudoRandom pr (seed);
for (s16 x=-1 ; x<=1 ; x++)
for (s16 z=-1 ; z<=1 ; z++)
{
if (pr.range (0 , 2 ) == 0 )
for (s16 x= -1 ; x <= 1 ; x++)
for (s16 z= -1 ; z <= 1 ; z++) {
if (pr.range (0 , 2 ) == 0 )
continue ;
v3s16 p1 = p0 + v3s16 (x,0 , z);
v3s16 p2 = p0 + v3s16 (x,-1 ,z);
v3s16 p1 = p0 + v3s16 (x, 0 , z);
v3s16 p2 = p0 + v3s16 (x, -1 , z);
u32 vi1 = vmanip.m_area .index (p1);
u32 vi2 = vmanip.m_area .index (p2);
if (vmanip.m_area .contains (p2) &&
vmanip.m_data [vi2].getContent () == CONTENT_AIR)
vmanip.m_data [vi2].getContent () == CONTENT_AIR)
vmanip.m_data [vi2] = treenode;
else if (vmanip.m_area .contains (p1) &&
vmanip.m_data [vi1].getContent () == CONTENT_AIR)
Expand All
@@ -572,71 +687,182 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
s16 trunk_h = pr.range (8 , 12 );
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)) {
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 is now the last piece of the trunk
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()]);
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 ;
// Force leaves at near the end of the trunk
{
s16 d = 1 ;
for (s16 z=-d; z<=d; z++)
for (s16 y=-d; y<=d; y++)
for (s16 x=-d; x<=d; x++)
{
leaves_d[leaves_a.index (v3s16 (x,y,z))] = 1 ;
}
s16 d = 1 ;
for (s16 z = -d; z <= d; z++)
for (s16 y = -d; y <= d; y++)
for (s16 x = -d; x <= d; x++) {
leaves_d[leaves_a.index (v3s16 (x,y,z))] = 1 ;
}
// Add leaves randomly
for (u32 iii=0 ; iii<30 ; iii++)
{
s16 d = 1 ;
for (u32 iii = 0 ; iii < 30 ; iii++) {
v3s16 p (
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 .Z , leaves_a.MaxEdge .Z - 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 .Z , leaves_a.MaxEdge .Z - d)
);
for (s16 z=0 ; z<=d; z++)
for (s16 y=0 ; y<=d; y++)
for (s16 x=0 ; x<=d; x++)
{
leaves_d[leaves_a.index (p+v3s16 (x,y,z))] = 1 ;
for (s16 z = 0 ; z <= d; z++)
for (s16 y = 0 ; y <= d; y++)
for (s16 x = 0 ; x <= d; x++) {
leaves_d[leaves_a.index (p + v3s16 (x, y, z))] = 1 ;
}
}
// 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++)
for (s16 x=leaves_a.MinEdge .X ; x<=leaves_a.MaxEdge .X ; x++)
{
v3s16 p (x,y,z);
p += p1;
if (vmanip.m_area .contains (p) == false )
continue ;
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 )
vmanip.m_data [vi] = leavesnode;
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)) {
if (leaves_d[i] == 1 )
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++;
}
}
}
Expand Down