Treegen: Add pine tree. Force place trunks
authorparamat <mat.gregory@virginmedia.com>
Sat, 28 Mar 2015 05:14:53 +0000 (05:14 +0000)
committerparamat <mat.gregory@virginmedia.com>
Wed, 1 Apr 2015 21:54:49 +0000 (22:54 +0100)
Speed-optimise leaves blits
Use MMVManip for make_jungletree
Use correct code style

src/treegen.cpp
src/treegen.h

index 5c95b250e1bf854af8e6c2d517be271a7c2556c6..1c915ca39052dfbf32654112e67dc203675f1912 100644 (file)
@@ -45,80 +45,75 @@ 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;
@@ -126,8 +121,8 @@ treegen::error spawn_ltree(ServerEnvironment *env, v3s16 p0, INodeDefManager *nd
        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;
 
@@ -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
@@ -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;
@@ -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
@@ -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
@@ -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;
@@ -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 psTreeDef &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);
@@ -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
@@ -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)
@@ -572,12 +687,10 @@ 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++;
        }
@@ -585,58 +698,171 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
        // 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++;
+               }
        }
 }
 
index febbc29ee31001f577ceeeeaab1b94699a10b334..4b0089d1e53770e11a638268e6a67913f2d7d2a3 100644 (file)
@@ -62,7 +62,10 @@ namespace treegen {
        void make_tree(MMVManip &vmanip, v3s16 p0,
                bool is_apple_tree, INodeDefManager *ndef, int seed);
        // 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);
 
        // Add L-Systems tree (used by engine)