]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/material/matmodel.cxx
model paging patch from Till Busch
[simgear.git] / simgear / scene / material / matmodel.cxx
index 24f8c8637b1690e0539beee1e8127fdbc79ec346..b2a4152d8ebc5601e88d81566ea8b39a7189df1d 100644 (file)
@@ -1,8 +1,8 @@
 // matmodel.cxx -- class to handle models tied to a material property
 //
-// Written by Curtis Olson, started May 1998.
+// Written by David Megginson, started May 1998.
 //
-// Copyright (C) 1998 - 2003  Curtis L. Olson  - curt@flightgear.org
+// Copyright (C) 1998 - 2003  Curtis L. Olson  - http://www.flightgear.org/~curt
 //
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
 #include <map>
 SG_USING_STD(map);
 
-#include <simgear/compiler.h>
+#include <osg/AlphaFunc>
+#include <osg/Group>
+#include <osg/LOD>
+#include <osg/StateSet>
+#include <osg/Transform>
 
 #ifdef SG_MATH_EXCEPTION_CLASH
 #  include <math.h>
@@ -40,10 +44,12 @@ SG_USING_STD(map);
 #include <simgear/math/sg_random.h>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/misc/sgstream.hxx>
-#include <simgear/scene/model/loader.hxx>
+#include <simgear/scene/model/modellib.hxx>
 
 #include "matmodel.hxx"
 
+using namespace simgear;
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Local static functions.
@@ -108,83 +114,68 @@ SGMatModel::SGMatModel (const SGPropertyNode * node, double range_m)
 
 SGMatModel::~SGMatModel ()
 {
-  for (unsigned int i = 0; i < _models.size(); i++) {
-    if (_models[i] != 0) {
-      _models[i]->deRef();
-      _models[i] = 0;
-    }
-  }
 }
 
 int
-SGMatModel::get_model_count( SGModelLoader *loader,
-                                   const string &fg_root,
-                                   SGPropertyNode *prop_root,
-                                   double sim_time_sec )
+SGMatModel::get_model_count( SGPropertyNode *prop_root )
 {
-  load_models( loader, fg_root, prop_root, sim_time_sec );
+  load_models( prop_root );
   return _models.size();
 }
 
 inline void
-SGMatModel::load_models ( SGModelLoader *loader,
-                                const string &fg_root,
-                                SGPropertyNode *prop_root,
-                                double sim_time_sec )
+SGMatModel::load_models( SGPropertyNode *prop_root )
 {
                                // Load model only on demand
   if (!_models_loaded) {
     for (unsigned int i = 0; i < _paths.size(); i++) {
-      ssgEntity *entity = loader->load_model( fg_root, _paths[i],
-                                              prop_root, sim_time_sec );
+      osg::Node *entity = SGModelLib::loadModel(_paths[i], prop_root);
       if (entity != 0) {
-                                // FIXME: this stuff can be handled
-                                // in the XML wrapper as well (at least,
-                                // the billboarding should be handled
-                                // there).
-       float ranges[] = {0, _range_m};
-       ssgRangeSelector * lod = new ssgRangeSelector;
-        lod->ref();
-        lod->setRanges(ranges, 2);
-       if (_heading_type == HEADING_BILLBOARD) {
-         ssgCutout * cutout = new ssgCutout(false);
-         cutout->addKid(entity);
-         lod->addKid(cutout);
-       } else {
-         lod->addKid(entity);
-       }
-       _models.push_back(lod);
+        // FIXME: this stuff can be handled
+        // in the XML wrapper as well (at least,
+        // the billboarding should be handled
+        // there).
+        
+        if (_heading_type == HEADING_BILLBOARD) {
+          // if the model is a billboard, it is likely :
+          // 1. a branch with only leaves,
+          // 2. a tree or a non rectangular shape faked by transparency
+          // We add alpha clamp then
+          osg::StateSet* stateSet = entity->getOrCreateStateSet();
+          osg::AlphaFunc* alphaFunc =
+            new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01f);
+          stateSet->setAttributeAndModes(alphaFunc,
+                                         osg::StateAttribute::OVERRIDE);
+          stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+        } 
+        
+        _models.push_back(entity);
+        
       } else {
-       SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << _paths[i]);
+        SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << _paths[i]);
       }
     }
   }
   _models_loaded = true;
 }
 
-ssgEntity *
+osg::Node*
 SGMatModel::get_model( int index,
-                               SGModelLoader *loader,
-                               const string &fg_root,
-                               SGPropertyNode *prop_root,
-                               double sim_time_sec )
+                       SGPropertyNode *prop_root )
 {
-  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
-  return _models[index];
+  load_models( prop_root ); // comment this out if preloading models
+  return _models[index].get();
 }
 
-ssgEntity *
-SGMatModel::get_random_model( SGModelLoader *loader,
-                                      const string &fg_root,
-                                      SGPropertyNode *prop_root,
-                                      double sim_time_sec )
+osg::Node*
+SGMatModel::get_random_model( SGPropertyNode *prop_root )
 {
-  load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
+  load_models( prop_root ); // comment this out if preloading models
   int nModels = _models.size();
   int index = int(sg_random() * nModels);
   if (index >= nModels)
     index = 0;
-  return _models[index];
+  return _models[index].get();
 }
 
 double
@@ -193,6 +184,24 @@ SGMatModel::get_coverage_m2 () const
   return _coverage_m2;
 }
 
+double SGMatModel::get_range_m() const
+{
+  return _range_m;
+}
+
+double SGMatModel::get_randomized_range_m(mt* seed) const
+{
+  double lrand = mt_rand(seed);
+  
+  // Note that the LoD is not completely randomized.
+  // 10% at 2   * range_m
+  // 30% at 1.5 * range_m
+  // 60% at 1   * range_m
+  if (lrand < 0.1) return 2   * _range_m;
+  if (lrand < 0.4) return 1.5 * _range_m;
+  else return _range_m;
+}
+
 SGMatModel::HeadingType
 SGMatModel::get_heading_type () const
 {
@@ -222,10 +231,6 @@ SGMatModelGroup::SGMatModelGroup (SGPropertyNode * node)
 
 SGMatModelGroup::~SGMatModelGroup ()
 {
-  for (unsigned int i = 0; i < _objects.size(); i++) {
-    delete _objects[i];
-    _objects[i] = 0;
-  }
 }
 
 double
@@ -246,5 +251,4 @@ SGMatModelGroup::get_object (int index) const
   return _objects[index];
 }
 
-
 // end of matmodel.cxx