]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/obj.cxx
Merge branch 'jmt/ref_ptr-conv'
[simgear.git] / simgear / scene / tgdb / obj.cxx
index d5964815e1bcd588016a42c58952fc2380e28776..fd6d42e29e13d5c5d6d6f077123622057514e8d4 100644 (file)
@@ -44,6 +44,8 @@
 #include <simgear/io/sg_binobj.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/math/sg_random.h>
+#include <simgear/scene/material/Effect.hxx>
+#include <simgear/scene/material/EffectGeode.hxx>
 #include <simgear/scene/material/mat.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/model/SGOffsetTransform.hxx>
@@ -129,7 +131,9 @@ struct SGTileGeometryBin {
 
     for (unsigned grp = 0; grp < obj.get_pts_v().size(); ++grp) {
       std::string materialName = obj.get_pt_materials()[grp];
-      SGMaterial* material = matlib->find(materialName);
+      SGMaterial* material = 0;
+      if (matlib)
+          material = matlib->find(materialName);
       SGVec4f color = getMaterialLightColor(material);
 
       if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") {
@@ -365,37 +369,27 @@ struct SGTileGeometryBin {
     if (materialTriangleMap.empty())
       return 0;
 
-    osg::Geode* geode = new osg::Geode;
+    EffectGeode* eg = 0;
+    osg::Group* group = (materialTriangleMap.size() > 1 ? new osg::Group : 0);
+    //osg::Geode* geode = new osg::Geode;
     SGMaterialTriangleMap::const_iterator i;
     for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
-      // CHUNCKED (sic) here splits up unconnected triangles parts of
-      // the mesh into different Geometry sets, presumably for better
-      // culling. I (timoore) believe it is more performant to build
-      // the biggest indexed sets possible at the expense of tight
-      // culling.
-//#define CHUNCKED
-#ifdef CHUNCKED
-      SGMaterial *mat = matlib->find(i->first);
-
-      std::list<SGTexturedTriangleBin::TriangleVector> connectSets;
-      i->second.getConnectedSets(connectSets);
-
-      std::list<SGTexturedTriangleBin::TriangleVector>::iterator j;
-      for (j = connectSets.begin(); j != connectSets.end(); ++j) {
-        osg::Geometry* geometry = i->second.buildGeometry(*j);
-        if (mat)
-          geometry->setStateSet(mat->get_state());
-        geode->addDrawable(geometry);
-      }
-#else
       osg::Geometry* geometry = i->second.buildGeometry();
-      SGMaterial *mat = matlib->find(i->first);
+      SGMaterial *mat = 0;
+      if (matlib)
+        mat = matlib->find(i->first);
+      eg = new EffectGeode;
       if (mat)
-        geometry->setStateSet(mat->get_state());
-      geode->addDrawable(geometry);
-#endif
+        eg->setEffect(mat->get_effect());
+      eg->addDrawable(geometry);
+      eg->runGenerators(geometry);  // Generate extra data needed by effect
+      if (group)
+        group->addChild(eg);
     }
-    return geode;
+    if (group)
+        return group;
+    else
+        return eg;
   }
 
   void computeRandomSurfaceLights(SGMaterialLib* matlib)
@@ -462,8 +456,8 @@ 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
@@ -474,15 +468,14 @@ struct SGTileGeometryBin {
       randomForest.texture_varieties = mat->get_tree_varieties();
 
       std::vector<SGVec3f> randomPoints;
-      i->second.addRandomSurfacePoints(coverage, 0, randomPoints);
+      i->second.addRandomTreePoints(wood_coverage,
+                                    mat->get_tree_density(),
+                                    mat->get_wood_size(),
+                                    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);
+        randomForest.insert(*j);
       }
     }
   }
@@ -605,7 +598,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
 
   if (use_random_objects || use_random_vegetation) {
     if (use_random_objects) {
-      tileGeometryBin.computeRandomObjects(matlib);
+      if (matlib)
+        tileGeometryBin.computeRandomObjects(matlib);
     
       if (tileGeometryBin.randomModels.getNumModels() > 0) {
         // Generate a repeatable random seed
@@ -617,13 +611,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;
@@ -642,7 +636,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
       }
     }
 
-    if (use_random_vegetation) {
+    if (use_random_vegetation && matlib) {
       // Now add some random forest.
       tileGeometryBin.computeRandomForest(matlib);
 
@@ -656,7 +650,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
 
   if (calc_lights) {
     // FIXME: ugly, has a side effect
-    tileGeometryBin.computeRandomSurfaceLights(matlib);
+    if (matlib)
+      tileGeometryBin.computeRandomSurfaceLights(matlib);
 
     if (tileGeometryBin.tileLights.getNumLights() > 0
         || tileGeometryBin.randomTileLights.getNumLights() > 0) {
@@ -688,36 +683,47 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
   }
 
   if (!tileGeometryBin.vasiLights.empty()) {
-    osg::Geode* vasiGeode = new osg::Geode;
+    EffectGeode* vasiGeode = new EffectGeode;
+    Effect* vasiEffect
+        = getLightEffect(6, osg::Vec3(1, 0.0001, 0.000001), 1, 6, true);
+    vasiGeode->setEffect(vasiEffect);
     SGVec4f red(1, 0, 0, 1);
-    SGMaterial* mat = matlib->find("RWY_RED_LIGHTS");
+    SGMaterial* mat = 0;
+    if (matlib)
+      mat = matlib->find("RWY_RED_LIGHTS");
     if (mat)
       red = mat->get_light_color();
     SGVec4f white(1, 1, 1, 1);
-    mat = matlib->find("RWY_WHITE_LIGHTS");
+    mat = 0;
+    if (matlib)
+      mat = matlib->find("RWY_WHITE_LIGHTS");
     if (mat)
       white = mat->get_light_color();
-
     SGDirectionalLightListBin::const_iterator i;
     for (i = tileGeometryBin.vasiLights.begin();
          i != tileGeometryBin.vasiLights.end(); ++i) {
       vasiGeode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
     }
-    vasiGeode->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
     vasiGeode->setStateSet(lightManager->getRunwayLightStateSet());
     lightGroup->addChild(vasiGeode);
   }
-
+  Effect* runwayEffect = 0;
+  if (tileGeometryBin.runwayLights.getNumLights() > 0
+      || !tileGeometryBin.rabitLights.empty()
+      || !tileGeometryBin.reilLights.empty()
+      || !tileGeometryBin.odalLights.empty()
+      || tileGeometryBin.taxiLights.getNumLights() > 0)
+      runwayEffect = getLightEffect(4, osg::Vec3(1, 0.001, 0.0002), 1, 4, true);
   if (tileGeometryBin.runwayLights.getNumLights() > 0
       || !tileGeometryBin.rabitLights.empty()
       || !tileGeometryBin.reilLights.empty()
       || !tileGeometryBin.odalLights.empty()) {
     osg::Group* rwyLights = new osg::Group;
-    rwyLights->setCullCallback(new SGPointSpriteLightCullCallback);
     rwyLights->setStateSet(lightManager->getRunwayLightStateSet());
     rwyLights->setNodeMask(RUNWAYLIGHTS_BIT);
     if (tileGeometryBin.runwayLights.getNumLights() != 0) {
-      osg::Geode* geode = new osg::Geode;
+      EffectGeode* geode = new EffectGeode;
+      geode->setEffect(runwayEffect);
       geode->addDrawable(SGLightFactory::getLights(tileGeometryBin
                                                    .runwayLights));
       rwyLights->addChild(geode);
@@ -741,10 +747,10 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
 
   if (tileGeometryBin.taxiLights.getNumLights() > 0) {
     osg::Group* taxiLights = new osg::Group;
-    taxiLights->setCullCallback(new SGPointSpriteLightCullCallback);
     taxiLights->setStateSet(lightManager->getTaxiLightStateSet());
     taxiLights->setNodeMask(RUNWAYLIGHTS_BIT);
-    osg::Geode* geode = new osg::Geode;
+    EffectGeode* geode = new EffectGeode;
+    geode->setEffect(runwayEffect);
     geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.taxiLights));
     taxiLights->addChild(geode);
     lightGroup->addChild(taxiLights);
@@ -753,8 +759,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;