Added ValidDataOperator base class and NoDataValue and ValidRange subclasses, and
support for it in osgTerrain::Layer and GeometryTechniqnue.
This commit is contained in:
parent
e72ec7bb15
commit
acb2ed177c
@ -81,6 +81,7 @@ int main(int argc, char** argv)
|
||||
|
||||
osg::ref_ptr<osgTerrain::TerrainNode> terrain = new osgTerrain::TerrainNode;
|
||||
osg::ref_ptr<osgTerrain::Locator> locator = new osgTerrain::EllipsoidLocator(-osg::PI, -osg::PI*0.5, 2.0*osg::PI, osg::PI, 0.0);
|
||||
osg::ref_ptr<osgTerrain::ValidDataOperator> validDataOperator = new osgTerrain::NoDataValue(0.0);
|
||||
|
||||
unsigned int layerNum = 0;
|
||||
|
||||
@ -136,6 +137,7 @@ int main(int argc, char** argv)
|
||||
hfl->setHeightField(hf.get());
|
||||
|
||||
hfl->setLocator(locator.get());
|
||||
hfl->setValidDataOperator(validDataOperator.get());
|
||||
|
||||
if (offset!=0.0f || scale!=1.0f)
|
||||
{
|
||||
@ -167,6 +169,7 @@ int main(int argc, char** argv)
|
||||
osg::ref_ptr<osgTerrain::ImageLayer> imageLayer = new osgTerrain::ImageLayer;
|
||||
imageLayer->setImage(image.get());
|
||||
imageLayer->setLocator(locator.get());
|
||||
imageLayer->setValidDataOperator(validDataOperator.get());
|
||||
|
||||
if (offset!=0.0f || scale!=1.0f)
|
||||
{
|
||||
@ -198,6 +201,7 @@ int main(int argc, char** argv)
|
||||
osg::ref_ptr<osgTerrain::ImageLayer> imageLayer = new osgTerrain::ImageLayer;
|
||||
imageLayer->setImage(image.get());
|
||||
imageLayer->setLocator(locator.get());
|
||||
imageLayer->setValidDataOperator(validDataOperator.get());
|
||||
|
||||
if (offset!=0.0f || scale!=1.0f)
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <osg/Array>
|
||||
|
||||
#include <osgTerrain/Locator>
|
||||
#include <osgTerrain/ValidDataOperator>
|
||||
|
||||
namespace osgTerrain {
|
||||
|
||||
@ -38,6 +39,11 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
|
||||
Locator* getLocator() { return _locator.get(); }
|
||||
const Locator* getLocator() const { return _locator.get(); }
|
||||
|
||||
void setValidDataOperator(ValidDataOperator* validDataOp) { _validDataOperator = validDataOp; }
|
||||
ValidDataOperator* getValidDataOperator() { return _validDataOperator.get(); }
|
||||
const ValidDataOperator* getValidDataOperator() const { return _validDataOperator.get(); }
|
||||
|
||||
|
||||
virtual unsigned int getNumColumns() const { return 0; }
|
||||
virtual unsigned int getNumRows() const { return 0; }
|
||||
|
||||
@ -46,11 +52,37 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
|
||||
|
||||
virtual bool transform(float offset, float scale) { return false; }
|
||||
|
||||
|
||||
virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, float& /*value*/) const { return false; }
|
||||
virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec2& /*value*/) const { return false; }
|
||||
virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec3& /*value*/) const { return false; }
|
||||
virtual bool getValue(unsigned int /*i*/, unsigned int /*j*/, osg::Vec4& /*value*/) const { return false; }
|
||||
|
||||
inline bool getValidValue(unsigned int i, unsigned int j, float& value) const
|
||||
{
|
||||
if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec2& value) const
|
||||
{
|
||||
if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec3& value) const
|
||||
{
|
||||
if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool getValidValue(unsigned int i, unsigned int j, osg::Vec4& value) const
|
||||
{
|
||||
if (getValue(i,j,value)) return _validDataOperator.valid() ? (*_validDataOperator)(value) : true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline void computeIndices(double ndc_x, double ndc_y, unsigned int& i, unsigned int& j, double& ir, double& jr)
|
||||
{
|
||||
ndc_x *= double(getNumColumns()-1);
|
||||
@ -115,8 +147,9 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
|
||||
|
||||
virtual ~Layer();
|
||||
|
||||
osg::ref_ptr<Locator> _locator;
|
||||
osg::Vec4 _defaultValue;
|
||||
osg::ref_ptr<Locator> _locator;
|
||||
osg::ref_ptr<ValidDataOperator> _validDataOperator;
|
||||
osg::Vec4 _defaultValue;
|
||||
|
||||
};
|
||||
|
||||
|
70
include/osgTerrain/ValidDataOperator
Normal file
70
include/osgTerrain/ValidDataOperator
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OSGTERRAIN_VALIDDATAOPERATOR
|
||||
#define OSGTERRAIN_VALIDDATAOPERATOR 1
|
||||
|
||||
#include <osgTerrain/Export>
|
||||
|
||||
namespace osgTerrain {
|
||||
|
||||
struct ValidDataOperator : public osg::Referenced
|
||||
{
|
||||
virtual bool operator() (float value) const { return true; }
|
||||
virtual bool operator() (const osg::Vec2& value) const { return operator()(value.x()) && operator()(value.y()) ; }
|
||||
virtual bool operator() (const osg::Vec3& value) const { return operator()(value.x()) && operator()(value.y()) && operator()(value.z()); }
|
||||
virtual bool operator() (const osg::Vec4& value) const { return operator()(value.x()) && operator()(value.y()) && operator()(value.z()) && operator()(value.w()); }
|
||||
};
|
||||
|
||||
struct ValidRange : public ValidDataOperator
|
||||
{
|
||||
ValidRange(float minValue, float maxValue):
|
||||
_minValue(minValue),
|
||||
_maxValue(maxValue) {}
|
||||
|
||||
void setRange(float minValue, float maxValue)
|
||||
{
|
||||
_minValue = minValue;
|
||||
_maxValue = maxValue;
|
||||
}
|
||||
|
||||
void setMinValue(float minValue) { _minValue = minValue; }
|
||||
float getMinValue() const { return _minValue; }
|
||||
|
||||
void setMaxValue(float maxValue) { _maxValue = maxValue; }
|
||||
float getMaxValue() const { return _maxValue; }
|
||||
|
||||
virtual bool operator() (float value) const { return value>=_minValue && value<=_maxValue; }
|
||||
|
||||
float _minValue, _maxValue;
|
||||
};
|
||||
|
||||
|
||||
struct NoDataValue : public ValidDataOperator
|
||||
{
|
||||
NoDataValue(float value):
|
||||
_value(value) {}
|
||||
|
||||
void setNoDataValue(float value) { _value = value; }
|
||||
float getValue() const { return _value; }
|
||||
|
||||
virtual bool operator() (float value) const { return value!=_value; }
|
||||
|
||||
float _value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -13,6 +13,7 @@ SET(LIB_PUBLIC_HEADERS
|
||||
${HEADER_PATH}/TerrainNode
|
||||
${HEADER_PATH}/TerrainTechnique
|
||||
${HEADER_PATH}/GeometryTechnique
|
||||
${HEADER_PATH}/ValidDataOperator
|
||||
${HEADER_PATH}/Version
|
||||
)
|
||||
|
||||
|
@ -142,12 +142,12 @@ void GeometryTechnique::init()
|
||||
unsigned int numVertices = numRows * numColumns;
|
||||
|
||||
// allocate and assign vertices
|
||||
osg::Vec3Array* _vertices = new osg::Vec3Array(numVertices);
|
||||
osg::Vec3Array* _vertices = new osg::Vec3Array;
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->setVertices(_vertices);
|
||||
if (_geometry.valid()) _geometry->setVertexArray(_vertices);
|
||||
|
||||
// allocate and assign normals
|
||||
osg::Vec3Array* _normals = new osg::Vec3Array(numVertices);
|
||||
osg::Vec3Array* _normals = new osg::Vec3Array;
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->setNormals(_normals);
|
||||
if (_geometry.valid())
|
||||
{
|
||||
@ -169,14 +169,14 @@ void GeometryTechnique::init()
|
||||
color_index = texcoord_index;
|
||||
++texcoord_index;
|
||||
|
||||
_texcoords = new osg::Vec2Array(numVertices);
|
||||
_texcoords = new osg::Vec2Array;
|
||||
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->setTexCoords(color_index, _texcoords);
|
||||
|
||||
if (_geometry.valid()) _geometry->setTexCoordArray(color_index, _texcoords);
|
||||
}
|
||||
|
||||
osg::FloatArray* _elevations = new osg::FloatArray(numVertices);
|
||||
osg::FloatArray* _elevations = new osg::FloatArray;
|
||||
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
|
||||
if (tf)
|
||||
{
|
||||
@ -194,6 +194,10 @@ void GeometryTechnique::init()
|
||||
}
|
||||
}
|
||||
|
||||
if (_vertices) _vertices->reserve(numVertices);
|
||||
if (_texcoords) _texcoords->reserve(numVertices);
|
||||
if (_elevations) _elevations->reserve(numVertices);
|
||||
if (_normals) _normals->reserve(numVertices);
|
||||
|
||||
// allocate and assign color
|
||||
osg::Vec4Array* _colors = new osg::Vec4Array(1);
|
||||
@ -205,6 +209,10 @@ void GeometryTechnique::init()
|
||||
_geometry->setColorArray(_colors);
|
||||
_geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
}
|
||||
|
||||
|
||||
typedef std::vector<int> Indices;
|
||||
Indices indices(numColumns*numRows, -1);
|
||||
|
||||
// populate vertex and tex coord arrays
|
||||
unsigned int j;
|
||||
@ -214,47 +222,59 @@ void GeometryTechnique::init()
|
||||
{
|
||||
unsigned int iv = j*numColumns + i;
|
||||
osg::Vec3d ndc( ((double)i)/(double)(numColumns-1), ((double)j)/(double)(numRows-1), 0.0);
|
||||
|
||||
bool validValue = true;
|
||||
|
||||
|
||||
if (elevationLayer)
|
||||
{
|
||||
float value = 0.0f;
|
||||
elevationLayer->getValue(i,j, value);
|
||||
validValue = elevationLayer->getValidValue(i,j, value);
|
||||
// osg::notify(osg::NOTICE)<<"i="<<i<<" j="<<j<<" z="<<value<<std::endl;
|
||||
ndc.z() = value;
|
||||
}
|
||||
|
||||
osg::Vec3d model;
|
||||
masterLocator->convertLocalToModel(ndc, model);
|
||||
|
||||
(*_vertices)[iv] = model - centerModel;
|
||||
|
||||
if (colorLayer)
|
||||
if (validValue)
|
||||
{
|
||||
if (colorLocator!= masterLocator)
|
||||
indices[iv] = _vertices->size();
|
||||
|
||||
osg::Vec3d model;
|
||||
masterLocator->convertLocalToModel(ndc, model);
|
||||
|
||||
(*_vertices).push_back(model - centerModel);
|
||||
|
||||
if (colorLayer)
|
||||
{
|
||||
osg::Vec3d color_ndc;
|
||||
Locator::convertLocalCoordBetween(*masterLocator, ndc, *colorLocator, color_ndc);
|
||||
(*_texcoords)[iv].set(color_ndc.x(), color_ndc.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
(*_texcoords)[iv].set(ndc.x(), ndc.y());
|
||||
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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (_elevations)
|
||||
{
|
||||
(*_elevations).push_back((ndc.z()-minHeight)*scaleHeight);
|
||||
}
|
||||
|
||||
if (_elevations)
|
||||
// compute the local normal
|
||||
osg::Vec3d ndc_one( (double)i/(double)(numColumns-1), (double)j/(double)(numColumns-1), 1.0);
|
||||
osg::Vec3d model_one;
|
||||
masterLocator->convertLocalToModel(ndc_one, model_one);
|
||||
model_one = model_one - model;
|
||||
model_one.normalize();
|
||||
(*_normals).push_back(model_one);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*_elevations)[iv] = (ndc.z()-minHeight)*scaleHeight;
|
||||
indices[iv] = -1;
|
||||
}
|
||||
|
||||
// compute the local normal
|
||||
osg::Vec3d ndc_one( (double)i/(double)(numColumns-1), (double)j/(double)(numColumns-1), 1.0);
|
||||
osg::Vec3d model_one;
|
||||
masterLocator->convertLocalToModel(ndc_one, model_one);
|
||||
model_one = model_one - model;
|
||||
model_one.normalize();
|
||||
(*_normals)[iv] = model_one;
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,67 +283,51 @@ void GeometryTechnique::init()
|
||||
bool optimizeOrientations = _elevations!=0;
|
||||
bool swapOrientation = !(masterLocator->orientationOpenGL());
|
||||
|
||||
if (!optimizeOrientations)
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
elements->reserve((numRows-1) * (numColumns-1) * 6);
|
||||
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->addPrimitiveSet(elements);
|
||||
if (_geometry.valid()) _geometry->addPrimitiveSet(elements);
|
||||
|
||||
for(j=0; j<numRows-1; ++j)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"Old tesselation"<<std::endl;
|
||||
for(j=0; j<numRows-1; ++j)
|
||||
for(unsigned int i=0; i<numColumns-1; ++i)
|
||||
{
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLE_STRIP, numColumns*2);
|
||||
for(unsigned int i=0; i<numColumns; ++i)
|
||||
int i00;
|
||||
int i01;
|
||||
if (swapOrientation)
|
||||
{
|
||||
unsigned int iv = j*numColumns + i;
|
||||
if (swapOrientation)
|
||||
{
|
||||
(*elements)[i*2] = iv + numColumns;
|
||||
(*elements)[i*2+1] = iv;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*elements)[i*2+1] = iv + numColumns;
|
||||
(*elements)[i*2] = iv;
|
||||
}
|
||||
i01 = j*numColumns + i;
|
||||
i00 = i01+numColumns;
|
||||
}
|
||||
else
|
||||
{
|
||||
i00 = j*numColumns + i;
|
||||
i01 = i00+numColumns;
|
||||
}
|
||||
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->addPrimitiveSet(elements);
|
||||
int i10 = i00+1;
|
||||
int i11 = i01+1;
|
||||
|
||||
if (_geometry.valid()) _geometry->addPrimitiveSet(elements);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"New tesselation"<<std::endl;
|
||||
|
||||
osg::DrawElementsUInt* elements = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
elements->reserve((numRows-1) * (numColumns-1) * 6);
|
||||
|
||||
if (_terrainGeometry.valid()) _terrainGeometry->addPrimitiveSet(elements);
|
||||
if (_geometry.valid()) _geometry->addPrimitiveSet(elements);
|
||||
|
||||
for(j=0; j<numRows-1; ++j)
|
||||
{
|
||||
for(unsigned int i=0; i<numColumns-1; ++i)
|
||||
// remap indices to final vertex positions
|
||||
i00 = indices[i00];
|
||||
i01 = indices[i01];
|
||||
i10 = indices[i10];
|
||||
i11 = indices[i11];
|
||||
|
||||
unsigned int numValid = 0;
|
||||
if (i00>=0) ++numValid;
|
||||
if (i01>=0) ++numValid;
|
||||
if (i10>=0) ++numValid;
|
||||
if (i11>=0) ++numValid;
|
||||
|
||||
if (numValid==4)
|
||||
{
|
||||
unsigned int i00;
|
||||
unsigned int i01;
|
||||
if (swapOrientation)
|
||||
{
|
||||
i01 = j*numColumns + i;
|
||||
i00 = i01+numColumns;
|
||||
}
|
||||
else
|
||||
{
|
||||
i00 = j*numColumns + i;
|
||||
i01 = i00+numColumns;
|
||||
}
|
||||
|
||||
unsigned int i10 = i00+1;
|
||||
unsigned int i11 = i01+1;
|
||||
|
||||
float e00 = (*_elevations)[i00];
|
||||
float e10 = (*_elevations)[i10];
|
||||
float e01 = (*_elevations)[i01];
|
||||
float e11 = (*_elevations)[i11];
|
||||
|
||||
|
||||
if (fabsf(e00-e11)<fabsf(e01-e10))
|
||||
{
|
||||
elements->push_back(i01);
|
||||
@ -345,9 +349,18 @@ void GeometryTechnique::init()
|
||||
elements->push_back(i11);
|
||||
}
|
||||
}
|
||||
else if (numValid==3)
|
||||
{
|
||||
if (i00>=0) elements->push_back(i00);
|
||||
if (i01>=0) elements->push_back(i01);
|
||||
if (i11>=0) elements->push_back(i11);
|
||||
if (i10>=0) elements->push_back(i10);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool containsTransparency = false;
|
||||
|
||||
if (colorLayer)
|
||||
|
@ -187,7 +187,7 @@ bool ImageLayer::getValue(unsigned int i, unsigned int j, float& value) const
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImageLayer::getValue(unsigned int i, unsigned int j, osg::Vec2& value) const
|
||||
|
Loading…
Reference in New Issue
Block a user