]> git.mxchange.org Git - simgear.git/commitdiff
Support for tree shadows from Thorsten RENK.
authorStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Thu, 19 Feb 2015 21:14:07 +0000 (21:14 +0000)
committerStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Thu, 19 Feb 2015 21:14:07 +0000 (21:14 +0000)
simgear/scene/tgdb/SGNodeTriangles.hxx
simgear/scene/tgdb/SGTexturedTriangleBin.hxx
simgear/scene/tgdb/SGTileDetailsCallback.hxx
simgear/scene/tgdb/TreeBin.cxx
simgear/scene/tgdb/TreeBin.hxx

index 9ec376580c6a78b0f935f406152e42cb2744d37f..1d3f72d22ddc4d4cd96722ecc1fb15ed32e59aa0 100644 (file)
@@ -291,7 +291,8 @@ public:
                              float vegetation_density,
                              float cos_max_density_angle,
                              float cos_zero_density_angle,
-                             std::vector<SGVec3f>& points)
+                             std::vector<SGVec3f>& points,
+                            std::vector<SGVec3f>& normals)
     {
         if ( !geometries.empty() ) {
             const osg::Vec3Array* vertices  = dynamic_cast<osg::Vec3Array*>(geometries[0]->getVertexArray());
@@ -366,9 +367,11 @@ public:
                             if (mt_rand(&seed) < img->getColor(x, y).g()) {  
                                 // The red channel contains the rotation for this object                                  
                                 points.push_back(randomPoint);
+                               normals.push_back(normalize(normal));
                             }
                         } else {
                             points.push_back(randomPoint);
+                           normals.push_back(normalize(normal));
                         }                
                     }
                 }
index b2fb3cd5dfec5949f96587e8ad3268f123647ea5..47939a752f81224335eedf7cb0114c2ce003d6c4 100644 (file)
@@ -216,7 +216,8 @@ public:
                            float vegetation_density,
                            float cos_max_density_angle,
                            float cos_zero_density_angle,
-                           std::vector<SGVec3f>& points)
+                           std::vector<SGVec3f>& points,
+                          std::vector<SGVec3f>& normals)
   {
     unsigned num = getNumTriangles();
     for (unsigned i = 0; i < num; ++i) {
@@ -282,9 +283,11 @@ public:
           if (mt_rand(&seed) < img->getColor(x, y).g()) {  
             // The red channel contains the rotation for this object                                  
             points.push_back(randomPoint);
+           normals.push_back(normalize(normal));
           }
         } else {
           points.push_back(randomPoint);
+          normals.push_back(normalize(normal));
         }                
       }
     }
index ced1403cfc0521496b2b7bfeae691915761960b0..fbee88f877e335fd87c6cf163fc6271e05ff3bbb 100644 (file)
@@ -723,7 +723,7 @@ public:
             BOOST_FOREACH(bin, randomForest)
             {
                 if ((bin->texture           == mat->get_tree_texture()  ) &&
-                               (bin->teffect           == mat->get_tree_effect()   ) &&
+                    (bin->teffect           == mat->get_tree_effect()   ) &&
                     (bin->texture_varieties == mat->get_tree_varieties()) &&
                     (bin->range             == mat->get_tree_range()    ) &&
                     (bin->width             == mat->get_tree_width()    ) &&
@@ -747,16 +747,19 @@ public:
             }
             
             std::vector<SGVec3f> randomPoints;
+            std::vector<SGVec3f> randomPointNormals;
             matTris[i].addRandomTreePoints(wood_coverage,
                                            mat->get_one_object_mask(matTris[i].getTextureIndex()),
                                            vegetation_density,
                                            mat->get_cos_tree_max_density_slope_angle(),
                                            mat->get_cos_tree_zero_density_slope_angle(),
-                                           randomPoints);
+                                           randomPoints,
+                                           randomPointNormals);
             
             std::vector<SGVec3f>::iterator k;
-            for (k = randomPoints.begin(); k != randomPoints.end(); ++k) {
-                bin->insert(*k);
+            std::vector<SGVec3f>::iterator j;
+            for (k = randomPoints.begin(), j = randomPointNormals.begin(); k != randomPoints.end(); ++k, ++j) {
+                     bin->insert(*k, *j);
             }
         }
     }
index 64928084b3b8556a94aca3b688bac27134aa855f..953b93609d4d6898e149333ea8bd119f37f69d76 100644 (file)
@@ -49,6 +49,7 @@
 #include <simgear/scene/util/QuadTreeBuilder.hxx>
 #include <simgear/scene/util/RenderConstants.hxx>
 #include <simgear/scene/util/StateAttributeFactory.hxx>
+#include <simgear/scene/util/SGReaderWriterOptions.hxx>
 #include <simgear/structure/OSGUtils.hxx>
 
 #include "ShaderGeometry.hxx"
@@ -62,6 +63,9 @@ using namespace osg;
 namespace simgear
 {
 
+bool use_tree_shadows;
+bool use_tree_normals;
+
 // Tree instance scheme:
 // vertex - local position of quad vertex.
 // normal - x y scaling, z number of varieties
@@ -164,15 +168,24 @@ Geometry* createTreeGeometry(float width, float height, int varieties)
     // Positions
     quadGeom->setColorArray(new Vec3Array);
     quadGeom->setColorBinding(Geometry::BIND_PER_VERTEX);
-    FloatArray* rotation = new FloatArray(2);
+    // Normals
+    if (use_tree_shadows || use_tree_normals)
+       {
+       quadGeom->setSecondaryColorArray(new Vec3Array);
+       quadGeom->setSecondaryColorBinding(Geometry::BIND_PER_VERTEX);
+       }       
+    FloatArray* rotation = new FloatArray(3);
     (*rotation)[0] = 0.0;
     (*rotation)[1] = PI_2;
+    if (use_tree_shadows) {(*rotation)[2] = -1.0;}
     quadGeom->setFogCoordArray(rotation);
     quadGeom->setFogCoordBinding(Geometry::BIND_PER_PRIMITIVE_SET);
     // The primitive sets render the same geometry, but the second
     // will rotated 90 degrees by the vertex shader, which uses the
     // fog coordinate as a rotation.
-    for (int i = 0; i < 2; ++i)
+    int imax = 2;
+    if (use_tree_shadows) {imax = 3;}
+    for (int i = 0; i < imax; ++i)
         quadGeom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS));
     return quadGeom;
 }
@@ -184,13 +197,17 @@ EffectGeode* createTreeGeode(float width, float height, int varieties)
     return result;
 }
 
-void addTreeToLeafGeode(Geode* geode, const SGVec3f& p)
+void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t)
 {
     Vec3 pos = toOsg(p);
+    Vec3 ter = toOsg(t);
     unsigned int numDrawables = geode->getNumDrawables();
     Geometry* geom
         = static_cast<Geometry*>(geode->getDrawable(numDrawables - 1));
     Vec3Array* posArray = static_cast<Vec3Array*>(geom->getColorArray());
+    Vec3Array* tnormalArray;
+    if (use_tree_shadows || use_tree_normals) 
+       {tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
     if (posArray->size()
         >= static_cast<Vec3Array*>(geom->getVertexArray())->size()) {
         Vec3Array* paramsArray
@@ -198,11 +215,17 @@ void addTreeToLeafGeode(Geode* geode, const SGVec3f& p)
         Vec3 params = (*paramsArray)[0];
         geom = createTreeGeometry(params.x(), params.y(), params.z());
         posArray = static_cast<Vec3Array*>(geom->getColorArray());
+       if (use_tree_shadows || use_tree_normals) 
+               {tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
         geode->addDrawable(geom);
     }
     posArray->insert(posArray->end(), 4, pos);
+    if (use_tree_shadows || use_tree_normals) 
+       {tnormalArray->insert(tnormalArray->end(),4,ter);}
     size_t numVerts = posArray->size();
-    for (int i = 0; i < 2; ++i) {
+    int imax = 2;
+    if (use_tree_shadows) {imax = 3;}
+    for (int i = 0; i < imax; ++i) {
         DrawArrays* primSet
             = static_cast<DrawArrays*>(geom->getPrimitiveSet(i));
         primSet->setCount(numVerts);
@@ -218,14 +241,14 @@ namespace
 {
 struct MakeTreesLeaf
 {
-    MakeTreesLeaf(float range, int varieties, float width, float height,
+    MakeTreesLeaf(float range, int varieties, float width, float height, 
         Effect* effect) :
         _range(range),  _varieties(varieties),
         _width(width), _height(height), _effect(effect) {}
 
     MakeTreesLeaf(const MakeTreesLeaf& rhs) :
         _range(rhs._range),
-        _varieties(rhs._varieties), _width(rhs._width), _height(rhs._height),
+        _varieties(rhs._varieties), _width(rhs._width), _height(rhs._height), 
         _effect(rhs._effect)
     {}
 
@@ -255,7 +278,7 @@ struct AddTreesLeafObject
     void operator() (LOD* lod, const TreeBin::Tree& tree) const
     {
         Geode* geode = static_cast<Geode*>(lod->getChild(int(tree.position.x() * 10.0f) % lod->getNumChildren()));
-        addTreeToLeafGeode(geode, tree.position);
+        addTreeToLeafGeode(geode, tree.position, tree.tnormal);
     }
 };
 
@@ -277,7 +300,8 @@ struct TreeTransformer
     TreeBin::Tree operator()(const TreeBin::Tree& tree) const
     {
         Vec3 pos = toOsg(tree.position);
-        return TreeBin::Tree(toSG(pos * mat));
+       Vec3 norm = toOsg(tree.tnormal);
+        return TreeBin::Tree(toSG(pos * mat),toSG(norm * mat));
     }
     Matrix mat;
 };
@@ -332,6 +356,20 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
     MatrixTransform* mt = new MatrixTransform(transform);
 
     SGTreeBinList::iterator i;
+     
+    use_tree_shadows = false;
+    use_tree_normals = false;
+    if (options) {
+        SGPropertyNode* propertyNode = options->getPropertyNode().get();
+        if (propertyNode) {
+            use_tree_shadows
+                = propertyNode->getBoolValue("/sim/rendering/random-vegetation-shadows",
+                                             use_tree_shadows);
+           use_tree_normals
+                = propertyNode->getBoolValue("/sim/rendering/random-vegetation-normals",
+                                             use_tree_normals);
+               }       
+       }
 
     for (i = forestList.begin(); i != forestList.end(); ++i) {
         TreeBin* forest = *i;
index 80441ec4d05e73bc0d7d0b3be32f16fe92cc2f0e..5f97d4f58c003168c13a71e924888495c643a0f2 100644 (file)
@@ -36,10 +36,10 @@ namespace simgear
 class TreeBin {
 public:
   struct Tree {
-    Tree(const SGVec3f& p) :
-      position(p)
-    { }
     SGVec3f position;
+    SGVec3f tnormal;
+    Tree(const SGVec3f& p, const SGVec3f& t) : position(p),tnormal(t)
+    { }
   };
 
     typedef std::vector<Tree> TreeList;
@@ -53,8 +53,9 @@ public:
     
     void insert(const Tree& t)
     { _trees.push_back(t); }
-    void insert(const SGVec3f& p, int t, float s)
-    { insert(Tree(p)); }
+
+    void insert(const SGVec3f& p, const SGVec3f& tnorm)
+    {insert(Tree(p,tnorm));}
 
     unsigned getNumTrees() const
     { return _trees.size(); }