]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/obj.cxx
Fixes for headless mode.
[simgear.git] / simgear / scene / tgdb / obj.cxx
index 3869c521ab2588a369ada417d8b8b4055aac6733..36011d723e489a60cc894c9d46dd0abbf0f364c5 100644 (file)
@@ -40,6 +40,8 @@
 #include <osg/StateSet>
 #include <osg/Switch>
 
+#include <boost/foreach.hpp>
+
 #include <simgear/debug/logstream.hxx>
 #include <simgear/io/sg_binobj.hxx>
 #include <simgear/math/sg_geodesy.hxx>
@@ -74,7 +76,7 @@ struct SGTileGeometryBin {
   SGMaterialTriangleMap materialTriangleMap;
   SGLightBin tileLights;
   SGLightBin randomTileLights;
-  TreeBin randomForest;
+  SGTreeBinList randomForest;
   SGDirectionalLightBin runwayLights;
   SGDirectionalLightBin taxiLights;
   SGDirectionalLightListBin vasiLights;
@@ -382,6 +384,7 @@ struct SGTileGeometryBin {
       if (mat)
         eg->setEffect(mat->get_effect());
       eg->addDrawable(geometry);
+      eg->runGenerators(geometry);  // Generate extra data needed by effect
       if (group)
         group->addChild(eg);
     }
@@ -455,27 +458,46 @@ struct SGTileGeometryBin {
       if (!mat)
         continue;
 
-      float coverage = mat->get_tree_coverage();
-      if (coverage <= 0)
+      float wood_coverage = mat->get_wood_coverage();
+      if (wood_coverage <= 0)
         continue;
-
-      // Attributes that don't vary by tree
-      randomForest.texture = mat->get_tree_texture();
-      randomForest.range   = mat->get_tree_range();
-      randomForest.width   = mat->get_tree_width();
-      randomForest.height  = mat->get_tree_height();
-      randomForest.texture_varieties = mat->get_tree_varieties();
+              
+      // Attributes that don't vary by tree but do vary by material
+      bool found = false;
+      TreeBin* bin = NULL;
+      
+      BOOST_FOREACH(bin, randomForest)
+      {
+        if ((bin->texture           == mat->get_tree_texture()  ) &&
+            (bin->texture_varieties == mat->get_tree_varieties()) &&
+            (bin->range             == mat->get_tree_range()    ) &&
+            (bin->width             == mat->get_tree_width()    ) &&
+            (bin->height            == mat->get_tree_height()   )   ) {
+            found = true;
+            break;
+        }
+      }
+      
+      if (!found) {
+        bin = new TreeBin();
+        bin->texture = mat->get_tree_texture();
+          SG_LOG(SG_INPUT, SG_DEBUG, "Tree texture " << bin->texture);
+        bin->range   = mat->get_tree_range();
+        bin->width   = mat->get_tree_width();
+        bin->height  = mat->get_tree_height();
+        bin->texture_varieties = mat->get_tree_varieties();
+        randomForest.push_back(bin);
+      }
 
       std::vector<SGVec3f> randomPoints;
-      i->second.addRandomSurfacePoints(coverage, 0, randomPoints);
-      std::vector<SGVec3f>::iterator j;
-      for (j = randomPoints.begin(); j != randomPoints.end(); ++j) {
-
-        // Apply a random scaling factor and texture index.
-        float scale = (mt_rand(&seed) + mt_rand(&seed)) / 2.0f + 0.5f;
-        int v = (int) (mt_rand(&seed) * mat->get_tree_varieties());
-        if (v == mat->get_tree_varieties()) v--;         
-        randomForest.insert(*j, v, scale);
+      i->second.addRandomTreePoints(wood_coverage,
+                                    mat->get_tree_density(),
+                                    mat->get_wood_size(),
+                                    randomPoints);
+      
+      std::vector<SGVec3f>::iterator k;
+      for (k = randomPoints.begin(); k != randomPoints.end(); ++k) {
+        bin->insert(*k);
       }
     }
   }
@@ -563,7 +585,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
   if (!tile.read_bin(path))
     return false;
 
-  SGVec3d center = tile.get_gbs_center2();
+  SGVec3d center = tile.get_gbs_center();
   SGGeod geodPos = SGGeod::fromCart(center);
   SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180);
 
@@ -589,7 +611,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
 
   osg::ref_ptr<osg::Group> lightGroup = new SGOffsetTransform(0.94);
   osg::ref_ptr<osg::Group> randomObjects;
-  osg::ref_ptr<osg::Group> randomForest;
+  osg::ref_ptr<osg::Group> forestNode;
   osg::Group* terrainGroup = new osg::Group;
 
   osg::Node* node = tileGeometryBin.getSurfaceGeometry(matlib);
@@ -611,13 +633,13 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
              i < tileGeometryBin.randomModels.getNumModels(); i++) {
           SGMatModelBin::MatModel obj
             = tileGeometryBin.randomModels.getMatModel(i);
-          osg::Node* node = sgGetRandomModel(obj.model);
+          osg::Node* node = sgGetRandomModel(obj.model, seed);
         
           // Create a matrix to place the object in the correct
           // location, and then apply the rotation matrix created
           // above, with an additional random heading rotation if appropriate.
           osg::Matrix transformMat;
-          transformMat = osg::Matrix::translate(obj.position.osg());
+          transformMat = osg::Matrix::translate(toOsg(obj.position));
           if (obj.model->get_heading_type() == SGMatModel::HEADING_RANDOM) {
             // Rotate the object around the z axis.
             double hdg = mt_rand(&seed) * M_PI * 2;
@@ -639,11 +661,10 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
     if (use_random_vegetation && matlib) {
       // Now add some random forest.
       tileGeometryBin.computeRandomForest(matlib);
-
-      if (tileGeometryBin.randomForest.getNumTrees() > 0) {
-        randomForest = createForest(tileGeometryBin.randomForest,
-                                    osg::Matrix::identity());
-        randomForest->setName("random trees");
+      
+      if (tileGeometryBin.randomForest.size() > 0) {
+        forestNode = createForest(tileGeometryBin.randomForest, osg::Matrix::identity());
+        forestNode->setName("Random trees");
       }
     } 
   }
@@ -759,8 +780,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
   // The toplevel transform for that tile.
   osg::MatrixTransform* transform = new osg::MatrixTransform;
   transform->setName(path);
-  transform->setMatrix(osg::Matrix::rotate(hlOr.osg())*
-                       osg::Matrix::translate(center.osg()));
+  transform->setMatrix(osg::Matrix::rotate(toOsg(hlOr))*
+                       osg::Matrix::translate(toOsg(center)));
   transform->addChild(terrainGroup);
   if (lightGroup->getNumChildren() > 0) {
     osg::LOD* lightLOD = new osg::LOD;
@@ -770,14 +791,14 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
     transform->addChild(lightLOD);
   }
   
-  if (randomObjects.valid() || randomForest.valid()) {
+  if (randomObjects.valid() || forestNode.valid()) {
   
     // Add a LoD node, so we don't try to display anything when the tile center
     // is more than 20km away.
     osg::LOD* objectLOD = new osg::LOD;
     
     if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 20000);
-    if (randomForest.valid())  objectLOD->addChild(randomForest.get(), 0, 20000);
+    if (forestNode.valid())  objectLOD->addChild(forestNode.get(), 0, 20000);
     
     unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT | SG_NODEMASK_TERRAIN_BIT;
     objectLOD->setNodeMask(nodeMask);