X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Ftgdb%2Fobj.cxx;h=fd6d42e29e13d5c5d6d6f077123622057514e8d4;hb=2cc2a857a2cc2daff30601e0f8f697c768dd5b30;hp=d5964815e1bcd588016a42c58952fc2380e28776;hpb=81eae3fa4801b095e7d6b51f51e3b10fbdf48501;p=simgear.git diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index d5964815..fd6d42e2 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include #include @@ -129,7 +131,9 @@ struct SGTileGeometryBin { for (unsigned grp = 0; grp < obj.get_pts_v().size(); ++grp) { std::string materialName = obj.get_pt_materials()[grp]; - SGMaterial* material = matlib->find(materialName); + SGMaterial* material = 0; + if (matlib) + material = matlib->find(materialName); SGVec4f color = getMaterialLightColor(material); if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") { @@ -365,37 +369,27 @@ struct SGTileGeometryBin { if (materialTriangleMap.empty()) return 0; - osg::Geode* geode = new osg::Geode; + EffectGeode* eg = 0; + osg::Group* group = (materialTriangleMap.size() > 1 ? new osg::Group : 0); + //osg::Geode* geode = new osg::Geode; SGMaterialTriangleMap::const_iterator i; for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) { - // CHUNCKED (sic) here splits up unconnected triangles parts of - // the mesh into different Geometry sets, presumably for better - // culling. I (timoore) believe it is more performant to build - // the biggest indexed sets possible at the expense of tight - // culling. -//#define CHUNCKED -#ifdef CHUNCKED - SGMaterial *mat = matlib->find(i->first); - - std::list connectSets; - i->second.getConnectedSets(connectSets); - - std::list::iterator j; - for (j = connectSets.begin(); j != connectSets.end(); ++j) { - osg::Geometry* geometry = i->second.buildGeometry(*j); - if (mat) - geometry->setStateSet(mat->get_state()); - geode->addDrawable(geometry); - } -#else osg::Geometry* geometry = i->second.buildGeometry(); - SGMaterial *mat = matlib->find(i->first); + SGMaterial *mat = 0; + if (matlib) + mat = matlib->find(i->first); + eg = new EffectGeode; if (mat) - geometry->setStateSet(mat->get_state()); - geode->addDrawable(geometry); -#endif + eg->setEffect(mat->get_effect()); + eg->addDrawable(geometry); + eg->runGenerators(geometry); // Generate extra data needed by effect + if (group) + group->addChild(eg); } - return geode; + if (group) + return group; + else + return eg; } void computeRandomSurfaceLights(SGMaterialLib* matlib) @@ -462,8 +456,8 @@ struct SGTileGeometryBin { if (!mat) continue; - float coverage = mat->get_tree_coverage(); - if (coverage <= 0) + float wood_coverage = mat->get_wood_coverage(); + if (wood_coverage <= 0) continue; // Attributes that don't vary by tree @@ -474,15 +468,14 @@ struct SGTileGeometryBin { randomForest.texture_varieties = mat->get_tree_varieties(); std::vector randomPoints; - i->second.addRandomSurfacePoints(coverage, 0, randomPoints); + i->second.addRandomTreePoints(wood_coverage, + mat->get_tree_density(), + mat->get_wood_size(), + randomPoints); + std::vector::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); + randomForest.insert(*j); } } } @@ -605,7 +598,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool if (use_random_objects || use_random_vegetation) { if (use_random_objects) { - tileGeometryBin.computeRandomObjects(matlib); + if (matlib) + tileGeometryBin.computeRandomObjects(matlib); if (tileGeometryBin.randomModels.getNumModels() > 0) { // Generate a repeatable random seed @@ -617,13 +611,13 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool 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; @@ -642,7 +636,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool } } - if (use_random_vegetation) { + if (use_random_vegetation && matlib) { // Now add some random forest. tileGeometryBin.computeRandomForest(matlib); @@ -656,7 +650,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool if (calc_lights) { // FIXME: ugly, has a side effect - tileGeometryBin.computeRandomSurfaceLights(matlib); + if (matlib) + tileGeometryBin.computeRandomSurfaceLights(matlib); if (tileGeometryBin.tileLights.getNumLights() > 0 || tileGeometryBin.randomTileLights.getNumLights() > 0) { @@ -688,36 +683,47 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool } if (!tileGeometryBin.vasiLights.empty()) { - osg::Geode* vasiGeode = new osg::Geode; + EffectGeode* vasiGeode = new EffectGeode; + Effect* vasiEffect + = getLightEffect(6, osg::Vec3(1, 0.0001, 0.000001), 1, 6, true); + vasiGeode->setEffect(vasiEffect); SGVec4f red(1, 0, 0, 1); - SGMaterial* mat = matlib->find("RWY_RED_LIGHTS"); + SGMaterial* mat = 0; + if (matlib) + mat = matlib->find("RWY_RED_LIGHTS"); if (mat) red = mat->get_light_color(); SGVec4f white(1, 1, 1, 1); - mat = matlib->find("RWY_WHITE_LIGHTS"); + mat = 0; + if (matlib) + mat = matlib->find("RWY_WHITE_LIGHTS"); if (mat) white = mat->get_light_color(); - SGDirectionalLightListBin::const_iterator i; for (i = tileGeometryBin.vasiLights.begin(); i != tileGeometryBin.vasiLights.end(); ++i) { vasiGeode->addDrawable(SGLightFactory::getVasi(up, *i, red, white)); } - vasiGeode->setCullCallback(new SGPointSpriteLightCullCallback(osg::Vec3(1, 0.0001, 0.000001), 6)); vasiGeode->setStateSet(lightManager->getRunwayLightStateSet()); lightGroup->addChild(vasiGeode); } - + Effect* runwayEffect = 0; + if (tileGeometryBin.runwayLights.getNumLights() > 0 + || !tileGeometryBin.rabitLights.empty() + || !tileGeometryBin.reilLights.empty() + || !tileGeometryBin.odalLights.empty() + || tileGeometryBin.taxiLights.getNumLights() > 0) + runwayEffect = getLightEffect(4, osg::Vec3(1, 0.001, 0.0002), 1, 4, true); if (tileGeometryBin.runwayLights.getNumLights() > 0 || !tileGeometryBin.rabitLights.empty() || !tileGeometryBin.reilLights.empty() || !tileGeometryBin.odalLights.empty()) { osg::Group* rwyLights = new osg::Group; - rwyLights->setCullCallback(new SGPointSpriteLightCullCallback); rwyLights->setStateSet(lightManager->getRunwayLightStateSet()); rwyLights->setNodeMask(RUNWAYLIGHTS_BIT); if (tileGeometryBin.runwayLights.getNumLights() != 0) { - osg::Geode* geode = new osg::Geode; + EffectGeode* geode = new EffectGeode; + geode->setEffect(runwayEffect); geode->addDrawable(SGLightFactory::getLights(tileGeometryBin .runwayLights)); rwyLights->addChild(geode); @@ -741,10 +747,10 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool if (tileGeometryBin.taxiLights.getNumLights() > 0) { osg::Group* taxiLights = new osg::Group; - taxiLights->setCullCallback(new SGPointSpriteLightCullCallback); taxiLights->setStateSet(lightManager->getTaxiLightStateSet()); taxiLights->setNodeMask(RUNWAYLIGHTS_BIT); - osg::Geode* geode = new osg::Geode; + EffectGeode* geode = new EffectGeode; + geode->setEffect(runwayEffect); geode->addDrawable(SGLightFactory::getLights(tileGeometryBin.taxiLights)); taxiLights->addChild(geode); lightGroup->addChild(taxiLights); @@ -753,8 +759,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool // 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;