#include <simgear/scene/util/SGUpdateVisitor.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/scene/util/QuadTreeBuilder.hxx>
-#include <simgear/threads/SGThread.hxx>
-#include <simgear/threads/SGGuard.hxx>
#include "SGTexturedTriangleBin.hxx"
#include "SGLightBin.hxx"
if (node)
terrainGroup->addChild(node);
- if (use_random_objects) {
+ if (use_random_objects || use_random_vegetation) {
// Simple matrix for used for flipping models that have been oriented
// with the center of the tile but upside down.
osg::Matrix mAtt = flip * osg::Matrix::rotate(hlOr.osg());
// The inverse goes from world coordinates to Z up tile coordinates.
osg::Matrix world2Tile(osg::Matrix(hlOr.osg().conj()) * flip);
-
- tileGeometryBin.computeRandomObjects(matlib);
+
+ if (use_random_objects) {
+ tileGeometryBin.computeRandomObjects(matlib);
- if (tileGeometryBin.randomModels.getNumModels() > 0) {
- // Generate a repeatable random seed
- mt seed;
- mt_init(&seed, unsigned(123));
-
- std::vector<ModelLOD> models;
- for (unsigned int i = 0; i < tileGeometryBin.randomModels.getNumModels(); i++) {
- SGMatModelBin::MatModel obj = tileGeometryBin.randomModels.getMatModel(i);
- osg::Node* node = sgGetRandomModel(obj.model);
+ if (tileGeometryBin.randomModels.getNumModels() > 0) {
+ // Generate a repeatable random seed
+ mt seed;
+ mt_init(&seed, unsigned(123));
+
+ std::vector<ModelLOD> models;
+ for (unsigned int i = 0;
+ i < tileGeometryBin.randomModels.getNumModels(); i++) {
+ SGMatModelBin::MatModel obj
+ = tileGeometryBin.randomModels.getMatModel(i);
+ osg::Node* node = sgGetRandomModel(obj.model);
- // 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 mPos = osg::Matrix::translate(obj.position.osg());
- osg::MatrixTransform* 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;
- osg::Matrix rot(cos(hdg), -sin(hdg), 0, 0,
- sin(hdg), cos(hdg), 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- position = new osg::MatrixTransform(rot * mAtt * mPos);
- } else {
- position = new osg::MatrixTransform(mAtt * mPos);
+ // 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(mAtt);
+ transformMat.postMult(osg::Matrix::translate(obj.position.osg()));
+ if (obj.model->get_heading_type() == SGMatModel::HEADING_RANDOM) {
+ // Rotate the object around the z axis.
+ double hdg = mt_rand(&seed) * M_PI * 2;
+ transformMat.preMult(osg::Matrix::rotate(hdg,
+ osg::Vec3d(0.0, 0.0, 1.0)));
+ }
+ osg::MatrixTransform* position =
+ new osg::MatrixTransform(transformMat);
+ position->addChild(node);
+ models.push_back(ModelLOD(position, obj.lod));
}
-
- position->addChild(node);
- models.push_back(ModelLOD(position, obj.lod));
+ RandomObjectsQuadtree quadtree((GetModelLODCoord(world2Tile)),
+ (AddModelLOD()));
+ quadtree.buildQuadTree(models.begin(), models.end());
+ randomObjects = quadtree.getRoot();
+ randomObjects->setName("random objects");
}
- RandomObjectsQuadtree quadtree((GetModelLODCoord(world2Tile)),
- (AddModelLOD()));
- quadtree.buildQuadTree(models.begin(), models.end());
- randomObjects = quadtree.getRoot();
- randomObjects->setName("random objects");
}
- if (use_random_vegetation)
- {
+ if (use_random_vegetation) {
// Now add some random forest.
tileGeometryBin.computeRandomForest(matlib);
lightGroup->addChild(groundLights2);
}
}
-
+
if (!tileGeometryBin.vasiLights.empty()) {
+ osg::Geode* vasiGeode = new osg::Geode;
SGVec4f red(1, 0, 0, 1);
SGMaterial* mat = matlib->find("RWY_RED_LIGHTS");
if (mat)
if (mat)
white = mat->get_light_color();
- osg::Geode* geode = new osg::Geode;
SGDirectionalLightListBin::const_iterator i;
for (i = tileGeometryBin.vasiLights.begin();
i != tileGeometryBin.vasiLights.end(); ++i) {
- geode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
+ vasiGeode->addDrawable(SGLightFactory::getVasi(up, *i, red, white));
}
- osg::Group* vasiLights = new osg::Group;
- vasiLights->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
- vasiLights->setStateSet(lightManager->getRunwayLightStateSet());
- vasiLights->addChild(geode);
- lightGroup->addChild(vasiLights);
+ vasiGeode->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6));
+ vasiGeode->setStateSet(lightManager->getRunwayLightStateSet());
+ lightGroup->addChild(vasiGeode);
}
if (tileGeometryBin.runwayLights.getNumLights() > 0
if (lightGroup->getNumChildren() > 0) {
osg::LOD* lightLOD = new osg::LOD;
lightLOD->addChild(lightGroup.get(), 0, 30000);
- unsigned nodeMask = ~0u;
- nodeMask &= ~SG_NODEMASK_CASTSHADOW_BIT;
- nodeMask &= ~SG_NODEMASK_RECIEVESHADOW_BIT;
- nodeMask &= ~SG_NODEMASK_PICK_BIT;
- nodeMask &= ~SG_NODEMASK_TERRAIN_BIT;
- lightLOD->setNodeMask(nodeMask);
+ // VASI is always on, so doesn't use light bits.
+ lightLOD->setNodeMask(LIGHTS_BITS | MODEL_BIT);
transform->addChild(lightLOD);
}
if (randomObjects.valid()) objectLOD->addChild(randomObjects.get(), 0, 20000);
if (randomForest.valid()) objectLOD->addChild(randomForest.get(), 0, 20000);
- unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT;
+ unsigned nodeMask = SG_NODEMASK_CASTSHADOW_BIT | SG_NODEMASK_RECIEVESHADOW_BIT | SG_NODEMASK_TERRAIN_BIT;
objectLOD->setNodeMask(nodeMask);
transform->addChild(objectLOD);
}