// 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
//
// 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 <simgear/compiler.h>
#include <map>
-SG_USING_STD(map);
-#include <simgear/compiler.h>
-#ifdef SG_MATH_EXCEPTION_CLASH
-# include <math.h>
-#endif
+#include <osg/AlphaFunc>
+#include <osg/Group>
+#include <osg/LOD>
+#include <osg/StateSet>
+#include <osg/Transform>
#include <simgear/debug/logstream.hxx>
+#include <simgear/math/SGMath.hxx>
#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"
-\f
-////////////////////////////////////////////////////////////////////////
-// Local static functions.
-////////////////////////////////////////////////////////////////////////
-
-/**
- * Internal method to test whether a file exists.
- *
- * TODO: this should be moved to a SimGear library of local file
- * functions.
- */
-static inline bool
-local_file_exists( const string& path ) {
- sg_gzifstream in( path );
- if ( ! in.is_open() ) {
- return false;
- } else {
- return true;
- }
-}
-
-
-\f
+using namespace simgear;
+using std::string;
+using std::map;\f
////////////////////////////////////////////////////////////////////////
// Implementation of SGMatModel.
////////////////////////////////////////////////////////////////////////
}
// Note all the model paths
- vector <SGPropertyNode_ptr> path_nodes = node->getChildren("path");
+ std::vector <SGPropertyNode_ptr> path_nodes = node->getChildren("path");
for (unsigned int i = 0; i < path_nodes.size(); i++)
_paths.push_back(path_nodes[i]->getStringValue());
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 *
-SGMatModel::get_model( int index,
- SGModelLoader *loader,
- const string &fg_root,
- SGPropertyNode *prop_root,
- double sim_time_sec )
+osg::Node*
+SGMatModel::get_random_model( SGPropertyNode *prop_root, mt seed )
{
- load_models( loader, fg_root, prop_root, sim_time_sec ); // comment this out if preloading models
- return _models[index];
-}
-
-ssgEntity *
-SGMatModel::get_random_model( SGModelLoader *loader,
- const string &fg_root,
- SGPropertyNode *prop_root,
- double sim_time_sec )
-{
- 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[mt_rand(&seed) * nModels].get();
}
double
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
{
: _range_m(node->getDoubleValue("range-m", 2000))
{
// Load the object subnodes
- vector<SGPropertyNode_ptr> object_nodes =
+ std::vector<SGPropertyNode_ptr> object_nodes =
((SGPropertyNode *)node)->getChildren("object");
for (unsigned int i = 0; i < object_nodes.size(); i++) {
const SGPropertyNode * object_node = object_nodes[i];
SGMatModelGroup::~SGMatModelGroup ()
{
- for (unsigned int i = 0; i < _objects.size(); i++) {
- delete _objects[i];
- _objects[i] = 0;
- }
}
double
return _objects[index];
}
-
// end of matmodel.cxx