]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/obj.cxx
Replace SG_USE_STD() by using std::
[simgear.git] / simgear / scene / tgdb / obj.cxx
index d319ec4cd80d1f35cdb8c8403d47e26f8ee03d6e..da21d9f16f05f77572b62ed71fae913753693a3f 100644 (file)
@@ -50,8 +50,6 @@
 #include <simgear/scene/util/SGUpdateVisitor.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
 #include <simgear/scene/util/QuadTreeBuilder.hxx>
-#include <simgear/threads/SGThread.hxx>
-#include <simgear/threads/SGGuard.hxx>
 
 #include "SGTexturedTriangleBin.hxx"
 #include "SGLightBin.hxx"
@@ -133,7 +131,7 @@ struct SGTileGeometryBin {
       std::string materialName = obj.get_pt_materials()[grp];
       SGMaterial* material = matlib->find(materialName);
       SGVec4f color = getMaterialLightColor(material);
-      
+
       if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") {
         // Just plain lights. Not something for the runway.
         addPointGeometry(tileLights, obj.get_wgs84_nodes(), color,
@@ -454,11 +452,11 @@ struct SGTileGeometryBin {
   void computeRandomForest(SGMaterialLib* matlib)
   {
     SGMaterialTriangleMap::iterator i;
-        
+
     // generate a repeatable random seed
     mt seed;
     mt_init(&seed, unsigned(586));
-    
+
     for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
       SGMaterial *mat = matlib->find(i->first);
       if (!mat)
@@ -467,24 +465,32 @@ struct SGTileGeometryBin {
       float coverage = mat->get_tree_coverage();
       if (coverage <= 0)
         continue;
-        
-      vector<string> textures = mat->get_tree_textures();
-      
+
+      // 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();
+
       std::vector<SGVec3f> randomPoints;
       i->second.addRandomSurfacePoints(coverage, 0, randomPoints);
       std::vector<SGVec3f>::iterator j;
-      for (j = randomPoints.begin(); j != randomPoints.end(); ++j) {      
-        int k = (int)(mt_rand(&seed) * textures.size());        
-        if (k == textures.size()) k--;         
-        randomForest.insert(*j, textures[k], mat->get_tree_height(), mat->get_tree_width(), mat->get_tree_range());
+      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);
       }
     }
   }
-  
+
   void computeRandomObjects(SGMaterialLib* matlib)
   {
     SGMaterialTriangleMap::iterator i;
-    
+
     // generate a repeatable random seed
     mt seed;
     mt_init(&seed, unsigned(123));
@@ -493,23 +499,23 @@ struct SGTileGeometryBin {
       SGMaterial *mat = matlib->find(i->first);
       if (!mat)
         continue;
-      
+
       int group_count = mat->get_object_group_count();
-      
+
       if (group_count > 0)
-      {      
+      {
         for (int j = 0; j < group_count; j++)
-        {      
+        {
           SGMatModelGroup *object_group =  mat->get_object_group(j);
           int nObjects = object_group->get_object_count();
-          
+
           if (nObjects > 0)
           {
             // For each of the random models in the group, determine an appropriate
             // number of random placements and insert them.
             for (int k = 0; k < nObjects; k++) {
               SGMatModel * object = object_group->get_object(k);
-              
+
               std::vector<SGVec3f> randomPoints;
 
               i->second.addRandomPoints(object->get_coverage_m2(), randomPoints);
@@ -559,7 +565,7 @@ typedef QuadTreeBuilder<osg::LOD*, ModelLOD, MakeQuadLeaf, AddModelLOD,
                         GetModelLODCoord>  RandomObjectsQuadtree;
 
 osg::Node*
-SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool use_random_objects)
+SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool use_random_objects, bool use_random_vegetation)
 {
   SGBinObject tile;
   if (!tile.read_bin(path))
@@ -579,13 +585,13 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
   osg::ref_ptr<osg::Group> randomObjects;
   osg::ref_ptr<osg::Group> randomForest;
   osg::Group* terrainGroup = new osg::Group;
-  
+
   osg::Node* node = tileGeometryBin.getSurfaceGeometry(matlib);
   if (node)
     terrainGroup->addChild(node);
-    
-  if (use_random_objects) {
-  
+
+  if (use_random_objects || use_random_vegetation) {
+
     // Simple matrix for used for flipping models that have been oriented
     // with the center of the tile but upside down.
     static const osg::Matrix flip(1,  0,  0, 0,
@@ -600,53 +606,54 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
     osg::Matrix mAtt = flip * osg::Matrix::rotate(hlOr.osg());
     // The inverse goes from world coordinates to Z up tile coordinates.
     osg::Matrix world2Tile(osg::Matrix(hlOr.osg().conj()) * flip);
-  
-    tileGeometryBin.computeRandomObjects(matlib);
+
+    if (use_random_objects) {
+      tileGeometryBin.computeRandomObjects(matlib);
     
-    if (tileGeometryBin.randomModels.getNumModels() > 0) {
-      // Generate a repeatable random seed
-      mt seed;
-      mt_init(&seed, unsigned(123));
-
-      std::vector<ModelLOD> models;
-      for (unsigned int i = 0; i < tileGeometryBin.randomModels.getNumModels(); i++) {
-        SGMatModelBin::MatModel obj = tileGeometryBin.randomModels.getMatModel(i);
-        osg::Node* node = sgGetRandomModel(obj.model);
+      if (tileGeometryBin.randomModels.getNumModels() > 0) {
+        // Generate a repeatable random seed
+        mt seed;
+        mt_init(&seed, unsigned(123));
+
+        std::vector<ModelLOD> models;
+        for (unsigned int i = 0;
+             i < tileGeometryBin.randomModels.getNumModels(); i++) {
+          SGMatModelBin::MatModel obj
+            = tileGeometryBin.randomModels.getMatModel(i);
+          osg::Node* node = sgGetRandomModel(obj.model);
         
-        // 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 mPos = osg::Matrix::translate(obj.position.osg());        
-        osg::MatrixTransform* 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;
-          osg::Matrix rot(cos(hdg), -sin(hdg), 0, 0,
-                          sin(hdg),  cos(hdg), 0, 0,
-                          0,         0, 1, 0,
-                          0,         0, 0, 1);     
-          position = new osg::MatrixTransform(rot * mAtt * mPos);
-        } else {
-          position = new osg::MatrixTransform(mAtt * mPos);
+          // 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(mAtt);
+          transformMat.postMult(osg::Matrix::translate(obj.position.osg()));
+          if (obj.model->get_heading_type() == SGMatModel::HEADING_RANDOM) {
+            // Rotate the object around the z axis.
+            double hdg = mt_rand(&seed) * M_PI * 2;
+            transformMat.preMult(osg::Matrix::rotate(hdg,
+                                                     osg::Vec3d(0.0, 0.0, 1.0)));
+          }
+          osg::MatrixTransform* position =
+            new osg::MatrixTransform(transformMat);
+          position->addChild(node);
+          models.push_back(ModelLOD(position, obj.lod));
         }
-
-        position->addChild(node);        
-        models.push_back(ModelLOD(position, obj.lod));
+        RandomObjectsQuadtree quadtree((GetModelLODCoord(world2Tile)),
+                                       (AddModelLOD()));
+        quadtree.buildQuadTree(models.begin(), models.end());
+        randomObjects = quadtree.getRoot();
+        randomObjects->setName("random objects");
       }
-      RandomObjectsQuadtree quadtree((GetModelLODCoord(world2Tile)),
-                                     (AddModelLOD()));
-      quadtree.buildQuadTree(models.begin(), models.end());
-      randomObjects = quadtree.getRoot();
-      randomObjects->setName("random objects");
     }
-      
-    // Now add some random forest.
-    tileGeometryBin.computeRandomForest(matlib);
-    
-    if (tileGeometryBin.randomForest.getNumTrees() > 0) {
-      randomForest = createForest(tileGeometryBin.randomForest, mAtt);
-      randomForest->setName("random trees");      
+
+    if (use_random_vegetation) {
+      // Now add some random forest.
+      tileGeometryBin.computeRandomForest(matlib);
+
+      if (tileGeometryBin.randomForest.getNumTrees() > 0) {
+        randomForest = createForest(tileGeometryBin.randomForest, mAtt);
+        randomForest->setName("random trees");
+      }
     } 
   }
 
@@ -682,8 +689,9 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
       lightGroup->addChild(groundLights2);
     }
   }
-    
+
   if (!tileGeometryBin.vasiLights.empty()) {
+    osg::Geode* vasiGeode = new osg::Geode;
     SGVec4f red(1, 0, 0, 1);
     SGMaterial* mat = matlib->find("RWY_RED_LIGHTS");
     if (mat)
@@ -693,17 +701,14 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
     if (mat)
       white = mat->get_light_color();
 
-    osg::Geode* geode = new osg::Geode;
     SGDirectionalLightListBin::const_iterator i;
     for (i = tileGeometryBin.vasiLights.begin();
          i != tileGeometryBin.vasiLights.end(); ++i) {
-      geode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
+      vasiGeode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
     }
-    osg::Group* vasiLights = new osg::Group;
-    vasiLights->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
-    vasiLights->setStateSet(lightManager->getRunwayLightStateSet());
-    vasiLights->addChild(geode);
-    lightGroup->addChild(vasiLights);
+    vasiGeode->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
+    vasiGeode->setStateSet(lightManager->getRunwayLightStateSet());
+    lightGroup->addChild(vasiGeode);
   }
 
   if (tileGeometryBin.runwayLights.getNumLights() > 0
@@ -756,12 +761,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
   if (lightGroup->getNumChildren() > 0) {
     osg::LOD* lightLOD = new osg::LOD;
     lightLOD->addChild(lightGroup.get(), 0, 30000);
-    unsigned nodeMask = ~0u;
-    nodeMask &= ~SG_NODEMASK_CASTSHADOW_BIT;
-    nodeMask &= ~SG_NODEMASK_RECIEVESHADOW_BIT;
-    nodeMask &= ~SG_NODEMASK_PICK_BIT;
-    nodeMask &= ~SG_NODEMASK_TERRAIN_BIT;
-    lightLOD->setNodeMask(nodeMask);
+    // VASI is always on, so doesn't use light bits.
+    lightLOD->setNodeMask(LIGHTS_BITS | MODEL_BIT); 
     transform->addChild(lightLOD);
   }
   
@@ -774,7 +775,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
     if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 20000);
     if (randomForest.valid())  objectLOD->addChild(randomForest.get(), 0, 20000);
     
-    unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT;
+    unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT | SG_NODEMASK_TERRAIN_BIT;
     objectLOD->setNodeMask(nodeMask);
     transform->addChild(objectLOD);
   }