Refactored osgTerrain so that the interface for setting up layer is more straight forward, and added support into GeometryTechnique for handling multiple layers

This commit is contained in:
Robert Osfield
2008-02-22 11:52:23 +00:00
parent 6516bf4910
commit 67f1503c7d
22 changed files with 819 additions and 456 deletions

View File

@@ -646,6 +646,8 @@ int main(int argc, char** argv)
std::string filterName;
osgTerrain::Layer::Filter filter = osgTerrain::Layer::LINEAR;
bool readParameter = false;
float minValue, maxValue;
float scale = 1.0f;
@@ -703,6 +705,7 @@ int main(int argc, char** argv)
hfl->setLocator(locator.get());
hfl->setValidDataOperator(validDataOperator.get());
hfl->setFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -737,6 +740,7 @@ int main(int argc, char** argv)
imageLayer->setImage(image.get());
imageLayer->setLocator(locator.get());
imageLayer->setValidDataOperator(validDataOperator.get());
imageLayer->setFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -771,6 +775,7 @@ int main(int argc, char** argv)
imageLayer->setImage(image.get());
imageLayer->setLocator(locator.get());
imageLayer->setValidDataOperator(validDataOperator.get());
imageLayer->setFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -800,17 +805,22 @@ int main(int argc, char** argv)
if (filterName=="NEAREST")
{
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<std::endl;
terrain->setColorFilter(layerNum, osgTerrain::Terrain::NEAREST);
filter = osgTerrain::Layer::NEAREST;
}
else if (filterName=="LINEAR")
{
filter = osgTerrain::Layer::LINEAR;
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<std::endl;
terrain->setColorFilter(layerNum, osgTerrain::Terrain::LINEAR);
}
else
{
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<" unrecognized filter name, please use LINEAER or NEAREST."<<std::endl;
}
if (terrain->getColorLayer(layerNum))
{
terrain->getColorLayer(layerNum)->setFilter(filter);
}
}
@@ -832,7 +842,7 @@ int main(int argc, char** argv)
osg::notify(osg::NOTICE)<<"--tf "<<minValue<<" "<<maxValue<<std::endl;
terrain->setColorTransferFunction(layerNum, tf.get());
terrain->setColorLayer(layerNum, new osgTerrain::ContourLayer(tf.get()));
}
else
{

View File

@@ -31,13 +31,6 @@ class OSG_EXPORT TransferFunction : public osg::Referenced
TransferFunction();
/** Set the texture unit to assign layer to if required.
* Negative values signifies that no texture unit has been assigned. */
void setTextureUnit(int textureUnit) { _textureUnit = textureUnit; }
/** Get the texture unit to assign layer to if required.*/
int getTextureUnit() const { return _textureUnit; }
osg::Image* getImage() { return _image.get(); }
const osg::Image* getImage() const { return _image.get(); }
@@ -53,7 +46,6 @@ class OSG_EXPORT TransferFunction : public osg::Referenced
typedef std::vector<osg::Vec4> Colors;
int _textureUnit;
Colors _colors;
osg::ref_ptr<osg::Image> _image;
osg::ref_ptr<osg::Texture> _texture;

View File

@@ -44,8 +44,6 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
virtual void applyColorLayers();
virtual void applyTransferFunctions();
virtual void applyTransparency();
virtual void smoothGeometry();

View File

@@ -17,6 +17,7 @@
#include <osg/Image>
#include <osg/Shape>
#include <osg/Array>
#include <osg/TransferFunction>
#include <osgTerrain/Locator>
#include <osgTerrain/ValidDataOperator>
@@ -42,13 +43,6 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
/** Get the file name of the layer. */
virtual const std::string& getFileName() const { return _filename; }
/** Set the texture unit to assign layer to if required.
* Negative values signifies that no texture unit has been assigned. */
void setTextureUnit(int textureUnit) { _textureUnit = textureUnit; }
/** Get the texture unit to assign layer to if required.*/
int getTextureUnit() const { return _textureUnit; }
void setLocator(Locator* locator) { _locator = locator; }
Locator* getLocator() { return _locator.get(); }
@@ -71,6 +65,26 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
void setDefaultValue(const osg::Vec4& value) { _defaultValue = value; }
const osg::Vec4& getDefaultValue() const { return _defaultValue; }
enum Filter
{
NEAREST,
LINEAR
};
/** Set the texture filter to use when do texture associated with this layer.*/
void setFilter(Filter filter) { _filter = filter; }
/** Get the texture filter to use when do texture associated with this layer.*/
Filter getFilter() const { return _filter; }
/** Return image associated with layer if supported. */
virtual osg::Image* getImage() { return 0; }
/** Return const image associated with layer if supported. */
virtual const osg::Image* getImage() const { return 0; }
virtual bool transform(float offset, float scale) { return false; }
@@ -178,12 +192,12 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
virtual ~Layer();
std::string _filename;
int _textureUnit;
osg::ref_ptr<Locator> _locator;
unsigned int _minLevel;
unsigned int _maxLevel;
osg::ref_ptr<ValidDataOperator> _validDataOperator;
osg::Vec4 _defaultValue;
Filter _filter;
};
@@ -191,7 +205,7 @@ class OSGTERRAIN_EXPORT ImageLayer : public Layer
{
public:
ImageLayer();
ImageLayer(osg::Image* image=0);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
ImageLayer(const ImageLayer& imageLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
@@ -204,8 +218,12 @@ class OSGTERRAIN_EXPORT ImageLayer : public Layer
virtual bool transform(float offset, float scale);
void setImage(osg::Image* image);
osg::Image* getImage() { return _image.get(); }
const osg::Image* getImage() const { return _image.get(); }
/** Return image associated with layer. */
virtual osg::Image* getImage() { return _image.get(); }
/** Return const image associated with layer. */
virtual const osg::Image* getImage() const { return _image.get(); }
virtual unsigned int getNumColumns() const { return _image.valid() ? _image->s() : 0; }
virtual unsigned int getNumRows() const { return _image.valid() ? _image->t() : 0; }
@@ -227,11 +245,55 @@ class OSGTERRAIN_EXPORT ImageLayer : public Layer
};
class OSGTERRAIN_EXPORT ContourLayer : public Layer
{
public:
ContourLayer(osg::TransferFunction1D* tf=0);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
ContourLayer(const ContourLayer& tfLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
META_Object(osgTerrain, ContourLayer);
virtual bool transform(float offset, float scale);
void setTransferFunction(osg::TransferFunction1D* tf);
osg::TransferFunction1D* getTransferFunction() { return _tf.get(); }
const osg::TransferFunction1D* getTransferFunction() const { return _tf.get(); }
/** Return image associated with layer. */
virtual osg::Image* getImage() { return _tf.valid() ? _tf->getImage() : 0; }
/** Return const image associated with layer. */
virtual const osg::Image* getImage() const { return _tf.valid() ? _tf->getImage() : 0; }
virtual unsigned int getNumColumns() const { return _tf.valid() ? _tf->getNumberCellsX() : 0; }
virtual unsigned int getNumRows() const { return _tf.valid() ? 1 : 0; }
virtual bool getValue(unsigned int i, unsigned int j, float& value) const;
virtual bool getValue(unsigned int i, unsigned int j, osg::Vec2& value) const;
virtual bool getValue(unsigned int i, unsigned int j, osg::Vec3& value) const;
virtual bool getValue(unsigned int i, unsigned int j, osg::Vec4& value) const;
virtual void dirty();
virtual void setModifiedCount(unsigned int value);
virtual unsigned int getModifiedCount() const;
protected:
virtual ~ContourLayer() {}
osg::ref_ptr<osg::TransferFunction1D> _tf;
};
class OSGTERRAIN_EXPORT HeightFieldLayer : public Layer
{
public:
HeightFieldLayer();
HeightFieldLayer(osg::HeightField* hf=0);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
HeightFieldLayer(const HeightFieldLayer& hfLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);

View File

@@ -16,7 +16,6 @@
#include <osg/Group>
#include <osg/CoordinateSystemNode>
#include <osg/TransferFunction>
#include <osgTerrain/TerrainTechnique>
#include <osgTerrain/Layer>
@@ -76,32 +75,10 @@ class OSGTERRAIN_EXPORT Terrain : public osg::Group
void setColorLayer(unsigned int i, osgTerrain::Layer* layer);
/** Get color layer with specified layer number.*/
Layer* getColorLayer(unsigned int i) { return i<_colorLayers.size() ? _colorLayers[i].layer.get() : 0; }
Layer* getColorLayer(unsigned int i) { return i<_colorLayers.size() ? _colorLayers[i].get() : 0; }
/** Set const color layer with specified layer number.*/
const Layer* getColorLayer(unsigned int i) const { return i<_colorLayers.size() ? _colorLayers[i].layer.get() : 0; }
/** Set a color transfer function with specified layer number.*/
void setColorTransferFunction(unsigned int i, osg::TransferFunction* tf);
/** Get color transfer function with specified layer number.*/
osg::TransferFunction* getColorTransferFunction(unsigned int i) { return i<_colorLayers.size() ? _colorLayers[i].transferFunction.get() : 0; }
/** Get const color transfer function with specified layer number.*/
const osg::TransferFunction* getColorTransferFunction(unsigned int i) const { return i<_colorLayers.size() ? _colorLayers[i].transferFunction.get() : 0; }
enum Filter
{
NEAREST,
LINEAR
};
/** Set a color filter with specified layer number.*/
void setColorFilter(unsigned int i, Filter filter);
/** Set const color filter with specified layer number.*/
Filter getColorFilter(unsigned int i) const { return i<_colorLayers.size() ? _colorLayers[i].filter : LINEAR; }
const Layer* getColorLayer(unsigned int i) const { return i<_colorLayers.size() ? _colorLayers[i].get() : 0; }
/** Get the number of colour layers.*/
unsigned int getNumColorLayers() const { return _colorLayers.size(); }
@@ -137,30 +114,7 @@ class OSGTERRAIN_EXPORT Terrain : public osg::Group
virtual ~Terrain();
struct LayerData
{
LayerData():
filter(LINEAR) {}
LayerData(const LayerData& rhs):
filter(rhs.filter),
layer(rhs.layer),
transferFunction(rhs.transferFunction) {}
LayerData& operator = (const LayerData& rhs)
{
filter = rhs.filter;
layer = rhs.layer;
transferFunction = rhs.transferFunction;
return *this;
}
Filter filter;
osg::ref_ptr<Layer> layer;
osg::ref_ptr<osg::TransferFunction> transferFunction;
};
typedef std::vector<LayerData> Layers;
typedef std::vector< osg::ref_ptr<Layer> > Layers;
osg::ref_ptr<TerrainTechnique> _terrainTechnique;
osg::ref_ptr<Locator> _locator;

View File

@@ -19,8 +19,7 @@ using namespace osg;
//
// TransferFunction base class
//
TransferFunction::TransferFunction():
_textureUnit(-1)
TransferFunction::TransferFunction()
{
}

View File

@@ -90,6 +90,10 @@
#include "Text.h"
#include "Terrain.h"
#include "Locator.h"
#include "ImageLayer.h"
#include "HeightFieldLayer.h"
#include "CompositeLayer.h"
#include <osg/Endian>
#include <osg/Notify>
@@ -1470,4 +1474,93 @@ osg::Node* DataInputStream::readNode()
return node;
}
osgTerrain::Layer* DataInputStream::readLayer()
{
// Read node unique ID.
int id = readInt();
if (id<0) return 0;
// See if layer is already in the list.
LayerMap::iterator itr= _layerMap.find(id);
if (itr!=_layerMap.end()) return itr->second.get();
// Layer is not in list.
// Create a new Layer,
osgTerrain::Layer* layer = 0;
int layerid = peekInt();
if (layerid==IVEHEIGHTFIELDLAYER)
{
layer = new osgTerrain::HeightFieldLayer;
((ive::HeightFieldLayer*)(layer))->read(this);
}
else if (layerid==IVEIMAGELAYER)
{
layer = new osgTerrain::ImageLayer;
((ive::ImageLayer*)(layer))->read(this);
}
else if (layerid==IVECOMPOSITELAYER)
{
layer = new osgTerrain::CompositeLayer;
((ive::CompositeLayer*)(layer))->read(this);
}
else if (layerid==IVEPROXYLAYER)
{
std::string filename = readString();
osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(filename+".gdal");
osgTerrain::ProxyLayer* proxyLayer = dynamic_cast<osgTerrain::ProxyLayer*>(object.get());
osg::ref_ptr<osgTerrain::Locator> locator = readLocator();
unsigned int minLevel = readUInt();
unsigned int maxLevel = readUInt();
if (proxyLayer)
{
if (locator.valid()) proxyLayer->setLocator(locator.get());
proxyLayer->setMinLevel(minLevel);
proxyLayer->setMaxLevel(maxLevel);
}
layer = proxyLayer;
}
else{
throw Exception("Unknown layer identification in DataInputStream::readLayer()");
}
// and add it to the node map,
_layerMap[id] = layer;
if (_verboseOutput) std::cout<<"read/writeLayer() ["<<id<<"]"<<std::endl;
return layer;
}
osgTerrain::Locator* DataInputStream::readLocator()
{
// Read statesets unique ID.
int id = readInt();
if (id<0) return 0;
// See if stateset is already in the list.
LocatorMap::iterator itr= _locatorMap.find(id);
if (itr!=_locatorMap.end()) return itr->second.get();
// Locator is not in list.
// Create a new locator,
osgTerrain::Locator* locator = new osgTerrain::Locator();
// read its properties from stream
((ive::Locator*)(locator))->read(this);
// and add it to the locator map,
_locatorMap[id] = locator;
if (_verboseOutput) std::cout<<"read/writeLocator() ["<<id<<"]"<<std::endl;
return locator;
}

View File

@@ -21,6 +21,8 @@
#include <osg/Uniform>
#include <osg/ref_ptr>
#include <osgTerrain/Terrain>
#include <osgDB/ReaderWriter>
#include "IveVersion.h"
@@ -37,8 +39,8 @@ public:
DataInputStream(std::istream* istream);
~DataInputStream();
void setOptions(const osgDB::ReaderWriter::Options* options);
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
void setOptions(const osgDB::ReaderWriter::Options* options);
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
inline unsigned int getVersion() const { return _version; }
bool readBool();
@@ -96,6 +98,8 @@ public:
osg::Drawable* readDrawable();
osg::Shape* readShape();
osg::Node* readNode();
osgTerrain::Layer* readLayer();
osgTerrain::Locator* readLocator();
// Set and get if must be generated external reference ive files
void setLoadExternalReferenceFiles(bool b) {_loadExternalReferenceFiles=b;};
@@ -109,12 +113,15 @@ public:
typedef std::map<int,osg::ref_ptr<osg::Drawable> > DrawableMap;
typedef std::map<int,osg::ref_ptr<osg::Shape> > ShapeMap;
typedef std::map<int,osg::ref_ptr<osg::Node> > NodeMap;
typedef std::map<int,osg::ref_ptr<osgTerrain::Layer> > LayerMap;
typedef std::map<int,osg::ref_ptr<osgTerrain::Locator> > LocatorMap;
bool _verboseOutput;
std::istream* _istream;
int _byteswap;
private:
int _version;
bool _peeking;
int _peekValue;
@@ -126,6 +133,8 @@ private:
DrawableMap _drawableMap;
ShapeMap _shapeMap;
NodeMap _nodeMap;
LayerMap _layerMap;
LocatorMap _locatorMap;
bool _loadExternalReferenceFiles;

View File

@@ -91,6 +91,10 @@
#include "Text.h"
#include "Terrain.h"
#include "Locator.h"
#include "ImageLayer.h"
#include "HeightFieldLayer.h"
#include "CompositeLayer.h"
#include <osg/Notify>
#include <osg/io_utils>
@@ -1184,3 +1188,99 @@ void DataOutputStream::writeImage(IncludeImageMode mode, osg::Image *image)
break;
}
}
void DataOutputStream::writeLayer(const osgTerrain::Layer* layer)
{
if (layer==0)
{
writeInt(-1);
return;
}
LayerMap::iterator itr = _layerMap.find(layer);
if (itr!=_layerMap.end())
{
// Id already exists so just write ID.
writeInt(itr->second);
if (_verboseOutput) std::cout<<"read/writeLayer() ["<<itr->second<<"]"<<std::endl;
}
else
{
// id doesn't exist so create a new ID and
// register the stateset.
int id = _layerMap.size();
_layerMap[layer] = id;
// write the id.
writeInt(id);
if (dynamic_cast<const osgTerrain::HeightFieldLayer*>(layer))
{
((ive::HeightFieldLayer*)(layer))->write(this);
}
else if (dynamic_cast<const osgTerrain::ImageLayer*>(layer))
{
((ive::ImageLayer*)(layer))->write(this);
}
else if (dynamic_cast<const osgTerrain::CompositeLayer*>(layer))
{
((ive::CompositeLayer*)(layer))->write(this);
}
else if (dynamic_cast<const osgTerrain::ProxyLayer*>(layer))
{
writeInt(IVEPROXYLAYER);
writeString(layer->getFileName());
const osgTerrain::Locator* locator = layer->getLocator();
bool writeOutLocator = locator && !locator->getDefinedInFile();
writeLocator(writeOutLocator ? locator : 0 );
writeUInt(layer->getMinLevel());
writeUInt(layer->getMaxLevel());
}
else
{
throw Exception("Unknown layer in DataOutputStream::writeLayer()");
}
if (_verboseOutput) std::cout<<"read/writeLayer() ["<<id<<"]"<<std::endl;
}
}
void DataOutputStream::writeLocator(const osgTerrain::Locator* locator)
{
if (locator==0)
{
writeInt(-1);
return;
}
LocatorMap::iterator itr = _locatorMap.find(locator);
if (itr!=_locatorMap.end())
{
// Id already exists so just write ID.
writeInt(itr->second);
if (_verboseOutput) std::cout<<"read/writeLocator() ["<<itr->second<<"]"<<std::endl;
}
else
{
// id doesn't exist so create a new ID and
// register the locator.
int id = _locatorMap.size();
_locatorMap[locator] = id;
// write the id.
writeInt(id);
// write the locator.
((ive::Locator*)(locator))->write(this);
if (_verboseOutput) std::cout<<"read/writeLocator() ["<<id<<"]"<<std::endl;
}
}

View File

@@ -16,6 +16,8 @@
#include <osg/Uniform>
#include <osgDB/ReaderWriter>
#include <osgTerrain/Terrain>
#include "IveVersion.h"
#include "DataTypeSize.h"
#include "Exception.h"
@@ -93,6 +95,10 @@ public:
void writeNode(const osg::Node* sa);
void writeImage(IncludeImageMode mode, osg::Image *image);
void writeLayer(const osgTerrain::Layer* layer);
void writeLocator(const osgTerrain::Locator* locator);
void setWriteDirectory(const std::string& directoryName) { _writeDirectory = directoryName; }
const std::string& getWriteDirectory() const { return _writeDirectory; }
@@ -115,16 +121,19 @@ public:
bool _verboseOutput;
private:
std::ostream* _ostream;
// Container to map stateset uniques to their respective stateset.
typedef std::map<const osg::StateSet*,int> StateSetMap;
typedef std::map<const osg::StateAttribute*,int> StateAttributeMap;
typedef std::map<const osg::Uniform*,int> UniformMap;
typedef std::map<const osg::Shader*,int> ShaderMap;
typedef std::map<const osg::Drawable*,int> DrawableMap;
typedef std::map<const osg::Shape*,int> ShapeMap;
typedef std::map<const osg::Node*,int> NodeMap;
typedef std::map<const osg::StateSet*,int> StateSetMap;
typedef std::map<const osg::StateAttribute*,int> StateAttributeMap;
typedef std::map<const osg::Uniform*,int> UniformMap;
typedef std::map<const osg::Shader*,int> ShaderMap;
typedef std::map<const osg::Drawable*,int> DrawableMap;
typedef std::map<const osg::Shape*,int> ShapeMap;
typedef std::map<const osg::Node*,int> NodeMap;
typedef std::map<const osgTerrain::Layer*,int> LayerMap;
typedef std::map<const osgTerrain::Locator*,int> LocatorMap;
StateSetMap _stateSetMap;
StateAttributeMap _stateAttributeMap;
@@ -133,6 +142,8 @@ private:
DrawableMap _drawableMap;
ShapeMap _shapeMap;
NodeMap _nodeMap;
LayerMap _layerMap;
LocatorMap _locatorMap;
std::string _writeDirectory;
bool _includeExternalReferences;

View File

@@ -36,14 +36,18 @@ void Layer::write(DataOutputStream* out)
else
throw Exception("Layer::write(): Could not cast this osgLayer::Layer to an osg::Object.");
LayerHelper helper;
helper.writeLocator(out, getLocator());
if (out->getVersion() >= VERSION_0023)
{
out->writeInt(getTextureUnit());
out->writeLocator(getLocator());
out->writeUInt(getFilter());
}
else
{
LayerHelper helper;
helper.writeLocator(out, getLocator());
}
out->writeUInt(getMinLevel());
out->writeUInt(getMaxLevel());
}
@@ -65,14 +69,17 @@ void Layer::read(DataInputStream* in)
else
throw Exception("Layer::read(): Could not cast this osgLayer::Layer to an osg::Group.");
LayerHelper helper;
setLocator(helper.readLocator(in));
if (in->getVersion() >= VERSION_0023)
{
setTextureUnit(in->readInt());
setLocator(in->readLocator());
setFilter(osgTerrain::Layer::Filter(in->readUInt()));
}
else
{
LayerHelper helper;
setLocator(helper.readLocator(in));
}
setMinLevel(in->readUInt());
setMaxLevel(in->readUInt());

View File

@@ -31,19 +31,33 @@ void Terrain::write(DataOutputStream* out)
else
throw Exception("Terrain::write(): Could not cast this osgTerrain::Terrain to an osg::Group.");
LayerHelper helper;
helper.writeLocator(out, getLocator());
helper.writeLayer(out, getElevationLayer());
out->writeUInt(getNumColorLayers());
for(unsigned int i=0; i<getNumColorLayers(); ++i)
if (out->getVersion() >= VERSION_0023)
{
helper.writeLayer(out, getColorLayer(i));
out->writeLocator(getLocator());
out->writeLayer(getElevationLayer());
out->writeUInt(getNumColorLayers());
for(unsigned int i=0; i<getNumColorLayers(); ++i)
{
out->writeLayer(getColorLayer(i));
}
}
else
{
LayerHelper helper;
helper.writeLocator(out, getLocator());
helper.writeLayer(out, getElevationLayer());
out->writeUInt(getNumColorLayers());
for(unsigned int i=0; i<getNumColorLayers(); ++i)
{
helper.writeLayer(out, getColorLayer(i));
}
}
writeTerrainTechnique(out, getTerrainTechnique());
}
@@ -63,18 +77,31 @@ void Terrain::read(DataInputStream* in)
else
throw Exception("Terrain::read(): Could not cast this osgTerrain::Terrain to an osg::Group.");
LayerHelper helper;
setLocator(helper.readLocator(in));
setElevationLayer(helper.readLayer(in));
unsigned int numColorLayers = in->readUInt();
for(unsigned int i=0; i<numColorLayers; ++i)
if (in->getVersion() >= VERSION_0023)
{
setColorLayer(i, helper.readLayer(in));
setLocator(in->readLocator());
setElevationLayer(in->readLayer());
unsigned int numColorLayers = in->readUInt();
for(unsigned int i=0; i<numColorLayers; ++i)
{
setColorLayer(i, in->readLayer());
}
}
else
{
LayerHelper helper;
setLocator(helper.readLocator(in));
setElevationLayer(helper.readLayer(in));
unsigned int numColorLayers = in->readUInt();
for(unsigned int i=0; i<numColorLayers; ++i)
{
setColorLayer(i, helper.readLayer(in));
}
}
setTerrainTechnique(readTerrainTechnique(in));
}

View File

@@ -35,13 +35,27 @@ bool Layer_readLocalData(osg::Object& obj, osgDB::Input &fr)
osgTerrain::Locator* locator = dynamic_cast<osgTerrain::Locator*>(readObject.get());
if (locator) layer.setLocator(locator);
int textureUnit=-1;
if (fr.read("TextureUnit",textureUnit))
if (fr[0].matchWord("Filter"))
{
unsigned int layerNum = 0;
if (fr.matchSequence("Filter %i"))
{
fr[1].getUInt(layerNum);
fr += 2;
}
else
{
++fr;
}
if (fr[0].matchWord("NEAREST")) layer.setFilter(osgTerrain::Layer::NEAREST);
else if (fr[0].matchWord("LINEAR")) layer.setFilter(osgTerrain::Layer::LINEAR);
++fr;
itrAdvanced = true;
layer.setTextureUnit(textureUnit);
}
unsigned int minLevel=0;
if (fr.read("MinLevel",minLevel))
{
@@ -67,11 +81,18 @@ bool Layer_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
{
fw.writeObject(*layer.getLocator());
}
if (layer.getTextureUnit()>=0)
if (layer.getFilter()!=osgTerrain::Layer::LINEAR)
{
fw.indent()<<"TextureUnit "<<layer.getTextureUnit()<<std::endl;
}
if (layer.getFilter()==osgTerrain::Layer::LINEAR)
{
fw.indent()<<"Filter LINEAER"<<std::endl;
}
else
{
fw.indent()<<"Filter NEAREST"<<std::endl;
}
}
if (layer.getMinLevel()!=0)
{

View File

@@ -258,40 +258,6 @@ bool Terrain_readLocalData(osg::Object& obj, osgDB::Input &fr)
itrAdvanced = true;
}
if ((firstMatched = fr.matchSequence("ColorTransferFunction %i {")) || fr.matchSequence("ColorTransferFunction {") )
{
unsigned int layerNum = 0;
if (firstMatched)
{
fr[1].getUInt(layerNum);
++fr;
}
osg::TransferFunction* tf = readTransferFunction(fr);
if (tf) terrain.setColorTransferFunction(layerNum, tf);
itrAdvanced = true;
}
if (fr[0].matchWord("ColorFilter"))
{
unsigned int layerNum = 0;
if (fr.matchSequence("ColorFilter %i"))
{
fr[1].getUInt(layerNum);
fr += 2;
}
else
{
++fr;
}
if (fr[0].matchWord("NEAREST")) terrain.setColorFilter(layerNum, osgTerrain::Terrain::NEAREST);
else if (fr[0].matchWord("LINEAR")) terrain.setColorFilter(layerNum, osgTerrain::Terrain::LINEAR);
++fr;
itrAdvanced = true;
}
readObject = fr.readObjectOfType(osgDB::type_wrapper<osgTerrain::TerrainTechnique>());
if (readObject.valid())

View File

@@ -27,6 +27,8 @@
using namespace osgTerrain;
#define NEW_COORD_CODE
GeometryTechnique::GeometryTechnique():
_currentReadOnlyBuffer(1),
_currentWriteBuffer(0)
@@ -98,7 +100,7 @@ void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
void GeometryTechnique::init()
{
osg::notify(osg::INFO)<<"Doing init()"<<std::endl;
// osg::notify(osg::NOTICE)<<"Doing GeometryTechnique::init()"<<std::endl;
if (!_terrain) return;
@@ -111,9 +113,6 @@ void GeometryTechnique::init()
generateGeometry(masterLocator, centerModel);
applyColorLayers();
applyTransferFunctions();
applyTransparency();
// smoothGeometry();
@@ -151,9 +150,6 @@ osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator)
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
@@ -213,22 +209,16 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
if (!colorLocator) colorLocator = masterLocator;
buffer._geode = new osg::Geode;
if(buffer._transform.valid())
buffer._transform->addChild(buffer._geode.get());
buffer._geometry = new osg::Geometry;
if (buffer._geometry.valid()) buffer._geode->addDrawable(buffer._geometry.get());
buffer._geode->addDrawable(buffer._geometry.get());
osg::Geometry* geometry = buffer._geometry.get();
unsigned int numRows = 20;
unsigned int numColumns = 20;
@@ -256,66 +246,55 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
// allocate and assign vertices
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
if (buffer._geometry.valid()) buffer._geometry->setVertexArray(vertices.get());
vertices->reserve(numVertices);
geometry->setVertexArray(vertices.get());
// allocate and assign normals
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
if (buffer._geometry.valid())
{
buffer._geometry->setNormalArray(normals.get());
buffer._geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
if (normals.valid()) normals->reserve(numVertices);
geometry->setNormalArray(normals.get());
geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
int texcoord_index = 0;
int color_index = -1;
int tf_index = -1;
float minHeight = 0.0;
float scaleHeight = 1.0;
// allocate and assign tex coords
osg::ref_ptr<osg::Vec2Array> texcoords;
if (colorLayer)
typedef std::pair< osg::ref_ptr<osg::Vec2Array>, Locator* > TexCoordLocatorPair;
typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap;
LayerToTexCoordMap layerToTexCoordMap;
for(unsigned int layerNum=0; layerNum<_terrain->getNumColorLayers(); ++layerNum)
{
color_index = texcoord_index;
++texcoord_index;
texcoords = new osg::Vec2Array;
if (buffer._geometry.valid()) buffer._geometry->setTexCoordArray(color_index, texcoords.get());
}
osg::ref_ptr<osg::FloatArray> elevations = new osg::FloatArray;
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
if (tf)
{
tf_index = texcoord_index;
++texcoord_index;
if (!colorLayer)
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(layerNum);
if (colorLayer)
{
// elevations = new osg::FloatArray(numVertices);
if (buffer._geometry.valid()) buffer._geometry->setTexCoordArray(tf_index, elevations.get());
minHeight = tf->getMinimum();
scaleHeight = 1.0f/(tf->getMaximum()-tf->getMinimum());
LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer);
if (itr!=layerToTexCoordMap.end())
{
geometry->setTexCoordArray(layerNum, itr->second.first.get());
}
else
{
TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer];
tclp.first = new osg::Vec2Array;
tclp.first->reserve(numVertices);
tclp.second = colorLayer->getLocator() ? colorLayer->getLocator() : masterLocator;
geometry->setTexCoordArray(layerNum, tclp.first.get());
}
}
}
if (vertices.valid()) vertices->reserve(numVertices);
if (texcoords.valid()) texcoords->reserve(numVertices);
osg::ref_ptr<osg::FloatArray> elevations = new osg::FloatArray;
if (elevations.valid()) elevations->reserve(numVertices);
if (normals.valid()) normals->reserve(numVertices);
// allocate and assign color
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f,1.0f,1.0f,1.0f);
if (buffer._geometry.valid())
{
buffer._geometry->setColorArray(colors.get());
buffer._geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
}
geometry->setColorArray(colors.get());
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
typedef std::vector<int> Indices;
@@ -350,9 +329,13 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
(*vertices).push_back(model - centerModel);
if (colorLayer)
for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
itr != layerToTexCoordMap.end();
++itr)
{
if (colorLocator!= masterLocator)
osg::Vec2Array* texcoords = itr->second.first.get();
Locator* colorLocator = itr->second.second;
if (colorLocator != masterLocator)
{
osg::Vec3d color_ndc;
Locator::convertLocalCoordBetween(*masterLocator, ndc, *colorLocator, color_ndc);
@@ -362,7 +345,6 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
(*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y()));
}
}
if (elevations.valid())
@@ -392,7 +374,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
osg::ref_ptr<osg::DrawElementsUInt> elements = new osg::DrawElementsUInt(GL_TRIANGLES);
elements->reserve((numRows-1) * (numColumns-1) * 6);
if (buffer._geometry.valid()) buffer._geometry->addPrimitiveSet(elements.get());
geometry->addPrimitiveSet(elements.get());
for(j=0; j<numRows-1; ++j)
{
@@ -471,7 +453,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
smoothGeometry();
normals = dynamic_cast<osg::Vec3Array*>(buffer._geometry->getNormalArray());
normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
if (!normals) createSkirt = false;
}
@@ -492,7 +474,13 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
if (texcoords.valid()) (*texcoords).push_back((*texcoords)[orig_i]);
for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
itr != layerToTexCoordMap.end();
++itr)
{
itr->second.first->push_back((*itr->second.first)[orig_i]);
}
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
@@ -501,7 +489,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -510,7 +498,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -525,7 +513,12 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
if (texcoords.valid()) (*texcoords).push_back((*texcoords)[orig_i]);
for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
itr != layerToTexCoordMap.end();
++itr)
{
itr->second.first->push_back((*itr->second.first)[orig_i]);
}
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
@@ -534,7 +527,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -543,7 +536,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -558,7 +551,12 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
if (texcoords.valid()) (*texcoords).push_back((*texcoords)[orig_i]);
for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
itr != layerToTexCoordMap.end();
++itr)
{
itr->second.first->push_back((*itr->second.first)[orig_i]);
}
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
@@ -567,7 +565,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -576,7 +574,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -591,7 +589,12 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight;
(*vertices).push_back(new_v);
if (normals.valid()) (*normals).push_back((*normals)[orig_i]);
if (texcoords.valid()) (*texcoords).push_back((*texcoords)[orig_i]);
for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin();
itr != layerToTexCoordMap.end();
++itr)
{
itr->second.first->push_back((*itr->second.first)[orig_i]);
}
skirtDrawElements->push_back(orig_i);
skirtDrawElements->push_back(new_i);
@@ -600,7 +603,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
@@ -609,136 +612,79 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
if (!skirtDrawElements->empty())
{
buffer._geometry->addPrimitiveSet(skirtDrawElements.get());
geometry->addPrimitiveSet(skirtDrawElements.get());
skirtDrawElements = new osg::DrawElementsUShort(GL_QUAD_STRIP);
}
}
// if (buffer._geometry.valid()) _terrainGeometry->setUseDisplayList(false);
if (buffer._geometry.valid()) buffer._geometry->setUseVertexBufferObjects(true);
// _terrainGeometry->setUseDisplayList(false);
geometry->setUseVertexBufferObjects(true);
}
void GeometryTechnique::applyColorLayers()
{
BufferData& buffer = getWriteBuffer();
typedef std::map<osgTerrain::Layer*, osg::Texture*> LayerToTextureMap;
LayerToTextureMap layerToTextureMap;
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
osgTerrain::Terrain::Filter filter = _terrain->getColorFilter(0);
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
int color_index = -1;
if (colorLayer)
for(unsigned int layerNum=0; layerNum<_terrain->getNumColorLayers(); ++layerNum)
{
color_index++;
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(layerNum);
if (!colorLayer) continue;
osg::Image* image = colorLayer->getImage();
if (!image) continue;
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
osgTerrain::ContourLayer* contourLayer = dynamic_cast<osgTerrain::ContourLayer*>(colorLayer);
if (imageLayer)
{
osg::Image* image = imageLayer->getImage();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::Texture2D* texture2D = new osg::Texture2D;
texture2D->setImage(image);
texture2D->setResizeNonPowerOfTwoHint(false);
stateset->setTextureAttributeAndModes(color_index, texture2D, osg::StateAttribute::ON);
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
texture2D->setFilter(osg::Texture::MAG_FILTER, filter==Terrain::LINEAR ? osg::Texture::LINEAR : 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);
if (tf)
osg::Texture2D* texture2D = dynamic_cast<osg::Texture2D*>(layerToTextureMap[colorLayer]);
if (!texture2D)
{
// up the precision of the internal texture format to its maximum.
//image->setInternalTextureFormat(GL_LUMINANCE32F_ARB);
image->setInternalTextureFormat(GL_LUMINANCE16);
}
}
}
}
texture2D = new osg::Texture2D;
texture2D->setImage(image);
texture2D->setResizeNonPowerOfTwoHint(false);
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
texture2D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getFilter()==Layer::LINEAR ? osg::Texture::LINEAR : 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);
void GeometryTechnique::applyTransferFunctions()
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
int color_index = -1;
int tf_index = -1;
if (colorLayer) {
color_index++;
tf_index++;
}
if (tf)
{
osg::notify(osg::INFO)<<"Requires TransferFunction"<<std::endl;
tf_index++;
osg::Image* image = tf->getImage();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::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, osg::Texture::NEAREST);
stateset->setTextureAttributeAndModes(tf_index, texture1D, osg::StateAttribute::ON);
layerToTextureMap[colorLayer] = texture2D;
if (colorLayer)
{
osg::notify(osg::INFO)<<"Using fragment program"<<std::endl;
osg::Program* program = new osg::Program;
stateset->setAttribute(program);
// osg::notify(osg::NOTICE)<<"Creating new ImageLayer texture "<<layerNum<<std::endl;
// get shaders from source
std::string vertexShaderFile = osgDB::findDataFile("shaders/lookup.vert");
if (!vertexShaderFile.empty())
{
program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexShaderFile));
}
else
{
osg::notify(osg::INFO)<<"Not found lookup.vert"<<std::endl;
// osg::notify(osg::NOTICE)<<"Reusing ImageLayer texture "<<layerNum<<std::endl;
}
std::string fragmentShaderFile = osgDB::findDataFile("shaders/lookup.frag");
if (!fragmentShaderFile.empty())
{
program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile));
}
else
{
osg::notify(osg::INFO)<<"Not found lookup.frag"<<std::endl;
}
osg::Uniform* sourceSampler = new osg::Uniform("sourceTexture",color_index);
stateset->addUniform(sourceSampler);
osg::Uniform* lookupTexture = new osg::Uniform("lookupTexture",tf_index);
stateset->addUniform(lookupTexture);
stateset->addUniform(_filterWidthUniform.get());
stateset->addUniform(_filterMatrixUniform.get());
stateset->addUniform(_filterBiasUniform.get());
osg::Uniform* lightingEnabled = new osg::Uniform("lightingEnabled",true);
stateset->addUniform(lightingEnabled);
osg::Uniform* minValue = new osg::Uniform("minValue", tf->getMinimum());
stateset->addUniform(minValue);
osg::Uniform* inverseRange = new osg::Uniform("inverseRange", 1.0f/(tf->getMaximum()-tf->getMinimum()));
stateset->addUniform(inverseRange);
stateset->setTextureAttributeAndModes(layerNum, texture2D, osg::StateAttribute::ON);
}
else
else if (contourLayer)
{
osg::notify(osg::INFO)<<"Using standard OpenGL fixed function pipeline"<<std::endl;
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::Texture1D* texture1D = dynamic_cast<osg::Texture1D*>(layerToTextureMap[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->getFilter()==Layer::LINEAR ? osg::Texture::LINEAR : osg::Texture::NEAREST);
layerToTextureMap[colorLayer] = texture1D;
}
stateset->setTextureAttributeAndModes(layerNum, texture1D, osg::StateAttribute::ON);
}
}
}
@@ -747,25 +693,15 @@ void GeometryTechnique::applyTransparency()
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
// if the elevationLayer and colorLayer are the same, and there is colorTF then
// simply assign as a texture coordinate.
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
bool containsTransparency = false;
if (colorLayer)
for(unsigned int i=0; i<_terrain->getNumColorLayers(); ++i)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
if (imageLayer)
osg::Image* image = _terrain->getColorLayer(i)->getImage();
if (image)
{
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
if (tf) containsTransparency = tf->getImage()->isImageTranslucent();
else containsTransparency = imageLayer->getImage() ? imageLayer->getImage()->isImageTranslucent() : false;
}
containsTransparency = image->isImageTranslucent();
break;
}
}
if (containsTransparency)
@@ -816,7 +752,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
// if app traversal update the frame count.
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
{
if (_dirty) init();
if (_dirty) _terrain->init();
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
if (uv)
@@ -840,7 +776,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
if (_dirty)
{
osg::notify(osg::INFO)<<"******* Doing init ***********"<<std::endl;
init();
_terrain->init();
}
BufferData& buffer = getReadOnlyBuffer();

View File

@@ -17,18 +17,18 @@
using namespace osgTerrain;
Layer::Layer():
_textureUnit(-1),
_minLevel(0),
_maxLevel(MAXIMUM_NUMBER_OF_LEVELS)
_maxLevel(MAXIMUM_NUMBER_OF_LEVELS),
_filter(LINEAR)
{
}
Layer::Layer(const Layer& layer,const osg::CopyOp& copyop):
osg::Object(layer,copyop),
_filename(layer._filename),
_textureUnit(layer._textureUnit),
_minLevel(layer._minLevel),
_maxLevel(layer._maxLevel)
_maxLevel(layer._maxLevel),
_filter(layer._filter)
{
}
@@ -94,7 +94,8 @@ osg::BoundingSphere Layer::computeBound(bool treatAsElevationLayer) const
//
// ImageLayer
//
ImageLayer::ImageLayer()
ImageLayer::ImageLayer(osg::Image* image):
_image(image)
{
}
@@ -261,12 +262,114 @@ unsigned int ImageLayer::getModifiedCount() const
}
/////////////////////////////////////////////////////////////////////////////
//
// ContourLayer
//
ContourLayer::ContourLayer(osg::TransferFunction1D* tf):
_tf(tf)
{
_filter = NEAREST;
}
ContourLayer::ContourLayer(const ContourLayer& contourLayer,const osg::CopyOp& copyop):
Layer(contourLayer, copyop),
_tf(contourLayer._tf)
{
}
void ContourLayer::setTransferFunction(osg::TransferFunction1D* tf)
{
_tf = tf;
}
bool ContourLayer::transform(float offset, float scale)
{
if (!_tf) return false;
osg::notify(osg::NOTICE)<<"ContourLayer::transform("<<offset<<","<<scale<<")"<<std::endl;;
for(unsigned int i=0; i<_tf->getNumberCellsX(); ++i)
{
osg::Vec4 value = _tf->getValue(i);
value.r() = offset + value.r()* scale;
value.g() = offset + value.g()* scale;
value.b() = offset + value.b()* scale;
value.a() = offset + value.a()* scale;
_tf->setValue(i, value);
}
dirty();
return true;
}
bool ContourLayer::getValue(unsigned int i, unsigned int j, float& value) const
{
if (!_tf) return false;
const osg::Vec4& v = _tf->getValue(i);
value = v[0];
return true;
}
bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec2& value) const
{
if (!_tf) return false;
const osg::Vec4& v = _tf->getValue(i);
value.x() = v.x();
value.y() = v.y();
return true;
}
bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec3& value) const
{
if (!_tf) return false;
const osg::Vec4& v = _tf->getValue(i);
value.x() = v.x();
value.y() = v.y();
value.z() = v.z();
return true;
}
bool ContourLayer::getValue(unsigned int i, unsigned int j, osg::Vec4& value) const
{
if (!_tf) return false;
value = _tf->getValue(i);
return true;
}
void ContourLayer::dirty()
{
if (getImage()) getImage()->dirty();
}
void ContourLayer::setModifiedCount(unsigned int value)
{
if (getImage()) getImage()->setModifiedCount(value);
}
unsigned int ContourLayer::getModifiedCount() const
{
if (!getImage()) return 0;
else return getImage()->getModifiedCount();
}
/////////////////////////////////////////////////////////////////////////////
//
// HeightFieldLayer
//
HeightFieldLayer::HeightFieldLayer():
_modifiedCount(0)
HeightFieldLayer::HeightFieldLayer(osg::HeightField* hf):
_modifiedCount(0),
_heightField(hf)
{
}

View File

@@ -93,21 +93,7 @@ void Terrain::setColorLayer(unsigned int i, osgTerrain::Layer* layer)
{
if (_colorLayers.size() <= i) _colorLayers.resize(i+1);
_colorLayers[i].layer = layer;
}
void Terrain::setColorTransferFunction(unsigned int i, osg::TransferFunction* tf)
{
if (_colorLayers.size() <= i) _colorLayers.resize(i+1);
_colorLayers[i].transferFunction = tf;
}
void Terrain::setColorFilter(unsigned int i, Filter filter)
{
if (_colorLayers.size() <= i) _colorLayers.resize(i+1);
_colorLayers[i].filter = filter;
_colorLayers[i] = layer;
}
osg::BoundingSphere Terrain::computeBound() const
@@ -124,7 +110,7 @@ osg::BoundingSphere Terrain::computeBound() const
itr != _colorLayers.end();
++itr)
{
if (itr->layer.valid()) bs.expandBy(itr->layer->computeBound(false));
if (itr->valid()) bs.expandBy((*itr)->computeBound(false));
}
}

View File

@@ -71,7 +71,7 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
// if app traversal update the frame count.
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
{
if (_dirty) init();
if (_dirty) _terrain->init();
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
if (uv)
@@ -91,7 +91,7 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
}
}
if (_dirty) init();
if (_dirty) _terrain->init();
// otherwise fallback to the Group::traverse()
_terrain->osg::Group::traverse(nv);

View File

@@ -30,16 +30,6 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction)
I_Constructor0(____TransferFunction,
"",
"");
I_Method1(void, setTextureUnit, IN, int, textureUnit,
Properties::NON_VIRTUAL,
__void__setTextureUnit__int,
"Set the texture unit to assign layer to if required. ",
"Negative values signifies that no texture unit has been assigned. ");
I_Method0(int, getTextureUnit,
Properties::NON_VIRTUAL,
__int__getTextureUnit,
"Get the texture unit to assign layer to if required. ",
"");
I_Method0(osg::Image *, getImage,
Properties::NON_VIRTUAL,
__osg_Image_P1__getImage,
@@ -79,9 +69,6 @@ BEGIN_OBJECT_REFLECTOR(osg::TransferFunction)
I_SimpleProperty(osg::Texture *, Texture,
__osg_Texture_P1__getTexture,
0);
I_SimpleProperty(int, TextureUnit,
__int__getTextureUnit,
__void__setTextureUnit__int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osg::TransferFunction1D)

View File

@@ -95,11 +95,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::GeometryTechnique)
__void__applyColorLayers,
"",
"");
I_Method0(void, applyTransferFunctions,
Properties::VIRTUAL,
__void__applyTransferFunctions,
"",
"");
I_Method0(void, applyTransparency,
Properties::VIRTUAL,
__void__applyTransparency,

View File

@@ -15,6 +15,7 @@
#include <osg/Image>
#include <osg/Object>
#include <osg/Shape>
#include <osg/TransferFunction>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
@@ -128,12 +129,137 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::CompositeLayer)
__void__removeLayer__unsigned_int);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::ContourLayer)
I_DeclaringFile("osgTerrain/Layer");
I_BaseType(osgTerrain::Layer);
I_ConstructorWithDefaults1(IN, osg::TransferFunction1D *, tf, 0,
Properties::NON_EXPLICIT,
____ContourLayer__osg_TransferFunction1D_P1,
"",
"");
I_ConstructorWithDefaults2(IN, const osgTerrain::ContourLayer &, tfLayer, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____ContourLayer__C5_ContourLayer_R1__C5_osg_CopyOp_R1,
"Copy constructor using CopyOp to manage deep vs shallow copy. ",
"");
I_Method0(osg::Object *, cloneType,
Properties::VIRTUAL,
__osg_Object_P1__cloneType,
"Clone the type of an object, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop,
Properties::VIRTUAL,
__osg_Object_P1__clone__C5_osg_CopyOp_R1,
"Clone an object, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj,
Properties::VIRTUAL,
__bool__isSameKindAs__C5_osg_Object_P1,
"",
"");
I_Method0(const char *, libraryName,
Properties::VIRTUAL,
__C5_char_P1__libraryName,
"return the name of the object's library. ",
"Must be defined by derived classes. The OpenSceneGraph convention is that the namespace of a library is the same as the library name. ");
I_Method0(const char *, className,
Properties::VIRTUAL,
__C5_char_P1__className,
"return the name of the object's class type. ",
"Must be defined by derived classes. ");
I_Method2(bool, transform, IN, float, offset, IN, float, scale,
Properties::VIRTUAL,
__bool__transform__float__float,
"",
"");
I_Method1(void, setTransferFunction, IN, osg::TransferFunction1D *, tf,
Properties::NON_VIRTUAL,
__void__setTransferFunction__osg_TransferFunction1D_P1,
"",
"");
I_Method0(osg::TransferFunction1D *, getTransferFunction,
Properties::NON_VIRTUAL,
__osg_TransferFunction1D_P1__getTransferFunction,
"",
"");
I_Method0(const osg::TransferFunction1D *, getTransferFunction,
Properties::NON_VIRTUAL,
__C5_osg_TransferFunction1D_P1__getTransferFunction,
"",
"");
I_Method0(osg::Image *, getImage,
Properties::VIRTUAL,
__osg_Image_P1__getImage,
"Return image associated with layer. ",
"");
I_Method0(const osg::Image *, getImage,
Properties::VIRTUAL,
__C5_osg_Image_P1__getImage,
"Return const image associated with layer. ",
"");
I_Method0(unsigned int, getNumColumns,
Properties::VIRTUAL,
__unsigned_int__getNumColumns,
"",
"");
I_Method0(unsigned int, getNumRows,
Properties::VIRTUAL,
__unsigned_int__getNumRows,
"",
"");
I_Method3(bool, getValue, IN, unsigned int, i, IN, unsigned int, j, IN, float &, value,
Properties::VIRTUAL,
__bool__getValue__unsigned_int__unsigned_int__float_R1,
"",
"");
I_Method3(bool, getValue, IN, unsigned int, i, IN, unsigned int, j, IN, osg::Vec2 &, value,
Properties::VIRTUAL,
__bool__getValue__unsigned_int__unsigned_int__osg_Vec2_R1,
"",
"");
I_Method3(bool, getValue, IN, unsigned int, i, IN, unsigned int, j, IN, osg::Vec3 &, value,
Properties::VIRTUAL,
__bool__getValue__unsigned_int__unsigned_int__osg_Vec3_R1,
"",
"");
I_Method3(bool, getValue, IN, unsigned int, i, IN, unsigned int, j, IN, osg::Vec4 &, value,
Properties::VIRTUAL,
__bool__getValue__unsigned_int__unsigned_int__osg_Vec4_R1,
"",
"");
I_Method0(void, dirty,
Properties::VIRTUAL,
__void__dirty,
"increment the modified count. ",
"\" ");
I_Method1(void, setModifiedCount, IN, unsigned int, value,
Properties::VIRTUAL,
__void__setModifiedCount__unsigned_int,
"Set the modified count value. ",
"");
I_Method0(unsigned int, getModifiedCount,
Properties::VIRTUAL,
__unsigned_int__getModifiedCount,
"Get modified count value. ",
"");
I_SimpleProperty(osg::Image *, Image,
__osg_Image_P1__getImage,
0);
I_SimpleProperty(unsigned int, ModifiedCount,
__unsigned_int__getModifiedCount,
__void__setModifiedCount__unsigned_int);
I_SimpleProperty(osg::TransferFunction1D *, TransferFunction,
__osg_TransferFunction1D_P1__getTransferFunction,
__void__setTransferFunction__osg_TransferFunction1D_P1);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::HeightFieldLayer)
I_DeclaringFile("osgTerrain/Layer");
I_BaseType(osgTerrain::Layer);
I_Constructor0(____HeightFieldLayer,
"",
"");
I_ConstructorWithDefaults1(IN, osg::HeightField *, hf, 0,
Properties::NON_EXPLICIT,
____HeightFieldLayer__osg_HeightField_P1,
"",
"");
I_ConstructorWithDefaults2(IN, const osgTerrain::HeightFieldLayer &, hfLayer, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____HeightFieldLayer__C5_HeightFieldLayer_R1__C5_osg_CopyOp_R1,
"Copy constructor using CopyOp to manage deep vs shallow copy. ",
@@ -252,9 +378,11 @@ END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::ImageLayer)
I_DeclaringFile("osgTerrain/Layer");
I_BaseType(osgTerrain::Layer);
I_Constructor0(____ImageLayer,
"",
"");
I_ConstructorWithDefaults1(IN, osg::Image *, image, 0,
Properties::NON_EXPLICIT,
____ImageLayer__osg_Image_P1,
"",
"");
I_ConstructorWithDefaults2(IN, const osgTerrain::ImageLayer &, imageLayer, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____ImageLayer__C5_ImageLayer_R1__C5_osg_CopyOp_R1,
"Copy constructor using CopyOp to manage deep vs shallow copy. ",
@@ -305,14 +433,14 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::ImageLayer)
"",
"");
I_Method0(osg::Image *, getImage,
Properties::NON_VIRTUAL,
Properties::VIRTUAL,
__osg_Image_P1__getImage,
"",
"Return image associated with layer. ",
"");
I_Method0(const osg::Image *, getImage,
Properties::NON_VIRTUAL,
Properties::VIRTUAL,
__C5_osg_Image_P1__getImage,
"",
"Return const image associated with layer. ",
"");
I_Method0(unsigned int, getNumColumns,
Properties::VIRTUAL,
@@ -370,6 +498,12 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::ImageLayer)
__void__setModifiedCount__unsigned_int);
END_REFLECTOR
BEGIN_ENUM_REFLECTOR(osgTerrain::Layer::Filter)
I_DeclaringFile("osgTerrain/Layer");
I_EnumLabel(osgTerrain::Layer::NEAREST);
I_EnumLabel(osgTerrain::Layer::LINEAR);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::Layer)
I_DeclaringFile("osgTerrain/Layer");
I_BaseType(osg::Object);
@@ -415,16 +549,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Layer)
__C5_std_string_R1__getFileName,
"Get the file name of the layer. ",
"");
I_Method1(void, setTextureUnit, IN, int, textureUnit,
Properties::NON_VIRTUAL,
__void__setTextureUnit__int,
"Set the texture unit to assign layer to if required. ",
"Negative values signifies that no texture unit has been assigned. ");
I_Method0(int, getTextureUnit,
Properties::NON_VIRTUAL,
__int__getTextureUnit,
"Get the texture unit to assign layer to if required. ",
"");
I_Method1(void, setLocator, IN, osgTerrain::Locator *, locator,
Properties::NON_VIRTUAL,
__void__setLocator__Locator_P1,
@@ -495,6 +619,26 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Layer)
__C5_osg_Vec4_R1__getDefaultValue,
"",
"");
I_Method1(void, setFilter, IN, osgTerrain::Layer::Filter, filter,
Properties::NON_VIRTUAL,
__void__setFilter__Filter,
"Set the texture filter to use when do texture associated with this layer. ",
"");
I_Method0(osgTerrain::Layer::Filter, getFilter,
Properties::NON_VIRTUAL,
__Filter__getFilter,
"Get the texture filter to use when do texture associated with this layer. ",
"");
I_Method0(osg::Image *, getImage,
Properties::VIRTUAL,
__osg_Image_P1__getImage,
"Return image associated with layer if supported. ",
"");
I_Method0(const osg::Image *, getImage,
Properties::VIRTUAL,
__C5_osg_Image_P1__getImage,
"Return const image associated with layer if supported. ",
"");
I_Method2(bool, transform, IN, float, offset, IN, float, scale,
Properties::VIRTUAL,
__bool__transform__float__float,
@@ -576,6 +720,12 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Layer)
I_SimpleProperty(const std::string &, FileName,
__C5_std_string_R1__getFileName,
__void__setFileName__C5_std_string_R1);
I_SimpleProperty(osgTerrain::Layer::Filter, Filter,
__Filter__getFilter,
__void__setFilter__Filter);
I_SimpleProperty(osg::Image *, Image,
__osg_Image_P1__getImage,
0);
I_SimpleProperty(osgTerrain::Locator *, Locator,
__Locator_P1__getLocator,
__void__setLocator__Locator_P1);
@@ -588,9 +738,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Layer)
I_SimpleProperty(unsigned, ModifiedCount,
0,
__void__setModifiedCount__unsigned);
I_SimpleProperty(int, TextureUnit,
__int__getTextureUnit,
__void__setTextureUnit__int);
I_SimpleProperty(osgTerrain::ValidDataOperator *, ValidDataOperator,
__ValidDataOperator_P1__getValidDataOperator,
__void__setValidDataOperator__ValidDataOperator_P1);

View File

@@ -15,7 +15,6 @@
#include <osg/NodeVisitor>
#include <osg/Object>
#include <osg/OperationThread>
#include <osg/TransferFunction>
#include <osgTerrain/Layer>
#include <osgTerrain/Locator>
#include <osgTerrain/Terrain>
@@ -29,12 +28,6 @@
#undef OUT
#endif
BEGIN_ENUM_REFLECTOR(osgTerrain::Terrain::Filter)
I_DeclaringFile("osgTerrain/Terrain");
I_EnumLabel(osgTerrain::Terrain::NEAREST);
I_EnumLabel(osgTerrain::Terrain::LINEAR);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::Terrain)
I_DeclaringFile("osgTerrain/Terrain");
I_BaseType(osg::Group);
@@ -145,31 +138,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Terrain)
__C5_Layer_P1__getColorLayer__unsigned_int,
"Set const color layer with specified layer number. ",
"");
I_Method2(void, setColorTransferFunction, IN, unsigned int, i, IN, osg::TransferFunction *, tf,
Properties::NON_VIRTUAL,
__void__setColorTransferFunction__unsigned_int__osg_TransferFunction_P1,
"Set a color transfer function with specified layer number. ",
"");
I_Method1(osg::TransferFunction *, getColorTransferFunction, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__osg_TransferFunction_P1__getColorTransferFunction__unsigned_int,
"Get color transfer function with specified layer number. ",
"");
I_Method1(const osg::TransferFunction *, getColorTransferFunction, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__C5_osg_TransferFunction_P1__getColorTransferFunction__unsigned_int,
"Get const color transfer function with specified layer number. ",
"");
I_Method2(void, setColorFilter, IN, unsigned int, i, IN, osgTerrain::Terrain::Filter, filter,
Properties::NON_VIRTUAL,
__void__setColorFilter__unsigned_int__Filter,
"Set a color filter with specified layer number. ",
"");
I_Method1(osgTerrain::Terrain::Filter, getColorFilter, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__Filter__getColorFilter__unsigned_int,
"Set const color filter with specified layer number. ",
"");
I_Method0(unsigned int, getNumColorLayers,
Properties::NON_VIRTUAL,
__unsigned_int__getNumColorLayers,
@@ -215,10 +183,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Terrain)
__osg_BoundingSphere__computeBound,
"Compute the bounding volume of the terrain by computing the union of the bounding volumes of all layers. ",
"");
I_IndexedProperty(osgTerrain::Terrain::Filter, ColorFilter,
__Filter__getColorFilter__unsigned_int,
__void__setColorFilter__unsigned_int__Filter,
0);
I_ArrayProperty(osgTerrain::Layer *, ColorLayer,
__Layer_P1__getColorLayer__unsigned_int,
__void__setColorLayer__unsigned_int__osgTerrain_Layer_P1,
@@ -226,10 +190,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Terrain)
0,
0,
0);
I_IndexedProperty(osg::TransferFunction *, ColorTransferFunction,
__osg_TransferFunction_P1__getColorTransferFunction__unsigned_int,
__void__setColorTransferFunction__unsigned_int__osg_TransferFunction_P1,
0);
I_SimpleProperty(osgTerrain::Layer *, ElevationLayer,
__Layer_P1__getElevationLayer,
__void__setElevationLayer__Layer_P1);