From 1163fdfa118636862997c40a32207e418c834f70 Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Wed, 23 Jan 2013 04:57:49 +0100 Subject: [PATCH] Treegen update. Some new symbols. Speed up code a bit. --- doc/lua_api.txt | 4 +- src/treegen.cpp | 126 +++++++++++++++++++++++++++++++++++------------- src/treegen.h | 27 ++++++----- 3 files changed, 112 insertions(+), 45 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f935849ca..7ba2ed001 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1098,7 +1098,9 @@ treedef={ Key for Special L-System Symbols used in Axioms G - move forward one unit with the pen up F - move forward one unit with the pen down drawing trunks and branches - f - move forward one unit with the pen down drawing leaves + f - move forward one unit with the pen down drawing leaves (100% chance) + T - move forward one unit with the pen down drawing trunks only + R - move forward one unit with the pen down placing fruit A - replace with rules set A B - replace with rules set B C - replace with rules set C diff --git a/src/treegen.cpp b/src/treegen.cpp index 49f0666bc..7530843d3 100644 --- a/src/treegen.cpp +++ b/src/treegen.cpp @@ -1,7 +1,7 @@ /* Minetest-c55 Copyright (C) 2010-2012 celeron55, Perttu Ahola , - 2012 RealBadAngel, Maciej Kasatkin + 2012-2013 RealBadAngel, Maciej Kasatkin This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or @@ -118,7 +118,7 @@ void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeD core::map modified_blocks; ManualMapVoxelManipulator vmanip(map); v3s16 tree_blockp = getNodeBlockPos(p0); - vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,2,1)); + vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,3,1)); make_ltree (vmanip, p0, ndef, tree_definition); vmanip.blitBackAll(&modified_blocks); @@ -169,8 +169,11 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd //initialize rotation matrix, position and stacks for branches core::matrix4 rotation; - rotation=setRotationAxisRadians(rotation, M_PI/2,v3f(0,0,1)); - v3f position = v3f(0,0,0); + rotation = setRotationAxisRadians(rotation, M_PI/2,v3f(0,0,1)); + v3f position; + position.X = p0.X; + position.Y = p0.Y; + position.Z = p0.Z; std::stack stack_orientation; std::stack stack_position; @@ -223,16 +226,16 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd //make sure tree is not floating in the air if (tree_definition.trunk_type == "double") { - make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode); - make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z+1),dirtnode); - make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z+1),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+1,position.Y-1,position.Z+1),dirtnode); } if (tree_definition.trunk_type == "crossed") { - make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode); - make_tree_node_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode); - make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z+1),dirtnode); - make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z-1),dirtnode); + 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 @@ -241,7 +244,9 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd G - move forward one unit with the pen up F - move forward one unit with the pen down drawing trunks and branches - f - move forward one unit with the pen down drawing leaves + f - move forward one unit with the pen down drawing leaves (100% chance) + T - move forward one unit with the pen down drawing trunks only + R - move forward one unit with the pen down placing fruit A - replace with rules set A B - replace with rules set B C - replace with rules set C @@ -275,35 +280,54 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd 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); + } + 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; + break; case 'F': - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z),tree_definition); + 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)) { - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z),tree_definition); - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z+1),tree_definition); - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z+1),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+1,position.Y,position.Z+1),tree_definition); } if ((stack_orientation.empty() && tree_definition.trunk_type == "crossed") || (!stack_orientation.empty() && tree_definition.trunk_type == "crossed" && !tree_definition.thin_branches)) { - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z),tree_definition); - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y,p0.Z+position.Z),tree_definition); - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z+1),tree_definition); - make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z-1),tree_definition); + 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; x0) { if (myrand_range(1,100) > 100-tree_definition.fruit_chance) @@ -413,6 +444,35 @@ void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0, vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode; } +void tree_single_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + TreeDef &tree_definition) +{ + MapNode leavesnode=tree_definition.leavesnode; + if (myrand_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) + return; + vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode; +} + +void tree_fruit_placement(ManualMapVoxelManipulator &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) + return; + u32 vi = vmanip.m_area.index(p1); + 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); diff --git a/src/treegen.h b/src/treegen.h index 1435d6bb2..cb365f4be 100644 --- a/src/treegen.h +++ b/src/treegen.h @@ -1,7 +1,7 @@ /* Minetest-c55 Copyright (C) 2010-2012 celeron55, Perttu Ahola , - 2012 RealBadAngel, Maciej Kasatkin + 2012-2013 RealBadAngel, Maciej Kasatkin This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or @@ -51,24 +51,29 @@ int fruit_chance; // Add default tree void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0, - bool is_apple_tree, INodeDefManager *ndef); - + bool is_apple_tree, INodeDefManager *ndef); + // Add L-Systems tree (used by engine) void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition); // Spawn L-systems tree from LUA - void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition); - + void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, + TreeDef tree_definition); + // L-System tree gen helper functions - void make_tree_node_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + void tree_node_placement(ManualMapVoxelManipulator &vmanip, v3f p0, MapNode node); - void make_tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + void tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + TreeDef &tree_definition); + void tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + TreeDef &tree_definition); + void tree_single_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0, + TreeDef &tree_definition); + void tree_fruit_placement(ManualMapVoxelManipulator &vmanip, v3f p0, TreeDef &tree_definition); - void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0, - TreeDef &tree_definition); irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle,v3f axis); - + v3f transposeMatrix(irr::core::matrix4 M ,v3f v); - + }; // namespace treegen #endif