Added osgSim::OverlayNode to osganimate and osgspheresegment examples, and
added support for setting texture size hint and coping with scene graphs with CoordinateSystemNode in them.
This commit is contained in:
parent
db24ea247c
commit
5283c11f8a
@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs
|
|||||||
CXXFILES =\
|
CXXFILES =\
|
||||||
osganimate.cpp\
|
osganimate.cpp\
|
||||||
|
|
||||||
LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
LIBS += -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
||||||
|
|
||||||
INSTFILES = \
|
INSTFILES = \
|
||||||
$(CXXFILES)\
|
$(CXXFILES)\
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
#include <osgGA/FlightManipulator>
|
#include <osgGA/FlightManipulator>
|
||||||
#include <osgGA/DriveManipulator>
|
#include <osgGA/DriveManipulator>
|
||||||
|
|
||||||
|
#include <osgSim/OverlayNode>
|
||||||
|
|
||||||
#include <osgProducer/Viewer>
|
#include <osgProducer/Viewer>
|
||||||
|
|
||||||
|
|
||||||
@ -179,9 +181,19 @@ osg::Node* createModel()
|
|||||||
|
|
||||||
osg::Group* root = new osg::Group;
|
osg::Group* root = new osg::Group;
|
||||||
|
|
||||||
root->addChild(createMovingModel(center,radius*0.8f));
|
osg::Node* baseModel = createBase(center-osg::Vec3(0.0f,0.0f,radius*0.5),radius);
|
||||||
|
osg::Node* movingModel = createMovingModel(center,radius*0.8f);
|
||||||
|
|
||||||
root->addChild(createBase(center-osg::Vec3(0.0f,0.0f,radius*0.5),radius));
|
#if 1
|
||||||
|
osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode;
|
||||||
|
overlayNode->setOverlaySubgraph(movingModel);
|
||||||
|
overlayNode->addChild(baseModel);
|
||||||
|
root->addChild(overlayNode);
|
||||||
|
#else
|
||||||
|
root->addChild(baseModel);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
root->addChild(movingModel);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <osgText/Text>
|
#include <osgText/Text>
|
||||||
|
|
||||||
#include <osgSim/SphereSegment>
|
#include <osgSim/SphereSegment>
|
||||||
|
#include <osgSim/OverlayNode>
|
||||||
|
|
||||||
#include <osgParticle/ExplosionEffect>
|
#include <osgParticle/ExplosionEffect>
|
||||||
#include <osgParticle/SmokeEffect>
|
#include <osgParticle/SmokeEffect>
|
||||||
@ -173,9 +174,11 @@ osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
|
|||||||
void build_world(osg::Group *root)
|
void build_world(osg::Group *root)
|
||||||
{
|
{
|
||||||
|
|
||||||
osg::Geode* terrainGeode = new osg::Geode;
|
|
||||||
// create terrain
|
// create terrain
|
||||||
|
osg::ref_ptr<osg::Geode> terrainGeode = 0;
|
||||||
{
|
{
|
||||||
|
terrainGeode = new osg::Geode;
|
||||||
|
|
||||||
osg::StateSet* stateset = new osg::StateSet();
|
osg::StateSet* stateset = new osg::StateSet();
|
||||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||||
if (image)
|
if (image)
|
||||||
@ -205,13 +208,15 @@ void build_world(osg::Group *root)
|
|||||||
}
|
}
|
||||||
terrainGeode->addDrawable(new osg::ShapeDrawable(grid));
|
terrainGeode->addDrawable(new osg::ShapeDrawable(grid));
|
||||||
|
|
||||||
root->addChild(terrainGeode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create sphere segment
|
// create sphere segment
|
||||||
|
osg::ref_ptr<osgSim::SphereSegment> ss = 0;
|
||||||
{
|
{
|
||||||
osgSim::SphereSegment* ss = new osgSim::SphereSegment(
|
ss = new osgSim::SphereSegment(
|
||||||
computeTerrainIntersection(terrainGeode,550.0f,780.0f), // center
|
computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
|
||||||
500.0f, // radius
|
500.0f, // radius
|
||||||
osg::DegreesToRadians(135.0f),
|
osg::DegreesToRadians(135.0f),
|
||||||
osg::DegreesToRadians(245.0f),
|
osg::DegreesToRadians(245.0f),
|
||||||
@ -221,13 +226,24 @@ void build_world(osg::Group *root)
|
|||||||
ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
|
ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
|
||||||
ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
|
ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
|
||||||
|
|
||||||
root->addChild(ss);
|
root->addChild(ss.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode;
|
||||||
|
overlayNode->setOverlaySubgraph(ss.get());
|
||||||
|
overlayNode->setOverlayTextureSizeHint(2048);
|
||||||
|
overlayNode->addChild(terrainGeode.get());
|
||||||
|
|
||||||
|
root->addChild(overlayNode);
|
||||||
|
#else
|
||||||
|
root->addChild(terrainGeode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// create particle effects
|
// create particle effects
|
||||||
{
|
{
|
||||||
osg::Vec3 position = computeTerrainIntersection(terrainGeode,100.0f,100.0f);
|
osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
|
||||||
|
|
||||||
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
|
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
|
||||||
osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
|
osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
|
||||||
@ -240,7 +256,7 @@ void build_world(osg::Group *root)
|
|||||||
|
|
||||||
// create particle effects
|
// create particle effects
|
||||||
{
|
{
|
||||||
osg::Vec3 position = computeTerrainIntersection(terrainGeode,200.0f,100.0f);
|
osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
|
||||||
|
|
||||||
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
|
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
|
||||||
osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
|
osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
|
||||||
|
@ -53,6 +53,11 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group
|
|||||||
/** Get the texture unit that the texture should be assigned to.*/
|
/** Get the texture unit that the texture should be assigned to.*/
|
||||||
unsigned int getOverlayTextureUnit() const { return _textureUnit; }
|
unsigned int getOverlayTextureUnit() const { return _textureUnit; }
|
||||||
|
|
||||||
|
/** Set the texture size hint. The size hint is used to request a texture of specified size.*/
|
||||||
|
void setOverlayTextureSizeHint(unsigned int size);
|
||||||
|
|
||||||
|
/** Get the texture size hint.*/
|
||||||
|
unsigned int getOverlayTextureSizeHint() const { return _textureSizeHint; }
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
@ -77,7 +82,8 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group
|
|||||||
|
|
||||||
// texture to render to, and to read from.
|
// texture to render to, and to read from.
|
||||||
unsigned int _textureUnit;
|
unsigned int _textureUnit;
|
||||||
osg::ref_ptr<osg::Texture> _texture;
|
unsigned int _textureSizeHint;
|
||||||
|
osg::ref_ptr<osg::Texture2D> _texture;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,13 +12,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <osg/Texture2D>
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/CoordinateSystemNode>
|
||||||
|
|
||||||
#include <osgUtil/CullVisitor>
|
#include <osgUtil/CullVisitor>
|
||||||
#include <osgSim/OverlayNode>
|
#include <osgSim/OverlayNode>
|
||||||
|
|
||||||
using namespace osgSim;
|
using namespace osgSim;
|
||||||
|
|
||||||
OverlayNode::OverlayNode():
|
OverlayNode::OverlayNode():
|
||||||
_textureUnit(1)
|
_textureUnit(1),
|
||||||
|
_textureSizeHint(1024)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@ -26,34 +29,38 @@ OverlayNode::OverlayNode():
|
|||||||
OverlayNode::OverlayNode(const OverlayNode& copy, const osg::CopyOp& copyop):
|
OverlayNode::OverlayNode(const OverlayNode& copy, const osg::CopyOp& copyop):
|
||||||
Group(copy,copyop),
|
Group(copy,copyop),
|
||||||
_overlaySubgraph(copy._overlaySubgraph),
|
_overlaySubgraph(copy._overlaySubgraph),
|
||||||
_textureUnit(copy._textureUnit)
|
_textureUnit(copy._textureUnit),
|
||||||
|
_textureSizeHint(copy._textureSizeHint)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayNode::init()
|
void OverlayNode::init()
|
||||||
{
|
{
|
||||||
unsigned int tex_width = 1024;
|
|
||||||
unsigned int tex_height = 1024;
|
unsigned int tex_width = _textureSizeHint;
|
||||||
|
unsigned int tex_height = _textureSizeHint;
|
||||||
|
|
||||||
osg::Texture2D* texture = new osg::Texture2D;
|
if (!_texture)
|
||||||
texture->setTextureSize(tex_width, tex_height);
|
{
|
||||||
texture->setInternalFormat(GL_RGBA);
|
osg::Texture2D* texture = new osg::Texture2D;
|
||||||
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
texture->setTextureSize(tex_width, tex_height);
|
||||||
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
texture->setInternalFormat(GL_RGBA);
|
||||||
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
|
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
|
||||||
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
|
texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
|
||||||
texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
|
||||||
|
texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
|
||||||
_texture = texture;
|
texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
||||||
|
_texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
// set up the render to texture camera.
|
// set up the render to texture camera.
|
||||||
|
if (!_camera)
|
||||||
{
|
{
|
||||||
|
|
||||||
// create the camera
|
// create the camera
|
||||||
_camera = new osg::CameraNode;
|
_camera = new osg::CameraNode;
|
||||||
|
|
||||||
_camera->setClearColor(osg::Vec4(1.0f,0.5f,0.5f,1.0f));
|
_camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
|
||||||
|
|
||||||
// set viewport
|
// set viewport
|
||||||
_camera->setViewport(0,0,tex_width,tex_height);
|
_camera->setViewport(0,0,tex_width,tex_height);
|
||||||
@ -68,11 +75,11 @@ void OverlayNode::init()
|
|||||||
_camera->attach(osg::CameraNode::COLOR_BUFFER, _texture.get());
|
_camera->attach(osg::CameraNode::COLOR_BUFFER, _texture.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
_texgenNode = new osg::TexGenNode;
|
if (!_texgenNode) _texgenNode = new osg::TexGenNode;
|
||||||
|
|
||||||
_mainSubgraphStateSet = new osg::StateSet;
|
if (!_mainSubgraphStateSet) _mainSubgraphStateSet = new osg::StateSet;
|
||||||
|
|
||||||
setOverlayTextureUnit(1);
|
setOverlayTextureUnit(_textureUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -97,8 +104,7 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
|
|||||||
// if we need to redraw then do cull traversal on camera.
|
// if we need to redraw then do cull traversal on camera.
|
||||||
if (!_textureObjectValidList[contextID])
|
if (!_textureObjectValidList[contextID])
|
||||||
{
|
{
|
||||||
osg::Vec3 _position(0,0,0);
|
|
||||||
|
|
||||||
// now compute the camera's view and projection matrix to point at the shadower (the camera's children)
|
// now compute the camera's view and projection matrix to point at the shadower (the camera's children)
|
||||||
osg::BoundingSphere bs;
|
osg::BoundingSphere bs;
|
||||||
for(unsigned int i=0; i<_camera->getNumChildren(); ++i)
|
for(unsigned int i=0; i<_camera->getNumChildren(); ++i)
|
||||||
@ -108,30 +114,66 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
|
|||||||
|
|
||||||
if (!bs.valid())
|
if (!bs.valid())
|
||||||
{
|
{
|
||||||
osg::notify(osg::WARN) << "bb invalid"<<_camera.get()<<std::endl;
|
osg::notify(osg::WARN) << "OverlayNode::traverse() - bb invalid"<<_camera.get()<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float centerDistance = (_position-bs.center()).length();
|
|
||||||
|
|
||||||
float znear = centerDistance-bs.radius();
|
|
||||||
float zfar = centerDistance+bs.radius();
|
|
||||||
float zNearRatio = 0.001f;
|
|
||||||
if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
|
|
||||||
|
|
||||||
float top = (bs.radius()/centerDistance)*znear;
|
|
||||||
float right = top;
|
|
||||||
|
|
||||||
|
// see if we are within a coordinate system node.
|
||||||
|
osg::CoordinateSystemNode* csn = 0;
|
||||||
|
osg::NodePath& nodePath = nv.getNodePath();
|
||||||
|
for(osg::NodePath::reverse_iterator itr = nodePath.rbegin();
|
||||||
|
itr != nodePath.rend() && csn==0;
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
csn = dynamic_cast<osg::CoordinateSystemNode*>(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
_camera->setReferenceFrame(osg::CameraNode::ABSOLUTE_RF);
|
_camera->setReferenceFrame(osg::CameraNode::ABSOLUTE_RF);
|
||||||
_camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
|
|
||||||
_camera->setViewMatrixAsLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));
|
if (csn)
|
||||||
|
{
|
||||||
|
osg::Vec3d eyePoint(0.0,0.0,0.0); // center of the planet
|
||||||
|
double centerDistance = (eyePoint-osg::Vec3d(bs.center())).length();
|
||||||
|
|
||||||
|
double znear = centerDistance-bs.radius();
|
||||||
|
double zfar = centerDistance+bs.radius();
|
||||||
|
double zNearRatio = 0.001f;
|
||||||
|
if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;
|
||||||
|
|
||||||
|
double top = (bs.radius()/centerDistance)*znear;
|
||||||
|
double right = top;
|
||||||
|
|
||||||
|
_camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar);
|
||||||
|
_camera->setViewMatrixAsLookAt(eyePoint, bs.center(), osg::Vec3(0.0f,1.0f,0.0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
osg::Vec3d upDirection(0.0,1.0,0.0);
|
||||||
|
osg::Vec3d viewDirection(0.0,0.0,1.0);
|
||||||
|
|
||||||
|
double viewDistance = 2.0*bs.radius();
|
||||||
|
osg::Vec3d center = bs.center();
|
||||||
|
osg::Vec3d eyePoint = center+viewDirection*viewDistance;
|
||||||
|
|
||||||
|
double znear = viewDistance-bs.radius();
|
||||||
|
double zfar = viewDistance+bs.radius();
|
||||||
|
|
||||||
|
float top = bs.radius();
|
||||||
|
float right = top;
|
||||||
|
|
||||||
|
_camera->setProjectionMatrixAsOrtho(-right,right,-top,top,znear,zfar);
|
||||||
|
_camera->setViewMatrixAsLookAt(eyePoint,center,upDirection);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// compute the matrix which takes a vertex from local coords into tex coords
|
// compute the matrix which takes a vertex from local coords into tex coords
|
||||||
// will use this later to specify osg::TexGen..
|
// will use this later to specify osg::TexGen..
|
||||||
osg::Matrix MVPT = _camera->getViewMatrix() *
|
osg::Matrix MVPT = _camera->getViewMatrix() *
|
||||||
_camera->getProjectionMatrix() *
|
_camera->getProjectionMatrix() *
|
||||||
osg::Matrix::translate(1.0,1.0,1.0) *
|
osg::Matrix::translate(1.0,1.0,1.0) *
|
||||||
osg::Matrix::scale(0.5f,0.5f,0.5f);
|
osg::Matrix::scale(0.5,0.5,0.5);
|
||||||
|
|
||||||
_texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
|
_texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
|
||||||
_texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
|
_texgenNode->getTexGen()->setPlanesFromMatrix(MVPT);
|
||||||
@ -139,7 +181,7 @@ void OverlayNode::traverse(osg::NodeVisitor& nv)
|
|||||||
|
|
||||||
_camera->accept(*cv);
|
_camera->accept(*cv);
|
||||||
|
|
||||||
// _textureObjectValidList[contextID] = 1;
|
_textureObjectValidList[contextID] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,3 +228,14 @@ void OverlayNode::setOverlayTextureUnit(unsigned int unit)
|
|||||||
_mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);
|
_mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);
|
||||||
_mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON);
|
_mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OverlayNode::setOverlayTextureSizeHint(unsigned int size)
|
||||||
|
{
|
||||||
|
if (_textureSizeHint == size) return;
|
||||||
|
|
||||||
|
_textureSizeHint = size;
|
||||||
|
//_texture->dirtyTextureObject();
|
||||||
|
_texture->setTextureSize(_textureSizeHint, _textureSizeHint);
|
||||||
|
_camera->setViewport(0,0,_textureSizeHint,_textureSizeHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user