WS30: Initial photoscenery work
Hack for hackathon
This commit is contained in:
parent
6ea99e43f1
commit
7a7b26e75d
@ -230,6 +230,53 @@ std::string SGBucket::gen_vpb_base() const {
|
||||
return raw_path;
|
||||
}
|
||||
|
||||
std::string SGBucket::gen_vpb_subtile(int level, int x, int y) const {
|
||||
// long int index;
|
||||
int top_lon, top_lat, main_lon, main_lat;
|
||||
char hem, pole;
|
||||
char raw_path[256];
|
||||
|
||||
top_lon = lon / 10;
|
||||
main_lon = lon;
|
||||
if ( (lon < 0) && (top_lon * 10 != lon) ) {
|
||||
top_lon -= 1;
|
||||
}
|
||||
top_lon *= 10;
|
||||
if ( top_lon >= 0 ) {
|
||||
hem = 'e';
|
||||
} else {
|
||||
hem = 'w';
|
||||
top_lon *= -1;
|
||||
}
|
||||
if ( main_lon < 0 ) {
|
||||
main_lon *= -1;
|
||||
}
|
||||
|
||||
top_lat = lat / 10;
|
||||
main_lat = lat;
|
||||
if ( (lat < 0) && (top_lat * 10 != lat) ) {
|
||||
top_lat -= 1;
|
||||
}
|
||||
top_lat *= 10;
|
||||
if ( top_lat >= 0 ) {
|
||||
pole = 'n';
|
||||
} else {
|
||||
pole = 's';
|
||||
top_lat *= -1;
|
||||
}
|
||||
if ( main_lat < 0 ) {
|
||||
main_lat *= -1;
|
||||
}
|
||||
|
||||
::snprintf(raw_path, 256, "%c%03d%c%02d/%c%03d%c%02d/ws_%c%03d%c%02d_root_L0_X0_Y0/ws_%c%03d%c%02d_L%d_X%d_Y%d_subtile",
|
||||
hem, top_lon, pole, top_lat,
|
||||
hem, main_lon, pole, main_lat,
|
||||
hem, main_lon, pole, main_lat,
|
||||
hem, main_lon, pole, main_lat,
|
||||
level, x, y);
|
||||
|
||||
return raw_path;
|
||||
}
|
||||
// Build the path name for this bucket
|
||||
std::string SGBucket::gen_base_path() const {
|
||||
// long int index;
|
||||
|
@ -215,6 +215,7 @@ public:
|
||||
*/
|
||||
std::string gen_vpb_base() const;
|
||||
std::string gen_vpb_base_alt() const;
|
||||
std::string gen_vpb_subtile(int level, int x, int y) const;
|
||||
|
||||
/**
|
||||
* @return the center lon of a tile.
|
||||
|
@ -1027,9 +1027,9 @@ struct OSGOptimizePolicy : public OptimizeModelPolicy {
|
||||
// Top level. This is likely to have the default GeometryTechnique already assigned which we need to replace with our own
|
||||
terrain->setSampleRatio(features->getVPBSampleRatio());
|
||||
terrain->setVerticalScale(features->getVPBVerticalScale());
|
||||
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt));
|
||||
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt, fileName));
|
||||
if (terrainTile != NULL) {
|
||||
terrainTile->setTerrainTechnique(new VPBTechnique(sgopt));
|
||||
terrainTile->setTerrainTechnique(new VPBTechnique(sgopt, fileName));
|
||||
terrainTile->setDirty(true);
|
||||
} else {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "VPB TerrainTile not found");
|
||||
@ -1039,7 +1039,7 @@ struct OSGOptimizePolicy : public OptimizeModelPolicy {
|
||||
terrain = new osgTerrain::Terrain;
|
||||
terrain->setSampleRatio(features->getVPBSampleRatio());
|
||||
terrain->setVerticalScale(features->getVPBVerticalScale());
|
||||
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt));
|
||||
terrain->setTerrainTechniquePrototype(new VPBTechnique(sgopt, fileName));
|
||||
|
||||
// if CoordinateSystemNode is present copy it's contents into the Terrain, and discard it.
|
||||
osg::CoordinateSystemNode* csn = findTopMostNodeOfType<osg::CoordinateSystemNode>(optimized.get());
|
||||
|
@ -56,7 +56,8 @@
|
||||
using namespace osgTerrain;
|
||||
using namespace simgear;
|
||||
|
||||
VPBTechnique::VPBTechnique()
|
||||
VPBTechnique::VPBTechnique():
|
||||
_fileName("")
|
||||
{
|
||||
setFilterBias(0);
|
||||
setFilterWidth(0.1);
|
||||
@ -64,17 +65,20 @@ VPBTechnique::VPBTechnique()
|
||||
_randomObjectsConstraintGroup = new osg::Group();
|
||||
}
|
||||
|
||||
VPBTechnique::VPBTechnique(const SGReaderWriterOptions* options)
|
||||
VPBTechnique::VPBTechnique(const SGReaderWriterOptions* options, const string& fileName):
|
||||
_fileName(fileName)
|
||||
{
|
||||
setFilterBias(0);
|
||||
setFilterWidth(0.1);
|
||||
setFilterMatrixAs(GAUSSIAN);
|
||||
setOptions(options);
|
||||
_randomObjectsConstraintGroup = new osg::Group();
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "VPBTechnique for " << _fileName);
|
||||
}
|
||||
|
||||
VPBTechnique::VPBTechnique(const VPBTechnique& gt,const osg::CopyOp& copyop):
|
||||
TerrainTechnique(gt,copyop)
|
||||
TerrainTechnique(gt,copyop),
|
||||
_fileName(gt._fileName)
|
||||
{
|
||||
setFilterBias(gt._filterBias);
|
||||
setFilterWidth(gt._filterWidth);
|
||||
@ -1279,55 +1283,91 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
||||
|
||||
void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
||||
{
|
||||
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
||||
if (!matlib) return;
|
||||
|
||||
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
||||
if (!colorLayer) return;
|
||||
const SGPropertyNode* propertyNode = _options->getPropertyNode().get();
|
||||
bool photoScenery = false;
|
||||
|
||||
osg::Image* image = colorLayer->getImage();
|
||||
if (!image || ! image->valid()) return;
|
||||
|
||||
// First time generating this texture, so process to change landclass IDs to texure indexes.
|
||||
SGPropertyNode_ptr landEffectProp;
|
||||
|
||||
const SGGeod loc = computeCenterGeod(buffer, masterLocator);
|
||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
||||
|
||||
SGMaterialCache::Atlas atlas = matlib->generateMatCache(loc, _options)->getAtlas();
|
||||
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
||||
|
||||
// Set the "g" color channel to an index into the atlas index.
|
||||
for (unsigned int s = 0; s < (unsigned int) image->s(); s++) {
|
||||
for (unsigned int t = 0; t < (unsigned int) image->t(); t++) {
|
||||
osg::Vec4d c = image->getColor(s, t);
|
||||
int i = int(round(c.x() * 255.0));
|
||||
c.set(c.x(), (double) (atlasIndex[i] / 255.0), c.z(), c.w() );
|
||||
image->setColor(c, s, t);
|
||||
}
|
||||
if (propertyNode) {
|
||||
photoScenery = _options->getPropertyNode()->getBoolValue("/sim/rendering/photoscenery/enabled");
|
||||
}
|
||||
|
||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "VPB Image level:" << _terrainTile->getTileID().level << " " << image->s() << "x" << image->t() << " mipmaps:" << image->getNumMipmapLevels() << " format:" << image->getInternalTextureFormat());
|
||||
if (photoScenery) {
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
|
||||
texture2D->setImage(image);
|
||||
texture2D->setMaxAnisotropy(16.0f);
|
||||
texture2D->setResizeNonPowerOfTwoHint(false);
|
||||
// Firstly, we need to work out the texture file we want to load. Fortunately this follows the same
|
||||
// naming convention as the VPB scenery itself.
|
||||
auto tileID = _terrainTile->getTileID();
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "Using Photoscenery for " << tileID.level << " X" << tileID.x << " Y" << tileID.y);
|
||||
|
||||
// Use mipmaps only in the minimization case because on magnification this results
|
||||
// in bad interpolation of boundaries between landclasses
|
||||
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_NEAREST);
|
||||
texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
||||
const osg::Vec3d world = buffer._transform->getMatrix().getTrans();
|
||||
const SGGeod loc = SGGeod::fromCart(toSG(world));
|
||||
const SGBucket bucket = SGBucket(loc);
|
||||
|
||||
texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
|
||||
texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
|
||||
// Bit of a hack - we assume the Orthophotos are in the same FG_SCENERY top level as the .osgb tiles.
|
||||
string base = _fileName.substr(0, _fileName.find("vpb"));
|
||||
SGPath orthotexture = SGPath(base);
|
||||
orthotexture.append("Orthophotos");
|
||||
orthotexture.append(bucket.gen_vpb_subtile(tileID.level, tileID.x, tileID.y) + ".dds");
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "Using " << orthotexture);
|
||||
|
||||
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(2, atlas.dimensions, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(3, atlas.diffuse, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(4, atlas.specular, osg::StateAttribute::ON);
|
||||
if (orthotexture.exists()) {
|
||||
osg::Texture2D* texture = SGLoadTexture2D(SGPath(orthotexture), _options, false, false);
|
||||
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||
stateset->setTextureAttributeAndModes(0, texture);
|
||||
} else {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to find " << orthotexture);
|
||||
}
|
||||
|
||||
} else {
|
||||
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
||||
if (!matlib) return;
|
||||
|
||||
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
||||
if (!colorLayer) return;
|
||||
|
||||
osg::Image* image = colorLayer->getImage();
|
||||
if (!image || ! image->valid()) return;
|
||||
|
||||
// First time generating this texture, so process to change landclass IDs to texure indexes.
|
||||
SGPropertyNode_ptr landEffectProp;
|
||||
|
||||
const SGGeod loc = computeCenterGeod(buffer, masterLocator);
|
||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
||||
|
||||
SGMaterialCache::Atlas atlas = matlib->generateMatCache(loc, _options)->getAtlas();
|
||||
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
||||
|
||||
// Set the "g" color channel to an index into the atlas index.
|
||||
for (unsigned int s = 0; s < (unsigned int) image->s(); s++) {
|
||||
for (unsigned int t = 0; t < (unsigned int) image->t(); t++) {
|
||||
osg::Vec4d c = image->getColor(s, t);
|
||||
int i = int(round(c.x() * 255.0));
|
||||
c.set(c.x(), (double) (atlasIndex[i] / 255.0), c.z(), c.w() );
|
||||
image->setColor(c, s, t);
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "VPB Image level:" << _terrainTile->getTileID().level << " " << image->s() << "x" << image->t() << " mipmaps:" << image->getNumMipmapLevels() << " format:" << image->getInternalTextureFormat());
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
|
||||
texture2D->setImage(image);
|
||||
texture2D->setMaxAnisotropy(16.0f);
|
||||
texture2D->setResizeNonPowerOfTwoHint(false);
|
||||
|
||||
// Use mipmaps only in the minimization case because on magnification this results
|
||||
// in bad interpolation of boundaries between landclasses
|
||||
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_NEAREST);
|
||||
texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
|
||||
|
||||
texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
|
||||
texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
|
||||
|
||||
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||
stateset->setTextureAttributeAndModes(0, texture2D, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(1, atlas.image, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(2, atlas.dimensions, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(3, atlas.diffuse, osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(4, atlas.specular, osg::StateAttribute::ON);
|
||||
}
|
||||
}
|
||||
|
||||
double VPBTechnique::det2(const osg::Vec2d a, const osg::Vec2d b)
|
||||
|
@ -45,7 +45,7 @@ class VPBTechnique : public TerrainTechnique
|
||||
public:
|
||||
|
||||
VPBTechnique();
|
||||
VPBTechnique(const SGReaderWriterOptions* options);
|
||||
VPBTechnique(const SGReaderWriterOptions* options, const string& fileName);
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
VPBTechnique(const VPBTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
@ -199,6 +199,7 @@ class VPBTechnique : public TerrainTechnique
|
||||
osg::Matrix3 _filterMatrix;
|
||||
osg::ref_ptr<osg::Uniform> _filterMatrixUniform;
|
||||
osg::ref_ptr<SGReaderWriterOptions> _options;
|
||||
const string& _fileName;
|
||||
osg::ref_ptr<osg::Group> _randomObjectsConstraintGroup;
|
||||
|
||||
inline static osg::ref_ptr<osg::Group> _elevationConstraintGroup = new osg::Group();
|
||||
|
Loading…
Reference in New Issue
Block a user