Change Terrain so that it subclassed from CoordinateSystemNode.
Implemented new update scheme of GeometryTechnique to avoid potential threading issues. Added Terrain support to .ive.
This commit is contained in:
parent
656efbf03f
commit
c6c26d5d44
@ -34,7 +34,7 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
|
||||
|
||||
META_Object(osgTerrain, GeometryTechnique);
|
||||
|
||||
virtual void init();
|
||||
virtual void init(int dirtyMask, bool assumeMultiThreaded);
|
||||
|
||||
virtual Locator* computeMasterLocator();
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#ifndef OSGTerrain
|
||||
#define OSGTerrain 1
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/CoordinateSystemNode>
|
||||
|
||||
#include <osgTerrain/TerrainTile>
|
||||
@ -23,7 +22,7 @@ namespace osgTerrain {
|
||||
|
||||
/** Terrain provides a framework for loosely coupling height field data with height rendering algorithms.
|
||||
* This allows TerrainTechniques to be plugged in at runtime.*/
|
||||
class OSGTERRAIN_EXPORT Terrain : public osg::Group
|
||||
class OSGTERRAIN_EXPORT Terrain : public osg::CoordinateSystemNode
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -63,7 +63,7 @@ class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object, public osg::Obser
|
||||
TerrainTile* getTerrainTile() { return _terrainTile; }
|
||||
const TerrainTile* getTerrainTile() const { return _terrainTile; }
|
||||
|
||||
virtual void init();
|
||||
virtual void init(int dirtyMask, bool assumeMultiThreaded);
|
||||
|
||||
virtual void update(osgUtil::UpdateVisitor* nv);
|
||||
|
||||
|
@ -78,8 +78,7 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
|
||||
virtual void traverse(osg::NodeVisitor& nv);
|
||||
|
||||
/** Call init on any attached TerrainTechnique.*/
|
||||
void init();
|
||||
|
||||
void init(int dirtyMask, bool assumeMultiThreaded);
|
||||
|
||||
/** Set the Terrain that this Terrain tile is a member of.*/
|
||||
void setTerrain(Terrain* ts);
|
||||
|
@ -101,6 +101,7 @@ SET(TARGET_SRC
|
||||
Stencil.cpp
|
||||
Switch.cpp
|
||||
SwitchLayer.cpp
|
||||
Terrain.cpp
|
||||
TerrainTile.cpp
|
||||
TexEnvCombine.cpp
|
||||
TexEnv.cpp
|
||||
|
@ -112,6 +112,7 @@
|
||||
|
||||
#include "Text.h"
|
||||
|
||||
#include "Terrain.h"
|
||||
#include "TerrainTile.h"
|
||||
#include "Locator.h"
|
||||
#include "ImageLayer.h"
|
||||
@ -1836,6 +1837,10 @@ osg::Node* DataInputStream::readNode()
|
||||
node = new osgTerrain::TerrainTile();
|
||||
((ive::TerrainTile*)(node.get()))->read(this);
|
||||
}
|
||||
else if(nodeTypeID== IVETERRAIN){
|
||||
node = new osgTerrain::Terrain();
|
||||
((ive::Terrain*)(node.get()))->read(this);
|
||||
}
|
||||
else if(nodeTypeID== IVEVOLUME){
|
||||
node = new osgVolume::Volume();
|
||||
((ive::Volume*)(node.get()))->read(this);
|
||||
|
@ -103,6 +103,7 @@
|
||||
|
||||
#include "Text.h"
|
||||
|
||||
#include "Terrain.h"
|
||||
#include "TerrainTile.h"
|
||||
#include "Locator.h"
|
||||
#include "ImageLayer.h"
|
||||
@ -1333,9 +1334,6 @@ void DataOutputStream::writeNode(const osg::Node* node)
|
||||
else if(dynamic_cast<const osg::Switch*>(node)){
|
||||
((ive::Switch*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<const osg::CoordinateSystemNode*>(node)){
|
||||
((ive::CoordinateSystemNode*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<const osgSim::MultiSwitch*>(node)){
|
||||
((ive::MultiSwitch*)(node))->write(this);
|
||||
}
|
||||
@ -1378,9 +1376,17 @@ void DataOutputStream::writeNode(const osg::Node* node)
|
||||
else if(dynamic_cast<const osgTerrain::TerrainTile*>(node)){
|
||||
((ive::TerrainTile*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<const osgTerrain::Terrain*>(node)){
|
||||
((ive::Terrain*)(node))->write(this);
|
||||
}
|
||||
else if(dynamic_cast<const osgVolume::Volume*>(node)){
|
||||
((ive::Volume*)(node))->write(this);
|
||||
}
|
||||
|
||||
else if(dynamic_cast<const osg::CoordinateSystemNode*>(node)){
|
||||
((ive::CoordinateSystemNode*)(node))->write(this);
|
||||
}
|
||||
|
||||
else if(dynamic_cast<const osgVolume::VolumeTile*>(node)){
|
||||
((ive::VolumeTile*)(node))->write(this);
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ namespace ive {
|
||||
#define IVEVALIDRANGE 0x0020000B
|
||||
#define IVENODATAVALUE 0x0020000C
|
||||
#define IVESWITCHLAYER 0x0020000D
|
||||
#define IVETERRAIN 0x0020000A
|
||||
#define IVETERRAIN 0x0020000E
|
||||
|
||||
// osgVolume classes
|
||||
#define IVEVOLUMETILE 0x00300001
|
||||
|
63
src/osgPlugins/ive/Terrain.cpp
Normal file
63
src/osgPlugins/ive/Terrain.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 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.
|
||||
*/
|
||||
|
||||
#include "Exception.h"
|
||||
#include "Terrain.h"
|
||||
#include "TerrainTile.h"
|
||||
#include "CoordinateSystemNode.h"
|
||||
|
||||
#include <osgTerrain/GeometryTechnique>
|
||||
|
||||
using namespace ive;
|
||||
|
||||
void Terrain::write(DataOutputStream* out)
|
||||
{
|
||||
// Write Terrain's identification.
|
||||
out->writeInt(IVETERRAIN);
|
||||
|
||||
// If the osg class is inherited by any other class we should also write this to file.
|
||||
osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(this);
|
||||
if(csn)
|
||||
((ive::CoordinateSystemNode*)(csn))->write(out);
|
||||
else
|
||||
out_THROW_EXCEPTION("Terrain::write(): Could not cast this osgTerrain::Terrain to an osg::CoordinateSystemNode.");
|
||||
|
||||
out->writeFloat(getSampleRatio());
|
||||
out->writeFloat(getVerticalScale());
|
||||
out->writeInt(getBlendingPolicy());
|
||||
|
||||
TerrainTile::writeTerrainTechnique(out, getTerrainTechniquePrototype());
|
||||
}
|
||||
|
||||
void Terrain::read(DataInputStream* in)
|
||||
{
|
||||
// Peek on Terrain's identification.
|
||||
int id = in->peekInt();
|
||||
if (id != IVETERRAIN) in_THROW_EXCEPTION("TerrainTile::read(): Expected Terrain identification.");
|
||||
|
||||
// Read Terrain's identification.
|
||||
id = in->readInt();
|
||||
|
||||
osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(this);
|
||||
if(csn)
|
||||
((ive::CoordinateSystemNode*)(csn))->read(in);
|
||||
else
|
||||
in_THROW_EXCEPTION("Terrain::read(): Could not cast this osgTerran::Terrain to an osg::CoordinateSystemNode.");
|
||||
|
||||
setSampleRatio(in->readFloat());
|
||||
setVerticalScale(in->readFloat());
|
||||
setBlendingPolicy(static_cast<osgTerrain::TerrainTile::BlendingPolicy>(in->readInt()));
|
||||
|
||||
setTerrainTechniquePrototype(TerrainTile::readTerrainTechnique(in));
|
||||
}
|
||||
|
33
src/osgPlugins/ive/Terrain.h
Normal file
33
src/osgPlugins/ive/Terrain.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 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 IVE_TERRAIN
|
||||
#define IVE_TERRAIN 1
|
||||
|
||||
#include <osgTerrain/Terrain>
|
||||
|
||||
#include "ReadWrite.h"
|
||||
|
||||
namespace ive
|
||||
{
|
||||
|
||||
class Terrain : public osgTerrain::Terrain, public ReadWrite
|
||||
{
|
||||
public:
|
||||
void write(DataOutputStream* out);
|
||||
void read(DataInputStream* in);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -27,8 +27,8 @@ public:
|
||||
void write(DataOutputStream* out);
|
||||
void read(DataInputStream* in);
|
||||
|
||||
void writeTerrainTechnique(DataOutputStream* out, osgTerrain::TerrainTechnique* technique);
|
||||
osgTerrain::TerrainTechnique* readTerrainTechnique(DataInputStream* out);
|
||||
static void writeTerrainTechnique(DataOutputStream* out, osgTerrain::TerrainTechnique* technique);
|
||||
static osgTerrain::TerrainTechnique* readTerrainTechnique(DataInputStream* out);
|
||||
|
||||
};
|
||||
|
||||
|
@ -95,7 +95,7 @@ void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
|
||||
};
|
||||
}
|
||||
|
||||
void GeometryTechnique::init()
|
||||
void GeometryTechnique::init(int dirtyMask, bool assumeMultiThreaded)
|
||||
{
|
||||
OSG_INFO<<"Doing GeometryTechnique::init()"<<std::endl;
|
||||
|
||||
@ -106,7 +106,7 @@ void GeometryTechnique::init()
|
||||
// take a temporary referecen
|
||||
osg::ref_ptr<TerrainTile> tile = _terrainTile;
|
||||
|
||||
if (_terrainTile->getDirtyMask()==0) return;
|
||||
if (dirtyMask==0) return;
|
||||
|
||||
osg::ref_ptr<BufferData> buffer = new BufferData;
|
||||
|
||||
@ -114,7 +114,7 @@ void GeometryTechnique::init()
|
||||
|
||||
osg::Vec3d centerModel = computeCenterModel(*buffer, masterLocator);
|
||||
|
||||
if ((_terrainTile->getDirtyMask() & TerrainTile::IMAGERY_DIRTY)==0)
|
||||
if ((dirtyMask & TerrainTile::IMAGERY_DIRTY)==0)
|
||||
{
|
||||
generateGeometry(*buffer, masterLocator, centerModel);
|
||||
|
||||
@ -141,12 +141,14 @@ void GeometryTechnique::init()
|
||||
|
||||
if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true);
|
||||
|
||||
if (!_currentBufferData)
|
||||
if (!_currentBufferData || !assumeMultiThreaded)
|
||||
{
|
||||
// no currentBufferData so we must be the first init to be applied
|
||||
_currentBufferData = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is already an active _currentBufferData so we'll request that this gets swapped on next frame.
|
||||
_newBufferData = buffer;
|
||||
if (_terrainTile->getTerrain()) _terrainTile->getTerrain()->updateTerrainTileOnNextFrame(_terrainTile);
|
||||
}
|
||||
@ -259,7 +261,7 @@ class VertexNormalGenerator
|
||||
{
|
||||
if (r<0 || r>=_numRows || c<0 || c>=_numColumns)
|
||||
{
|
||||
i = -(1+_boundaryVertices->size());
|
||||
i = -(1+static_cast<int>(_boundaryVertices->size()));
|
||||
_boundaryVertices->push_back(v);
|
||||
// OSG_NOTICE<<"setVertex("<<c<<", "<<r<<", ["<<v<<"], ["<<n<<"]), i="<<i<<" _boundaryVertices["<<-i-1<<"]="<<(*_boundaryVertices)[-i-1]<<"]"<<std::endl;
|
||||
}
|
||||
@ -817,27 +819,27 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
||||
{
|
||||
if (!(left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||
{
|
||||
left_tile->setDirtyMask(left_tile->getDirtyMask() | TerrainTile::LEFT_EDGE_DIRTY);
|
||||
if (updateNeighboursImmediately)
|
||||
{
|
||||
left_tile->init();
|
||||
}
|
||||
int dirtyMask = left_tile->getDirtyMask() | TerrainTile::LEFT_EDGE_DIRTY;
|
||||
if (updateNeighboursImmediately) left_tile->init(dirtyMask, true);
|
||||
else left_tile->setDirtyMask(dirtyMask);
|
||||
}
|
||||
}
|
||||
if (right_tile.valid())
|
||||
{
|
||||
if (!(right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||
{
|
||||
right_tile->setDirtyMask(right_tile->getDirtyMask() | TerrainTile::RIGHT_EDGE_DIRTY);
|
||||
if (updateNeighboursImmediately) right_tile->init();
|
||||
int dirtyMask = right_tile->getDirtyMask() | TerrainTile::RIGHT_EDGE_DIRTY;
|
||||
if (updateNeighboursImmediately) right_tile->init(dirtyMask, true);
|
||||
else right_tile->setDirtyMask(dirtyMask);
|
||||
}
|
||||
}
|
||||
if (top_tile.valid())
|
||||
{
|
||||
if (!(top_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||
{
|
||||
top_tile->setDirtyMask(top_tile->getDirtyMask() | TerrainTile::TOP_EDGE_DIRTY);
|
||||
if (updateNeighboursImmediately) top_tile->init();
|
||||
int dirtyMask = top_tile->getDirtyMask() | TerrainTile::TOP_EDGE_DIRTY;
|
||||
if (updateNeighboursImmediately) top_tile->init(dirtyMask, true);
|
||||
else top_tile->setDirtyMask(dirtyMask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -845,8 +847,9 @@ void GeometryTechnique::generateGeometry(BufferData& buffer, Locator* masterLoca
|
||||
{
|
||||
if (!(bottom_tile->getTerrainTechnique()->containsNeighbour(_terrainTile)))
|
||||
{
|
||||
bottom_tile->setDirtyMask(bottom_tile->getDirtyMask() | TerrainTile::BOTTOM_EDGE_DIRTY);
|
||||
if (updateNeighboursImmediately) bottom_tile->init();
|
||||
int dirtyMask = bottom_tile->getDirtyMask() | TerrainTile::BOTTOM_EDGE_DIRTY;
|
||||
if (updateNeighboursImmediately) bottom_tile->init(dirtyMask, true);
|
||||
else bottom_tile->setDirtyMask(dirtyMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1322,7 +1325,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
|
||||
// if app traversal update the frame count.
|
||||
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
|
||||
{
|
||||
if (_terrainTile->getDirty()) _terrainTile->init();
|
||||
if (_terrainTile->getDirty()) _terrainTile->init(_terrainTile->getDirtyMask(), false);
|
||||
|
||||
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
|
||||
if (uv)
|
||||
@ -1345,7 +1348,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv)
|
||||
if (_terrainTile->getDirty())
|
||||
{
|
||||
OSG_INFO<<"******* Doing init ***********"<<std::endl;
|
||||
_terrainTile->init();
|
||||
_terrainTile->init(_terrainTile->getDirtyMask(), false);
|
||||
}
|
||||
|
||||
if (_currentBufferData.valid())
|
||||
|
@ -30,7 +30,7 @@ Terrain::Terrain():
|
||||
}
|
||||
|
||||
Terrain::Terrain(const Terrain& ts, const osg::CopyOp& copyop):
|
||||
osg::Group(ts,copyop),
|
||||
osg::CoordinateSystemNode(ts,copyop),
|
||||
_sampleRatio(ts._sampleRatio),
|
||||
_verticalScale(ts._verticalScale),
|
||||
_blendingPolicy(ts._blendingPolicy),
|
||||
@ -69,7 +69,7 @@ void Terrain::traverse(osg::NodeVisitor& nv)
|
||||
++itr)
|
||||
{
|
||||
TerrainTile* tile = *itr;
|
||||
if (tile->getTerrainTechnique()) tile->getTerrainTechnique()->update(uv);
|
||||
tile->traverse(nv);
|
||||
}
|
||||
_updateTerrainTileSet.clear();
|
||||
}
|
||||
|
@ -83,9 +83,9 @@ void TerrainTechnique::setTerrainTile(TerrainTile* tile)
|
||||
_terrainTile = tile;
|
||||
}
|
||||
|
||||
void TerrainTechnique::init()
|
||||
void TerrainTechnique::init(int dirtyMask, bool assumeMultiThreaded)
|
||||
{
|
||||
OSG_NOTIFY(osg::NOTICE)<<className()<<"::initialize(..) not implementated yet"<<std::endl;
|
||||
OSG_NOTIFY(osg::NOTICE)<<className()<<"::init(..) not implementated yet"<<std::endl;
|
||||
}
|
||||
|
||||
void TerrainTechnique::update(osgUtil::UpdateVisitor* uv)
|
||||
@ -112,7 +112,7 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
|
||||
// if app traversal update the frame count.
|
||||
if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
|
||||
{
|
||||
if (_terrainTile->getDirty()) _terrainTile->init();
|
||||
if (_terrainTile->getDirty()) _terrainTile->init(_terrainTile->getDirtyMask(), false);
|
||||
|
||||
osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
|
||||
if (uv)
|
||||
@ -132,7 +132,10 @@ void TerrainTechnique::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
if (_terrainTile->getDirty()) _terrainTile->init();
|
||||
if (_terrainTile->getDirty())
|
||||
{
|
||||
_terrainTile->init(_terrainTile->getDirtyMask(), false);
|
||||
}
|
||||
|
||||
// otherwise fallback to the Group::traverse()
|
||||
_terrainTile->osg::Group::traverse(nv);
|
||||
|
@ -140,7 +140,7 @@ void TerrainTile::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
init(getDirtyMask(), false);
|
||||
|
||||
_hasBeenTraversal = true;
|
||||
}
|
||||
@ -164,7 +164,7 @@ void TerrainTile::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainTile::init()
|
||||
void TerrainTile::init(int dirtyMask, bool assumeMultiThreaded)
|
||||
{
|
||||
if (!_terrainTechnique)
|
||||
{
|
||||
@ -179,9 +179,9 @@ void TerrainTile::init()
|
||||
}
|
||||
}
|
||||
|
||||
if (_terrainTechnique.valid() && getDirty())
|
||||
if (_terrainTechnique.valid())
|
||||
{
|
||||
_terrainTechnique->init();
|
||||
_terrainTechnique->init(dirtyMask, assumeMultiThreaded);
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,6 +218,15 @@ void TerrainTile::setDirtyMask(int dirtyMask)
|
||||
|
||||
if (_dirtyMask!=NOT_DIRTY) dirtyDelta += 1;
|
||||
|
||||
#if 1
|
||||
if (dirtyDelta>0)
|
||||
{
|
||||
// need to signal that we need an update
|
||||
if (_terrain) _terrain->updateTerrainTileOnNextFrame(this);
|
||||
}
|
||||
#else
|
||||
|
||||
// setNumChildrenRequeingUpdateTraversal() isn't thread safe so should avoid using it.
|
||||
if (dirtyDelta>0)
|
||||
{
|
||||
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
|
||||
@ -226,6 +235,7 @@ void TerrainTile::setDirtyMask(int dirtyMask)
|
||||
{
|
||||
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ REGISTER_DOTOSGWRAPPER(Terrain)
|
||||
(
|
||||
new osgTerrain::Terrain,
|
||||
"Terrain",
|
||||
"Object Node Terrain Group",
|
||||
"Object Node Terrain CoordinateSystemNode Group",
|
||||
&Terrain_readLocalData,
|
||||
&Terrain_writeLocalData
|
||||
);
|
||||
|
@ -6,7 +6,7 @@
|
||||
REGISTER_OBJECT_WRAPPER( osgTerrain_Terrain,
|
||||
new osgTerrain::Terrain,
|
||||
osgTerrain::Terrain,
|
||||
"osg::Object osg::Node osg::Group osgTerrain::Terrain" )
|
||||
"osg::Object osg::Node osg::CoordinateSystemNode osgTerrain::Terrain" )
|
||||
{
|
||||
ADD_FLOAT_SERIALIZER( SampleRatio, 1.0f ); // _sampleRatio
|
||||
ADD_FLOAT_SERIALIZER( VerticalScale, 1.0f ); // _verticalScale
|
||||
|
Loading…
Reference in New Issue
Block a user