WS30: Separate Water mesh and Effects
- Rip out various pieces of irrelevant code, simplifying VPBTechnique. Largely dealing with multiple textures per terrain tile, which we don't need. - Use a lookup of the landclass of mesh vertices to identify sections of the mesh that are entirely in water, and split those out into a separate water mesh, using it's own Effect.
This commit is contained in:
parent
55e0d4760f
commit
a02353a280
@ -32,6 +32,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
|
|
||||||
@ -157,13 +158,14 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
|
|||||||
SGPropertyNode_ptr node = lc_iter->get();
|
SGPropertyNode_ptr node = lc_iter->get();
|
||||||
int lc = node->getIntValue("landclass");
|
int lc = node->getIntValue("landclass");
|
||||||
const std::string mat = node->getStringValue("material-name");
|
const std::string mat = node->getStringValue("material-name");
|
||||||
|
const bool water = node->getBoolValue("water");
|
||||||
|
|
||||||
// Verify that the landclass mapping exists before creating the mapping
|
// Verify that the landclass mapping exists before creating the mapping
|
||||||
const_material_map_iterator it = matlib.find( mat );
|
const_material_map_iterator it = matlib.find( mat );
|
||||||
if ( it == end() ) {
|
if ( it == end() ) {
|
||||||
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to find material " << mat << " for landclass " << lc);
|
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to find material " << mat << " for landclass " << lc);
|
||||||
} else {
|
} else {
|
||||||
landclasslib[lc] = mat;
|
landclasslib[lc] = std::pair(mat, water);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +199,7 @@ SGMaterial *SGMaterialLib::find( int lc, const SGVec2f center ) const
|
|||||||
{
|
{
|
||||||
const_landclass_map_iterator it = landclasslib.find( lc );
|
const_landclass_map_iterator it = landclasslib.find( lc );
|
||||||
if (it != landclasslib.end()) {
|
if (it != landclasslib.end()) {
|
||||||
return find(it->second, center);
|
return find(it->second.first, center);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -215,7 +217,7 @@ SGMaterial *SGMaterialLib::find( int lc, const SGGeod& center ) const
|
|||||||
{
|
{
|
||||||
const_landclass_map_iterator it = landclasslib.find( lc );
|
const_landclass_map_iterator it = landclasslib.find( lc );
|
||||||
if (it != landclasslib.end()) {
|
if (it != landclasslib.end()) {
|
||||||
return find(it->second, center);
|
return find(it->second.first, center);
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -234,7 +236,7 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center, const simgear::
|
|||||||
// Collapse down the mapping from landclasses to materials.
|
// Collapse down the mapping from landclasses to materials.
|
||||||
const_landclass_map_iterator lc_iter = landclasslib.begin();
|
const_landclass_map_iterator lc_iter = landclasslib.begin();
|
||||||
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
||||||
newCache->insert(lc_iter->first, find(lc_iter->second, center));
|
newCache->insert(lc_iter->first, find(lc_iter->second.first, center));
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCache;
|
return newCache;
|
||||||
@ -313,7 +315,7 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
std::string id;
|
std::string id;
|
||||||
const_landclass_map_iterator lc_iter = landclasslib.begin();
|
const_landclass_map_iterator lc_iter = landclasslib.begin();
|
||||||
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
for (; lc_iter != landclasslib.end(); ++lc_iter) {
|
||||||
SGMaterial* mat = find(lc_iter->second, center);
|
SGMaterial* mat = find(lc_iter->second.first, center);
|
||||||
const std::string texture = mat->get_one_texture(0,0);
|
const std::string texture = mat->get_one_texture(0,0);
|
||||||
id.append(texture);
|
id.append(texture);
|
||||||
id.append(";");
|
id.append(";");
|
||||||
@ -371,8 +373,9 @@ SGMaterialCache::Atlas SGMaterialLib::getMaterialTextureAtlas(SGVec2f center, co
|
|||||||
// mapping based on the lanclassList, even if we fail to process the texture.
|
// mapping based on the lanclassList, even if we fail to process the texture.
|
||||||
++index;
|
++index;
|
||||||
int i = lc_iter->first;
|
int i = lc_iter->first;
|
||||||
SGMaterial* mat = find(lc_iter->second, center);
|
SGMaterial* mat = find(lc_iter->second.first, center);
|
||||||
atlas.index[i] = index;
|
atlas.index[i] = index;
|
||||||
|
atlas.waterAtlas[i] = lc_iter->second.second;
|
||||||
|
|
||||||
if (mat == NULL) continue;
|
if (mat == NULL) continue;
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
// of texture1D containing further data
|
// of texture1D containing further data
|
||||||
typedef std::map<int, int> AtlasIndex;
|
typedef std::map<int, int> AtlasIndex;
|
||||||
typedef osg::ref_ptr<osg::Texture2DArray> AtlasImage;
|
typedef osg::ref_ptr<osg::Texture2DArray> AtlasImage;
|
||||||
|
typedef std::map<int, bool> WaterAtlas;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
AtlasIndex index;
|
AtlasIndex index;
|
||||||
@ -61,6 +62,7 @@ public:
|
|||||||
osg::ref_ptr<osg::Texture1D> dimensions;
|
osg::ref_ptr<osg::Texture1D> dimensions;
|
||||||
osg::ref_ptr<osg::Texture1D> diffuse;
|
osg::ref_ptr<osg::Texture1D> diffuse;
|
||||||
osg::ref_ptr<osg::Texture1D> specular;
|
osg::ref_ptr<osg::Texture1D> specular;
|
||||||
|
WaterAtlas waterAtlas;
|
||||||
} Atlas;
|
} Atlas;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -105,7 +107,7 @@ private:
|
|||||||
typedef material_map::iterator material_map_iterator;
|
typedef material_map::iterator material_map_iterator;
|
||||||
typedef material_map::const_iterator const_material_map_iterator;
|
typedef material_map::const_iterator const_material_map_iterator;
|
||||||
|
|
||||||
typedef std::map < int, std::string> landclass_map;
|
typedef std::map < int, std::pair<std::string, bool> > landclass_map;
|
||||||
typedef landclass_map::iterator landclass_map_iterator;
|
typedef landclass_map::iterator landclass_map_iterator;
|
||||||
typedef landclass_map::const_iterator const_landclass_map_iterator;
|
typedef landclass_map::const_iterator const_landclass_map_iterator;
|
||||||
|
|
||||||
|
@ -157,10 +157,10 @@ void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded)
|
|||||||
|
|
||||||
osg::ref_ptr<BufferData> read_buffer = _currentBufferData;
|
osg::ref_ptr<BufferData> read_buffer = _currentBufferData;
|
||||||
|
|
||||||
osg::StateSet* stateset = read_buffer->_geode->getStateSet();
|
osg::StateSet* stateset = read_buffer->_landGeode->getStateSet();
|
||||||
if (stateset)
|
if (stateset)
|
||||||
{
|
{
|
||||||
buffer->_geode->setStateSet(stateset);
|
buffer->_landGeode->setStateSet(stateset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -287,7 +287,7 @@ class VertexNormalGenerator
|
|||||||
|
|
||||||
VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColmns, float scaleHeight, float vtx_gap, bool createSkirt);
|
VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColmns, float scaleHeight, float vtx_gap, bool createSkirt);
|
||||||
|
|
||||||
void populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap);
|
void populateCenter(osgTerrain::Layer* elevationLayer, osg::Vec2Array* texcoords);
|
||||||
void populateLeftBoundary(osgTerrain::Layer* elevationLayer);
|
void populateLeftBoundary(osgTerrain::Layer* elevationLayer);
|
||||||
void populateRightBoundary(osgTerrain::Layer* elevationLayer);
|
void populateRightBoundary(osgTerrain::Layer* elevationLayer);
|
||||||
void populateAboveBoundary(osgTerrain::Layer* elevationLayer);
|
void populateAboveBoundary(osgTerrain::Layer* elevationLayer);
|
||||||
@ -493,7 +493,7 @@ VertexNormalGenerator::VertexNormalGenerator(Locator* masterLocator, const osg::
|
|||||||
_boundaryVertices->reserve(_numRows*2 + _numColumns*2 + 4);
|
_boundaryVertices->reserve(_numRows*2 + _numColumns*2 + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap)
|
void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, osg::Vec2Array* texcoords)
|
||||||
{
|
{
|
||||||
// OSG_NOTICE<<std::endl<<"VertexNormalGenerator::populateCenter("<<elevationLayer<<")"<<std::endl;
|
// OSG_NOTICE<<std::endl<<"VertexNormalGenerator::populateCenter("<<elevationLayer<<")"<<std::endl;
|
||||||
|
|
||||||
@ -525,65 +525,7 @@ void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, La
|
|||||||
|
|
||||||
model = VPBTechnique::checkAgainstElevationConstraints(origin, model, _constraint_vtx_gap);
|
model = VPBTechnique::checkAgainstElevationConstraints(origin, model, _constraint_vtx_gap);
|
||||||
|
|
||||||
for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
|
texcoords->push_back(osg::Vec2(ndc.x(), ndc.y()));
|
||||||
itr != layerToTexCoordMap.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
osg::Vec2Array* texcoords = itr->second.first.get();
|
|
||||||
osgTerrain::ImageLayer* imageLayer(dynamic_cast<osgTerrain::ImageLayer*>(itr->first));
|
|
||||||
|
|
||||||
if (imageLayer != NULL)
|
|
||||||
{
|
|
||||||
Locator* colorLocator = itr->second.second;
|
|
||||||
if (colorLocator != _masterLocator)
|
|
||||||
{
|
|
||||||
osg::Vec3d color_ndc;
|
|
||||||
Locator::convertLocalCoordBetween(*_masterLocator, ndc, *colorLocator, color_ndc);
|
|
||||||
(*texcoords).push_back(osg::Vec2(color_ndc.x(), color_ndc.y()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
osgTerrain::ContourLayer* contourLayer(dynamic_cast<osgTerrain::ContourLayer*>(itr->first));
|
|
||||||
|
|
||||||
bool texCoordSet = false;
|
|
||||||
if (contourLayer)
|
|
||||||
{
|
|
||||||
osg::TransferFunction1D* transferFunction = contourLayer->getTransferFunction();
|
|
||||||
if (transferFunction)
|
|
||||||
{
|
|
||||||
float difference = transferFunction->getMaximum()-transferFunction->getMinimum();
|
|
||||||
if (difference != 0.0f)
|
|
||||||
{
|
|
||||||
osg::Vec3d color_ndc;
|
|
||||||
osgTerrain::Locator* colorLocator(itr->second.second);
|
|
||||||
|
|
||||||
if (colorLocator != _masterLocator)
|
|
||||||
{
|
|
||||||
Locator::convertLocalCoordBetween(*_masterLocator,ndc,*colorLocator,color_ndc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color_ndc = ndc;
|
|
||||||
}
|
|
||||||
|
|
||||||
color_ndc[2] /= _scaleHeight;
|
|
||||||
|
|
||||||
(*texcoords).push_back(osg::Vec2((color_ndc[2]-transferFunction->getMinimum())/difference,0.0f));
|
|
||||||
texCoordSet = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!texCoordSet)
|
|
||||||
{
|
|
||||||
(*texcoords).push_back(osg::Vec2(0.0f,0.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_elevations.valid())
|
if (_elevations.valid())
|
||||||
{
|
{
|
||||||
@ -598,6 +540,8 @@ void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, La
|
|||||||
model_one.normalize();
|
model_one.normalize();
|
||||||
|
|
||||||
setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
|
setVertex(i, j, osg::Vec3(model-_centerModel), model_one);
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_TERRAIN, SG_ALERT, "Invalid elevation value found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,51 +745,67 @@ void VertexNormalGenerator::computeNormals()
|
|||||||
|
|
||||||
void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel)
|
void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel)
|
||||||
{
|
{
|
||||||
|
osg::Image* landclassImage = 0;
|
||||||
|
SGMaterialCache::Atlas atlas;
|
||||||
|
|
||||||
Terrain* terrain = _terrainTile->getTerrain();
|
Terrain* terrain = _terrainTile->getTerrain();
|
||||||
osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
|
osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
|
||||||
|
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
||||||
|
if (colorLayer) landclassImage = colorLayer->getImage();
|
||||||
|
|
||||||
// Determine the correct Effect for this, based on a material lookup taking into account
|
// Determine the correct Effect for this, based on a material lookup taking into account
|
||||||
// the lat/lon of the center.
|
// the lat/lon of the center.
|
||||||
SGPropertyNode_ptr effectProp;
|
|
||||||
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
||||||
|
|
||||||
if (matlib) {
|
|
||||||
// Determine the center of the tile, sadly non-trivial.
|
|
||||||
osg::Vec3d tileloc = computeCenter(buffer, masterLocator);
|
osg::Vec3d tileloc = computeCenter(buffer, masterLocator);
|
||||||
osg::Vec3d world;
|
osg::Vec3d world;
|
||||||
masterLocator->convertLocalToModel(tileloc, world);
|
masterLocator->convertLocalToModel(tileloc, world);
|
||||||
const SGVec3d world2 = SGVec3d(world.x(), world.y(), world.z());
|
const SGVec3d world2 = SGVec3d(world.x(), world.y(), world.z());
|
||||||
const SGGeod loc = SGGeod::fromCart(world2);
|
const SGGeod loc = SGGeod::fromCart(world2);
|
||||||
|
|
||||||
|
SGPropertyNode_ptr landEffectProp = new SGPropertyNode();
|
||||||
|
SGPropertyNode_ptr waterEffectProp = new SGPropertyNode();
|
||||||
|
|
||||||
|
if (matlib) {
|
||||||
|
// Determine the center of the tile, sadly non-trivial.
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
||||||
SGMaterialCache* matcache = _options->getMaterialLib()->generateMatCache(loc, _options);
|
SGMaterialCache* matcache = _options->getMaterialLib()->generateMatCache(loc, _options);
|
||||||
SGMaterial* mat = matcache->find("ws30");
|
atlas = matcache->getAtlas();
|
||||||
|
SGMaterial* landmat = matcache->find("ws30land");
|
||||||
|
SGMaterial* watermat = matcache->find("ws30water");
|
||||||
delete matcache;
|
delete matcache;
|
||||||
|
|
||||||
if (mat) {
|
if (landmat && watermat) {
|
||||||
effectProp = new SGPropertyNode();
|
makeChild(landEffectProp.ptr(), "inherits-from")->setStringValue(landmat->get_effect_name());
|
||||||
makeChild(effectProp, "inherits-from")->setStringValue(mat->get_effect_name());
|
makeChild(waterEffectProp.ptr(), "inherits-from")->setStringValue(watermat->get_effect_name());
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for VPB - no matching material in library");
|
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for VPB - no matching material in library");
|
||||||
effectProp = new SGPropertyNode;
|
makeChild(landEffectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
||||||
makeChild(effectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
makeChild(waterEffectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for VPB - no material library available");
|
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for VPB - no material library available");
|
||||||
effectProp = new SGPropertyNode;
|
makeChild(landEffectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
||||||
makeChild(effectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
makeChild(waterEffectProp.ptr(), "inherits-from")->setStringValue("Effects/model-default");
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer._geode = new EffectGeode();
|
buffer._landGeode = new EffectGeode();
|
||||||
if(buffer._transform.valid())
|
buffer._waterGeode = new EffectGeode();
|
||||||
buffer._transform->addChild(buffer._geode.get());
|
if(buffer._transform.valid()) {
|
||||||
|
buffer._transform->addChild(buffer._landGeode.get());
|
||||||
|
buffer._transform->addChild(buffer._waterGeode.get());
|
||||||
|
}
|
||||||
|
|
||||||
buffer._geometry = new osg::Geometry;
|
buffer._landGeometry = new osg::Geometry;
|
||||||
buffer._geode->addDrawable(buffer._geometry.get());
|
buffer._landGeode->addDrawable(buffer._landGeometry.get());
|
||||||
|
|
||||||
osg::ref_ptr<Effect> effect = makeEffect(effectProp, true, _options);
|
osg::ref_ptr<Effect> landEffect = makeEffect(landEffectProp, true, _options);
|
||||||
buffer._geode->setEffect(effect.get());
|
buffer._landGeode->setEffect(landEffect.get());
|
||||||
|
|
||||||
osg::Geometry* geometry = buffer._geometry.get();
|
buffer._waterGeometry = new osg::Geometry;
|
||||||
|
buffer._waterGeode->addDrawable(buffer._waterGeometry.get());
|
||||||
|
|
||||||
|
osg::ref_ptr<Effect> waterEffect = makeEffect(waterEffectProp, true, _options);
|
||||||
|
buffer._waterGeode->setEffect(waterEffect.get());
|
||||||
|
|
||||||
unsigned int numRows = 20;
|
unsigned int numRows = 20;
|
||||||
unsigned int numColumns = 20;
|
unsigned int numColumns = 20;
|
||||||
@ -856,7 +816,6 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
numRows = elevationLayer->getNumRows();
|
numRows = elevationLayer->getNumRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double scaleHeight = SGSceneFeatures::instance()->getVPBVerticalScale();
|
double scaleHeight = SGSceneFeatures::instance()->getVPBVerticalScale();
|
||||||
double sampleRatio = SGSceneFeatures::instance()->getVPBSampleRatio();
|
double sampleRatio = SGSceneFeatures::instance()->getVPBSampleRatio();
|
||||||
double constraint_gap = SGSceneFeatures::instance()->getVPBConstraintGap();
|
double constraint_gap = SGSceneFeatures::instance()->getVPBConstraintGap();
|
||||||
@ -891,64 +850,25 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
unsigned int numVertices = VNG.capacity();
|
unsigned int numVertices = VNG.capacity();
|
||||||
|
|
||||||
// allocate and assign vertices
|
// allocate and assign vertices
|
||||||
geometry->setVertexArray(VNG._vertices.get());
|
buffer._landGeometry->setVertexArray(VNG._vertices.get());
|
||||||
|
buffer._waterGeometry->setVertexArray(VNG._vertices.get());
|
||||||
|
|
||||||
// allocate and assign normals
|
// allocate and assign normals
|
||||||
geometry->setNormalArray(VNG._normals.get(), osg::Array::BIND_PER_VERTEX);
|
buffer._landGeometry->setNormalArray(VNG._normals.get(), osg::Array::BIND_PER_VERTEX);
|
||||||
|
buffer._waterGeometry->setNormalArray(VNG._normals.get(), osg::Array::BIND_PER_VERTEX);
|
||||||
|
|
||||||
// allocate and assign tex coords
|
|
||||||
// typedef std::pair< osg::ref_ptr<osg::Vec2Array>, Locator* > TexCoordLocatorPair;
|
|
||||||
// typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap;
|
|
||||||
|
|
||||||
VertexNormalGenerator::LayerToTexCoordMap layerToTexCoordMap;
|
|
||||||
for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
|
|
||||||
{
|
|
||||||
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
|
|
||||||
if (colorLayer)
|
|
||||||
{
|
|
||||||
VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer);
|
|
||||||
if (itr!=layerToTexCoordMap.end())
|
|
||||||
{
|
|
||||||
geometry->setTexCoordArray(layerNum, itr->second.first.get());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
Locator* locator = colorLayer->getLocator();
|
|
||||||
if (!locator)
|
|
||||||
{
|
|
||||||
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
|
|
||||||
if (switchLayer)
|
|
||||||
{
|
|
||||||
if (switchLayer->getActiveLayer()>=0 &&
|
|
||||||
static_cast<unsigned int>(switchLayer->getActiveLayer())<switchLayer->getNumLayers() &&
|
|
||||||
switchLayer->getLayer(switchLayer->getActiveLayer()))
|
|
||||||
{
|
|
||||||
locator = switchLayer->getLayer(switchLayer->getActiveLayer())->getLocator();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexNormalGenerator::TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer];
|
|
||||||
tclp.first = new osg::Vec2Array;
|
|
||||||
tclp.first->reserve(numVertices);
|
|
||||||
tclp.second = locator ? locator : masterLocator;
|
|
||||||
geometry->setTexCoordArray(layerNum, tclp.first.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate and assign color
|
// allocate and assign color
|
||||||
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
|
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
|
||||||
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
|
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
|
||||||
|
|
||||||
geometry->setColorArray(colors.get(), osg::Array::BIND_OVERALL);
|
buffer._landGeometry->setColorArray(colors.get(), osg::Array::BIND_OVERALL);
|
||||||
|
buffer._waterGeometry->setColorArray(colors.get(), osg::Array::BIND_OVERALL);
|
||||||
|
|
||||||
//
|
// allocate and assign texture coordinates
|
||||||
// populate vertex and tex coord arrays
|
auto texcoords = new osg::Vec2Array;
|
||||||
//
|
VNG.populateCenter(elevationLayer, texcoords);
|
||||||
VNG.populateCenter(elevationLayer, layerToTexCoordMap);
|
buffer._landGeometry->setTexCoordArray(0, texcoords);
|
||||||
|
buffer._waterGeometry->setTexCoordArray(0, texcoords);
|
||||||
|
|
||||||
if (terrain && terrain->getEqualizeBoundaries())
|
if (terrain && terrain->getEqualizeBoundaries())
|
||||||
{
|
{
|
||||||
@ -959,12 +879,6 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
osg::ref_ptr<TerrainTile> top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1));
|
osg::ref_ptr<TerrainTile> top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1));
|
||||||
osg::ref_ptr<TerrainTile> bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1));
|
osg::ref_ptr<TerrainTile> bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1));
|
||||||
|
|
||||||
#if 0
|
|
||||||
osg::ref_ptr<TerrainTile> top_left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y+1));
|
|
||||||
osg::ref_ptr<TerrainTile> top_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y+1));
|
|
||||||
osg::ref_ptr<TerrainTile> bottom_left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y-1));
|
|
||||||
osg::ref_ptr<TerrainTile> bottom_right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y-1));
|
|
||||||
#endif
|
|
||||||
VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0);
|
VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0);
|
||||||
VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0);
|
VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0);
|
||||||
VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0);
|
VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0);
|
||||||
@ -979,13 +893,6 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
if (top_tile.valid()) addNeighbour(top_tile.get());
|
if (top_tile.valid()) addNeighbour(top_tile.get());
|
||||||
if (bottom_tile.valid()) addNeighbour(bottom_tile.get());
|
if (bottom_tile.valid()) addNeighbour(bottom_tile.get());
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (bottom_left_tile.valid()) addNeighbour(bottom_left_tile.get());
|
|
||||||
if (bottom_right_tile.valid()) addNeighbour(bottom_right_tile.get());
|
|
||||||
if (top_left_tile.valid()) addNeighbour(top_left_tile.get());
|
|
||||||
if (top_right_tile.valid()) addNeighbour(top_right_tile.get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (left_tile.valid())
|
if (left_tile.valid())
|
||||||
{
|
{
|
||||||
if (left_tile->getTerrainTechnique()==0 || !(left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
if (left_tile->getTerrainTechnique()==0 || !(left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||||
@ -1023,48 +930,6 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
else bottom_tile->setDirtyMask(dirtyMask);
|
else bottom_tile->setDirtyMask(dirtyMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (bottom_left_tile.valid())
|
|
||||||
{
|
|
||||||
if (!(bottom_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
|
||||||
{
|
|
||||||
int dirtyMask = bottom_left_tile->getDirtyMask() | TerrainTile::BOTTOM_LEFT_CORNER_DIRTY;
|
|
||||||
if (updateNeighboursImmediately) bottom_left_tile->init(dirtyMask, true);
|
|
||||||
else bottom_left_tile->setDirtyMask(dirtyMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottom_right_tile.valid())
|
|
||||||
{
|
|
||||||
if (!(bottom_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
|
||||||
{
|
|
||||||
int dirtyMask = bottom_right_tile->getDirtyMask() | TerrainTile::BOTTOM_RIGHT_CORNER_DIRTY;
|
|
||||||
if (updateNeighboursImmediately) bottom_right_tile->init(dirtyMask, true);
|
|
||||||
else bottom_right_tile->setDirtyMask(dirtyMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (top_right_tile.valid())
|
|
||||||
{
|
|
||||||
if (!(top_right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
|
||||||
{
|
|
||||||
int dirtyMask = top_right_tile->getDirtyMask() | TerrainTile::TOP_RIGHT_CORNER_DIRTY;
|
|
||||||
if (updateNeighboursImmediately) top_right_tile->init(dirtyMask, true);
|
|
||||||
else top_right_tile->setDirtyMask(dirtyMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (top_left_tile.valid())
|
|
||||||
{
|
|
||||||
if (!(top_left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
|
||||||
{
|
|
||||||
int dirtyMask = top_left_tile->getDirtyMask() | TerrainTile::TOP_LEFT_CORNER_DIRTY;
|
|
||||||
if (updateNeighboursImmediately) top_left_tile->init(dirtyMask, true);
|
|
||||||
else top_left_tile->setDirtyMask(dirtyMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*VNG._normals));
|
osg::ref_ptr<osg::Vec3Array> skirtVectors = new osg::Vec3Array((*VNG._normals));
|
||||||
@ -1078,13 +943,18 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
// OSG_NOTICE<<"smallTile = "<<smallTile<<std::endl;
|
// OSG_NOTICE<<"smallTile = "<<smallTile<<std::endl;
|
||||||
|
|
||||||
osg::ref_ptr<osg::DrawElements> elements = smallTile ?
|
osg::ref_ptr<osg::DrawElements> landElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_TRIANGLES));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_TRIANGLES));
|
||||||
|
landElements->reserveElements((numRows-1) * (numColumns-1) * 6);
|
||||||
|
|
||||||
elements->reserveElements((numRows-1) * (numColumns-1) * 6);
|
buffer._landGeometry->addPrimitiveSet(landElements.get());
|
||||||
|
|
||||||
geometry->addPrimitiveSet(elements.get());
|
osg::ref_ptr<osg::DrawElements> waterElements = smallTile ?
|
||||||
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_TRIANGLES)) :
|
||||||
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_TRIANGLES));
|
||||||
|
waterElements->reserveElements((numRows-1) * (numColumns-1) * 6);
|
||||||
|
buffer._waterGeometry->addPrimitiveSet(waterElements.get());
|
||||||
|
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
for(j=0; j<numRows-1; ++j)
|
for(j=0; j<numRows-1; ++j)
|
||||||
@ -1103,6 +973,19 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
std::swap(i10,i11);
|
std::swap(i10,i11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if this quad or triangle should be water or not, and therefore which geometry to add it to.
|
||||||
|
bool w00 = false;
|
||||||
|
bool w01 = false;
|
||||||
|
bool w10 = false;
|
||||||
|
bool w11 = false;
|
||||||
|
|
||||||
|
if (landclassImage && matlib) {
|
||||||
|
if (i00>=0) w00 = atlas.waterAtlas[int(round(landclassImage->getColor((*texcoords)[i00]).r() * 255.0))];
|
||||||
|
if (i01>=0) w01 = atlas.waterAtlas[int(round(landclassImage->getColor((*texcoords)[i01]).r() * 255.0))];
|
||||||
|
if (i10>=0) w10 = atlas.waterAtlas[int(round(landclassImage->getColor((*texcoords)[i10]).r() * 255.0))];
|
||||||
|
if (i11>=0) w11 = atlas.waterAtlas[int(round(landclassImage->getColor((*texcoords)[i11]).r() * 255.0))];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int numValid = 0;
|
unsigned int numValid = 0;
|
||||||
if (i00>=0) ++numValid;
|
if (i00>=0) ++numValid;
|
||||||
if (i01>=0) ++numValid;
|
if (i01>=0) ++numValid;
|
||||||
@ -1111,27 +994,34 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
if (numValid==4)
|
if (numValid==4)
|
||||||
{
|
{
|
||||||
|
osg::ref_ptr<osg::DrawElements> elements;
|
||||||
|
|
||||||
// optimize which way to put the diagonal by choosing to
|
// optimize which way to put the diagonal by choosing to
|
||||||
// place it between the two corners that have the least curvature
|
// place it between the two corners that have the least curvature
|
||||||
// relative to each other.
|
// relative to each other.
|
||||||
float dot_00_11 = (*VNG._normals)[i00] * (*VNG._normals)[i11];
|
float dot_00_11 = (*VNG._normals)[i00] * (*VNG._normals)[i11];
|
||||||
float dot_01_10 = (*VNG._normals)[i01] * (*VNG._normals)[i10];
|
float dot_01_10 = (*VNG._normals)[i01] * (*VNG._normals)[i10];
|
||||||
|
|
||||||
if (dot_00_11 > dot_01_10)
|
if (dot_00_11 > dot_01_10)
|
||||||
{
|
{
|
||||||
|
elements = (w01 && w00 && w11) ? waterElements : landElements;
|
||||||
elements->addElement(i01);
|
elements->addElement(i01);
|
||||||
elements->addElement(i00);
|
elements->addElement(i00);
|
||||||
elements->addElement(i11);
|
elements->addElement(i11);
|
||||||
|
|
||||||
|
elements = (w00 && w10 && w11) ? waterElements : landElements;
|
||||||
elements->addElement(i00);
|
elements->addElement(i00);
|
||||||
elements->addElement(i10);
|
elements->addElement(i10);
|
||||||
elements->addElement(i11);
|
elements->addElement(i11);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
elements = (w01 && w00 && w10) ? waterElements : landElements;
|
||||||
elements->addElement(i01);
|
elements->addElement(i01);
|
||||||
elements->addElement(i00);
|
elements->addElement(i00);
|
||||||
elements->addElement(i10);
|
elements->addElement(i10);
|
||||||
|
|
||||||
|
elements = (w01 && w10 && w11) ? waterElements : landElements;
|
||||||
elements->addElement(i01);
|
elements->addElement(i01);
|
||||||
elements->addElement(i10);
|
elements->addElement(i10);
|
||||||
elements->addElement(i11);
|
elements->addElement(i11);
|
||||||
@ -1139,6 +1029,15 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
}
|
}
|
||||||
else if (numValid==3)
|
else if (numValid==3)
|
||||||
{
|
{
|
||||||
|
// If this is a triangle, we need to look for exactly 3 our of the four
|
||||||
|
// vertices to be in water, as the fourth will be fales, as above.
|
||||||
|
unsigned int water_count = 0;
|
||||||
|
if (w00) water_count++;
|
||||||
|
if (w01) water_count++;
|
||||||
|
if (w10) water_count++;
|
||||||
|
if (w11) water_count++;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::DrawElements> elements = (water_count == 3) ? waterElements : landElements;
|
||||||
if (i00>=0) elements->addElement(i00);
|
if (i00>=0) elements->addElement(i00);
|
||||||
if (i01>=0) elements->addElement(i01);
|
if (i01>=0) elements->addElement(i01);
|
||||||
if (i11>=0) elements->addElement(i11);
|
if (i11>=0) elements->addElement(i11);
|
||||||
@ -1170,12 +1069,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
(*vertices).push_back(new_v);
|
(*vertices).push_back(new_v);
|
||||||
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
||||||
|
|
||||||
for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
|
texcoords->push_back((*texcoords)[orig_i]);
|
||||||
itr != layerToTexCoordMap.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
itr->second.first->push_back((*itr->second.first)[orig_i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
skirtDrawElements->addElement(orig_i);
|
skirtDrawElements->addElement(orig_i);
|
||||||
skirtDrawElements->addElement(new_i);
|
skirtDrawElements->addElement(new_i);
|
||||||
@ -1184,7 +1078,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
{
|
{
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1195,7 +1089,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1212,12 +1106,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
||||||
(*vertices).push_back(new_v);
|
(*vertices).push_back(new_v);
|
||||||
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
||||||
for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
|
texcoords->push_back((*texcoords)[orig_i]);
|
||||||
itr != layerToTexCoordMap.end();
|
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
itr->second.first->push_back((*itr->second.first)[orig_i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
skirtDrawElements->addElement(orig_i);
|
skirtDrawElements->addElement(orig_i);
|
||||||
skirtDrawElements->addElement(new_i);
|
skirtDrawElements->addElement(new_i);
|
||||||
@ -1226,7 +1115,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
{
|
{
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1237,7 +1126,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1254,12 +1143,8 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
||||||
(*vertices).push_back(new_v);
|
(*vertices).push_back(new_v);
|
||||||
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
||||||
for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
|
|
||||||
itr != layerToTexCoordMap.end();
|
texcoords->push_back((*texcoords)[orig_i]);
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
itr->second.first->push_back((*itr->second.first)[orig_i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
skirtDrawElements->addElement(orig_i);
|
skirtDrawElements->addElement(orig_i);
|
||||||
skirtDrawElements->addElement(new_i);
|
skirtDrawElements->addElement(new_i);
|
||||||
@ -1268,7 +1153,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
{
|
{
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1279,7 +1164,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = smallTile ?
|
skirtDrawElements = smallTile ?
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUAD_STRIP)) :
|
||||||
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUAD_STRIP));
|
||||||
@ -1296,12 +1181,8 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
|
||||||
(*vertices).push_back(new_v);
|
(*vertices).push_back(new_v);
|
||||||
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
|
||||||
for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
|
|
||||||
itr != layerToTexCoordMap.end();
|
texcoords->push_back((*texcoords)[orig_i]);
|
||||||
++itr)
|
|
||||||
{
|
|
||||||
itr->second.first->push_back((*itr->second.first)[orig_i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
skirtDrawElements->addElement(orig_i);
|
skirtDrawElements->addElement(orig_i);
|
||||||
skirtDrawElements->addElement(new_i);
|
skirtDrawElements->addElement(new_i);
|
||||||
@ -1310,7 +1191,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
{
|
{
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
|
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1318,38 +1199,24 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
if (skirtDrawElements->getNumIndices()!=0)
|
if (skirtDrawElements->getNumIndices()!=0)
|
||||||
{
|
{
|
||||||
geometry->addPrimitiveSet(skirtDrawElements.get());
|
buffer._landGeometry->addPrimitiveSet(skirtDrawElements.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waterElements->resizeElements(waterElements->getNumIndices());
|
||||||
|
landElements->resizeElements(landElements->getNumIndices());
|
||||||
|
|
||||||
geometry->setUseDisplayList(false);
|
buffer._landGeometry->setUseDisplayList(false);
|
||||||
geometry->setUseVertexBufferObjects(true);
|
buffer._landGeometry->setUseVertexBufferObjects(true);
|
||||||
|
buffer._waterGeometry->setUseDisplayList(false);
|
||||||
#if 0
|
buffer._waterGeometry->setUseVertexBufferObjects(true);
|
||||||
{
|
|
||||||
osgUtil::VertexCacheMissVisitor vcmv_before;
|
|
||||||
osgUtil::VertexCacheMissVisitor vcmv_after;
|
|
||||||
osgUtil::VertexCacheVisitor vcv;
|
|
||||||
osgUtil::VertexAccessOrderVisitor vaov;
|
|
||||||
|
|
||||||
vcmv_before.doGeometry(*geometry);
|
|
||||||
vcv.optimizeVertices(*geometry);
|
|
||||||
vaov.optimizeOrder(*geometry);
|
|
||||||
vcmv_after.doGeometry(*geometry);
|
|
||||||
#if 0
|
|
||||||
OSG_NOTICE<<"vcmv_before.triangles="<<vcmv_before.triangles<<std::endl;
|
|
||||||
OSG_NOTICE<<"vcmv_before.misses="<<vcmv_before.misses<<std::endl;
|
|
||||||
OSG_NOTICE<<"vcmv_after.misses="<<vcmv_after.misses<<std::endl;
|
|
||||||
OSG_NOTICE<<std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Tile-specific information for the shaders
|
// Tile-specific information for the shaders
|
||||||
osg::StateSet *ss = buffer._geode->getOrCreateStateSet();
|
osg::StateSet *landStateSet = buffer._landGeode->getOrCreateStateSet();
|
||||||
|
osg::StateSet *waterStateSet = buffer._waterGeode->getOrCreateStateSet();
|
||||||
osg::ref_ptr<osg::Uniform> level = new osg::Uniform("tile_level", _terrainTile->getTileID().level);
|
osg::ref_ptr<osg::Uniform> level = new osg::Uniform("tile_level", _terrainTile->getTileID().level);
|
||||||
ss->addUniform(level);
|
landStateSet->addUniform(level);
|
||||||
|
waterStateSet->addUniform(level);
|
||||||
|
|
||||||
// Determine the x and y texture scaling. Has to be performed after we've generated all the vertices.
|
// Determine the x and y texture scaling. Has to be performed after we've generated all the vertices.
|
||||||
// Because the earth is round, each tile is not a rectangle. Apart from edge cases like the poles, the
|
// Because the earth is round, each tile is not a rectangle. Apart from edge cases like the poles, the
|
||||||
@ -1376,9 +1243,11 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tile Level " << _terrainTile->getTileID().level << " width " << tile_width << " height " << tile_height);
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tile Level " << _terrainTile->getTileID().level << " width " << tile_width << " height " << tile_height);
|
||||||
|
|
||||||
osg::ref_ptr<osg::Uniform> twu = new osg::Uniform("tile_width", tile_width);
|
osg::ref_ptr<osg::Uniform> twu = new osg::Uniform("tile_width", tile_width);
|
||||||
ss->addUniform(twu);
|
landStateSet->addUniform(twu);
|
||||||
|
waterStateSet->addUniform(twu);
|
||||||
osg::ref_ptr<osg::Uniform> thu = new osg::Uniform("tile_height", tile_height);
|
osg::ref_ptr<osg::Uniform> thu = new osg::Uniform("tile_height", tile_height);
|
||||||
ss->addUniform(thu);
|
landStateSet->addUniform(thu);
|
||||||
|
waterStateSet->addUniform(thu);
|
||||||
|
|
||||||
// Force build of KD trees?
|
// Force build of KD trees?
|
||||||
if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
|
if (osgDB::Registry::instance()->getBuildKdTreesHint()==osgDB::ReaderWriter::Options::BUILD_KDTREES &&
|
||||||
@ -1388,7 +1257,8 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
//osg::Timer_t before = osg::Timer::instance()->tick();
|
//osg::Timer_t before = osg::Timer::instance()->tick();
|
||||||
//OSG_NOTICE<<"osgTerrain::VPBTechnique::build kd tree"<<std::endl;
|
//OSG_NOTICE<<"osgTerrain::VPBTechnique::build kd tree"<<std::endl;
|
||||||
osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
|
osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
|
||||||
buffer._geode->accept(*builder);
|
buffer._landGeode->accept(*builder);
|
||||||
|
buffer._waterGeode->accept(*builder);
|
||||||
//osg::Timer_t after = osg::Timer::instance()->tick();
|
//osg::Timer_t after = osg::Timer::instance()->tick();
|
||||||
//OSG_NOTICE<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
|
//OSG_NOTICE<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
|
||||||
}
|
}
|
||||||
@ -1396,57 +1266,20 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
|
|||||||
|
|
||||||
void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
||||||
{
|
{
|
||||||
typedef std::map<osgTerrain::Layer*, SGMaterialCache::Atlas> LayerToAtlasMap;
|
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
||||||
typedef std::map<osgTerrain::Layer*, osg::ref_ptr<osg::Texture2D>> LayerToTexture2DMap;
|
if (!matlib) return;
|
||||||
typedef std::map<osgTerrain::Layer*, osg::ref_ptr<osg::Texture1D>> LayerToTexture1DMap;
|
|
||||||
LayerToAtlasMap layerToAtlasMap;
|
|
||||||
LayerToTexture2DMap layerToTextureMap;
|
|
||||||
LayerToTexture1DMap layerToContourMap;
|
|
||||||
|
|
||||||
for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum)
|
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
||||||
{
|
if (!colorLayer) return;
|
||||||
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum);
|
|
||||||
if (!colorLayer) continue;
|
|
||||||
|
|
||||||
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(colorLayer);
|
|
||||||
if (switchLayer)
|
|
||||||
{
|
|
||||||
if (switchLayer->getActiveLayer()<0 ||
|
|
||||||
static_cast<unsigned int>(switchLayer->getActiveLayer())>=switchLayer->getNumLayers())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
colorLayer = switchLayer->getLayer(switchLayer->getActiveLayer());
|
|
||||||
if (!colorLayer) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::Image* image = colorLayer->getImage();
|
osg::Image* image = colorLayer->getImage();
|
||||||
if (!image) continue;
|
if (!image) return;
|
||||||
|
|
||||||
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
|
|
||||||
osgTerrain::ContourLayer* contourLayer = dynamic_cast<osgTerrain::ContourLayer*>(colorLayer);
|
|
||||||
SGMaterialCache::Atlas atlas = layerToAtlasMap[colorLayer];
|
|
||||||
if (imageLayer)
|
|
||||||
{
|
|
||||||
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Texture2D> texture2D = layerToTextureMap[colorLayer];
|
|
||||||
SGMaterialCache::Atlas atlas = layerToAtlasMap[colorLayer];
|
|
||||||
|
|
||||||
if (!texture2D)
|
|
||||||
{
|
|
||||||
texture2D = new osg::Texture2D;
|
|
||||||
|
|
||||||
// First time generating this texture, so process to change landclass IDs to texure indexes.
|
// First time generating this texture, so process to change landclass IDs to texure indexes.
|
||||||
SGPropertyNode_ptr effectProp;
|
SGPropertyNode_ptr landEffectProp;
|
||||||
SGMaterialLibPtr matlib = _options->getMaterialLib();
|
|
||||||
osg::Vec3d world;
|
osg::Vec3d world;
|
||||||
SGGeod loc;
|
SGGeod loc;
|
||||||
|
|
||||||
if (matlib)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Generating texture atlas for " << image->getName());
|
|
||||||
// Determine the center of the tile, sadly non-trivial.
|
// Determine the center of the tile, sadly non-trivial.
|
||||||
osg::Vec3d tileloc = computeCenter(buffer, masterLocator);
|
osg::Vec3d tileloc = computeCenter(buffer, masterLocator);
|
||||||
masterLocator->convertLocalToModel(tileloc, world);
|
masterLocator->convertLocalToModel(tileloc, world);
|
||||||
@ -1454,9 +1287,7 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
loc = SGGeod::fromCart(world2);
|
loc = SGGeod::fromCart(world2);
|
||||||
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
|
||||||
|
|
||||||
if (_matcache ==0) _matcache = _options->getMaterialLib()->generateMatCache(loc, _options);
|
SGMaterialCache::Atlas atlas = matlib->generateMatCache(loc, _options)->getAtlas();
|
||||||
|
|
||||||
atlas = _matcache->getAtlas();
|
|
||||||
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
SGMaterialCache::AtlasIndex atlasIndex = atlas.index;
|
||||||
|
|
||||||
// Set the "g" color channel to an index into the atlas index.
|
// Set the "g" color channel to an index into the atlas index.
|
||||||
@ -1469,8 +1300,7 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
|
||||||
|
|
||||||
texture2D->setImage(image);
|
texture2D->setImage(image);
|
||||||
texture2D->setMaxAnisotropy(16.0f);
|
texture2D->setMaxAnisotropy(16.0f);
|
||||||
texture2D->setResizeNonPowerOfTwoHint(false);
|
texture2D->setResizeNonPowerOfTwoHint(false);
|
||||||
@ -1491,35 +1321,12 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator)
|
|||||||
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
layerToTextureMap[colorLayer] = texture2D;
|
osg::StateSet* stateset = buffer._landGeode->getOrCreateStateSet();
|
||||||
layerToAtlasMap[colorLayer] = atlas;
|
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(5*layerNum, texture2D, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(3, atlas.diffuse, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(5*layerNum + 1, atlas.image, osg::StateAttribute::ON);
|
stateset->setTextureAttributeAndModes(4, atlas.specular, osg::StateAttribute::ON);
|
||||||
stateset->setTextureAttributeAndModes(5*layerNum + 2, atlas.dimensions, osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureAttributeAndModes(5*layerNum + 3, atlas.diffuse, osg::StateAttribute::ON);
|
|
||||||
stateset->setTextureAttributeAndModes(5*layerNum + 4, atlas.specular, osg::StateAttribute::ON);
|
|
||||||
}
|
|
||||||
else if (contourLayer)
|
|
||||||
{
|
|
||||||
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
|
|
||||||
|
|
||||||
osg::ref_ptr< osg::Texture1D> texture1D = layerToContourMap[colorLayer];
|
|
||||||
if (!texture1D)
|
|
||||||
{
|
|
||||||
texture1D = new osg::Texture1D;
|
|
||||||
texture1D->setImage(image);
|
|
||||||
texture1D->setResizeNonPowerOfTwoHint(false);
|
|
||||||
texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
|
|
||||||
texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
|
|
||||||
|
|
||||||
layerToContourMap[colorLayer] = texture1D;
|
|
||||||
}
|
|
||||||
|
|
||||||
stateset->setTextureAttributeAndModes(layerNum, texture1D, osg::StateAttribute::ON);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double VPBTechnique::det2(const osg::Vec2d a, const osg::Vec2d b)
|
double VPBTechnique::det2(const osg::Vec2d a, const osg::Vec2d b)
|
||||||
@ -1624,13 +1431,13 @@ void VPBTechnique::applyTrees(BufferData& buffer, Locator* masterLocator)
|
|||||||
loc.getLongitudeRad(), osg::Vec3d(0.0, 0.0, 1.0),
|
loc.getLongitudeRad(), osg::Vec3d(0.0, 0.0, 1.0),
|
||||||
0.0, osg::Vec3d(1.0, 0.0, 0.0));
|
0.0, osg::Vec3d(1.0, 0.0, 0.0));
|
||||||
|
|
||||||
const osg::Array* vertices = buffer._geometry->getVertexArray();
|
const osg::Array* vertices = buffer._landGeometry->getVertexArray();
|
||||||
const osg::Array* texture_coords = buffer._geometry->getTexCoordArray(0);
|
const osg::Array* texture_coords = buffer._landGeometry->getTexCoordArray(0);
|
||||||
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
|
||||||
osg::Image* image = colorLayer->getImage();
|
osg::Image* image = colorLayer->getImage();
|
||||||
|
|
||||||
// Just want the first primitive set, not the others which will be the "skirts" below.
|
// Just want the first primitive set, not the others which will be the "skirts" below.
|
||||||
const osg::PrimitiveSet* primSet = buffer._geometry->getPrimitiveSet(0);
|
const osg::PrimitiveSet* primSet = buffer._landGeometry->getPrimitiveSet(0);
|
||||||
const osg::DrawElements* drawElements = primSet->getDrawElements();
|
const osg::DrawElements* drawElements = primSet->getDrawElements();
|
||||||
const unsigned int triangle_count = drawElements->getNumPrimitives();
|
const unsigned int triangle_count = drawElements->getNumPrimitives();
|
||||||
|
|
||||||
@ -1859,7 +1666,7 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato
|
|||||||
|
|
||||||
for (; road_iter != road._nodes.end(); road_iter++) {
|
for (; road_iter != road._nodes.end(); road_iter++) {
|
||||||
mb = getMeshIntersection(buffer, masterLocator, *road_iter - modelCenter, up);
|
mb = getMeshIntersection(buffer, masterLocator, *road_iter - modelCenter, up);
|
||||||
auto esl = VPBElevationSlice::computeVPBElevationSlice(buffer._geometry, ma, mb, up);
|
auto esl = VPBElevationSlice::computeVPBElevationSlice(buffer._landGeometry, ma, mb, up);
|
||||||
|
|
||||||
for(auto eslitr = esl.begin(); eslitr != esl.end(); ++eslitr) {
|
for(auto eslitr = esl.begin(); eslitr != esl.end(); ++eslitr) {
|
||||||
roadPoints.push_back(*eslitr);
|
roadPoints.push_back(*eslitr);
|
||||||
@ -1940,7 +1747,7 @@ osg::Vec3d VPBTechnique::getMeshIntersection(BufferData& buffer, Locator* master
|
|||||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector;
|
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector;
|
||||||
intersector = new osgUtil::LineSegmentIntersector(pt - up*100.0, pt + up*8000.0);
|
intersector = new osgUtil::LineSegmentIntersector(pt - up*100.0, pt + up*8000.0);
|
||||||
osgUtil::IntersectionVisitor visitor(intersector.get());
|
osgUtil::IntersectionVisitor visitor(intersector.get());
|
||||||
buffer._geometry->accept(visitor);
|
buffer._landGeometry->accept(visitor);
|
||||||
|
|
||||||
if (intersector->containsIntersections()) {
|
if (intersector->containsIntersections()) {
|
||||||
// We have an intersection with the terrain model, so return it
|
// We have an intersection with the terrain model, so return it
|
||||||
|
@ -108,8 +108,10 @@ class VPBTechnique : public TerrainTechnique
|
|||||||
BufferData() {}
|
BufferData() {}
|
||||||
|
|
||||||
osg::ref_ptr<osg::MatrixTransform> _transform;
|
osg::ref_ptr<osg::MatrixTransform> _transform;
|
||||||
osg::ref_ptr<EffectGeode> _geode;
|
osg::ref_ptr<EffectGeode> _landGeode;
|
||||||
osg::ref_ptr<osg::Geometry> _geometry;
|
osg::ref_ptr<EffectGeode> _waterGeode;
|
||||||
|
osg::ref_ptr<osg::Geometry> _landGeometry;
|
||||||
|
osg::ref_ptr<osg::Geometry> _waterGeometry;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~BufferData() {}
|
~BufferData() {}
|
||||||
@ -150,8 +152,6 @@ class VPBTechnique : public TerrainTechnique
|
|||||||
osg::Matrix3 _filterMatrix;
|
osg::Matrix3 _filterMatrix;
|
||||||
osg::ref_ptr<osg::Uniform> _filterMatrixUniform;
|
osg::ref_ptr<osg::Uniform> _filterMatrixUniform;
|
||||||
osg::ref_ptr<SGReaderWriterOptions> _options;
|
osg::ref_ptr<SGReaderWriterOptions> _options;
|
||||||
osg::ref_ptr<osg::Image> _atlas;
|
|
||||||
osg::ref_ptr<SGMaterialCache> _matcache;
|
|
||||||
|
|
||||||
inline static osg::ref_ptr<osg::Group> _constraintGroup = new osg::Group();;
|
inline static osg::ref_ptr<osg::Group> _constraintGroup = new osg::Group();;
|
||||||
inline static std::mutex _constraint_mutex; // protects the _constraintGroup;
|
inline static std::mutex _constraint_mutex; // protects the _constraintGroup;
|
||||||
|
Loading…
Reference in New Issue
Block a user