00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 # include <simgear_config.h>
00026 #endif
00027
00028 #include <simgear/compiler.h>
00029
00030 #include <map>
00031 using std::map;
00032
00033 #include <osg/AlphaFunc>
00034 #include <osg/Group>
00035 #include <osg/LOD>
00036 #include <osg/StateSet>
00037 #include <osg/Transform>
00038
00039 #include <simgear/debug/logstream.hxx>
00040 #include <simgear/math/SGMath.hxx>
00041 #include <simgear/math/sg_random.h>
00042 #include <simgear/misc/sg_path.hxx>
00043 #include <simgear/misc/sgstream.hxx>
00044 #include <simgear/scene/model/modellib.hxx>
00045
00046 #include "matmodel.hxx"
00047
00048 using namespace simgear;
00049
00050
00052
00054
00055 SGMatModel::SGMatModel (const SGPropertyNode * node, double range_m)
00056 : _models_loaded(false),
00057 _coverage_m2(node->getDoubleValue("coverage-m2", 1000000)),
00058 _range_m(range_m)
00059 {
00060
00061 if (_coverage_m2 < 1000) {
00062 SG_LOG(SG_INPUT, SG_ALERT, "Random object coverage " << _coverage_m2
00063 << " is too small, forcing, to 1000");
00064 _coverage_m2 = 1000;
00065 }
00066
00067
00068 vector <SGPropertyNode_ptr> path_nodes = node->getChildren("path");
00069 for (unsigned int i = 0; i < path_nodes.size(); i++)
00070 _paths.push_back(path_nodes[i]->getStringValue());
00071
00072
00073 string hdg = node->getStringValue("heading-type", "fixed");
00074 if (hdg == "fixed") {
00075 _heading_type = HEADING_FIXED;
00076 } else if (hdg == "billboard") {
00077 _heading_type = HEADING_BILLBOARD;
00078 } else if (hdg == "random") {
00079 _heading_type = HEADING_RANDOM;
00080 } else {
00081 _heading_type = HEADING_FIXED;
00082 SG_LOG(SG_INPUT, SG_ALERT, "Unknown heading type: " << hdg
00083 << "; using 'fixed' instead.");
00084 }
00085
00086
00087
00088 }
00089
00090 SGMatModel::~SGMatModel ()
00091 {
00092 }
00093
00094 int
00095 SGMatModel::get_model_count( SGPropertyNode *prop_root )
00096 {
00097 load_models( prop_root );
00098 return _models.size();
00099 }
00100
00101 inline void
00102 SGMatModel::load_models( SGPropertyNode *prop_root )
00103 {
00104
00105 if (!_models_loaded) {
00106 for (unsigned int i = 0; i < _paths.size(); i++) {
00107 osg::Node *entity = SGModelLib::loadModel(_paths[i], prop_root);
00108 if (entity != 0) {
00109
00110
00111
00112
00113
00114 if (_heading_type == HEADING_BILLBOARD) {
00115
00116
00117
00118
00119 osg::StateSet* stateSet = entity->getOrCreateStateSet();
00120 osg::AlphaFunc* alphaFunc =
00121 new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01f);
00122 stateSet->setAttributeAndModes(alphaFunc,
00123 osg::StateAttribute::OVERRIDE);
00124 stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
00125 }
00126
00127 _models.push_back(entity);
00128
00129 } else {
00130 SG_LOG(SG_INPUT, SG_ALERT, "Failed to load object " << _paths[i]);
00131 }
00132 }
00133 }
00134 _models_loaded = true;
00135 }
00136
00137 osg::Node*
00138 SGMatModel::get_random_model( SGPropertyNode *prop_root )
00139 {
00140 load_models( prop_root );
00141 int nModels = _models.size();
00142
00143 static int index = -1;
00144 if (++index >= nModels)
00145 index = 0;
00146 return _models[index].get();
00147 }
00148
00149 double
00150 SGMatModel::get_coverage_m2 () const
00151 {
00152 return _coverage_m2;
00153 }
00154
00155 double SGMatModel::get_range_m() const
00156 {
00157 return _range_m;
00158 }
00159
00160 double SGMatModel::get_randomized_range_m(mt* seed) const
00161 {
00162 double lrand = mt_rand(seed);
00163
00164
00165
00166
00167
00168 if (lrand < 0.1) return 2 * _range_m;
00169 if (lrand < 0.4) return 1.5 * _range_m;
00170 else return _range_m;
00171 }
00172
00173 SGMatModel::HeadingType
00174 SGMatModel::get_heading_type () const
00175 {
00176 return _heading_type;
00177 }
00178
00179
00180
00182
00184
00185 SGMatModelGroup::SGMatModelGroup (SGPropertyNode * node)
00186 : _range_m(node->getDoubleValue("range-m", 2000))
00187 {
00188
00189 vector<SGPropertyNode_ptr> object_nodes =
00190 ((SGPropertyNode *)node)->getChildren("object");
00191 for (unsigned int i = 0; i < object_nodes.size(); i++) {
00192 const SGPropertyNode * object_node = object_nodes[i];
00193 if (object_node->hasChild("path"))
00194 _objects.push_back(new SGMatModel(object_node, _range_m));
00195 else
00196 SG_LOG(SG_INPUT, SG_ALERT, "No path supplied for object");
00197 }
00198 }
00199
00200 SGMatModelGroup::~SGMatModelGroup ()
00201 {
00202 }
00203
00204 double
00205 SGMatModelGroup::get_range_m () const
00206 {
00207 return _range_m;
00208 }
00209
00210 int
00211 SGMatModelGroup::get_object_count () const
00212 {
00213 return _objects.size();
00214 }
00215
00216 SGMatModel *
00217 SGMatModelGroup::get_object (int index) const
00218 {
00219 return _objects[index];
00220 }
00221
00222