#include <osg/StateSet>
#include <osg/Switch>
+#include <boost/foreach.hpp>
+
#include <simgear/debug/logstream.hxx>
#include <simgear/io/sg_binobj.hxx>
#include <simgear/math/sg_geodesy.hxx>
SGMaterialTriangleMap materialTriangleMap;
SGLightBin tileLights;
SGLightBin randomTileLights;
- TreeBin randomForest;
+ SGTreeBinList randomForest;
SGDirectionalLightBin runwayLights;
SGDirectionalLightBin taxiLights;
SGDirectionalLightListBin vasiLights;
if (mat)
eg->setEffect(mat->get_effect());
eg->addDrawable(geometry);
+ eg->runGenerators(geometry); // Generate extra data needed by effect
if (group)
group->addChild(eg);
}
float wood_coverage = mat->get_wood_coverage();
if (wood_coverage <= 0)
continue;
-
- // 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();
+
+ // Attributes that don't vary by tree but do vary by material
+ bool found = false;
+ TreeBin* bin = NULL;
+
+ BOOST_FOREACH(bin, randomForest)
+ {
+ if ((bin->texture == mat->get_tree_texture() ) &&
+ (bin->texture_varieties == mat->get_tree_varieties()) &&
+ (bin->range == mat->get_tree_range() ) &&
+ (bin->width == mat->get_tree_width() ) &&
+ (bin->height == mat->get_tree_height() ) ) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ bin = new TreeBin();
+ bin->texture = mat->get_tree_texture();
+ SG_LOG(SG_INPUT, SG_DEBUG, "Tree texture " << bin->texture);
+ bin->range = mat->get_tree_range();
+ bin->width = mat->get_tree_width();
+ bin->height = mat->get_tree_height();
+ bin->texture_varieties = mat->get_tree_varieties();
+ randomForest.push_back(bin);
+ }
std::vector<SGVec3f> randomPoints;
i->second.addRandomTreePoints(wood_coverage,
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);
+ std::vector<SGVec3f>::iterator k;
+ for (k = randomPoints.begin(); k != randomPoints.end(); ++k) {
+ bin->insert(*k);
}
}
}
if (!tile.read_bin(path))
return false;
- SGVec3d center = tile.get_gbs_center2();
+ SGVec3d center = tile.get_gbs_center();
SGGeod geodPos = SGGeod::fromCart(center);
SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180);
osg::ref_ptr<osg::Group> lightGroup = new SGOffsetTransform(0.94);
osg::ref_ptr<osg::Group> randomObjects;
- osg::ref_ptr<osg::Group> randomForest;
+ osg::ref_ptr<osg::Group> forestNode;
osg::Group* terrainGroup = new osg::Group;
osg::Node* node = tileGeometryBin.getSurfaceGeometry(matlib);
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;
if (use_random_vegetation && matlib) {
// Now add some random forest.
tileGeometryBin.computeRandomForest(matlib);
-
- if (tileGeometryBin.randomForest.getNumTrees() > 0) {
- randomForest = createForest(tileGeometryBin.randomForest,
- osg::Matrix::identity());
- randomForest->setName("random trees");
+
+ if (tileGeometryBin.randomForest.size() > 0) {
+ forestNode = createForest(tileGeometryBin.randomForest, osg::Matrix::identity());
+ forestNode->setName("Random trees");
}
}
}
// 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;
transform->addChild(lightLOD);
}
- if (randomObjects.valid() || randomForest.valid()) {
+ if (randomObjects.valid() || forestNode.valid()) {
// Add a LoD node, so we don't try to display anything when the tile center
// is more than 20km away.
osg::LOD* objectLOD = new osg::LOD;
if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 20000);
- if (randomForest.valid()) objectLOD->addChild(randomForest.get(), 0, 20000);
+ if (forestNode.valid()) objectLOD->addChild(forestNode.get(), 0, 20000);
unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT | SG_NODEMASK_TERRAIN_BIT;
objectLOD->setNodeMask(nodeMask);