WS30: Terrasync compatible files, LoD control
Change WS30 file format to match standard scenery directory structure, add controls for LOD ranges.
This commit is contained in:
parent
23a4fb1429
commit
bbef23deae
@ -192,39 +192,40 @@ std::string SGBucket::gen_vpb_base() const {
|
|||||||
|
|
||||||
top_lon = lon / 10;
|
top_lon = lon / 10;
|
||||||
main_lon = lon;
|
main_lon = lon;
|
||||||
if ((lon < 0) && (top_lon * 10 != lon)) {
|
if ( (lon < 0) && (top_lon * 10 != lon) ) {
|
||||||
top_lon -= 1;
|
top_lon -= 1;
|
||||||
}
|
}
|
||||||
top_lon *= 10;
|
top_lon *= 10;
|
||||||
if (top_lon >= 0) {
|
if ( top_lon >= 0 ) {
|
||||||
hem = 'E';
|
hem = 'e';
|
||||||
|
} else {
|
||||||
|
hem = 'w';
|
||||||
|
top_lon *= -1;
|
||||||
}
|
}
|
||||||
else {
|
if ( main_lon < 0 ) {
|
||||||
hem = 'W';
|
main_lon *= -1;
|
||||||
top_lon *= -1;
|
|
||||||
}
|
|
||||||
if (main_lon < 0) {
|
|
||||||
main_lon *= -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
top_lat = lat / 10;
|
top_lat = lat / 10;
|
||||||
main_lat = lat;
|
main_lat = lat;
|
||||||
if ((lat < 0) && (top_lat * 10 != lat)) {
|
if ( (lat < 0) && (top_lat * 10 != lat) ) {
|
||||||
top_lat -= 1;
|
top_lat -= 1;
|
||||||
}
|
}
|
||||||
top_lat *= 10;
|
top_lat *= 10;
|
||||||
if (top_lat >= 0) {
|
if ( top_lat >= 0 ) {
|
||||||
pole = 'N';
|
pole = 'n';
|
||||||
|
} else {
|
||||||
|
pole = 's';
|
||||||
|
top_lat *= -1;
|
||||||
}
|
}
|
||||||
else {
|
if ( main_lat < 0 ) {
|
||||||
pole = 'S';
|
main_lat *= -1;
|
||||||
top_lat *= -1;
|
|
||||||
}
|
|
||||||
if (main_lat < 0) {
|
|
||||||
main_lat *= -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::snprintf(raw_path, 256, "WS_%c%d%c%2d", hem, main_lon, pole, main_lat);
|
::snprintf(raw_path, 256, "%c%03d%c%02d/%c%03d%c%02d/ws_%c%03d%c%02d",
|
||||||
|
hem, top_lon, pole, top_lat,
|
||||||
|
hem, main_lon, pole, main_lat,
|
||||||
|
hem, main_lon, pole, main_lat);
|
||||||
|
|
||||||
return raw_path;
|
return raw_path;
|
||||||
}
|
}
|
||||||
|
@ -937,6 +937,40 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AdjustLODVisitor : public osg::NodeVisitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float _rangeFactor;
|
||||||
|
float _maxRange;
|
||||||
|
AdjustLODVisitor(float rangeFactor, float maxRange): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
|
||||||
|
{
|
||||||
|
_rangeFactor = rangeFactor;
|
||||||
|
_maxRange = maxRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(osg::PagedLOD& node)
|
||||||
|
{
|
||||||
|
if (node.getNumChildren() == 0) return;
|
||||||
|
|
||||||
|
if (node.getNumFileNames() == 2) {
|
||||||
|
// We use internal knowledge of VPB to modify the LOD ranges.
|
||||||
|
// The first child is the current node. The second is the sub-tile at higher resolution.
|
||||||
|
// See VirtualPlanetBuild src/vpb/Destination.cpp CompositeDestination::createPagedLODScene()
|
||||||
|
// lines 3330-3333
|
||||||
|
node.dirtyBound(); // At this point the bounds haven't been calculated, so we need to force this.
|
||||||
|
float maxRange = _maxRange + node.getBound().radius();
|
||||||
|
float cutoff = std::min(node.getBound().radius() * _rangeFactor, maxRange);
|
||||||
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "VPB PagedLOD range " << cutoff << " " << maxRange);
|
||||||
|
node.setRange(0, cutoff, maxRange);
|
||||||
|
node.setRange(1, 0, cutoff);
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_TERRAIN, SG_ALERT, "Unexpected PagedLOD type in LOD range update");
|
||||||
|
}
|
||||||
|
|
||||||
|
traverse(node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct OSGOptimizePolicy : public OptimizeModelPolicy {
|
struct OSGOptimizePolicy : public OptimizeModelPolicy {
|
||||||
|
|
||||||
|
|
||||||
@ -950,27 +984,34 @@ struct OSGOptimizePolicy : public OptimizeModelPolicy {
|
|||||||
{
|
{
|
||||||
ref_ptr<Node> optimized = node;
|
ref_ptr<Node> optimized = node;
|
||||||
|
|
||||||
const SGReaderWriterOptions* sgopt
|
const SGReaderWriterOptions* sgopt = SGReaderWriterOptions::copyOrCreate(opt);
|
||||||
= dynamic_cast<const SGReaderWriterOptions*>(opt);
|
|
||||||
|
|
||||||
if (fileName.find("vpb/WS_") != string::npos) {
|
if (fileName.find("ws_") != string::npos) {
|
||||||
// Currently the only way we have to identify WS3.0 / VirtualPlanetBuilder files is by the filename
|
// Currently the only way we have to identify WS3.0 / VirtualPlanetBuilder files is by the filename
|
||||||
|
|
||||||
// Clean out any existing osgTerrain techniques
|
// Clean out any existing osgTerrain techniques
|
||||||
CleanTechniqueVisitor ctv;
|
CleanTechniqueVisitor ctv;
|
||||||
optimized->accept(ctv);
|
optimized->accept(ctv);
|
||||||
|
|
||||||
|
// Adjust the LOD ranges as required.
|
||||||
|
double rangeFactor = SGSceneFeatures::instance()->getVPBRangeFactor();
|
||||||
|
double maxRange = SGSceneFeatures::instance()->getVPBMaxRange();
|
||||||
|
AdjustLODVisitor alv = AdjustLODVisitor(rangeFactor, maxRange);
|
||||||
|
optimized->accept(alv);
|
||||||
|
|
||||||
osg::ref_ptr<osgTerrain::Terrain> terrain = findTopMostNodeOfType<osgTerrain::Terrain>(optimized.get());
|
osg::ref_ptr<osgTerrain::Terrain> terrain = findTopMostNodeOfType<osgTerrain::Terrain>(optimized.get());
|
||||||
|
|
||||||
if (terrain != NULL) {
|
if (terrain != NULL) {
|
||||||
// Top level
|
// Top level
|
||||||
terrain->setSampleRatio(1.0);
|
terrain->setSampleRatio(1.0);
|
||||||
terrain->setVerticalScale(1.0);
|
terrain->setVerticalScale(1.0);
|
||||||
terrain->setBlendingPolicy(osgTerrain::TerrainTile::INHERIT);
|
|
||||||
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt));
|
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt));
|
||||||
} else {
|
} else {
|
||||||
// no Terrain node present insert one above the loaded model.
|
// no Terrain node present insert one above the loaded model.
|
||||||
terrain = new osgTerrain::Terrain;
|
terrain = new osgTerrain::Terrain;
|
||||||
|
terrain->setSampleRatio(1.0);
|
||||||
|
terrain->setVerticalScale(1.0);
|
||||||
|
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt));
|
||||||
//SG_LOG(SG_TERRAIN, SG_ALERT, "Creating Terrain Node for " << fileName);
|
//SG_LOG(SG_TERRAIN, SG_ALERT, "Creating Terrain Node for " << fileName);
|
||||||
|
|
||||||
// if CoordinateSystemNode is present copy it's contents into the Terrain, and discard it.
|
// if CoordinateSystemNode is present copy it's contents into the Terrain, and discard it.
|
||||||
|
@ -37,9 +37,10 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
|
||||||
#include <simgear/scene/material/Effect.hxx>
|
#include <simgear/scene/material/Effect.hxx>
|
||||||
#include <simgear/scene/material/EffectGeode.hxx>
|
#include <simgear/scene/material/EffectGeode.hxx>
|
||||||
|
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
||||||
|
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||||
|
|
||||||
#include "VPBTechnique.hxx"
|
#include "VPBTechnique.hxx"
|
||||||
|
|
||||||
@ -156,14 +157,12 @@ void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
applyColorLayers(*buffer, masterLocator);
|
applyColorLayers(*buffer, masterLocator);
|
||||||
applyTransparency(*buffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
generateGeometry(*buffer, masterLocator, centerModel);
|
generateGeometry(*buffer, masterLocator, centerModel);
|
||||||
applyColorLayers(*buffer, masterLocator);
|
applyColorLayers(*buffer, masterLocator);
|
||||||
applyTransparency(*buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true);
|
if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true);
|
||||||
@ -847,11 +846,10 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
numRows = elevationLayer->getNumRows();
|
numRows = elevationLayer->getNumRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
double scaleHeight = atof(_options->getPluginStringData("SimGear::ELEV_MESH_VERTICAL_SCALE").c_str());
|
|
||||||
double sampleRatio = atof(_options->getPluginStringData("SimGear::ELEV_MESH_SAMPLE_RATIO").c_str());
|
|
||||||
double constraint_gap = atof(_options->getPluginStringData("SimGear::ELEV_MESH_CONSTRAINT_GAP").c_str());
|
|
||||||
|
|
||||||
// OSG_NOTICE<<"Sample ratio="<<sampleRatio<<std::endl;
|
double scaleHeight = SGSceneFeatures::instance()->getVPBVerticalScale();
|
||||||
|
double sampleRatio = SGSceneFeatures::instance()->getVPBSampleRatio();
|
||||||
|
double constraint_gap = SGSceneFeatures::instance()->getVPBConstraintGap();
|
||||||
|
|
||||||
unsigned int minimumNumColumns = 16u;
|
unsigned int minimumNumColumns = 16u;
|
||||||
unsigned int minimumNumRows = 16u;
|
unsigned int minimumNumRows = 16u;
|
||||||
@ -865,8 +863,6 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
numRows = std::max((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),minimumNumRows);
|
numRows = std::max((unsigned int) (float(originalNumRows)*sqrtf(sampleRatio)),minimumNumRows);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
|
bool treatBoundariesToValidDataAsDefaultValue = _terrainTile->getTreatBoundariesToValidDataAsDefaultValue();
|
||||||
OSG_INFO<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
|
OSG_INFO<<"TreatBoundariesToValidDataAsDefaultValue="<<treatBoundariesToValidDataAsDefaultValue<<std::endl;
|
||||||
|
|
||||||
@ -1516,57 +1512,6 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VPBTechnique::applyTransparency(BufferData& buffer)
|
|
||||||
{
|
|
||||||
TerrainTile::BlendingPolicy blendingPolicy = _terrainTile->getBlendingPolicy();
|
|
||||||
if (blendingPolicy == TerrainTile::INHERIT && _terrainTile->getTerrain())
|
|
||||||
{
|
|
||||||
OSG_INFO<<"VPBTechnique::applyTransparency() inheriting policy from Terrain"<<std::endl;
|
|
||||||
blendingPolicy = _terrainTile->getTerrain()->getBlendingPolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blendingPolicy == TerrainTile::INHERIT)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"VPBTechnique::applyTransparency() policy is INHERIT, defaulting to ENABLE_BLENDING_WHEN_ALPHA_PRESENT"<<std::endl;
|
|
||||||
blendingPolicy = TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blendingPolicy == TerrainTile::DO_NOT_SET_BLENDING)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"blendingPolicy == TerrainTile::DO_NOT_SET_BLENDING"<<std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enableBlending = false;
|
|
||||||
|
|
||||||
if (blendingPolicy == TerrainTile::ENABLE_BLENDING)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"blendingPolicy == TerrainTile::ENABLE_BLENDING"<<std::endl;
|
|
||||||
enableBlending = true;
|
|
||||||
}
|
|
||||||
else if (blendingPolicy == TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"blendingPolicy == TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT"<<std::endl;
|
|
||||||
for(unsigned int i=0; i<_terrainTile->getNumColorLayers(); ++i)
|
|
||||||
{
|
|
||||||
osg::Image* image = (_terrainTile->getColorLayer(i)!=0) ? _terrainTile->getColorLayer(i)->getImage() : 0;
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
enableBlending = image->isImageTranslucent();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enableBlending)
|
|
||||||
{
|
|
||||||
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
|
|
||||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
||||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VPBTechnique::update(osg::NodeVisitor& nv)
|
void VPBTechnique::update(osg::NodeVisitor& nv)
|
||||||
{
|
{
|
||||||
if (_terrainTile) _terrainTile->osg::Group::traverse(nv);
|
if (_terrainTile) _terrainTile->osg::Group::traverse(nv);
|
||||||
|
@ -115,8 +115,6 @@ class VPBTechnique : public TerrainTechnique
|
|||||||
|
|
||||||
virtual void applyColorLayers(BufferData& buffer, Locator* masterLocator);
|
virtual void applyColorLayers(BufferData& buffer, Locator* masterLocator);
|
||||||
|
|
||||||
virtual void applyTransparency(BufferData& buffer);
|
|
||||||
|
|
||||||
OpenThreads::Mutex _writeBufferMutex;
|
OpenThreads::Mutex _writeBufferMutex;
|
||||||
osg::ref_ptr<BufferData> _currentBufferData;
|
osg::ref_ptr<BufferData> _currentBufferData;
|
||||||
osg::ref_ptr<BufferData> _newBufferData;
|
osg::ref_ptr<BufferData> _newBufferData;
|
||||||
|
@ -64,6 +64,21 @@ public:
|
|||||||
bool getVPBActive() const { return _VPBActive; }
|
bool getVPBActive() const { return _VPBActive; }
|
||||||
void setVPBActive(const bool val) { _VPBActive = val; }
|
void setVPBActive(const bool val) { _VPBActive = val; }
|
||||||
|
|
||||||
|
float getVPBRangeFactor() const { return _VPBRangeFactor; }
|
||||||
|
void setVPBRangeFactor(const float val) { _VPBRangeFactor = val; }
|
||||||
|
|
||||||
|
float getVPBMaxRange() const { return _VPBMaxRange; }
|
||||||
|
void setVPBMaxRange(const float val) { _VPBMaxRange = val; }
|
||||||
|
|
||||||
|
float getVPBConstraintGap() const { return _VPBConstraintGap; }
|
||||||
|
void setVPBConstraintGap(const float val) { _VPBConstraintGap = val; }
|
||||||
|
|
||||||
|
float getVPBSampleRatio() const { return _VPBSampleRatio; }
|
||||||
|
void setVPBSampleRatio(const float val) { _VPBSampleRatio = val; }
|
||||||
|
|
||||||
|
float getVPBVerticalScale() const { return _VPBVerticalScale; }
|
||||||
|
void setVPBVerticalScale(const float val) { _VPBVerticalScale = val; }
|
||||||
|
|
||||||
void setEnablePointSpriteLights(bool enable)
|
void setEnablePointSpriteLights(bool enable)
|
||||||
{
|
{
|
||||||
_pointSpriteLights = enable;
|
_pointSpriteLights = enable;
|
||||||
@ -150,6 +165,11 @@ private:
|
|||||||
bool _distanceAttenuationLights;
|
bool _distanceAttenuationLights;
|
||||||
int _textureFilter;
|
int _textureFilter;
|
||||||
bool _VPBActive;
|
bool _VPBActive;
|
||||||
|
float _VPBConstraintGap;
|
||||||
|
float _VPBRangeFactor;
|
||||||
|
float _VPBMaxRange;
|
||||||
|
float _VPBSampleRatio;
|
||||||
|
float _VPBVerticalScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user