Replaced tabs with spaces in examples.
This commit is contained in:
parent
39db6b28b3
commit
91855e7c50
@ -31,9 +31,9 @@ void display(void)
|
||||
|
||||
// set the view
|
||||
osg::Vec3 viewPos(
|
||||
viewRadius * cos(viewElev) * sin(viewRot),
|
||||
viewRadius * cos(viewElev) * cos(viewRot),
|
||||
viewRadius * sin(viewElev));
|
||||
viewRadius * cos(viewElev) * sin(viewRot),
|
||||
viewRadius * cos(viewElev) * cos(viewRot),
|
||||
viewRadius * sin(viewElev));
|
||||
sceneView->setViewMatrixAsLookAt( centerPos-viewPos, centerPos, osg::Vec3(0.0f,0.0f,1.0f) );
|
||||
|
||||
// do the update traversal the scene graph - such as updating animations
|
||||
@ -78,15 +78,15 @@ void keyboard( unsigned char key, int /*x*/, int /*y*/ )
|
||||
{
|
||||
switch( key )
|
||||
{
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
case ' ':
|
||||
viewRot = 0.0f;
|
||||
viewElev = 0.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
case ' ':
|
||||
viewRot = 0.0f;
|
||||
viewElev = 0.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,26 +13,26 @@
|
||||
const int _eq_nb=8;
|
||||
const osg::BlendEquation::Equation _equations[_eq_nb]=
|
||||
{
|
||||
osg::BlendEquation::FUNC_ADD,
|
||||
osg::BlendEquation::FUNC_SUBTRACT,
|
||||
osg::BlendEquation::FUNC_REVERSE_SUBTRACT,
|
||||
osg::BlendEquation::RGBA_MIN,
|
||||
osg::BlendEquation::RGBA_MAX,
|
||||
osg::BlendEquation::ALPHA_MIN,
|
||||
osg::BlendEquation::ALPHA_MAX,
|
||||
osg::BlendEquation::LOGIC_OP
|
||||
osg::BlendEquation::FUNC_ADD,
|
||||
osg::BlendEquation::FUNC_SUBTRACT,
|
||||
osg::BlendEquation::FUNC_REVERSE_SUBTRACT,
|
||||
osg::BlendEquation::RGBA_MIN,
|
||||
osg::BlendEquation::RGBA_MAX,
|
||||
osg::BlendEquation::ALPHA_MIN,
|
||||
osg::BlendEquation::ALPHA_MAX,
|
||||
osg::BlendEquation::LOGIC_OP
|
||||
};
|
||||
|
||||
const char* _equations_name[_eq_nb]=
|
||||
{
|
||||
"osg::BlendEquation::FUNC_ADD",
|
||||
"osg::BlendEquation::FUNC_SUBTRACT",
|
||||
"osg::BlendEquation::FUNC_REVERSE_SUBTRACT",
|
||||
"osg::BlendEquation::RGBA_MIN",
|
||||
"osg::BlendEquation::RGBA_MAX",
|
||||
"osg::BlendEquation::ALPHA_MIN",
|
||||
"osg::BlendEquation::ALPHA_MAX",
|
||||
"osg::BlendEquation::LOGIC_OP"
|
||||
"osg::BlendEquation::FUNC_ADD",
|
||||
"osg::BlendEquation::FUNC_SUBTRACT",
|
||||
"osg::BlendEquation::FUNC_REVERSE_SUBTRACT",
|
||||
"osg::BlendEquation::RGBA_MIN",
|
||||
"osg::BlendEquation::RGBA_MAX",
|
||||
"osg::BlendEquation::ALPHA_MIN",
|
||||
"osg::BlendEquation::ALPHA_MAX",
|
||||
"osg::BlendEquation::LOGIC_OP"
|
||||
};
|
||||
|
||||
|
||||
@ -57,14 +57,14 @@ protected:
|
||||
|
||||
TechniqueEventHandler(const TechniqueEventHandler&,const osg::CopyOp&) {}
|
||||
|
||||
osg::BlendEquation* _blendEq;
|
||||
osg::BlendEquation* _blendEq;
|
||||
|
||||
int _eq_index;
|
||||
int _eq_index;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool TechniqueEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
@ -74,21 +74,19 @@ bool TechniqueEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAc
|
||||
if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right)
|
||||
{
|
||||
_eq_index++;
|
||||
if (_eq_index>=_eq_nb)
|
||||
_eq_index=0;
|
||||
_blendEq->setEquation(_equations[_eq_index]);
|
||||
std::cout<<"Equation name = "<<_equations_name[_eq_index]<<std::endl;
|
||||
_eq_index++;
|
||||
if (_eq_index>=_eq_nb) _eq_index=0;
|
||||
_blendEq->setEquation(_equations[_eq_index]);
|
||||
std::cout<<"Equation name = "<<_equations_name[_eq_index]<<std::endl;
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)
|
||||
{
|
||||
_eq_index--;
|
||||
if (_eq_index<0)
|
||||
_eq_index=_eq_nb-1;
|
||||
_blendEq->setEquation(_equations[_eq_index]);
|
||||
std::cout<<"Operation name = "<<_equations_name[_eq_index]<<std::endl;
|
||||
_eq_index--;
|
||||
if (_eq_index<0) _eq_index=_eq_nb-1;
|
||||
_blendEq->setEquation(_equations[_eq_index]);
|
||||
std::cout<<"Operation name = "<<_equations_name[_eq_index]<<std::endl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -134,14 +132,14 @@ int main( int argc, char **argv )
|
||||
root->addChild(loadedModel);
|
||||
|
||||
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
osg::BlendEquation* blendEquation = new osg::BlendEquation(osg::BlendEquation::FUNC_ADD);
|
||||
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
osg::BlendEquation* blendEquation = new osg::BlendEquation(osg::BlendEquation::FUNC_ADD);
|
||||
|
||||
stateset->setAttributeAndModes(blendEquation,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
|
||||
|
||||
//tell to sort the mesh before displaying it
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
|
||||
|
||||
|
||||
loadedModel->setStateSet(stateset);
|
||||
|
||||
@ -202,8 +200,6 @@ int main( int argc, char **argv )
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -81,14 +81,14 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
|
||||
{
|
||||
texCoordRange = dynamic_cast<osgDB::ImageOptions::TexCoordRange*>(image->getUserData());
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
|
||||
texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
|
||||
texture->setMaxAnisotropy(8);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
|
||||
if (useCompressedTextures)
|
||||
{
|
||||
@ -163,8 +163,8 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
|
||||
double latitude = orig_latitude;
|
||||
|
||||
tex.x() = tex_orig.x();
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
double sin_longitude = sin(longitude);
|
||||
if (leftHemisphere)
|
||||
{
|
||||
@ -174,14 +174,14 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
|
||||
{
|
||||
normal.set(-cos(latitude)*sin_longitude,-sin(latitude)*sin_longitude,-cos(longitude));
|
||||
}
|
||||
v[vi] = normal;
|
||||
n[vi] = normal;
|
||||
v[vi] = normal;
|
||||
n[vi] = normal;
|
||||
|
||||
t[vi].set(tex.x(),tex.y());
|
||||
t[vi].set(tex.x(),tex.y());
|
||||
latitude+=delta_latitude;
|
||||
tex.x()+=columnTexDelta;
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
longitude += delta_longitude;
|
||||
tex.y() += rowTexDelta;
|
||||
}
|
||||
@ -198,11 +198,11 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x
|
||||
osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
|
||||
geometry->addPrimitiveSet(&drawElements);
|
||||
int ei=0;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
}
|
||||
|
||||
osgUtil::TriStripVisitor tsv;
|
||||
|
@ -138,7 +138,7 @@ int main( int argc, char **argv )
|
||||
|
||||
// load the osgProducer library manually.
|
||||
osg::ref_ptr<osgDB::DynamicLibrary> windowingLib =
|
||||
osgDB::DynamicLibrary::loadLibrary(osgDB::Registry::instance()->createLibraryNameForNodeKit(windowingLibrary));
|
||||
osgDB::DynamicLibrary::loadLibrary(osgDB::Registry::instance()->createLibraryNameForNodeKit(windowingLibrary));
|
||||
|
||||
|
||||
if (!windowingLib)
|
||||
|
@ -30,55 +30,55 @@ class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
|
||||
{
|
||||
public:
|
||||
|
||||
MyKeyboardMouseCallback() :
|
||||
Producer::KeyboardMouseCallback(),
|
||||
_mx(0.0f),_my(0.0f),_mbutton(0),
|
||||
_done(false)
|
||||
{}
|
||||
MyKeyboardMouseCallback() :
|
||||
Producer::KeyboardMouseCallback(),
|
||||
_mx(0.0f),_my(0.0f),_mbutton(0),
|
||||
_done(false)
|
||||
{}
|
||||
|
||||
virtual void specialKeyPress( Producer::KeyCharacter key )
|
||||
{
|
||||
if (key==Producer::KeyChar_Escape)
|
||||
virtual void specialKeyPress( Producer::KeyCharacter key )
|
||||
{
|
||||
if (key==Producer::KeyChar_Escape)
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void shutdown()
|
||||
{
|
||||
_done = true;
|
||||
}
|
||||
|
||||
virtual void keyPress( Producer::KeyCharacter )
|
||||
{
|
||||
}
|
||||
virtual void keyPress( Producer::KeyCharacter )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void mouseMotion( float mx, float my )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
}
|
||||
virtual void buttonPress( float mx, float my, unsigned int mbutton )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
_mbutton |= (1<<(mbutton-1));
|
||||
}
|
||||
virtual void buttonRelease( float mx, float my, unsigned int mbutton )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
_mbutton &= ~(1<<(mbutton-1));
|
||||
}
|
||||
virtual void mouseMotion( float mx, float my )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
}
|
||||
virtual void buttonPress( float mx, float my, unsigned int mbutton )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
_mbutton |= (1<<(mbutton-1));
|
||||
}
|
||||
virtual void buttonRelease( float mx, float my, unsigned int mbutton )
|
||||
{
|
||||
_mx = mx;
|
||||
_my = my;
|
||||
_mbutton &= ~(1<<(mbutton-1));
|
||||
}
|
||||
|
||||
bool done() { return _done; }
|
||||
float mx() { return _mx; }
|
||||
float my() { return _my; }
|
||||
unsigned int mbutton() { return _mbutton; }
|
||||
bool done() { return _done; }
|
||||
float mx() { return _mx; }
|
||||
float my() { return _my; }
|
||||
unsigned int mbutton() { return _mbutton; }
|
||||
|
||||
private:
|
||||
|
||||
float _mx, _my;
|
||||
unsigned int _mbutton;
|
||||
bool _done;
|
||||
float _mx, _my;
|
||||
unsigned int _mbutton;
|
||||
bool _done;
|
||||
};
|
||||
|
||||
int main( int argc, char **argv )
|
||||
@ -168,7 +168,7 @@ int main( int argc, char **argv )
|
||||
// call all node update callbacks and animations.
|
||||
cg.getSceneData()->accept(update);
|
||||
|
||||
tb->input( kbmcb->mx(), kbmcb->my(), kbmcb->mbutton() );
|
||||
tb->input( kbmcb->mx(), kbmcb->my(), kbmcb->mbutton() );
|
||||
|
||||
// update the main producer camera
|
||||
cg.setViewByMatrix(tb->getMatrix());
|
||||
|
@ -146,11 +146,11 @@ void Broadcaster::setHost( const char *hostname )
|
||||
struct hostent *h;
|
||||
if( (h = gethostbyname( hostname )) == 0L )
|
||||
{
|
||||
fprintf( stderr, "Broadcaster::setHost() - Cannot resolv an address for \"%s\".\n", hostname );
|
||||
_address = 0;
|
||||
fprintf( stderr, "Broadcaster::setHost() - Cannot resolv an address for \"%s\".\n", hostname );
|
||||
_address = 0;
|
||||
}
|
||||
else
|
||||
_address = *(( unsigned long *)h->h_addr);
|
||||
_address = *(( unsigned long *)h->h_addr);
|
||||
}
|
||||
|
||||
void Broadcaster::setPort( const short port )
|
||||
@ -170,8 +170,8 @@ void Broadcaster::sync( void )
|
||||
|
||||
if( _buffer == 0L )
|
||||
{
|
||||
fprintf( stderr, "Broadcaster::sync() - No buffer\n" );
|
||||
return;
|
||||
fprintf( stderr, "Broadcaster::sync() - No buffer\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined (WIN32) && !defined(__CYGWIN__)
|
||||
|
@ -100,8 +100,8 @@ void Receiver::sync( void )
|
||||
|
||||
if( _buffer == 0L )
|
||||
{
|
||||
fprintf( stderr, "Receiver::sync() - No buffer\n" );
|
||||
return;
|
||||
fprintf( stderr, "Receiver::sync() - No buffer\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__linux) || defined(__FreeBSD__) || defined( __APPLE__ )
|
||||
|
@ -4,252 +4,252 @@
|
||||
#define CURRENT_CLASS DepthPartitionNode
|
||||
CURRENT_CLASS::CURRENT_CLASS()
|
||||
{
|
||||
_distAccumulator = new DistanceAccumulator;
|
||||
init();
|
||||
_distAccumulator = new DistanceAccumulator;
|
||||
init();
|
||||
}
|
||||
|
||||
CURRENT_CLASS::CURRENT_CLASS(const CURRENT_CLASS& dpn, const osg::CopyOp& copyop)
|
||||
: Group(dpn, copyop),
|
||||
: Group(dpn, copyop),
|
||||
_active(dpn._active),
|
||||
_renderOrder(dpn._renderOrder),
|
||||
_clearColorBuffer(dpn._clearColorBuffer)
|
||||
_renderOrder(dpn._renderOrder),
|
||||
_clearColorBuffer(dpn._clearColorBuffer)
|
||||
{
|
||||
_distAccumulator = new DistanceAccumulator;
|
||||
_numCameras = 0;
|
||||
_distAccumulator = new DistanceAccumulator;
|
||||
_numCameras = 0;
|
||||
}
|
||||
|
||||
CURRENT_CLASS::~CURRENT_CLASS() {}
|
||||
|
||||
void CURRENT_CLASS::init()
|
||||
{
|
||||
_active = true;
|
||||
_numCameras = 0;
|
||||
setCullingActive(false);
|
||||
_renderOrder = osg::CameraNode::POST_RENDER;
|
||||
_clearColorBuffer = true;
|
||||
_active = true;
|
||||
_numCameras = 0;
|
||||
setCullingActive(false);
|
||||
_renderOrder = osg::CameraNode::POST_RENDER;
|
||||
_clearColorBuffer = true;
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::setActive(bool active)
|
||||
{
|
||||
if(_active == active) return;
|
||||
_active = active;
|
||||
if(_active == active) return;
|
||||
_active = active;
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::setClearColorBuffer(bool clear)
|
||||
{
|
||||
_clearColorBuffer = clear;
|
||||
_clearColorBuffer = clear;
|
||||
|
||||
// Update the render order for the first CameraNode if it exists
|
||||
if(!_cameraList.empty())
|
||||
{
|
||||
if(clear)
|
||||
_cameraList[0]->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
_cameraList[0]->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
// Update the render order for the first CameraNode if it exists
|
||||
if(!_cameraList.empty())
|
||||
{
|
||||
if(clear)
|
||||
_cameraList[0]->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
_cameraList[0]->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::setRenderOrder(osg::CameraNode::RenderOrder order)
|
||||
{
|
||||
_renderOrder = order;
|
||||
_renderOrder = order;
|
||||
|
||||
// Update the render order for existing CameraNodes
|
||||
unsigned int numCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < numCameras; i++)
|
||||
{
|
||||
_cameraList[i]->setRenderOrder(_renderOrder);
|
||||
}
|
||||
// Update the render order for existing CameraNodes
|
||||
unsigned int numCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < numCameras; i++)
|
||||
{
|
||||
_cameraList[i]->setRenderOrder(_renderOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::traverse(osg::NodeVisitor &nv)
|
||||
{
|
||||
// If the scene hasn't been defined then don't do anything
|
||||
unsigned int numChildren = _children.size();
|
||||
if(numChildren == 0) return;
|
||||
// If the scene hasn't been defined then don't do anything
|
||||
unsigned int numChildren = _children.size();
|
||||
if(numChildren == 0) return;
|
||||
|
||||
// If the node is not active then don't analyze it
|
||||
if(!_active)
|
||||
{
|
||||
// Traverse the graph as usual
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
// If the node is not active then don't analyze it
|
||||
if(!_active)
|
||||
{
|
||||
// Traverse the graph as usual
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the visitor is not a cull visitor, pass it directly onto the scene.
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
if(!cv)
|
||||
{
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
// If the visitor is not a cull visitor, pass it directly onto the scene.
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
if(!cv)
|
||||
{
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
// We are in the cull traversal, so first collect information on the
|
||||
// current modelview and projection matrices and viewport.
|
||||
osg::RefMatrix& modelview = cv->getModelViewMatrix();
|
||||
osg::RefMatrix& projection = cv->getProjectionMatrix();
|
||||
osg::Viewport* viewport = cv->getViewport();
|
||||
// We are in the cull traversal, so first collect information on the
|
||||
// current modelview and projection matrices and viewport.
|
||||
osg::RefMatrix& modelview = cv->getModelViewMatrix();
|
||||
osg::RefMatrix& projection = cv->getProjectionMatrix();
|
||||
osg::Viewport* viewport = cv->getViewport();
|
||||
|
||||
// Prepare for scene traversal.
|
||||
_distAccumulator->setMatrices(modelview, projection);
|
||||
_distAccumulator->setNearFarRatio(cv->getNearFarRatio());
|
||||
_distAccumulator->reset();
|
||||
// Prepare for scene traversal.
|
||||
_distAccumulator->setMatrices(modelview, projection);
|
||||
_distAccumulator->setNearFarRatio(cv->getNearFarRatio());
|
||||
_distAccumulator->reset();
|
||||
|
||||
// Step 1: Traverse the children, collecting the near/far distances.
|
||||
unsigned int i;
|
||||
for(i = 0; i < numChildren; i++)
|
||||
{
|
||||
_children[i]->accept(*(_distAccumulator.get()));
|
||||
}
|
||||
// Step 1: Traverse the children, collecting the near/far distances.
|
||||
unsigned int i;
|
||||
for(i = 0; i < numChildren; i++)
|
||||
{
|
||||
_children[i]->accept(*(_distAccumulator.get()));
|
||||
}
|
||||
|
||||
// Step 2: Compute the near and far distances for every CameraNode that
|
||||
// should be used to render the scene.
|
||||
_distAccumulator->computeCameraPairs();
|
||||
// Step 2: Compute the near and far distances for every CameraNode that
|
||||
// should be used to render the scene.
|
||||
_distAccumulator->computeCameraPairs();
|
||||
|
||||
// Step 3: Create the CameraNodes, and add them as children.
|
||||
DistanceAccumulator::PairList& camPairs = _distAccumulator->getCameraPairs();
|
||||
_numCameras = camPairs.size(); // Get the number of cameras
|
||||
// Step 3: Create the CameraNodes, and add them as children.
|
||||
DistanceAccumulator::PairList& camPairs = _distAccumulator->getCameraPairs();
|
||||
_numCameras = camPairs.size(); // Get the number of cameras
|
||||
|
||||
// Create the CameraNodes, and add them as children.
|
||||
if(_numCameras > 0)
|
||||
{
|
||||
osg::CameraNode *currCam;
|
||||
DistanceAccumulator::DistancePair currPair;
|
||||
// Create the CameraNodes, and add them as children.
|
||||
if(_numCameras > 0)
|
||||
{
|
||||
osg::CameraNode *currCam;
|
||||
DistanceAccumulator::DistancePair currPair;
|
||||
|
||||
for(i = 0; i < _numCameras; i++)
|
||||
{
|
||||
// Create the camera, and clamp it's projection matrix
|
||||
currPair = camPairs[i]; // (near,far) pair for current camera
|
||||
currCam = createOrReuseCamera(projection, currPair.first,
|
||||
currPair.second, i);
|
||||
for(i = 0; i < _numCameras; i++)
|
||||
{
|
||||
// Create the camera, and clamp it's projection matrix
|
||||
currPair = camPairs[i]; // (near,far) pair for current camera
|
||||
currCam = createOrReuseCamera(projection, currPair.first,
|
||||
currPair.second, i);
|
||||
|
||||
// Set the modelview matrix and viewport of the camera
|
||||
currCam->setViewMatrix(modelview);
|
||||
currCam->setViewport(viewport);
|
||||
// Set the modelview matrix and viewport of the camera
|
||||
currCam->setViewMatrix(modelview);
|
||||
currCam->setViewport(viewport);
|
||||
|
||||
// Redirect the CullVisitor to the current camera
|
||||
currCam->accept(nv);
|
||||
}
|
||||
// Redirect the CullVisitor to the current camera
|
||||
currCam->accept(nv);
|
||||
}
|
||||
|
||||
// Set the clear color for the first camera
|
||||
_cameraList[0]->setClearColor(cv->getRenderStage()->getClearColor());
|
||||
}
|
||||
// Set the clear color for the first camera
|
||||
_cameraList[0]->setClearColor(cv->getRenderStage()->getClearColor());
|
||||
}
|
||||
}
|
||||
|
||||
bool CURRENT_CLASS::addChild(osg::Node *child)
|
||||
{
|
||||
return insertChild(_children.size(), child);
|
||||
return insertChild(_children.size(), child);
|
||||
}
|
||||
|
||||
bool CURRENT_CLASS::insertChild(unsigned int index, osg::Node *child)
|
||||
{
|
||||
if(!Group::insertChild(index, child)) return false; // Insert child
|
||||
if(!Group::insertChild(index, child)) return false; // Insert child
|
||||
|
||||
// Insert child into each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < totalCameras; i++)
|
||||
{
|
||||
_cameraList[i]->insertChild(index, child);
|
||||
}
|
||||
return true;
|
||||
// Insert child into each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < totalCameras; i++)
|
||||
{
|
||||
_cameraList[i]->insertChild(index, child);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CURRENT_CLASS::removeChild(osg::Node *child)
|
||||
{
|
||||
return Group::removeChild(child);
|
||||
return Group::removeChild(child);
|
||||
}
|
||||
|
||||
bool CURRENT_CLASS::removeChild(unsigned int pos, unsigned int numRemove)
|
||||
{
|
||||
if(!Group::removeChild(pos, numRemove)) return false; // Remove child
|
||||
if(!Group::removeChild(pos, numRemove)) return false; // Remove child
|
||||
|
||||
// Remove child from each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < totalCameras; i++)
|
||||
{
|
||||
_cameraList[i]->removeChild(pos, numRemove);
|
||||
}
|
||||
return true;
|
||||
// Remove child from each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int i = 0; i < totalCameras; i++)
|
||||
{
|
||||
_cameraList[i]->removeChild(pos, numRemove);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CURRENT_CLASS::setChild(unsigned int i, osg::Node *node)
|
||||
{
|
||||
if(!Group::setChild(i, node)) return false; // Set child
|
||||
if(!Group::setChild(i, node)) return false; // Set child
|
||||
|
||||
// Set child for each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int j = 0; j < totalCameras; j++)
|
||||
{
|
||||
_cameraList[j]->setChild(i, node);
|
||||
}
|
||||
return true;
|
||||
// Set child for each CameraNode
|
||||
unsigned int totalCameras = _cameraList.size();
|
||||
for(unsigned int j = 0; j < totalCameras; j++)
|
||||
{
|
||||
_cameraList[j]->setChild(i, node);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::CameraNode* CURRENT_CLASS::createOrReuseCamera(const osg::Matrix& proj,
|
||||
double znear, double zfar,
|
||||
const unsigned int &camNum)
|
||||
{
|
||||
if(_cameraList.size() <= camNum) _cameraList.resize(camNum+1);
|
||||
osg::CameraNode *camera = _cameraList[camNum].get();
|
||||
|
||||
if(!camera) // Create a new CameraNode
|
||||
{
|
||||
camera = new osg::CameraNode;
|
||||
camera->setCullingActive(false);
|
||||
camera->setRenderOrder(_renderOrder);
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
if(_cameraList.size() <= camNum) _cameraList.resize(camNum+1);
|
||||
osg::CameraNode *camera = _cameraList[camNum].get();
|
||||
|
||||
if(!camera) // Create a new CameraNode
|
||||
{
|
||||
camera = new osg::CameraNode;
|
||||
camera->setCullingActive(false);
|
||||
camera->setRenderOrder(_renderOrder);
|
||||
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
|
||||
// We will compute the near/far planes ourselves
|
||||
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
camera->setCullingMode(osg::CullSettings::ENABLE_ALL_CULLING);
|
||||
// We will compute the near/far planes ourselves
|
||||
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
camera->setCullingMode(osg::CullSettings::ENABLE_ALL_CULLING);
|
||||
|
||||
if(camNum == 0 && _clearColorBuffer)
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
if(camNum == 0 && _clearColorBuffer)
|
||||
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
else
|
||||
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Add our children to the new CameraNode's children
|
||||
unsigned int numChildren = _children.size();
|
||||
for(unsigned int i = 0; i < numChildren; i++)
|
||||
{
|
||||
camera->addChild(_children[i].get());
|
||||
}
|
||||
// Add our children to the new CameraNode's children
|
||||
unsigned int numChildren = _children.size();
|
||||
for(unsigned int i = 0; i < numChildren; i++)
|
||||
{
|
||||
camera->addChild(_children[i].get());
|
||||
}
|
||||
|
||||
_cameraList[camNum] = camera;
|
||||
}
|
||||
_cameraList[camNum] = camera;
|
||||
}
|
||||
|
||||
osg::Matrixd &projection = camera->getProjectionMatrix();
|
||||
projection = proj;
|
||||
osg::Matrixd &projection = camera->getProjectionMatrix();
|
||||
projection = proj;
|
||||
|
||||
// Slightly inflate the near & far planes to avoid objects at the
|
||||
// extremes being clipped out.
|
||||
znear *= 0.999;
|
||||
zfar *= 1.001;
|
||||
// Slightly inflate the near & far planes to avoid objects at the
|
||||
// extremes being clipped out.
|
||||
znear *= 0.999;
|
||||
zfar *= 1.001;
|
||||
|
||||
// Clamp the projection matrix z values to the range (near, far)
|
||||
double epsilon = 1.0e-6;
|
||||
if(fabs(projection(0,3)) < epsilon &&
|
||||
fabs(projection(1,3)) < epsilon &&
|
||||
fabs(projection(2,3)) < epsilon ) // Projection is Orthographic
|
||||
{
|
||||
epsilon = -1.0/(zfar - znear); // Used as a temp variable
|
||||
projection(2,2) = 2.0*epsilon;
|
||||
projection(3,2) = (zfar + znear)*epsilon;
|
||||
}
|
||||
else // Projection is Perspective
|
||||
{
|
||||
double trans_near = (-znear*projection(2,2) + projection(3,2)) /
|
||||
(-znear*projection(2,3) + projection(3,3));
|
||||
double trans_far = (-zfar*projection(2,2) + projection(3,2)) /
|
||||
(-zfar*projection(2,3) + projection(3,3));
|
||||
double ratio = fabs(2.0/(trans_near - trans_far));
|
||||
double center = -0.5*(trans_near + trans_far);
|
||||
// Clamp the projection matrix z values to the range (near, far)
|
||||
double epsilon = 1.0e-6;
|
||||
if(fabs(projection(0,3)) < epsilon &&
|
||||
fabs(projection(1,3)) < epsilon &&
|
||||
fabs(projection(2,3)) < epsilon ) // Projection is Orthographic
|
||||
{
|
||||
epsilon = -1.0/(zfar - znear); // Used as a temp variable
|
||||
projection(2,2) = 2.0*epsilon;
|
||||
projection(3,2) = (zfar + znear)*epsilon;
|
||||
}
|
||||
else // Projection is Perspective
|
||||
{
|
||||
double trans_near = (-znear*projection(2,2) + projection(3,2)) /
|
||||
(-znear*projection(2,3) + projection(3,3));
|
||||
double trans_far = (-zfar*projection(2,2) + projection(3,2)) /
|
||||
(-zfar*projection(2,3) + projection(3,3));
|
||||
double ratio = fabs(2.0/(trans_near - trans_far));
|
||||
double center = -0.5*(trans_near + trans_far);
|
||||
|
||||
projection.postMult(osg::Matrixd(1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, ratio, 0.0,
|
||||
0.0, 0.0, center*ratio, 1.0));
|
||||
}
|
||||
projection.postMult(osg::Matrixd(1.0, 0.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0, 0.0,
|
||||
0.0, 0.0, ratio, 0.0,
|
||||
0.0, 0.0, center*ratio, 1.0));
|
||||
}
|
||||
|
||||
return camera;
|
||||
return camera;
|
||||
}
|
||||
#undef CURRENT_CLASS
|
||||
|
@ -10,66 +10,66 @@
|
||||
bool precedes(const DistanceAccumulator::DistancePair &a,
|
||||
const DistanceAccumulator::DistancePair &b)
|
||||
{
|
||||
// This results in sorting in order of descending far distances
|
||||
if(a.second > b.second) return true;
|
||||
else return false;
|
||||
// This results in sorting in order of descending far distances
|
||||
if(a.second > b.second) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/** Computes distance betwen a point and the viewpoint of a matrix */
|
||||
double distance(const osg::Vec3 &coord, const osg::Matrix& matrix)
|
||||
{
|
||||
return -( coord[0]*matrix(0,2) + coord[1]*matrix(1,2) +
|
||||
coord[2]*matrix(2,2) + matrix(3,2) );
|
||||
return -( coord[0]*matrix(0,2) + coord[1]*matrix(1,2) +
|
||||
coord[2]*matrix(2,2) + matrix(3,2) );
|
||||
}
|
||||
|
||||
#define CURRENT_CLASS DistanceAccumulator
|
||||
CURRENT_CLASS::CURRENT_CLASS()
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
|
||||
_nearFarRatio(0.0005), _maxDepth(UINT_MAX)
|
||||
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
|
||||
_nearFarRatio(0.0005), _maxDepth(UINT_MAX)
|
||||
{
|
||||
setMatrices(osg::Matrix::identity(), osg::Matrix::identity());
|
||||
reset();
|
||||
setMatrices(osg::Matrix::identity(), osg::Matrix::identity());
|
||||
reset();
|
||||
}
|
||||
|
||||
CURRENT_CLASS::~CURRENT_CLASS() {}
|
||||
|
||||
void CURRENT_CLASS::pushLocalFrustum()
|
||||
{
|
||||
osg::Matrix& currMatrix = _viewMatrices.back();
|
||||
osg::Matrix& currMatrix = _viewMatrices.back();
|
||||
|
||||
// Compute the frustum in local space
|
||||
osg::Polytope localFrustum;
|
||||
localFrustum.setToUnitFrustum(false, false);
|
||||
localFrustum.transformProvidingInverse(currMatrix*_projectionMatrices.back());
|
||||
_localFrusta.push_back(localFrustum);
|
||||
// Compute the frustum in local space
|
||||
osg::Polytope localFrustum;
|
||||
localFrustum.setToUnitFrustum(false, false);
|
||||
localFrustum.transformProvidingInverse(currMatrix*_projectionMatrices.back());
|
||||
_localFrusta.push_back(localFrustum);
|
||||
|
||||
// Compute new bounding box corners
|
||||
bbCornerPair corner;
|
||||
corner.second = (currMatrix(0,2)<=0?1:0) |
|
||||
(currMatrix(1,2)<=0?2:0) |
|
||||
(currMatrix(2,2)<=0?4:0);
|
||||
corner.first = (~corner.second)&7;
|
||||
_bbCorners.push_back(corner);
|
||||
// Compute new bounding box corners
|
||||
bbCornerPair corner;
|
||||
corner.second = (currMatrix(0,2)<=0?1:0) |
|
||||
(currMatrix(1,2)<=0?2:0) |
|
||||
(currMatrix(2,2)<=0?4:0);
|
||||
corner.first = (~corner.second)&7;
|
||||
_bbCorners.push_back(corner);
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::pushDistancePair(double zNear, double zFar)
|
||||
{
|
||||
if(zFar > 0.0) // Make sure some of drawable is visible
|
||||
{
|
||||
// Make sure near plane is in front of viewpoint.
|
||||
if(zNear <= 0.0)
|
||||
{
|
||||
zNear = zFar*_nearFarRatio;
|
||||
if(zNear >= 1.0) zNear = 1.0; // 1.0 limit chosen arbitrarily!
|
||||
}
|
||||
if(zFar > 0.0) // Make sure some of drawable is visible
|
||||
{
|
||||
// Make sure near plane is in front of viewpoint.
|
||||
if(zNear <= 0.0)
|
||||
{
|
||||
zNear = zFar*_nearFarRatio;
|
||||
if(zNear >= 1.0) zNear = 1.0; // 1.0 limit chosen arbitrarily!
|
||||
}
|
||||
|
||||
// Add distance pair for current drawable
|
||||
_distancePairs.push_back(DistancePair(zNear, zFar));
|
||||
// Add distance pair for current drawable
|
||||
_distancePairs.push_back(DistancePair(zNear, zFar));
|
||||
|
||||
// Override the current nearest/farthest planes if necessary
|
||||
if(zNear < _limits.first) _limits.first = zNear;
|
||||
if(zFar > _limits.second) _limits.second = zFar;
|
||||
}
|
||||
// Override the current nearest/farthest planes if necessary
|
||||
if(zNear < _limits.first) _limits.first = zNear;
|
||||
if(zFar > _limits.second) _limits.second = zFar;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return true if the node should be traversed, and false if the bounding sphere
|
||||
@ -77,265 +77,265 @@ void CURRENT_CLASS::pushDistancePair(double zNear, double zFar)
|
||||
is true, then store the node's near & far plane distances. */
|
||||
bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node)
|
||||
{
|
||||
// Allow traversal to continue if we haven't reached maximum depth.
|
||||
bool keepTraversing = (_currentDepth < _maxDepth);
|
||||
// Allow traversal to continue if we haven't reached maximum depth.
|
||||
bool keepTraversing = (_currentDepth < _maxDepth);
|
||||
|
||||
const osg::BoundingSphere &bs = node.getBound();
|
||||
double zNear = 0.0, zFar = 0.0;
|
||||
const osg::BoundingSphere &bs = node.getBound();
|
||||
double zNear = 0.0, zFar = 0.0;
|
||||
|
||||
// Make sure bounding sphere is valid and within viewing volume
|
||||
if(bs.valid())
|
||||
{
|
||||
if(!_localFrusta.back().contains(bs)) keepTraversing = false;
|
||||
else
|
||||
{
|
||||
// Compute near and far planes for this node
|
||||
zNear = distance(bs._center, _viewMatrices.back());
|
||||
zFar = zNear + bs._radius;
|
||||
zNear -= bs._radius;
|
||||
// Make sure bounding sphere is valid and within viewing volume
|
||||
if(bs.valid())
|
||||
{
|
||||
if(!_localFrusta.back().contains(bs)) keepTraversing = false;
|
||||
else
|
||||
{
|
||||
// Compute near and far planes for this node
|
||||
zNear = distance(bs._center, _viewMatrices.back());
|
||||
zFar = zNear + bs._radius;
|
||||
zNear -= bs._radius;
|
||||
|
||||
// If near/far ratio is big enough, then we don't need to keep
|
||||
// traversing children of this node.
|
||||
if(zNear >= zFar*_nearFarRatio) keepTraversing = false;
|
||||
}
|
||||
}
|
||||
// If near/far ratio is big enough, then we don't need to keep
|
||||
// traversing children of this node.
|
||||
if(zNear >= zFar*_nearFarRatio) keepTraversing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If traversal should stop, then store this node's (near,far) pair
|
||||
if(!keepTraversing) pushDistancePair(zNear, zFar);
|
||||
// If traversal should stop, then store this node's (near,far) pair
|
||||
if(!keepTraversing) pushDistancePair(zNear, zFar);
|
||||
|
||||
return keepTraversing;
|
||||
return keepTraversing;
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::apply(osg::Node &node)
|
||||
{
|
||||
if(shouldContinueTraversal(node))
|
||||
{
|
||||
// Traverse this node
|
||||
_currentDepth++;
|
||||
traverse(node);
|
||||
_currentDepth--;
|
||||
}
|
||||
if(shouldContinueTraversal(node))
|
||||
{
|
||||
// Traverse this node
|
||||
_currentDepth++;
|
||||
traverse(node);
|
||||
_currentDepth--;
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::apply(osg::Projection &proj)
|
||||
{
|
||||
if(shouldContinueTraversal(proj))
|
||||
{
|
||||
// Push the new projection matrix view frustum
|
||||
_projectionMatrices.push_back(proj.getMatrix());
|
||||
pushLocalFrustum();
|
||||
if(shouldContinueTraversal(proj))
|
||||
{
|
||||
// Push the new projection matrix view frustum
|
||||
_projectionMatrices.push_back(proj.getMatrix());
|
||||
pushLocalFrustum();
|
||||
|
||||
// Traverse the group
|
||||
_currentDepth++;
|
||||
traverse(proj);
|
||||
_currentDepth--;
|
||||
// Traverse the group
|
||||
_currentDepth++;
|
||||
traverse(proj);
|
||||
_currentDepth--;
|
||||
|
||||
// Reload original matrix and frustum
|
||||
_localFrusta.pop_back();
|
||||
_bbCorners.pop_back();
|
||||
_projectionMatrices.pop_back();
|
||||
}
|
||||
// Reload original matrix and frustum
|
||||
_localFrusta.pop_back();
|
||||
_bbCorners.pop_back();
|
||||
_projectionMatrices.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::apply(osg::Transform &transform)
|
||||
{
|
||||
if(shouldContinueTraversal(transform))
|
||||
{
|
||||
// Compute transform for current node
|
||||
osg::Matrix currMatrix = _viewMatrices.back();
|
||||
bool pushMatrix = transform.computeLocalToWorldMatrix(currMatrix, this);
|
||||
if(shouldContinueTraversal(transform))
|
||||
{
|
||||
// Compute transform for current node
|
||||
osg::Matrix currMatrix = _viewMatrices.back();
|
||||
bool pushMatrix = transform.computeLocalToWorldMatrix(currMatrix, this);
|
||||
|
||||
if(pushMatrix)
|
||||
{
|
||||
// Store the new modelview matrix and view frustum
|
||||
_viewMatrices.push_back(currMatrix);
|
||||
pushLocalFrustum();
|
||||
}
|
||||
if(pushMatrix)
|
||||
{
|
||||
// Store the new modelview matrix and view frustum
|
||||
_viewMatrices.push_back(currMatrix);
|
||||
pushLocalFrustum();
|
||||
}
|
||||
|
||||
_currentDepth++;
|
||||
traverse(transform);
|
||||
_currentDepth--;
|
||||
_currentDepth++;
|
||||
traverse(transform);
|
||||
_currentDepth--;
|
||||
|
||||
if(pushMatrix)
|
||||
{
|
||||
// Restore the old modelview matrix and view frustum
|
||||
_localFrusta.pop_back();
|
||||
_bbCorners.pop_back();
|
||||
_viewMatrices.pop_back();
|
||||
}
|
||||
}
|
||||
if(pushMatrix)
|
||||
{
|
||||
// Restore the old modelview matrix and view frustum
|
||||
_localFrusta.pop_back();
|
||||
_bbCorners.pop_back();
|
||||
_viewMatrices.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::apply(osg::Geode &geode)
|
||||
{
|
||||
// Contained drawables will only be individually considered if we are
|
||||
// allowed to continue traversing.
|
||||
if(shouldContinueTraversal(geode))
|
||||
{
|
||||
osg::Drawable *drawable;
|
||||
double zNear, zFar;
|
||||
// Contained drawables will only be individually considered if we are
|
||||
// allowed to continue traversing.
|
||||
if(shouldContinueTraversal(geode))
|
||||
{
|
||||
osg::Drawable *drawable;
|
||||
double zNear, zFar;
|
||||
|
||||
// Handle each drawable in this geode
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); i++)
|
||||
{
|
||||
drawable = geode.getDrawable(i);
|
||||
// Handle each drawable in this geode
|
||||
for(unsigned int i = 0; i < geode.getNumDrawables(); i++)
|
||||
{
|
||||
drawable = geode.getDrawable(i);
|
||||
|
||||
const osg::BoundingBox &bb = drawable->getBound();
|
||||
if(bb.valid())
|
||||
{
|
||||
// Make sure drawable will be visible in the scene
|
||||
if(!_localFrusta.back().contains(bb)) continue;
|
||||
const osg::BoundingBox &bb = drawable->getBound();
|
||||
if(bb.valid())
|
||||
{
|
||||
// Make sure drawable will be visible in the scene
|
||||
if(!_localFrusta.back().contains(bb)) continue;
|
||||
|
||||
// Compute near/far distances for current drawable
|
||||
zNear = distance(bb.corner(_bbCorners.back().first),
|
||||
// Compute near/far distances for current drawable
|
||||
zNear = distance(bb.corner(_bbCorners.back().first),
|
||||
_viewMatrices.back());
|
||||
zFar = distance(bb.corner(_bbCorners.back().second),
|
||||
_viewMatrices.back());
|
||||
if(zNear > zFar) std::swap(zNear, zFar);
|
||||
pushDistancePair(zNear, zFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
zFar = distance(bb.corner(_bbCorners.back().second),
|
||||
_viewMatrices.back());
|
||||
if(zNear > zFar) std::swap(zNear, zFar);
|
||||
pushDistancePair(zNear, zFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::setMatrices(const osg::Matrix &modelview,
|
||||
const osg::Matrix &projection)
|
||||
{
|
||||
_modelview = modelview;
|
||||
_projection = projection;
|
||||
_modelview = modelview;
|
||||
_projection = projection;
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::reset()
|
||||
{
|
||||
// Clear vectors & values
|
||||
_distancePairs.clear();
|
||||
_cameraPairs.clear();
|
||||
_limits.first = DBL_MAX;
|
||||
_limits.second = 0.0;
|
||||
_currentDepth = 0;
|
||||
// Clear vectors & values
|
||||
_distancePairs.clear();
|
||||
_cameraPairs.clear();
|
||||
_limits.first = DBL_MAX;
|
||||
_limits.second = 0.0;
|
||||
_currentDepth = 0;
|
||||
|
||||
// Initial transform matrix is the modelview matrix
|
||||
_viewMatrices.clear();
|
||||
_viewMatrices.push_back(_modelview);
|
||||
// Initial transform matrix is the modelview matrix
|
||||
_viewMatrices.clear();
|
||||
_viewMatrices.push_back(_modelview);
|
||||
|
||||
// Set the initial projection matrix
|
||||
_projectionMatrices.clear();
|
||||
_projectionMatrices.push_back(_projection);
|
||||
// Set the initial projection matrix
|
||||
_projectionMatrices.clear();
|
||||
_projectionMatrices.push_back(_projection);
|
||||
|
||||
// Create a frustum without near/far planes, for cull computations
|
||||
_localFrusta.clear();
|
||||
_bbCorners.clear();
|
||||
pushLocalFrustum();
|
||||
// Create a frustum without near/far planes, for cull computations
|
||||
_localFrusta.clear();
|
||||
_bbCorners.clear();
|
||||
pushLocalFrustum();
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::computeCameraPairs()
|
||||
{
|
||||
// Nothing in the scene, so no cameras needed
|
||||
if(_distancePairs.empty()) return;
|
||||
// Nothing in the scene, so no cameras needed
|
||||
if(_distancePairs.empty()) return;
|
||||
|
||||
// Entire scene can be handled by just one camera
|
||||
if(_limits.first >= _limits.second*_nearFarRatio)
|
||||
{
|
||||
_cameraPairs.push_back(_limits);
|
||||
return;
|
||||
}
|
||||
// Entire scene can be handled by just one camera
|
||||
if(_limits.first >= _limits.second*_nearFarRatio)
|
||||
{
|
||||
_cameraPairs.push_back(_limits);
|
||||
return;
|
||||
}
|
||||
|
||||
PairList::iterator i,j;
|
||||
PairList::iterator i,j;
|
||||
|
||||
// Sort the list of distance pairs by descending far distance
|
||||
std::sort(_distancePairs.begin(), _distancePairs.end(), precedes);
|
||||
// Sort the list of distance pairs by descending far distance
|
||||
std::sort(_distancePairs.begin(), _distancePairs.end(), precedes);
|
||||
|
||||
// Combine overlapping distance pairs. The resulting set of distance
|
||||
// pairs (called combined pairs) will not overlap.
|
||||
PairList combinedPairs;
|
||||
DistancePair currPair = _distancePairs.front();
|
||||
for(i = _distancePairs.begin(); i != _distancePairs.end(); i++)
|
||||
{
|
||||
// Current distance pair does not overlap current combined pair, so
|
||||
// save the current combined pair and start a new one.
|
||||
if(i->second < 0.99*currPair.first)
|
||||
{
|
||||
combinedPairs.push_back(currPair);
|
||||
currPair = *i;
|
||||
}
|
||||
// Combine overlapping distance pairs. The resulting set of distance
|
||||
// pairs (called combined pairs) will not overlap.
|
||||
PairList combinedPairs;
|
||||
DistancePair currPair = _distancePairs.front();
|
||||
for(i = _distancePairs.begin(); i != _distancePairs.end(); i++)
|
||||
{
|
||||
// Current distance pair does not overlap current combined pair, so
|
||||
// save the current combined pair and start a new one.
|
||||
if(i->second < 0.99*currPair.first)
|
||||
{
|
||||
combinedPairs.push_back(currPair);
|
||||
currPair = *i;
|
||||
}
|
||||
|
||||
// Current distance pair overlaps current combined pair, so expand
|
||||
// current combined pair to encompass distance pair.
|
||||
else
|
||||
currPair.first = std::min(i->first, currPair.first);
|
||||
}
|
||||
combinedPairs.push_back(currPair); // Add last pair
|
||||
// Current distance pair overlaps current combined pair, so expand
|
||||
// current combined pair to encompass distance pair.
|
||||
else
|
||||
currPair.first = std::min(i->first, currPair.first);
|
||||
}
|
||||
combinedPairs.push_back(currPair); // Add last pair
|
||||
|
||||
// Compute the (near,far) distance pairs for each camera.
|
||||
// Each of these distance pairs is called a "view segment".
|
||||
double currNearLimit, numSegs, new_ratio;
|
||||
double ratio_invlog = 1.0/log(_nearFarRatio);
|
||||
unsigned int temp;
|
||||
for(i = combinedPairs.begin(); i != combinedPairs.end(); i++)
|
||||
{
|
||||
currPair = *i; // Save current view segment
|
||||
// Compute the (near,far) distance pairs for each camera.
|
||||
// Each of these distance pairs is called a "view segment".
|
||||
double currNearLimit, numSegs, new_ratio;
|
||||
double ratio_invlog = 1.0/log(_nearFarRatio);
|
||||
unsigned int temp;
|
||||
for(i = combinedPairs.begin(); i != combinedPairs.end(); i++)
|
||||
{
|
||||
currPair = *i; // Save current view segment
|
||||
|
||||
// Compute the fractional number of view segments needed to span
|
||||
// the current combined distance pair.
|
||||
currNearLimit = currPair.second*_nearFarRatio;
|
||||
if(currPair.first >= currNearLimit) numSegs = 1.0;
|
||||
else
|
||||
{
|
||||
numSegs = log(currPair.first/currPair.second)*ratio_invlog;
|
||||
// Compute the fractional number of view segments needed to span
|
||||
// the current combined distance pair.
|
||||
currNearLimit = currPair.second*_nearFarRatio;
|
||||
if(currPair.first >= currNearLimit) numSegs = 1.0;
|
||||
else
|
||||
{
|
||||
numSegs = log(currPair.first/currPair.second)*ratio_invlog;
|
||||
|
||||
// Compute the near plane of the last view segment
|
||||
//currNearLimit *= pow(_nearFarRatio, -floor(-numSegs) - 1);
|
||||
for(temp = (unsigned int)(-floor(-numSegs)); temp > 1; temp--)
|
||||
{
|
||||
currNearLimit *= _nearFarRatio;
|
||||
}
|
||||
}
|
||||
// Compute the near plane of the last view segment
|
||||
//currNearLimit *= pow(_nearFarRatio, -floor(-numSegs) - 1);
|
||||
for(temp = (unsigned int)(-floor(-numSegs)); temp > 1; temp--)
|
||||
{
|
||||
currNearLimit *= _nearFarRatio;
|
||||
}
|
||||
}
|
||||
|
||||
// See if the closest view segment can absorb other combined pairs
|
||||
for(j = i+1; j != combinedPairs.end(); j++)
|
||||
{
|
||||
// No other distance pairs can be included
|
||||
if(j->first < currNearLimit) break;
|
||||
}
|
||||
// See if the closest view segment can absorb other combined pairs
|
||||
for(j = i+1; j != combinedPairs.end(); j++)
|
||||
{
|
||||
// No other distance pairs can be included
|
||||
if(j->first < currNearLimit) break;
|
||||
}
|
||||
|
||||
// If we did absorb another combined distance pair, recompute the
|
||||
// number of required view segments.
|
||||
if(i != j-1)
|
||||
{
|
||||
i = j-1;
|
||||
currPair.first = i->first;
|
||||
if(currPair.first >= currPair.second*_nearFarRatio) numSegs = 1.0;
|
||||
else numSegs = log(currPair.first/currPair.second)*ratio_invlog;
|
||||
}
|
||||
// If we did absorb another combined distance pair, recompute the
|
||||
// number of required view segments.
|
||||
if(i != j-1)
|
||||
{
|
||||
i = j-1;
|
||||
currPair.first = i->first;
|
||||
if(currPair.first >= currPair.second*_nearFarRatio) numSegs = 1.0;
|
||||
else numSegs = log(currPair.first/currPair.second)*ratio_invlog;
|
||||
}
|
||||
|
||||
/* Compute an integer number of segments by rounding the fractional
|
||||
number of segments according to how many segments there are.
|
||||
In general, the more segments there are, the more likely that the
|
||||
integer number of segments will be rounded down.
|
||||
The purpose of this is to try to minimize the number of view segments
|
||||
that are used to render any section of the scene without violating
|
||||
the specified _nearFarRatio by too much. */
|
||||
if(numSegs < 10.0) numSegs = floor(numSegs + 1.0 - 0.1*floor(numSegs));
|
||||
else numSegs = floor(numSegs);
|
||||
/* Compute an integer number of segments by rounding the fractional
|
||||
number of segments according to how many segments there are.
|
||||
In general, the more segments there are, the more likely that the
|
||||
integer number of segments will be rounded down.
|
||||
The purpose of this is to try to minimize the number of view segments
|
||||
that are used to render any section of the scene without violating
|
||||
the specified _nearFarRatio by too much. */
|
||||
if(numSegs < 10.0) numSegs = floor(numSegs + 1.0 - 0.1*floor(numSegs));
|
||||
else numSegs = floor(numSegs);
|
||||
|
||||
|
||||
// Compute the near/far ratio that will be used for each view segment
|
||||
// in this section of the scene.
|
||||
new_ratio = pow(currPair.first/currPair.second, 1.0/numSegs);
|
||||
// Compute the near/far ratio that will be used for each view segment
|
||||
// in this section of the scene.
|
||||
new_ratio = pow(currPair.first/currPair.second, 1.0/numSegs);
|
||||
|
||||
// Add numSegs new view segments to the camera pairs list
|
||||
for(temp = (unsigned int)numSegs; temp > 0; temp--)
|
||||
{
|
||||
currPair.first = currPair.second*new_ratio;
|
||||
_cameraPairs.push_back(currPair);
|
||||
currPair.second = currPair.first;
|
||||
}
|
||||
}
|
||||
// Add numSegs new view segments to the camera pairs list
|
||||
for(temp = (unsigned int)numSegs; temp > 0; temp--)
|
||||
{
|
||||
currPair.first = currPair.second*new_ratio;
|
||||
_cameraPairs.push_back(currPair);
|
||||
currPair.second = currPair.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CURRENT_CLASS::setNearFarRatio(double ratio)
|
||||
{
|
||||
if(ratio <= 0.0 || ratio >= 1.0) return;
|
||||
_nearFarRatio = ratio;
|
||||
if(ratio <= 0.0 || ratio >= 1.0) return;
|
||||
_nearFarRatio = ratio;
|
||||
}
|
||||
#undef CURRENT_CLASS
|
||||
|
@ -23,38 +23,38 @@ const double AU = 149697900.0;
|
||||
|
||||
osg::Node* createScene()
|
||||
{
|
||||
// Create the Earth, in blue
|
||||
osg::ShapeDrawable *earth_sd = new osg::ShapeDrawable;
|
||||
osg::Sphere* earth_sphere = new osg::Sphere;
|
||||
earth_sphere->setRadius(r_earth);
|
||||
earth_sd->setShape(earth_sphere);
|
||||
earth_sd->setColor(osg::Vec4(0, 0, 1.0, 1.0));
|
||||
// Create the Earth, in blue
|
||||
osg::ShapeDrawable *earth_sd = new osg::ShapeDrawable;
|
||||
osg::Sphere* earth_sphere = new osg::Sphere;
|
||||
earth_sphere->setRadius(r_earth);
|
||||
earth_sd->setShape(earth_sphere);
|
||||
earth_sd->setColor(osg::Vec4(0, 0, 1.0, 1.0));
|
||||
|
||||
osg::Geode* earth = new osg::Geode;
|
||||
earth->setName("earth");
|
||||
earth->addDrawable(earth_sd);
|
||||
osg::Geode* earth = new osg::Geode;
|
||||
earth->setName("earth");
|
||||
earth->addDrawable(earth_sd);
|
||||
|
||||
// Create the Sun, in yellow
|
||||
osg::ShapeDrawable *sun_sd = new osg::ShapeDrawable;
|
||||
osg::Sphere* sun_sphere = new osg::Sphere;
|
||||
sun_sphere->setRadius(r_sun);
|
||||
sun_sd->setShape(sun_sphere);
|
||||
sun_sd->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));
|
||||
// Create the Sun, in yellow
|
||||
osg::ShapeDrawable *sun_sd = new osg::ShapeDrawable;
|
||||
osg::Sphere* sun_sphere = new osg::Sphere;
|
||||
sun_sphere->setRadius(r_sun);
|
||||
sun_sd->setShape(sun_sphere);
|
||||
sun_sd->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));
|
||||
|
||||
osg::Geode* sun = new osg::Geode;
|
||||
sun->setName("sun");
|
||||
sun->addDrawable(sun_sd);
|
||||
osg::Geode* sun = new osg::Geode;
|
||||
sun->setName("sun");
|
||||
sun->addDrawable(sun_sd);
|
||||
|
||||
// Move the sun behind the earth
|
||||
osg::PositionAttitudeTransform *pat = new osg::PositionAttitudeTransform;
|
||||
pat->setPosition(osg::Vec3d(0.0, AU, 0.0));
|
||||
// Move the sun behind the earth
|
||||
osg::PositionAttitudeTransform *pat = new osg::PositionAttitudeTransform;
|
||||
pat->setPosition(osg::Vec3d(0.0, AU, 0.0));
|
||||
|
||||
osg::Group* scene = new osg::Group;
|
||||
scene->addChild(earth);
|
||||
scene->addChild(pat);
|
||||
pat->addChild(sun);
|
||||
osg::Group* scene = new osg::Group;
|
||||
scene->addChild(earth);
|
||||
scene->addChild(pat);
|
||||
pat->addChild(sun);
|
||||
|
||||
return scene;
|
||||
return scene;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
|
@ -101,7 +101,7 @@ ref_ptr<MatrixTransform> _create_lights()
|
||||
light_0->setSpotCutoff(60.0f);
|
||||
light_0->setSpotExponent(2.0f);
|
||||
|
||||
ref_ptr<LightSource> light_source_0 = new LightSource;
|
||||
ref_ptr<LightSource> light_source_0 = new LightSource;
|
||||
light_source_0->setLight(light_0.get());
|
||||
light_source_0->setLocalStateSetModes(StateAttribute::ON);
|
||||
transform_0->setUpdateCallback(new LightTransformCallback(inDegrees(90.0f), 8, 5));
|
||||
|
@ -357,9 +357,9 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
|
||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
geode->setStateSet( stateset );
|
||||
@ -374,11 +374,11 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
|
||||
float max_z = -FLT_MAX;
|
||||
for(r=0;r<numRows;++r)
|
||||
{
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
|
||||
max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
|
||||
max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
|
||||
}
|
||||
}
|
||||
|
||||
float scale_z = size.z()/(max_z-min_z);
|
||||
@ -396,10 +396,10 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
|
||||
|
||||
for(r=0;r<numRows;++r)
|
||||
{
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
grid->setHeight(c,r,(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
grid->setHeight(c,r,(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
}
|
||||
}
|
||||
|
||||
geode->addDrawable(new osg::ShapeDrawable(grid));
|
||||
@ -427,14 +427,14 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
|
||||
{
|
||||
pos.x() = origin.x();
|
||||
tex.x() = 0.0f;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
t[vi].set(tex.x(),tex.y());
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
t[vi].set(tex.x(),tex.y());
|
||||
pos.x()+=columnCoordDelta;
|
||||
tex.x()+=columnTexDelta;
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
pos.y() += rowCoordDelta;
|
||||
tex.y() += rowTexDelta;
|
||||
}
|
||||
@ -449,11 +449,11 @@ osg::Geode* ForestTechniqueManager::createTerrain(const osg::Vec3& origin, const
|
||||
osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
|
||||
geometry->addPrimitiveSet(&drawElements);
|
||||
int ei=0;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
}
|
||||
|
||||
geode->addDrawable(geometry);
|
||||
|
@ -28,18 +28,18 @@
|
||||
|
||||
class RotateCallback: public osg::NodeCallback {
|
||||
public:
|
||||
RotateCallback(): osg::NodeCallback(), enabled_(true) {}
|
||||
void operator()(osg::Node* node, osg::NodeVisitor *nv)
|
||||
{
|
||||
osg::MatrixTransform *xform = dynamic_cast<osg::MatrixTransform *>(node);
|
||||
if (xform && enabled_) {
|
||||
double t = nv->getFrameStamp()->getReferenceTime();
|
||||
xform->setMatrix(osg::Matrix::rotate(t, osg::Vec3(0, 0, 1)));
|
||||
}
|
||||
traverse(node, nv);
|
||||
}
|
||||
RotateCallback(): osg::NodeCallback(), enabled_(true) {}
|
||||
void operator()(osg::Node* node, osg::NodeVisitor *nv)
|
||||
{
|
||||
osg::MatrixTransform *xform = dynamic_cast<osg::MatrixTransform *>(node);
|
||||
if (xform && enabled_) {
|
||||
double t = nv->getFrameStamp()->getReferenceTime();
|
||||
xform->setMatrix(osg::Matrix::rotate(t, osg::Vec3(0, 0, 1)));
|
||||
}
|
||||
traverse(node, nv);
|
||||
}
|
||||
|
||||
bool enabled_;
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
|
||||
@ -51,223 +51,223 @@ RotateCallback *rotate_cb;
|
||||
class EffectPanel: public osgfxbrowser::Frame {
|
||||
public:
|
||||
|
||||
class KeyboardHandler: public osgGA::GUIEventHandler {
|
||||
public:
|
||||
KeyboardHandler(EffectPanel* ep): ep_(ep) {}
|
||||
class KeyboardHandler: public osgGA::GUIEventHandler {
|
||||
public:
|
||||
KeyboardHandler(EffectPanel* ep): ep_(ep) {}
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &)
|
||||
{
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right) {
|
||||
ep_->setEffectIndex(ep_->getEffectIndex()+1);
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) {
|
||||
ep_->setEffectIndex(ep_->getEffectIndex()-1);
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Return) {
|
||||
ep_->setNodeMask(0xffffffff - ep_->getNodeMask());
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Delete) {
|
||||
ep_->setEffectsEnabled(!ep_->getEffectsEnabled());
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == 'x') {
|
||||
osgDB::writeNodeFile(*ep_->getRoot(), "osgfx_model.osg");
|
||||
std::cout << "written nodes to \"osgfx_model.osg\"\n";
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == 'r') {
|
||||
rotate_cb->enabled_ = !rotate_cb->enabled_;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &)
|
||||
{
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right) {
|
||||
ep_->setEffectIndex(ep_->getEffectIndex()+1);
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) {
|
||||
ep_->setEffectIndex(ep_->getEffectIndex()-1);
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Return) {
|
||||
ep_->setNodeMask(0xffffffff - ep_->getNodeMask());
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Delete) {
|
||||
ep_->setEffectsEnabled(!ep_->getEffectsEnabled());
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == 'x') {
|
||||
osgDB::writeNodeFile(*ep_->getRoot(), "osgfx_model.osg");
|
||||
std::cout << "written nodes to \"osgfx_model.osg\"\n";
|
||||
return true;
|
||||
}
|
||||
if (ea.getKey() == 'r') {
|
||||
rotate_cb->enabled_ = !rotate_cb->enabled_;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<EffectPanel> ep_;
|
||||
};
|
||||
private:
|
||||
osg::ref_ptr<EffectPanel> ep_;
|
||||
};
|
||||
|
||||
EffectPanel()
|
||||
: osgfxbrowser::Frame(),
|
||||
_selected_fx(-1),
|
||||
_fxen(true),
|
||||
_root(new osg::Group),
|
||||
_hints_color(0.75f, 0.75f, 0.75f, 1.0f),
|
||||
_name_color(1, 1, 1, 1),
|
||||
_desc_color(1, 1, 0.7f, 1)
|
||||
{
|
||||
setBackgroundColor(osg::Vec4(0.3f, 0.1f, 0.15f, 0.75f));
|
||||
EffectPanel()
|
||||
: osgfxbrowser::Frame(),
|
||||
_selected_fx(-1),
|
||||
_fxen(true),
|
||||
_root(new osg::Group),
|
||||
_hints_color(0.75f, 0.75f, 0.75f, 1.0f),
|
||||
_name_color(1, 1, 1, 1),
|
||||
_desc_color(1, 1, 0.7f, 1)
|
||||
{
|
||||
setBackgroundColor(osg::Vec4(0.3f, 0.1f, 0.15f, 0.75f));
|
||||
|
||||
std::cout << "INFO: available osgFX effects:\n";
|
||||
osgFX::Registry::EffectMap emap = osgFX::Registry::instance()->getEffectMap();
|
||||
for (osgFX::Registry::EffectMap::const_iterator i=emap.begin(); i!=emap.end(); ++i) {
|
||||
std::cout << "INFO: \t" << i->first << "\n";
|
||||
osg::ref_ptr<osgFX::Effect> effect = static_cast<osgFX::Effect *>(i->second->cloneType());
|
||||
_effects.push_back(effect.get());
|
||||
}
|
||||
std::cout << "INFO: available osgFX effects:\n";
|
||||
osgFX::Registry::EffectMap emap = osgFX::Registry::instance()->getEffectMap();
|
||||
for (osgFX::Registry::EffectMap::const_iterator i=emap.begin(); i!=emap.end(); ++i) {
|
||||
std::cout << "INFO: \t" << i->first << "\n";
|
||||
osg::ref_ptr<osgFX::Effect> effect = static_cast<osgFX::Effect *>(i->second->cloneType());
|
||||
_effects.push_back(effect.get());
|
||||
}
|
||||
|
||||
std::cout << "INFO: " << emap.size() << " effect(s) ready.\n";
|
||||
std::cout << "INFO: " << emap.size() << " effect(s) ready.\n";
|
||||
|
||||
if (!_effects.empty()) {
|
||||
_selected_fx = 0;
|
||||
}
|
||||
}
|
||||
if (!_effects.empty()) {
|
||||
_selected_fx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline osg::Group* getRoot() { return _root.get(); }
|
||||
inline void setRoot(osg::Group* node) { _root = node; }
|
||||
inline osg::Group* getRoot() { return _root.get(); }
|
||||
inline void setRoot(osg::Group* node) { _root = node; }
|
||||
|
||||
inline osg::Node* getScene() { return _scene.get(); }
|
||||
inline void setScene(osg::Node* node) { _scene = node; }
|
||||
inline osg::Node* getScene() { return _scene.get(); }
|
||||
inline void setScene(osg::Node* node) { _scene = node; }
|
||||
|
||||
inline bool getEffectsEnabled() const { return _fxen; }
|
||||
inline void setEffectsEnabled(bool v)
|
||||
{
|
||||
_fxen = v;
|
||||
if (getSelectedEffect()) {
|
||||
getSelectedEffect()->setEnabled(_fxen);
|
||||
}
|
||||
}
|
||||
inline bool getEffectsEnabled() const { return _fxen; }
|
||||
inline void setEffectsEnabled(bool v)
|
||||
{
|
||||
_fxen = v;
|
||||
if (getSelectedEffect()) {
|
||||
getSelectedEffect()->setEnabled(_fxen);
|
||||
}
|
||||
}
|
||||
|
||||
inline int getEffectIndex() const { return _selected_fx; }
|
||||
inline void setEffectIndex(int i)
|
||||
{
|
||||
if (i >= static_cast<int>(_effects.size())) i = 0;
|
||||
if (i < 0) i = static_cast<int>(_effects.size()-1);
|
||||
_selected_fx = i;
|
||||
rebuild();
|
||||
}
|
||||
inline int getEffectIndex() const { return _selected_fx; }
|
||||
inline void setEffectIndex(int i)
|
||||
{
|
||||
if (i >= static_cast<int>(_effects.size())) i = 0;
|
||||
if (i < 0) i = static_cast<int>(_effects.size()-1);
|
||||
_selected_fx = i;
|
||||
rebuild();
|
||||
}
|
||||
|
||||
inline osgFX::Effect *getSelectedEffect()
|
||||
{
|
||||
if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) {
|
||||
return _effects[_selected_fx].get();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline osgFX::Effect *getSelectedEffect()
|
||||
{
|
||||
if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) {
|
||||
return _effects[_selected_fx].get();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
void rebuild_client_area(const osgfxbrowser::Rect &client_rect)
|
||||
{
|
||||
void rebuild_client_area(const osgfxbrowser::Rect &client_rect)
|
||||
{
|
||||
float zPos = -0.1; // note from Robert, was 0.1f, but now must be -0.1f to keep text visible??#!? due
|
||||
// to some other change in the OSG not tracked down yet...
|
||||
|
||||
osg::ref_ptr<osgText::Font> arial = osgText::readFontFile("fonts/arial.ttf");
|
||||
osg::ref_ptr<osgText::Font> arial = osgText::readFontFile("fonts/arial.ttf");
|
||||
|
||||
osg::ref_ptr<osgText::Text> hints = new osgText::Text;
|
||||
hints->setFont(arial.get());
|
||||
hints->setColor(_hints_color);
|
||||
hints->setAlignment(osgText::Text::CENTER_BOTTOM);
|
||||
hints->setCharacterSize(13);
|
||||
hints->setFontResolution(13, 13);
|
||||
hints->setPosition(osg::Vec3((client_rect.x0+client_rect.x1)/2, client_rect.y0 + 4, zPos));
|
||||
hints->setText("<RETURN> show/hide this panel <LEFT> previous effect <RIGHT> next effect <DEL> enable/disable effects 'x' save to file 'r' rotate/stop");
|
||||
addDrawable(hints.get());
|
||||
osg::ref_ptr<osgText::Text> hints = new osgText::Text;
|
||||
hints->setFont(arial.get());
|
||||
hints->setColor(_hints_color);
|
||||
hints->setAlignment(osgText::Text::CENTER_BOTTOM);
|
||||
hints->setCharacterSize(13);
|
||||
hints->setFontResolution(13, 13);
|
||||
hints->setPosition(osg::Vec3((client_rect.x0+client_rect.x1)/2, client_rect.y0 + 4, zPos));
|
||||
hints->setText("<RETURN> show/hide this panel <LEFT> previous effect <RIGHT> next effect <DEL> enable/disable effects 'x' save to file 'r' rotate/stop");
|
||||
addDrawable(hints.get());
|
||||
|
||||
std::string effect_name = "No Effect Selected";
|
||||
std::string effect_description = "";
|
||||
std::string effect_name = "No Effect Selected";
|
||||
std::string effect_description = "";
|
||||
|
||||
if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) {
|
||||
effect_name = _effects[_selected_fx]->effectName();
|
||||
std::string author_name = _effects[_selected_fx]->effectAuthor();
|
||||
if (!author_name.empty()) {
|
||||
effect_description = author_name = "AUTHOR: " + std::string(_effects[_selected_fx]->effectAuthor()) + std::string("\n\n");
|
||||
}
|
||||
effect_description += "DESCRIPTION:\n" + std::string(_effects[_selected_fx]->effectDescription());
|
||||
if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) {
|
||||
effect_name = _effects[_selected_fx]->effectName();
|
||||
std::string author_name = _effects[_selected_fx]->effectAuthor();
|
||||
if (!author_name.empty()) {
|
||||
effect_description = author_name = "AUTHOR: " + std::string(_effects[_selected_fx]->effectAuthor()) + std::string("\n\n");
|
||||
}
|
||||
effect_description += "DESCRIPTION:\n" + std::string(_effects[_selected_fx]->effectDescription());
|
||||
|
||||
if (_scene.valid() && _root.valid()) {
|
||||
_root->removeChild(0, _root->getNumChildren());
|
||||
osg::ref_ptr<osgFX::Effect> effect = _effects[_selected_fx].get();
|
||||
effect->setEnabled(_fxen);
|
||||
effect->removeChild(0, effect->getNumChildren());
|
||||
effect->addChild(_scene.get());
|
||||
effect->setUpDemo();
|
||||
_root->addChild(effect.get());
|
||||
}
|
||||
}
|
||||
if (_scene.valid() && _root.valid()) {
|
||||
_root->removeChild(0, _root->getNumChildren());
|
||||
osg::ref_ptr<osgFX::Effect> effect = _effects[_selected_fx].get();
|
||||
effect->setEnabled(_fxen);
|
||||
effect->removeChild(0, effect->getNumChildren());
|
||||
effect->addChild(_scene.get());
|
||||
effect->setUpDemo();
|
||||
_root->addChild(effect.get());
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgText::Text> ename = new osgText::Text;
|
||||
ename->setFont(arial.get());
|
||||
ename->setColor(_name_color);
|
||||
ename->setAlignment(osgText::Text::CENTER_TOP);
|
||||
ename->setCharacterSize(32);
|
||||
ename->setFontResolution(32, 32);
|
||||
ename->setPosition(osg::Vec3((client_rect.x0 + client_rect.x1) / 2, client_rect.y1 - 22, zPos));
|
||||
ename->setText(effect_name);
|
||||
addDrawable(ename.get());
|
||||
osg::ref_ptr<osgText::Text> ename = new osgText::Text;
|
||||
ename->setFont(arial.get());
|
||||
ename->setColor(_name_color);
|
||||
ename->setAlignment(osgText::Text::CENTER_TOP);
|
||||
ename->setCharacterSize(32);
|
||||
ename->setFontResolution(32, 32);
|
||||
ename->setPosition(osg::Vec3((client_rect.x0 + client_rect.x1) / 2, client_rect.y1 - 22, zPos));
|
||||
ename->setText(effect_name);
|
||||
addDrawable(ename.get());
|
||||
|
||||
osg::ref_ptr<osgText::Text> edesc = new osgText::Text;
|
||||
edesc->setMaximumWidth(client_rect.width() - 16);
|
||||
edesc->setFont(arial.get());
|
||||
edesc->setColor(_desc_color);
|
||||
edesc->setAlignment(osgText::Text::LEFT_TOP);
|
||||
edesc->setCharacterSize(16);
|
||||
edesc->setFontResolution(16, 16);
|
||||
edesc->setPosition(osg::Vec3(client_rect.x0 + 8, client_rect.y1 - 60, zPos));
|
||||
edesc->setText(effect_description);
|
||||
addDrawable(edesc.get());
|
||||
}
|
||||
osg::ref_ptr<osgText::Text> edesc = new osgText::Text;
|
||||
edesc->setMaximumWidth(client_rect.width() - 16);
|
||||
edesc->setFont(arial.get());
|
||||
edesc->setColor(_desc_color);
|
||||
edesc->setAlignment(osgText::Text::LEFT_TOP);
|
||||
edesc->setCharacterSize(16);
|
||||
edesc->setFontResolution(16, 16);
|
||||
edesc->setPosition(osg::Vec3(client_rect.x0 + 8, client_rect.y1 - 60, zPos));
|
||||
edesc->setText(effect_description);
|
||||
addDrawable(edesc.get());
|
||||
}
|
||||
|
||||
private:
|
||||
int _selected_fx;
|
||||
typedef std::vector<osg::ref_ptr<osgFX::Effect> > Effect_list;
|
||||
Effect_list _effects;
|
||||
bool _fxen;
|
||||
osg::ref_ptr<osg::Group> _root;
|
||||
osg::ref_ptr<osg::Node> _scene;
|
||||
osg::Vec4 _hints_color;
|
||||
osg::Vec4 _name_color;
|
||||
osg::Vec4 _desc_color;
|
||||
int _selected_fx;
|
||||
typedef std::vector<osg::ref_ptr<osgFX::Effect> > Effect_list;
|
||||
Effect_list _effects;
|
||||
bool _fxen;
|
||||
osg::ref_ptr<osg::Group> _root;
|
||||
osg::ref_ptr<osg::Node> _scene;
|
||||
osg::Vec4 _hints_color;
|
||||
osg::Vec4 _name_color;
|
||||
osg::Vec4 _desc_color;
|
||||
};
|
||||
|
||||
|
||||
osg::Group* build_hud_base(osg::Group* root)
|
||||
{
|
||||
osg::ref_ptr<osg::Projection> proj = new osg::Projection(osg::Matrix::ortho2D(0, 1024, 0, 768));
|
||||
proj->setCullingActive(false);
|
||||
root->addChild(proj.get());
|
||||
osg::ref_ptr<osg::Projection> proj = new osg::Projection(osg::Matrix::ortho2D(0, 1024, 0, 768));
|
||||
proj->setCullingActive(false);
|
||||
root->addChild(proj.get());
|
||||
|
||||
osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform(osg::Matrix::identity());
|
||||
xform->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
proj->addChild(xform.get());
|
||||
osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform(osg::Matrix::identity());
|
||||
xform->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
|
||||
proj->addChild(xform.get());
|
||||
|
||||
osg::StateSet *ss = xform->getOrCreateStateSet();
|
||||
ss->setRenderBinDetails(100, "RenderBin");
|
||||
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
ss->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||
osg::StateSet *ss = xform->getOrCreateStateSet();
|
||||
ss->setRenderBinDetails(100, "RenderBin");
|
||||
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
ss->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||
|
||||
osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc;
|
||||
ss->setAttributeAndModes(bf.get());
|
||||
osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc;
|
||||
ss->setAttributeAndModes(bf.get());
|
||||
|
||||
return xform.take();
|
||||
return xform.take();
|
||||
}
|
||||
|
||||
EffectPanel* build_gui(osg::Group* root)
|
||||
{
|
||||
osg::ref_ptr<osg::Group> hud = build_hud_base(root);
|
||||
osg::ref_ptr<osg::Group> hud = build_hud_base(root);
|
||||
|
||||
osg::ref_ptr<EffectPanel> effect_panel = new EffectPanel;
|
||||
effect_panel->setCaption("osgFX Effect Browser");
|
||||
effect_panel->setRect(osgfxbrowser::Rect(20, 20, 1000, 280));
|
||||
osg::ref_ptr<EffectPanel> effect_panel = new EffectPanel;
|
||||
effect_panel->setCaption("osgFX Effect Browser");
|
||||
effect_panel->setRect(osgfxbrowser::Rect(20, 20, 1000, 280));
|
||||
|
||||
hud->addChild(effect_panel.get());
|
||||
hud->addChild(effect_panel.get());
|
||||
|
||||
return effect_panel.take();
|
||||
return effect_panel.take();
|
||||
}
|
||||
|
||||
void build_world(osg::Group* root, osg::Node* scene, osgProducer::Viewer& viewer)
|
||||
{
|
||||
osg::ref_ptr<EffectPanel> effect_panel = build_gui(root);
|
||||
effect_panel->setScene(scene);
|
||||
effect_panel->rebuild();
|
||||
osg::ref_ptr<EffectPanel> effect_panel = build_gui(root);
|
||||
effect_panel->setScene(scene);
|
||||
effect_panel->rebuild();
|
||||
|
||||
viewer.getEventHandlerList().push_front(new EffectPanel::KeyboardHandler(effect_panel.get()));
|
||||
viewer.getEventHandlerList().push_front(new EffectPanel::KeyboardHandler(effect_panel.get()));
|
||||
|
||||
root->addChild(effect_panel->getRoot());
|
||||
root->addChild(effect_panel->getRoot());
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -280,11 +280,11 @@ int main(int argc, char *argv[])
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName() + " is a simple browser that allows you to apply osgFX effects to models interactively.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName() + " [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help", "Display this information");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Left", "Apply previous effect");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Right", "Apply next effect");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Del", "Enable or disable osgFX");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Return", "Show or hide the effect information panel");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("x", "Save the scene graph with current effect applied");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Left", "Apply previous effect");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Right", "Apply next effect");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Del", "Enable or disable osgFX");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("Return", "Show or hide the effect information panel");
|
||||
arguments.getApplicationUsage()->addKeyboardMouseBinding("x", "Save the scene graph with current effect applied");
|
||||
|
||||
|
||||
// construct the viewer.
|
||||
@ -336,24 +336,24 @@ int main(int argc, char *argv[])
|
||||
osgUtil::Optimizer optimizer;
|
||||
optimizer.optimize(loadedModel.get());
|
||||
|
||||
// set up a transform to rotate the model
|
||||
osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform;
|
||||
rotate_cb = new RotateCallback;
|
||||
xform->setUpdateCallback(rotate_cb);
|
||||
xform->addChild(loadedModel.get());
|
||||
// set up a transform to rotate the model
|
||||
osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform;
|
||||
rotate_cb = new RotateCallback;
|
||||
xform->setUpdateCallback(rotate_cb);
|
||||
xform->addChild(loadedModel.get());
|
||||
|
||||
osg::ref_ptr<osg::Light> light = new osg::Light;
|
||||
light->setLightNum(0);
|
||||
light->setDiffuse(osg::Vec4(1, 1, 1, 1));
|
||||
light->setSpecular(osg::Vec4(1, 1, 0.8f, 1));
|
||||
light->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 0.2f));
|
||||
light->setPosition(osg::Vec4(1, -1, 1, 0));
|
||||
osg::ref_ptr<osg::Light> light = new osg::Light;
|
||||
light->setLightNum(0);
|
||||
light->setDiffuse(osg::Vec4(1, 1, 1, 1));
|
||||
light->setSpecular(osg::Vec4(1, 1, 0.8f, 1));
|
||||
light->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 0.2f));
|
||||
light->setPosition(osg::Vec4(1, -1, 1, 0));
|
||||
|
||||
osg::ref_ptr<osg::LightSource> root = new osg::LightSource;
|
||||
root->setLight(light.get());
|
||||
root->setLocalStateSetModes();
|
||||
osg::ref_ptr<osg::LightSource> root = new osg::LightSource;
|
||||
root->setLight(light.get());
|
||||
root->setLocalStateSetModes();
|
||||
|
||||
build_world(root.get(), xform.get(), viewer);
|
||||
build_world(root.get(), xform.get(), viewer);
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(root.get());
|
||||
|
@ -492,11 +492,11 @@ osg::Node* createScene()
|
||||
polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP,6,6));
|
||||
polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,12,5));
|
||||
|
||||
// polygon stipple
|
||||
osg::StateSet* stateSet = new osg::StateSet();
|
||||
polyGeom->setStateSet(stateSet);
|
||||
osg::PolygonStipple* polygonStipple = new osg::PolygonStipple;
|
||||
stateSet->setAttributeAndModes(polygonStipple,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
// polygon stipple
|
||||
osg::StateSet* stateSet = new osg::StateSet();
|
||||
polyGeom->setStateSet(stateSet);
|
||||
osg::PolygonStipple* polygonStipple = new osg::PolygonStipple;
|
||||
stateSet->setAttributeAndModes(polygonStipple,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
|
||||
printTriangles("Triangles/Strip/Fan",*polyGeom);
|
||||
|
||||
|
@ -51,8 +51,8 @@ void TestManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
|
||||
const osg::BoundingSphere& boundingSphere=_node->getBound();
|
||||
|
||||
computePosition(boundingSphere.center()+osg::Vec3(0.0f, 0.0f, 20.0f),
|
||||
osg::Vec3(0.0f, 1.0f, 0.0f),
|
||||
osg::Vec3(0.0f, 0.0f, 1.0f));
|
||||
osg::Vec3(0.0f, 1.0f, 0.0f),
|
||||
osg::Vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
us.requestRedraw();
|
||||
}
|
||||
@ -237,7 +237,7 @@ bool TestManipulator::calcMovement()
|
||||
// rotate camera.
|
||||
|
||||
osg::Quat new_rotate;
|
||||
new_rotate.makeRotate(dx / 3.0f, osg::Vec3(0.0f, 0.0f, 1.0f));
|
||||
new_rotate.makeRotate(dx / 3.0f, osg::Vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
_rotation = _rotation*new_rotate;
|
||||
|
||||
@ -249,7 +249,7 @@ bool TestManipulator::calcMovement()
|
||||
|
||||
// pan model.
|
||||
|
||||
osg::Vec3 dv = osg::Vec3(0.0f, 0.0f, -500.0f) * dy;
|
||||
osg::Vec3 dv = osg::Vec3(0.0f, 0.0f, -500.0f) * dy;
|
||||
|
||||
_center += dv;
|
||||
|
||||
@ -260,7 +260,7 @@ bool TestManipulator::calcMovement()
|
||||
{
|
||||
osg::Matrixd rotation_matrix(_rotation);
|
||||
|
||||
|
||||
|
||||
osg::Vec3 uv = osg::Vec3(0.0f,1.0f,0.0f)*rotation_matrix;
|
||||
osg::Vec3 sv = osg::Vec3(1.0f,0.0f,0.0f)*rotation_matrix;
|
||||
osg::Vec3 fv = uv ^ sv;
|
||||
@ -268,7 +268,7 @@ bool TestManipulator::calcMovement()
|
||||
|
||||
_center += dv;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -18,198 +18,198 @@
|
||||
#include <list>
|
||||
|
||||
// container storing all house nodes
|
||||
typedef osg::ref_ptr<osg::Node> NodePtr;
|
||||
typedef std::list<NodePtr> NodeContainer;
|
||||
typedef NodeContainer::iterator NodeIterator;
|
||||
typedef osg::ref_ptr<osg::Node> NodePtr;
|
||||
typedef std::list<NodePtr> NodeContainer;
|
||||
typedef NodeContainer::iterator NodeIterator;
|
||||
|
||||
NodeContainer nodes;
|
||||
NodeContainer nodes;
|
||||
|
||||
//
|
||||
osg::Group * Root = 0;
|
||||
|
||||
const int HOUSES_SIZE = 25000; // total number of houses
|
||||
double XDim = 5000.0f; // area dimension +/- XDim
|
||||
double ZDim = 5000.0f; // area dimension +/- YDim
|
||||
const int HOUSES_SIZE = 25000; // total number of houses
|
||||
double XDim = 5000.0f; // area dimension +/- XDim
|
||||
double ZDim = 5000.0f; // area dimension +/- YDim
|
||||
|
||||
int GridX = 20; // number of grids in x direction
|
||||
int GridY = 20; // number of grids in y direction
|
||||
int GridX = 20; // number of grids in x direction
|
||||
int GridY = 20; // number of grids in y direction
|
||||
|
||||
bool UseImpostor = true; // use impostor (or do not use)
|
||||
bool UseImpostor = true; // use impostor (or do not use)
|
||||
|
||||
float Threshold = 3000.0f; // distance where impostor are shown
|
||||
float Threshold = 3000.0f; // distance where impostor are shown
|
||||
|
||||
// create houses and store nodes in container
|
||||
void CreateHouses()
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
GLubyte indices[48] = {
|
||||
0, 2, 1,
|
||||
3, 2, 0,
|
||||
0, 4, 7,
|
||||
7, 3, 0,
|
||||
0, 1, 5,
|
||||
5, 4, 0,
|
||||
1, 6, 5,
|
||||
2, 6, 1,
|
||||
2, 3, 7,
|
||||
2, 7, 6,
|
||||
4, 8, 7,
|
||||
5, 6, 9,
|
||||
4, 5, 8,
|
||||
8, 5, 9,
|
||||
6, 7, 8,
|
||||
8, 9, 6
|
||||
};
|
||||
GLubyte indices[48] = {
|
||||
0, 2, 1,
|
||||
3, 2, 0,
|
||||
0, 4, 7,
|
||||
7, 3, 0,
|
||||
0, 1, 5,
|
||||
5, 4, 0,
|
||||
1, 6, 5,
|
||||
2, 6, 1,
|
||||
2, 3, 7,
|
||||
2, 7, 6,
|
||||
4, 8, 7,
|
||||
5, 6, 9,
|
||||
4, 5, 8,
|
||||
8, 5, 9,
|
||||
6, 7, 8,
|
||||
8, 9, 6
|
||||
};
|
||||
|
||||
// use the same color, normal and indices for all houses.
|
||||
// use the same color, normal and indices for all houses.
|
||||
osg::Vec4Array* colors = new osg::Vec4Array(1);
|
||||
(*colors)[0] = osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
(*colors)[0] = osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
// normals
|
||||
osg::Vec3Array * normals = new osg::Vec3Array(16);
|
||||
(*normals)[0] = osg::Vec3( 0.0f, -0.0f, -1.0f);
|
||||
(*normals)[1] = osg::Vec3( 0.0f, -0.0f, -1.0f);
|
||||
(*normals)[2] = osg::Vec3( 0.0f, -1.0f, 0.0f);
|
||||
(*normals)[3] = osg::Vec3( 0.0f, -1.0f, 0.0f);
|
||||
(*normals)[4] = osg::Vec3( 1.0f, -0.0f, 0.0f);
|
||||
(*normals)[5] = osg::Vec3( 1.0f, -0.0f, 0.0f);
|
||||
(*normals)[6] = osg::Vec3( 0.0f, 1.0f, 0.0f);
|
||||
(*normals)[7] = osg::Vec3( 0.0f, 1.0f, 0.0f);
|
||||
(*normals)[8] = osg::Vec3(-1.0f, -0.0f, 0.0f);
|
||||
(*normals)[9] = osg::Vec3(-1.0f, -0.0f, 0.0f);
|
||||
(*normals)[10] = osg::Vec3( 0.0f, -0.928477f, 0.371391f);
|
||||
(*normals)[11] = osg::Vec3( 0.0f, 0.928477f, 0.371391f);
|
||||
(*normals)[12] = osg::Vec3( 0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[13] = osg::Vec3( 0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[14] = osg::Vec3(-0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[15] = osg::Vec3(-0.707107f, 0.0f, 0.707107f);
|
||||
// normals
|
||||
osg::Vec3Array * normals = new osg::Vec3Array(16);
|
||||
(*normals)[0] = osg::Vec3( 0.0f, -0.0f, -1.0f);
|
||||
(*normals)[1] = osg::Vec3( 0.0f, -0.0f, -1.0f);
|
||||
(*normals)[2] = osg::Vec3( 0.0f, -1.0f, 0.0f);
|
||||
(*normals)[3] = osg::Vec3( 0.0f, -1.0f, 0.0f);
|
||||
(*normals)[4] = osg::Vec3( 1.0f, -0.0f, 0.0f);
|
||||
(*normals)[5] = osg::Vec3( 1.0f, -0.0f, 0.0f);
|
||||
(*normals)[6] = osg::Vec3( 0.0f, 1.0f, 0.0f);
|
||||
(*normals)[7] = osg::Vec3( 0.0f, 1.0f, 0.0f);
|
||||
(*normals)[8] = osg::Vec3(-1.0f, -0.0f, 0.0f);
|
||||
(*normals)[9] = osg::Vec3(-1.0f, -0.0f, 0.0f);
|
||||
(*normals)[10] = osg::Vec3( 0.0f, -0.928477f, 0.371391f);
|
||||
(*normals)[11] = osg::Vec3( 0.0f, 0.928477f, 0.371391f);
|
||||
(*normals)[12] = osg::Vec3( 0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[13] = osg::Vec3( 0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[14] = osg::Vec3(-0.707107f, 0.0f, 0.707107f);
|
||||
(*normals)[15] = osg::Vec3(-0.707107f, 0.0f, 0.707107f);
|
||||
|
||||
// coordIndices
|
||||
osg::UByteArray* coordIndices = new osg::UByteArray(48,indices);
|
||||
// coordIndices
|
||||
osg::UByteArray* coordIndices = new osg::UByteArray(48,indices);
|
||||
|
||||
// share the primtive set.
|
||||
osg::PrimitiveSet* primitives = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,48);
|
||||
|
||||
for (int q = 0; q < HOUSES_SIZE; q++)
|
||||
{
|
||||
float xPos = ((static_cast<double> (rand()) /
|
||||
static_cast<double> (RAND_MAX))
|
||||
* 2.0 * XDim) - XDim;
|
||||
for (int q = 0; q < HOUSES_SIZE; q++)
|
||||
{
|
||||
float xPos = ((static_cast<double> (rand()) /
|
||||
static_cast<double> (RAND_MAX))
|
||||
* 2.0 * XDim) - XDim;
|
||||
|
||||
float yPos = ((static_cast<double> (rand()) /
|
||||
static_cast<double> (RAND_MAX))
|
||||
* 2 * ZDim) - ZDim;
|
||||
float yPos = ((static_cast<double> (rand()) /
|
||||
static_cast<double> (RAND_MAX))
|
||||
* 2 * ZDim) - ZDim;
|
||||
|
||||
float scale = 10.0f;
|
||||
float scale = 10.0f;
|
||||
|
||||
osg::Vec3 offset(xPos,yPos,0.0f);
|
||||
|
||||
// coords
|
||||
osg::Vec3Array* coords = new osg::Vec3Array(10);
|
||||
(*coords)[0] = osg::Vec3( 0.5f, -0.7f, 0.0f);
|
||||
(*coords)[1] = osg::Vec3( 0.5f, 0.7f, 0.0f);
|
||||
(*coords)[2] = osg::Vec3(-0.5f, 0.7f, 0.0f);
|
||||
(*coords)[3] = osg::Vec3(-0.5f, -0.7f, 0.0f);
|
||||
(*coords)[4] = osg::Vec3( 0.5f, -0.7f, 1.0f);
|
||||
(*coords)[5] = osg::Vec3( 0.5f, 0.7f, 1.0f);
|
||||
(*coords)[6] = osg::Vec3(-0.5f, 0.7f, 1.0f);
|
||||
(*coords)[7] = osg::Vec3(-0.5f, -0.7f, 1.0f);
|
||||
(*coords)[8] = osg::Vec3( 0.0f, -0.5f, 1.5f);
|
||||
(*coords)[9] = osg::Vec3( 0.0f, 0.5f, 1.5f);
|
||||
// coords
|
||||
osg::Vec3Array* coords = new osg::Vec3Array(10);
|
||||
(*coords)[0] = osg::Vec3( 0.5f, -0.7f, 0.0f);
|
||||
(*coords)[1] = osg::Vec3( 0.5f, 0.7f, 0.0f);
|
||||
(*coords)[2] = osg::Vec3(-0.5f, 0.7f, 0.0f);
|
||||
(*coords)[3] = osg::Vec3(-0.5f, -0.7f, 0.0f);
|
||||
(*coords)[4] = osg::Vec3( 0.5f, -0.7f, 1.0f);
|
||||
(*coords)[5] = osg::Vec3( 0.5f, 0.7f, 1.0f);
|
||||
(*coords)[6] = osg::Vec3(-0.5f, 0.7f, 1.0f);
|
||||
(*coords)[7] = osg::Vec3(-0.5f, -0.7f, 1.0f);
|
||||
(*coords)[8] = osg::Vec3( 0.0f, -0.5f, 1.5f);
|
||||
(*coords)[9] = osg::Vec3( 0.0f, 0.5f, 1.5f);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
(*coords)[i] = (*coords)[i] * scale + offset;
|
||||
}
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
(*coords)[i] = (*coords)[i] * scale + offset;
|
||||
}
|
||||
|
||||
|
||||
// create geometry
|
||||
osg::Geometry * geometry = new osg::Geometry();
|
||||
// create geometry
|
||||
osg::Geometry * geometry = new osg::Geometry();
|
||||
|
||||
geometry->addPrimitiveSet(primitives);
|
||||
geometry->addPrimitiveSet(primitives);
|
||||
|
||||
geometry->setVertexArray(coords);
|
||||
geometry->setVertexArray(coords);
|
||||
geometry->setVertexIndices(coordIndices);
|
||||
|
||||
geometry->setColorArray(colors);
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
geometry->setColorArray(colors);
|
||||
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
|
||||
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
geometry->setNormalArray(normals);
|
||||
geometry->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
|
||||
|
||||
osg::Geode * geode = new osg::Geode();
|
||||
geode->addDrawable(geometry);
|
||||
|
||||
nodes.push_back(geode);
|
||||
}
|
||||
osg::Geode * geode = new osg::Geode();
|
||||
geode->addDrawable(geometry);
|
||||
|
||||
nodes.push_back(geode);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutAsGrid()
|
||||
{
|
||||
// calculate bounding box
|
||||
osg::BoundingBox bbox;
|
||||
for (NodeIterator node = nodes.begin(); node != nodes.end(); ++node)
|
||||
bbox.expandBy((*node)->getBound());
|
||||
// calculate bounding box
|
||||
osg::BoundingBox bbox;
|
||||
for (NodeIterator node = nodes.begin(); node != nodes.end(); ++node)
|
||||
bbox.expandBy((*node)->getBound());
|
||||
|
||||
// setup grid information
|
||||
osg::Group ** groups = new osg::Group*[GridX * GridY];
|
||||
// setup grid information
|
||||
osg::Group ** groups = new osg::Group*[GridX * GridY];
|
||||
int i;
|
||||
for (i = 0; i < GridX * GridY; i++)
|
||||
groups[i] = new osg::Group();
|
||||
for (i = 0; i < GridX * GridY; i++)
|
||||
groups[i] = new osg::Group();
|
||||
|
||||
float xGridStart = bbox.xMin();
|
||||
float xGridSize = (bbox.xMax() - bbox.xMin()) / GridX;
|
||||
float xGridStart = bbox.xMin();
|
||||
float xGridSize = (bbox.xMax() - bbox.xMin()) / GridX;
|
||||
|
||||
float yGridStart = bbox.yMin();
|
||||
float yGridSize = (bbox.yMax() - bbox.yMin()) / GridY;
|
||||
float yGridStart = bbox.yMin();
|
||||
float yGridSize = (bbox.yMax() - bbox.yMin()) / GridY;
|
||||
|
||||
// arrange buildings into right grid
|
||||
for (NodeIterator nodeIter = nodes.begin(); nodeIter != nodes.end(); ++nodeIter)
|
||||
{
|
||||
osg::Node * node = nodeIter->get();
|
||||
osg::Vec3 center = node->getBound().center();
|
||||
|
||||
int x = (int)floor((center.x() - xGridStart) / xGridSize);
|
||||
int z = (int)floor((center.y() - yGridStart) / yGridSize);
|
||||
// arrange buildings into right grid
|
||||
for (NodeIterator nodeIter = nodes.begin(); nodeIter != nodes.end(); ++nodeIter)
|
||||
{
|
||||
osg::Node * node = nodeIter->get();
|
||||
osg::Vec3 center = node->getBound().center();
|
||||
|
||||
int x = (int)floor((center.x() - xGridStart) / xGridSize);
|
||||
int z = (int)floor((center.y() - yGridStart) / yGridSize);
|
||||
|
||||
groups[z * GridX + x]->addChild(node);
|
||||
}
|
||||
groups[z * GridX + x]->addChild(node);
|
||||
}
|
||||
|
||||
// add nodes to building root
|
||||
for (i = 0; i < GridX * GridY; i++)
|
||||
{
|
||||
osg::StateSet * stateset = new osg::StateSet();
|
||||
// add nodes to building root
|
||||
for (i = 0; i < GridX * GridY; i++)
|
||||
{
|
||||
osg::StateSet * stateset = new osg::StateSet();
|
||||
|
||||
osg::Material * material = new osg::Material();
|
||||
osg::Vec4 color = osg::Vec4(
|
||||
0.5f + (static_cast<double> (rand()) / (2.0*static_cast<double> (RAND_MAX))),
|
||||
0.5f + (static_cast<double> (rand()) / (2.0*static_cast<double> (RAND_MAX))),
|
||||
0.5f + (static_cast<double> (rand()) / ( 2.0*static_cast<double>(RAND_MAX))),
|
||||
1.0f);
|
||||
|
||||
material->setAmbient(osg::Material::FRONT_AND_BACK, color);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
|
||||
stateset->setAttributeAndModes(material, osg::StateAttribute::ON);
|
||||
osg::Material * material = new osg::Material();
|
||||
osg::Vec4 color = osg::Vec4(
|
||||
0.5f + (static_cast<double> (rand()) / (2.0*static_cast<double> (RAND_MAX))),
|
||||
0.5f + (static_cast<double> (rand()) / (2.0*static_cast<double> (RAND_MAX))),
|
||||
0.5f + (static_cast<double> (rand()) / ( 2.0*static_cast<double>(RAND_MAX))),
|
||||
1.0f);
|
||||
|
||||
material->setAmbient(osg::Material::FRONT_AND_BACK, color);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
|
||||
stateset->setAttributeAndModes(material, osg::StateAttribute::ON);
|
||||
|
||||
groups[i]->setStateSet(stateset);
|
||||
groups[i]->setStateSet(stateset);
|
||||
|
||||
if (UseImpostor)
|
||||
{
|
||||
osgSim::Impostor * impostor = new osgSim::Impostor();
|
||||
impostor->setImpostorThreshold(static_cast<float> (Threshold));
|
||||
impostor->addChild(groups[i]);
|
||||
impostor->setRange(0, 0.0f, 1e7f);
|
||||
impostor->setCenter(groups[i]->getBound().center());
|
||||
Root->addChild(impostor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Root->addChild(groups[i]);
|
||||
}
|
||||
}
|
||||
if (UseImpostor)
|
||||
{
|
||||
osgSim::Impostor * impostor = new osgSim::Impostor();
|
||||
impostor->setImpostorThreshold(static_cast<float> (Threshold));
|
||||
impostor->addChild(groups[i]);
|
||||
impostor->setRange(0, 0.0f, 1e7f);
|
||||
impostor->setCenter(groups[i]->getBound().center());
|
||||
Root->addChild(impostor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Root->addChild(groups[i]);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] groups;
|
||||
delete[] groups;
|
||||
}
|
||||
|
||||
|
||||
@ -309,9 +309,9 @@ int main( int argc, char **argv )
|
||||
else
|
||||
{
|
||||
// no user model so we'll create our own world.
|
||||
model = Root = new osg::Group();
|
||||
CreateHouses();
|
||||
LayoutAsGrid();
|
||||
model = Root = new osg::Group();
|
||||
CreateHouses();
|
||||
LayoutAsGrid();
|
||||
}
|
||||
|
||||
// add model to viewer.
|
||||
|
@ -42,210 +42,210 @@ std::string createLibraryNameForWrapper(const std::string& ext)
|
||||
|
||||
bool type_order(const Type *v1, const Type *v2)
|
||||
{
|
||||
if (!v1->isDefined()) return v2->isDefined();
|
||||
if (!v2->isDefined()) return false;
|
||||
return v1->getQualifiedName().compare(v2->getQualifiedName()) < 0;
|
||||
if (!v1->isDefined()) return v2->isDefined();
|
||||
if (!v2->isDefined()) return false;
|
||||
return v1->getQualifiedName().compare(v2->getQualifiedName()) < 0;
|
||||
}
|
||||
|
||||
typedef std::vector<const Type *> TypeList;
|
||||
|
||||
void print_types()
|
||||
{
|
||||
// get the map of types that have been reflected
|
||||
const TypeMap &tm = Reflection::getTypes();
|
||||
|
||||
// create a sortable list of types
|
||||
TypeList types(tm.size());
|
||||
TypeList::iterator j = types.begin();
|
||||
for (TypeMap::const_iterator i=tm.begin(); i!=tm.end(); ++i, ++j)
|
||||
*j = i->second;
|
||||
|
||||
// sort the map
|
||||
std::sort(types.begin(), types.end(), &type_order);
|
||||
// get the map of types that have been reflected
|
||||
const TypeMap &tm = Reflection::getTypes();
|
||||
|
||||
// create a sortable list of types
|
||||
TypeList types(tm.size());
|
||||
TypeList::iterator j = types.begin();
|
||||
for (TypeMap::const_iterator i=tm.begin(); i!=tm.end(); ++i, ++j)
|
||||
*j = i->second;
|
||||
|
||||
// sort the map
|
||||
std::sort(types.begin(), types.end(), &type_order);
|
||||
|
||||
// iterate through the type map and display some
|
||||
// details for each type
|
||||
for (TypeList::const_iterator i=types.begin(); i!=types.end(); ++i)
|
||||
{
|
||||
// ignore pointer types and undefined types
|
||||
if (!(*i)->isDefined() || (*i)->isPointer())
|
||||
continue;
|
||||
// iterate through the type map and display some
|
||||
// details for each type
|
||||
for (TypeList::const_iterator i=types.begin(); i!=types.end(); ++i)
|
||||
{
|
||||
// ignore pointer types and undefined types
|
||||
if (!(*i)->isDefined() || (*i)->isPointer())
|
||||
continue;
|
||||
|
||||
// print the type name
|
||||
std::cout << (*i)->getQualifiedName() << "\n";
|
||||
// print the type name
|
||||
std::cout << (*i)->getQualifiedName() << "\n";
|
||||
|
||||
// check whether the type is abstract
|
||||
if ((*i)->isAbstract()) std::cout << "\t[abstract]\n";
|
||||
// check whether the type is abstract
|
||||
if ((*i)->isAbstract()) std::cout << "\t[abstract]\n";
|
||||
|
||||
// check whether the type is atomic
|
||||
if ((*i)->isAtomic()) std::cout << "\t[atomic]\n";
|
||||
// check whether the type is atomic
|
||||
if ((*i)->isAtomic()) std::cout << "\t[atomic]\n";
|
||||
|
||||
// check whether the type is an enumeration. If yes, display
|
||||
// the list of enumeration labels
|
||||
if ((*i)->isEnum())
|
||||
{
|
||||
std::cout << "\t[enum]\n";
|
||||
std::cout << "\tenumeration values:\n";
|
||||
const EnumLabelMap &emap = (*i)->getEnumLabels();
|
||||
for (EnumLabelMap::const_iterator j=emap.begin(); j!=emap.end(); ++j)
|
||||
{
|
||||
std::cout << "\t\t" << j->second << " = " << j->first << "\n";
|
||||
}
|
||||
}
|
||||
// check whether the type is an enumeration. If yes, display
|
||||
// the list of enumeration labels
|
||||
if ((*i)->isEnum())
|
||||
{
|
||||
std::cout << "\t[enum]\n";
|
||||
std::cout << "\tenumeration values:\n";
|
||||
const EnumLabelMap &emap = (*i)->getEnumLabels();
|
||||
for (EnumLabelMap::const_iterator j=emap.begin(); j!=emap.end(); ++j)
|
||||
{
|
||||
std::cout << "\t\t" << j->second << " = " << j->first << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// if the type has one or more base types, then display their
|
||||
// names
|
||||
if ((*i)->getNumBaseTypes() > 0)
|
||||
{
|
||||
std::cout << "\tderived from: ";
|
||||
for (int j=0; j<(*i)->getNumBaseTypes(); ++j)
|
||||
{
|
||||
const Type &base = (*i)->getBaseType(j);
|
||||
if (base.isDefined())
|
||||
std::cout << base.getQualifiedName() << " ";
|
||||
else
|
||||
std::cout << "[undefined type] ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
// if the type has one or more base types, then display their
|
||||
// names
|
||||
if ((*i)->getNumBaseTypes() > 0)
|
||||
{
|
||||
std::cout << "\tderived from: ";
|
||||
for (int j=0; j<(*i)->getNumBaseTypes(); ++j)
|
||||
{
|
||||
const Type &base = (*i)->getBaseType(j);
|
||||
if (base.isDefined())
|
||||
std::cout << base.getQualifiedName() << " ";
|
||||
else
|
||||
std::cout << "[undefined type] ";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
// display a list of methods defined for the current type
|
||||
const MethodInfoList &mil = (*i)->getMethods();
|
||||
if (!mil.empty())
|
||||
{
|
||||
std::cout << "\t* methods:\n";
|
||||
for (MethodInfoList::const_iterator j=mil.begin(); j!=mil.end(); ++j)
|
||||
{
|
||||
// get the MethodInfo object that describes the current
|
||||
// method
|
||||
const MethodInfo &mi = **j;
|
||||
// display a list of methods defined for the current type
|
||||
const MethodInfoList &mil = (*i)->getMethods();
|
||||
if (!mil.empty())
|
||||
{
|
||||
std::cout << "\t* methods:\n";
|
||||
for (MethodInfoList::const_iterator j=mil.begin(); j!=mil.end(); ++j)
|
||||
{
|
||||
// get the MethodInfo object that describes the current
|
||||
// method
|
||||
const MethodInfo &mi = **j;
|
||||
|
||||
std::cout << "\t ";
|
||||
std::cout << "\t ";
|
||||
|
||||
// display the method's return type if defined
|
||||
if (mi.getReturnType().isDefined())
|
||||
std::cout << mi.getReturnType().getQualifiedName() << " ";
|
||||
else
|
||||
std::cout << "[UNDEFINED TYPE] ";
|
||||
// display the method's return type if defined
|
||||
if (mi.getReturnType().isDefined())
|
||||
std::cout << mi.getReturnType().getQualifiedName() << " ";
|
||||
else
|
||||
std::cout << "[UNDEFINED TYPE] ";
|
||||
|
||||
// display the method's name
|
||||
std::cout << mi.getName() << "(";
|
||||
// display the method's name
|
||||
std::cout << mi.getName() << "(";
|
||||
|
||||
// display method's parameters
|
||||
const ParameterInfoList ¶ms = mi.getParameters();
|
||||
for (ParameterInfoList::const_iterator k=params.begin(); k!=params.end(); ++k)
|
||||
{
|
||||
// get the ParameterInfo object that describes the
|
||||
// current parameter
|
||||
const ParameterInfo &pi = **k;
|
||||
// display method's parameters
|
||||
const ParameterInfoList ¶ms = mi.getParameters();
|
||||
for (ParameterInfoList::const_iterator k=params.begin(); k!=params.end(); ++k)
|
||||
{
|
||||
// get the ParameterInfo object that describes the
|
||||
// current parameter
|
||||
const ParameterInfo &pi = **k;
|
||||
|
||||
// display the parameter's modifier
|
||||
if (pi.isIn())
|
||||
std::cout << "IN";
|
||||
if (pi.isOut())
|
||||
std::cout << "OUT";
|
||||
if (pi.isIn() || pi.isOut())
|
||||
std::cout << " ";
|
||||
// display the parameter's modifier
|
||||
if (pi.isIn())
|
||||
std::cout << "IN";
|
||||
if (pi.isOut())
|
||||
std::cout << "OUT";
|
||||
if (pi.isIn() || pi.isOut())
|
||||
std::cout << " ";
|
||||
|
||||
// display the parameter's type name
|
||||
if (pi.getParameterType().isDefined())
|
||||
std::cout << pi.getParameterType().getQualifiedName();
|
||||
// display the parameter's type name
|
||||
if (pi.getParameterType().isDefined())
|
||||
std::cout << pi.getParameterType().getQualifiedName();
|
||||
|
||||
// display the parameter's name if defined
|
||||
if (!pi.getName().empty())
|
||||
std::cout << " " << pi.getName();
|
||||
// display the parameter's name if defined
|
||||
if (!pi.getName().empty())
|
||||
std::cout << " " << pi.getName();
|
||||
|
||||
if ((k+1)!=params.end())
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << ")";
|
||||
if (mi.isConst())
|
||||
std::cout << " const";
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
if ((k+1)!=params.end())
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << ")";
|
||||
if (mi.isConst())
|
||||
std::cout << " const";
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// display a list of properties defined for the current type
|
||||
const PropertyInfoList &pil = (*i)->getProperties();
|
||||
if (!pil.empty())
|
||||
{
|
||||
std::cout << "\t* properties:\n";
|
||||
for (PropertyInfoList::const_iterator j=pil.begin(); j!=pil.end(); ++j)
|
||||
{
|
||||
// get the PropertyInfo object that describes the current
|
||||
// property
|
||||
const PropertyInfo &pi = **j;
|
||||
// display a list of properties defined for the current type
|
||||
const PropertyInfoList &pil = (*i)->getProperties();
|
||||
if (!pil.empty())
|
||||
{
|
||||
std::cout << "\t* properties:\n";
|
||||
for (PropertyInfoList::const_iterator j=pil.begin(); j!=pil.end(); ++j)
|
||||
{
|
||||
// get the PropertyInfo object that describes the current
|
||||
// property
|
||||
const PropertyInfo &pi = **j;
|
||||
|
||||
std::cout << "\t ";
|
||||
std::cout << "\t ";
|
||||
|
||||
std::cout << "{";
|
||||
std::cout << (pi.canGet()? "G": " ");
|
||||
std::cout << (pi.canSet()? "S": " ");
|
||||
std::cout << (pi.canCount()? "C": " ");
|
||||
std::cout << (pi.canAdd()? "A": " ");
|
||||
std::cout << "} ";
|
||||
std::cout << "{";
|
||||
std::cout << (pi.canGet()? "G": " ");
|
||||
std::cout << (pi.canSet()? "S": " ");
|
||||
std::cout << (pi.canCount()? "C": " ");
|
||||
std::cout << (pi.canAdd()? "A": " ");
|
||||
std::cout << "} ";
|
||||
|
||||
// display the property's name
|
||||
std::cout << pi.getName();
|
||||
// display the property's name
|
||||
std::cout << pi.getName();
|
||||
|
||||
// display the property's value type if defined
|
||||
std::cout << " (";
|
||||
if (pi.getPropertyType().isDefined())
|
||||
std::cout << pi.getPropertyType().getQualifiedName();
|
||||
else
|
||||
std::cout << "UNDEFINED TYPE";
|
||||
std::cout << ") ";
|
||||
// display the property's value type if defined
|
||||
std::cout << " (";
|
||||
if (pi.getPropertyType().isDefined())
|
||||
std::cout << pi.getPropertyType().getQualifiedName();
|
||||
else
|
||||
std::cout << "UNDEFINED TYPE";
|
||||
std::cout << ") ";
|
||||
|
||||
// check whether the property is an array property
|
||||
if (pi.isArray())
|
||||
{
|
||||
std::cout << " [ARRAY]";
|
||||
}
|
||||
// check whether the property is an array property
|
||||
if (pi.isArray())
|
||||
{
|
||||
std::cout << " [ARRAY]";
|
||||
}
|
||||
|
||||
// check whether the property is an indexed property
|
||||
if (pi.isIndexed())
|
||||
{
|
||||
std::cout << " [INDEXED]\n\t\t indices:\n";
|
||||
// check whether the property is an indexed property
|
||||
if (pi.isIndexed())
|
||||
{
|
||||
std::cout << " [INDEXED]\n\t\t indices:\n";
|
||||
|
||||
const ParameterInfoList &ind = pi.getIndexParameters();
|
||||
const ParameterInfoList &ind = pi.getIndexParameters();
|
||||
|
||||
// print the list of indices
|
||||
int num = 1;
|
||||
for (ParameterInfoList::const_iterator k=ind.begin(); k!=ind.end(); ++k, ++num)
|
||||
{
|
||||
std::cout << "\t\t " << num << ") ";
|
||||
const ParameterInfo &par = **k;
|
||||
std::cout << par.getParameterType().getQualifiedName() << " " << par.getName();
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
// print the list of indices
|
||||
int num = 1;
|
||||
for (ParameterInfoList::const_iterator k=ind.begin(); k!=ind.end(); ++k, ++num)
|
||||
{
|
||||
std::cout << "\t\t " << num << ") ";
|
||||
const ParameterInfo &par = **k;
|
||||
std::cout << par.getParameterType().getQualifiedName() << " " << par.getName();
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "\n" << std::string(75, '-') << "\n";
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
std::cout << "\n" << std::string(75, '-') << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// load the library of wrappers that reflect the
|
||||
// classes defined in the 'osg' namespace. In the
|
||||
// future this will be done automatically under
|
||||
// certain circumstances (like deserialization).
|
||||
osg::ref_ptr<osgDB::DynamicLibrary> osg_reflectors =
|
||||
osgDB::DynamicLibrary::loadLibrary(createLibraryNameForWrapper("osg"));
|
||||
|
||||
// display a detailed list of reflected types
|
||||
try
|
||||
{
|
||||
print_types();
|
||||
}
|
||||
catch(const osgIntrospection::Exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
// load the library of wrappers that reflect the
|
||||
// classes defined in the 'osg' namespace. In the
|
||||
// future this will be done automatically under
|
||||
// certain circumstances (like deserialization).
|
||||
osg::ref_ptr<osgDB::DynamicLibrary> osg_reflectors =
|
||||
osgDB::DynamicLibrary::loadLibrary(createLibraryNameForWrapper("osg"));
|
||||
|
||||
// display a detailed list of reflected types
|
||||
try
|
||||
{
|
||||
print_types();
|
||||
}
|
||||
catch(const osgIntrospection::Exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
|
||||
osg::Matrixd getViewMatrix()
|
||||
{
|
||||
_trackBall->input( mx(), my(), mbutton() );
|
||||
_trackBall->input( mx(), my(), mbutton() );
|
||||
return osg::Matrixd(_trackBall->getMatrix().ptr());
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
|
||||
myLight1->setSpotExponent(50.0f);
|
||||
myLight1->setDirection(osg::Vec3(1.0f,1.0f,-1.0f));
|
||||
|
||||
osg::LightSource* lightS1 = new osg::LightSource;
|
||||
osg::LightSource* lightS1 = new osg::LightSource;
|
||||
lightS1->setLight(myLight1);
|
||||
lightS1->setLocalStateSetModes(osg::StateAttribute::ON);
|
||||
|
||||
@ -101,7 +101,7 @@ osg::Node* createLights(osg::BoundingBox& bb,osg::StateSet* rootStateSet)
|
||||
myLight2->setLinearAttenuation(2.0f/modelSize);
|
||||
myLight2->setQuadraticAttenuation(2.0f/osg::square(modelSize));
|
||||
|
||||
osg::LightSource* lightS2 = new osg::LightSource;
|
||||
osg::LightSource* lightS2 = new osg::LightSource;
|
||||
lightS2->setLight(myLight2);
|
||||
lightS2->setLocalStateSetModes(osg::StateAttribute::ON);
|
||||
|
||||
|
@ -12,43 +12,43 @@
|
||||
|
||||
const int _ops_nb=16;
|
||||
const osg::LogicOp::Opcode _operations[_ops_nb]=
|
||||
{
|
||||
osg::LogicOp::CLEAR,
|
||||
osg::LogicOp::SET,
|
||||
osg::LogicOp::COPY,
|
||||
osg::LogicOp::COPY_INVERTED,
|
||||
osg::LogicOp::NOOP,
|
||||
osg::LogicOp::INVERT,
|
||||
osg::LogicOp::AND,
|
||||
osg::LogicOp::NAND,
|
||||
osg::LogicOp::OR,
|
||||
osg::LogicOp::NOR,
|
||||
osg::LogicOp::XOR,
|
||||
osg::LogicOp::EQUIV,
|
||||
osg::LogicOp::AND_REVERSE,
|
||||
osg::LogicOp::AND_INVERTED,
|
||||
osg::LogicOp::OR_REVERSE,
|
||||
osg::LogicOp::OR_INVERTED
|
||||
{
|
||||
osg::LogicOp::CLEAR,
|
||||
osg::LogicOp::SET,
|
||||
osg::LogicOp::COPY,
|
||||
osg::LogicOp::COPY_INVERTED,
|
||||
osg::LogicOp::NOOP,
|
||||
osg::LogicOp::INVERT,
|
||||
osg::LogicOp::AND,
|
||||
osg::LogicOp::NAND,
|
||||
osg::LogicOp::OR,
|
||||
osg::LogicOp::NOR,
|
||||
osg::LogicOp::XOR,
|
||||
osg::LogicOp::EQUIV,
|
||||
osg::LogicOp::AND_REVERSE,
|
||||
osg::LogicOp::AND_INVERTED,
|
||||
osg::LogicOp::OR_REVERSE,
|
||||
osg::LogicOp::OR_INVERTED
|
||||
};
|
||||
|
||||
const char* _ops_name[_ops_nb]=
|
||||
{
|
||||
"osg::LogicOp::CLEAR",
|
||||
"osg::LogicOp::SET",
|
||||
"osg::LogicOp::COPY",
|
||||
"osg::LogicOp::COPY_INVERTED",
|
||||
"osg::LogicOp::NOOP",
|
||||
"osg::LogicOp::INVERT",
|
||||
"osg::LogicOp::AND",
|
||||
"osg::LogicOp::NAND",
|
||||
"osg::LogicOp::OR",
|
||||
"osg::LogicOp::NOR",
|
||||
"osg::LogicOp::XOR",
|
||||
"osg::LogicOp::EQUIV",
|
||||
"osg::LogicOp::AND_REVERSE",
|
||||
"osg::LogicOp::AND_INVERTED",
|
||||
"osg::LogicOp::OR_REVERSE",
|
||||
"osg::LogicOp::OR_INVERTED"
|
||||
{
|
||||
"osg::LogicOp::CLEAR",
|
||||
"osg::LogicOp::SET",
|
||||
"osg::LogicOp::COPY",
|
||||
"osg::LogicOp::COPY_INVERTED",
|
||||
"osg::LogicOp::NOOP",
|
||||
"osg::LogicOp::INVERT",
|
||||
"osg::LogicOp::AND",
|
||||
"osg::LogicOp::NAND",
|
||||
"osg::LogicOp::OR",
|
||||
"osg::LogicOp::NOR",
|
||||
"osg::LogicOp::XOR",
|
||||
"osg::LogicOp::EQUIV",
|
||||
"osg::LogicOp::AND_REVERSE",
|
||||
"osg::LogicOp::AND_INVERTED",
|
||||
"osg::LogicOp::OR_REVERSE",
|
||||
"osg::LogicOp::OR_INVERTED"
|
||||
};
|
||||
|
||||
class TechniqueEventHandler : public osgGA::GUIEventHandler
|
||||
@ -72,9 +72,8 @@ protected:
|
||||
|
||||
TechniqueEventHandler(const TechniqueEventHandler&,const osg::CopyOp&) {}
|
||||
|
||||
osg::LogicOp* _logicOp;
|
||||
|
||||
int _ops_index;
|
||||
osg::LogicOp* _logicOp;
|
||||
int _ops_index;
|
||||
|
||||
};
|
||||
|
||||
@ -87,21 +86,19 @@ bool TechniqueEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAc
|
||||
if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right)
|
||||
{
|
||||
_ops_index++;
|
||||
if (_ops_index>=_ops_nb)
|
||||
_ops_index=0;
|
||||
_logicOp->setOpcode(_operations[_ops_index]);
|
||||
std::cout<<"Operation name = "<<_ops_name[_ops_index]<<std::endl;
|
||||
_ops_index++;
|
||||
if (_ops_index>=_ops_nb) _ops_index=0;
|
||||
_logicOp->setOpcode(_operations[_ops_index]);
|
||||
std::cout<<"Operation name = "<<_ops_name[_ops_index]<<std::endl;
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left)
|
||||
{
|
||||
_ops_index--;
|
||||
if (_ops_index<0)
|
||||
_ops_index=_ops_nb-1;
|
||||
_logicOp->setOpcode(_operations[_ops_index]);
|
||||
std::cout<<"Operation name = "<<_ops_name[_ops_index]<<std::endl;
|
||||
_ops_index--;
|
||||
if (_ops_index<0) _ops_index=_ops_nb-1;
|
||||
_logicOp->setOpcode(_operations[_ops_index]);
|
||||
std::cout<<"Operation name = "<<_ops_name[_ops_index]<<std::endl;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -146,15 +143,14 @@ int main( int argc, char **argv )
|
||||
root->addChild(loadedModel);
|
||||
|
||||
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
osg::LogicOp* logicOp = new osg::LogicOp(osg::LogicOp::OR_INVERTED);
|
||||
|
||||
osg::StateSet* stateset = new osg::StateSet;
|
||||
osg::LogicOp* logicOp = new osg::LogicOp(osg::LogicOp::OR_INVERTED);
|
||||
|
||||
stateset->setAttributeAndModes(logicOp,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
|
||||
|
||||
|
||||
//tell to sort the mesh before displaying it
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
|
||||
|
||||
|
||||
loadedModel->setStateSet(stateset);
|
||||
|
||||
@ -215,9 +211,6 @@ int main( int argc, char **argv )
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
|
@ -212,10 +212,10 @@ osg:: Node* createGlobe(const osg::BoundingBox& bb,float ratio, const std::strin
|
||||
osg::Image* image = osgDB::readImageFile("Images/land_shallow_topo_2048.jpg");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
texture->setMaxAnisotropy(8);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
texture->setMaxAnisotropy(8);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
osg::Material* material = new osg::Material;
|
||||
|
@ -16,44 +16,44 @@
|
||||
class MotionBlurDrawCallback: public osgProducer::OsgSceneHandler::Callback
|
||||
{
|
||||
public:
|
||||
MotionBlurDrawCallback(double persistence)
|
||||
: cleared_(false),
|
||||
persistence_(persistence)
|
||||
{
|
||||
}
|
||||
MotionBlurDrawCallback(double persistence)
|
||||
: cleared_(false),
|
||||
persistence_(persistence)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator()(osgProducer::OsgSceneHandler &handler, Producer::Camera &camera)
|
||||
{
|
||||
double t = handler.getSceneView()->getFrameStamp()->getReferenceTime();
|
||||
virtual void operator()(osgProducer::OsgSceneHandler &handler, Producer::Camera &camera)
|
||||
{
|
||||
double t = handler.getSceneView()->getFrameStamp()->getReferenceTime();
|
||||
|
||||
if (!cleared_)
|
||||
{
|
||||
// clear the accumulation buffer
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_ACCUM_BUFFER_BIT);
|
||||
cleared_ = true;
|
||||
t0_ = t;
|
||||
}
|
||||
if (!cleared_)
|
||||
{
|
||||
// clear the accumulation buffer
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_ACCUM_BUFFER_BIT);
|
||||
cleared_ = true;
|
||||
t0_ = t;
|
||||
}
|
||||
|
||||
double dt = fabs(t - t0_);
|
||||
t0_ = t;
|
||||
double dt = fabs(t - t0_);
|
||||
t0_ = t;
|
||||
|
||||
// call the scene handler's draw function
|
||||
handler.drawImplementation(camera);
|
||||
// call the scene handler's draw function
|
||||
handler.drawImplementation(camera);
|
||||
|
||||
// compute the blur factor
|
||||
double s = powf(0.2, dt / persistence_);
|
||||
// compute the blur factor
|
||||
double s = powf(0.2, dt / persistence_);
|
||||
|
||||
// scale, accumulate and return
|
||||
glAccum(GL_MULT, s);
|
||||
glAccum(GL_ACCUM, 1 - s);
|
||||
glAccum(GL_RETURN, 1.0f);
|
||||
}
|
||||
// scale, accumulate and return
|
||||
glAccum(GL_MULT, s);
|
||||
glAccum(GL_ACCUM, 1 - s);
|
||||
glAccum(GL_RETURN, 1.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
bool cleared_;
|
||||
double t0_;
|
||||
double persistence_;
|
||||
bool cleared_;
|
||||
double t0_;
|
||||
double persistence_;
|
||||
};
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ int main( int argc, char **argv )
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is an OpenSceneGraph example that shows how to use the accumulation buffer to achieve a simple motion blur effect.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-P or --persistence","Set the motion blur persistence time");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-P or --persistence","Set the motion blur persistence time");
|
||||
|
||||
|
||||
// construct the viewer.
|
||||
@ -87,8 +87,8 @@ int main( int argc, char **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
double persistence = 0.25;
|
||||
arguments.read("-P", persistence) || arguments.read("--persistence", persistence);
|
||||
double persistence = 0.25;
|
||||
arguments.read("-P", persistence) || arguments.read("--persistence", persistence);
|
||||
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
@ -141,12 +141,12 @@ int main( int argc, char **argv )
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
// set our motion blur callback as the draw callback for each scene handler
|
||||
osgProducer::Viewer::SceneHandlerList &shl = viewer.getSceneHandlerList();
|
||||
for (osgProducer::Viewer::SceneHandlerList::iterator i=shl.begin(); i!=shl.end(); ++i)
|
||||
{
|
||||
(*i)->setDrawCallback(new MotionBlurDrawCallback(persistence));
|
||||
}
|
||||
// set our motion blur callback as the draw callback for each scene handler
|
||||
osgProducer::Viewer::SceneHandlerList &shl = viewer.getSceneHandlerList();
|
||||
for (osgProducer::Viewer::SceneHandlerList::iterator i=shl.begin(); i!=shl.end(); ++i)
|
||||
{
|
||||
(*i)->setDrawCallback(new MotionBlurDrawCallback(persistence));
|
||||
}
|
||||
|
||||
while( !viewer.done() )
|
||||
{
|
||||
|
@ -144,10 +144,10 @@ osg::Node* createModel(const std::string& shader, const std::string& textureFile
|
||||
image->allocateImage(tx,ty,1,GL_LUMINANCE,GL_FLOAT,1);
|
||||
for(unsigned int r=0;r<ty;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<tx;++c)
|
||||
{
|
||||
*((float*)image->data(c,r)) = vertex[r+c*39][2]*0.1;
|
||||
}
|
||||
for(unsigned int c=0;c<tx;++c)
|
||||
{
|
||||
*((float*)image->data(c,r)) = vertex[r+c*39][2]*0.1;
|
||||
}
|
||||
}
|
||||
|
||||
num_x = tx;
|
||||
|
@ -25,70 +25,70 @@
|
||||
// for more details.
|
||||
class VortexOperator: public osgParticle::Operator {
|
||||
public:
|
||||
VortexOperator()
|
||||
: osgParticle::Operator(), center_(0, 0, 0), axis_(0, 0, 1), intensity_(0.1f) {}
|
||||
VortexOperator()
|
||||
: osgParticle::Operator(), center_(0, 0, 0), axis_(0, 0, 1), intensity_(0.1f) {}
|
||||
|
||||
VortexOperator(const VortexOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY)
|
||||
: osgParticle::Operator(copy, copyop), center_(copy.center_), axis_(copy.axis_), intensity_(copy.intensity_) {}
|
||||
VortexOperator(const VortexOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY)
|
||||
: osgParticle::Operator(copy, copyop), center_(copy.center_), axis_(copy.axis_), intensity_(copy.intensity_) {}
|
||||
|
||||
META_Object(osgParticle, VortexOperator);
|
||||
META_Object(osgParticle, VortexOperator);
|
||||
|
||||
void setCenter(const osg::Vec3 &c)
|
||||
{
|
||||
center_ = c;
|
||||
}
|
||||
void setCenter(const osg::Vec3 &c)
|
||||
{
|
||||
center_ = c;
|
||||
}
|
||||
|
||||
void setAxis(const osg::Vec3 &a)
|
||||
{
|
||||
axis_ = a / a.length();
|
||||
}
|
||||
void setAxis(const osg::Vec3 &a)
|
||||
{
|
||||
axis_ = a / a.length();
|
||||
}
|
||||
|
||||
// this method is called by ModularProgram before applying
|
||||
// operators on the particle set via the operate() method.
|
||||
void beginOperate(osgParticle::Program *prg)
|
||||
{
|
||||
// we have to check whether the reference frame is RELATIVE_RF to parents
|
||||
// or it's absolute; in the first case, we must transform the vectors
|
||||
// from local to world space.
|
||||
if (prg->getReferenceFrame() == osgParticle::Program::RELATIVE_RF) {
|
||||
// transform the center point (full transformation)
|
||||
xf_center_ = prg->transformLocalToWorld(center_);
|
||||
// transform the axis vector (only rotation and scale)
|
||||
xf_axis_ = prg->rotateLocalToWorld(axis_);
|
||||
} else {
|
||||
xf_center_ = center_;
|
||||
xf_axis_ = axis_;
|
||||
}
|
||||
}
|
||||
// this method is called by ModularProgram before applying
|
||||
// operators on the particle set via the operate() method.
|
||||
void beginOperate(osgParticle::Program *prg)
|
||||
{
|
||||
// we have to check whether the reference frame is RELATIVE_RF to parents
|
||||
// or it's absolute; in the first case, we must transform the vectors
|
||||
// from local to world space.
|
||||
if (prg->getReferenceFrame() == osgParticle::Program::RELATIVE_RF) {
|
||||
// transform the center point (full transformation)
|
||||
xf_center_ = prg->transformLocalToWorld(center_);
|
||||
// transform the axis vector (only rotation and scale)
|
||||
xf_axis_ = prg->rotateLocalToWorld(axis_);
|
||||
} else {
|
||||
xf_center_ = center_;
|
||||
xf_axis_ = axis_;
|
||||
}
|
||||
}
|
||||
|
||||
// apply a vortex-like acceleration. This code is not optimized,
|
||||
// it's here only for demonstration purposes.
|
||||
void operate(osgParticle::Particle *P, double dt)
|
||||
{
|
||||
float l = xf_axis_ * (P->getPosition() - xf_center_);
|
||||
osg::Vec3 lc = xf_center_ + xf_axis_ * l;
|
||||
osg::Vec3 R = P->getPosition() - lc;
|
||||
osg::Vec3 v = (R ^ xf_axis_) * P->getMassInv() * intensity_;
|
||||
// apply a vortex-like acceleration. This code is not optimized,
|
||||
// it's here only for demonstration purposes.
|
||||
void operate(osgParticle::Particle *P, double dt)
|
||||
{
|
||||
float l = xf_axis_ * (P->getPosition() - xf_center_);
|
||||
osg::Vec3 lc = xf_center_ + xf_axis_ * l;
|
||||
osg::Vec3 R = P->getPosition() - lc;
|
||||
osg::Vec3 v = (R ^ xf_axis_) * P->getMassInv() * intensity_;
|
||||
|
||||
// compute new position
|
||||
osg::Vec3 newpos = P->getPosition() + v * dt;
|
||||
// compute new position
|
||||
osg::Vec3 newpos = P->getPosition() + v * dt;
|
||||
|
||||
// update the position of the particle without modifying its
|
||||
// velocity vector (this is unusual, normally you should call
|
||||
// the Particle::setVelocity() or Particle::addVelocity()
|
||||
// methods).
|
||||
P->setPosition(newpos);
|
||||
}
|
||||
// update the position of the particle without modifying its
|
||||
// velocity vector (this is unusual, normally you should call
|
||||
// the Particle::setVelocity() or Particle::addVelocity()
|
||||
// methods).
|
||||
P->setPosition(newpos);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~VortexOperator() {}
|
||||
virtual ~VortexOperator() {}
|
||||
|
||||
private:
|
||||
osg::Vec3 center_;
|
||||
osg::Vec3 xf_center_;
|
||||
osg::Vec3 axis_;
|
||||
osg::Vec3 xf_axis_;
|
||||
float intensity_;
|
||||
osg::Vec3 center_;
|
||||
osg::Vec3 xf_center_;
|
||||
osg::Vec3 axis_;
|
||||
osg::Vec3 xf_axis_;
|
||||
float intensity_;
|
||||
};
|
||||
|
||||
|
||||
@ -100,81 +100,81 @@ private:
|
||||
osgParticle::ParticleSystem *create_simple_particle_system(osg::Group *root)
|
||||
{
|
||||
|
||||
// Ok folks, this is the first particle system we build; it will be
|
||||
// very simple, with no textures and no special effects, just default
|
||||
// values except for a couple of attributes.
|
||||
// Ok folks, this is the first particle system we build; it will be
|
||||
// very simple, with no textures and no special effects, just default
|
||||
// values except for a couple of attributes.
|
||||
|
||||
// First of all, we create the ParticleSystem object; it will hold
|
||||
// our particles and expose the interface for managing them; this object
|
||||
// is a Drawable, so we'll have to add it to a Geode later.
|
||||
// First of all, we create the ParticleSystem object; it will hold
|
||||
// our particles and expose the interface for managing them; this object
|
||||
// is a Drawable, so we'll have to add it to a Geode later.
|
||||
|
||||
osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
|
||||
osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
|
||||
|
||||
// As for other Drawable classes, the aspect of graphical elements of
|
||||
// ParticleSystem (the particles) depends on the StateAttribute's we
|
||||
// give it. The ParticleSystem class has an helper function that let
|
||||
// us specify a set of the most common attributes: setDefaultAttributes().
|
||||
// This method can accept up to three parameters; the first is a texture
|
||||
// name (std::string), which can be empty to disable texturing, the second
|
||||
// sets whether particles have to be "emissive" (additive blending) or not;
|
||||
// the third parameter enables or disables lighting.
|
||||
// As for other Drawable classes, the aspect of graphical elements of
|
||||
// ParticleSystem (the particles) depends on the StateAttribute's we
|
||||
// give it. The ParticleSystem class has an helper function that let
|
||||
// us specify a set of the most common attributes: setDefaultAttributes().
|
||||
// This method can accept up to three parameters; the first is a texture
|
||||
// name (std::string), which can be empty to disable texturing, the second
|
||||
// sets whether particles have to be "emissive" (additive blending) or not;
|
||||
// the third parameter enables or disables lighting.
|
||||
|
||||
ps->setDefaultAttributes("", true, false);
|
||||
ps->setDefaultAttributes("", true, false);
|
||||
|
||||
// Now that our particle system is set we have to create an emitter, that is
|
||||
// an object (actually a Node descendant) that generate new particles at
|
||||
// each frame. The best choice is to use a ModularEmitter, which allow us to
|
||||
// achieve a wide variety of emitting styles by composing the emitter using
|
||||
// three objects: a "counter", a "placer" and a "shooter". The counter must
|
||||
// tell the ModularEmitter how many particles it has to create for the
|
||||
// current frame; then, the ModularEmitter creates these particles, and for
|
||||
// each new particle it instructs the placer and the shooter to set its
|
||||
// position vector and its velocity vector, respectively.
|
||||
// By default, a ModularEmitter object initializes itself with a counter of
|
||||
// type RandomRateCounter, a placer of type PointPlacer and a shooter of
|
||||
// type RadialShooter (see documentation for details). We are going to leave
|
||||
// these default objects there, but we'll modify the counter so that it
|
||||
// counts faster (more particles are emitted at each frame).
|
||||
// Now that our particle system is set we have to create an emitter, that is
|
||||
// an object (actually a Node descendant) that generate new particles at
|
||||
// each frame. The best choice is to use a ModularEmitter, which allow us to
|
||||
// achieve a wide variety of emitting styles by composing the emitter using
|
||||
// three objects: a "counter", a "placer" and a "shooter". The counter must
|
||||
// tell the ModularEmitter how many particles it has to create for the
|
||||
// current frame; then, the ModularEmitter creates these particles, and for
|
||||
// each new particle it instructs the placer and the shooter to set its
|
||||
// position vector and its velocity vector, respectively.
|
||||
// By default, a ModularEmitter object initializes itself with a counter of
|
||||
// type RandomRateCounter, a placer of type PointPlacer and a shooter of
|
||||
// type RadialShooter (see documentation for details). We are going to leave
|
||||
// these default objects there, but we'll modify the counter so that it
|
||||
// counts faster (more particles are emitted at each frame).
|
||||
|
||||
osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
|
||||
osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
|
||||
|
||||
// the first thing you *MUST* do after creating an emitter is to set the
|
||||
// destination particle system, otherwise it won't know where to create
|
||||
// new particles.
|
||||
// the first thing you *MUST* do after creating an emitter is to set the
|
||||
// destination particle system, otherwise it won't know where to create
|
||||
// new particles.
|
||||
|
||||
emitter->setParticleSystem(ps);
|
||||
emitter->setParticleSystem(ps);
|
||||
|
||||
// Ok, get a pointer to the emitter's Counter object. We could also
|
||||
// create a new RandomRateCounter object and assign it to the emitter,
|
||||
// but since the default counter is already a RandomRateCounter, we
|
||||
// just get a pointer to it and change a value.
|
||||
// Ok, get a pointer to the emitter's Counter object. We could also
|
||||
// create a new RandomRateCounter object and assign it to the emitter,
|
||||
// but since the default counter is already a RandomRateCounter, we
|
||||
// just get a pointer to it and change a value.
|
||||
|
||||
osgParticle::RandomRateCounter *rrc =
|
||||
static_cast<osgParticle::RandomRateCounter *>(emitter->getCounter());
|
||||
osgParticle::RandomRateCounter *rrc =
|
||||
static_cast<osgParticle::RandomRateCounter *>(emitter->getCounter());
|
||||
|
||||
// Now set the rate range to a better value. The actual rate at each frame
|
||||
// will be chosen randomly within that range.
|
||||
// Now set the rate range to a better value. The actual rate at each frame
|
||||
// will be chosen randomly within that range.
|
||||
|
||||
rrc->setRateRange(20, 30); // generate 20 to 30 particles per second
|
||||
rrc->setRateRange(20, 30); // generate 20 to 30 particles per second
|
||||
|
||||
// The emitter is done! Let's add it to the scene graph. The cool thing is
|
||||
// that any emitter node will take into account the accumulated local-to-world
|
||||
// matrix, so you can attach an emitter to a transform node and see it move.
|
||||
// The emitter is done! Let's add it to the scene graph. The cool thing is
|
||||
// that any emitter node will take into account the accumulated local-to-world
|
||||
// matrix, so you can attach an emitter to a transform node and see it move.
|
||||
|
||||
root->addChild(emitter);
|
||||
root->addChild(emitter);
|
||||
|
||||
// Ok folks, we have almost finished. We don't add any particle modifier
|
||||
// here (see ModularProgram and Operator classes), so all we still need is
|
||||
// to create a Geode and add the particle system to it, so it can be
|
||||
// displayed.
|
||||
// Ok folks, we have almost finished. We don't add any particle modifier
|
||||
// here (see ModularProgram and Operator classes), so all we still need is
|
||||
// to create a Geode and add the particle system to it, so it can be
|
||||
// displayed.
|
||||
|
||||
osg::Geode *geode = new osg::Geode;
|
||||
geode->addDrawable(ps);
|
||||
osg::Geode *geode = new osg::Geode;
|
||||
geode->addDrawable(ps);
|
||||
|
||||
// add the geode to the scene graph
|
||||
root->addChild(geode);
|
||||
// add the geode to the scene graph
|
||||
root->addChild(geode);
|
||||
|
||||
return ps;
|
||||
return ps;
|
||||
|
||||
}
|
||||
|
||||
@ -187,120 +187,120 @@ osgParticle::ParticleSystem *create_simple_particle_system(osg::Group *root)
|
||||
|
||||
osgParticle::ParticleSystem *create_complex_particle_system(osg::Group *root)
|
||||
{
|
||||
// Are you ready for a more complex particle system? Well, read on!
|
||||
// Are you ready for a more complex particle system? Well, read on!
|
||||
|
||||
// Now we take one step we didn't before: create a particle template.
|
||||
// A particle template is simply a Particle object for which you set
|
||||
// the desired properties (see documentation for details). When the
|
||||
// particle system has to create a new particle and it's been assigned
|
||||
// a particle template, the new particle will inherit the template's
|
||||
// properties.
|
||||
// You can even assign different particle templates to each emitter; in
|
||||
// this case, the emitter's template will override the particle system's
|
||||
// default template.
|
||||
// Now we take one step we didn't before: create a particle template.
|
||||
// A particle template is simply a Particle object for which you set
|
||||
// the desired properties (see documentation for details). When the
|
||||
// particle system has to create a new particle and it's been assigned
|
||||
// a particle template, the new particle will inherit the template's
|
||||
// properties.
|
||||
// You can even assign different particle templates to each emitter; in
|
||||
// this case, the emitter's template will override the particle system's
|
||||
// default template.
|
||||
|
||||
osgParticle::Particle ptemplate;
|
||||
osgParticle::Particle ptemplate;
|
||||
|
||||
ptemplate.setLifeTime(3); // 3 seconds of life
|
||||
ptemplate.setLifeTime(3); // 3 seconds of life
|
||||
|
||||
// the following ranges set the envelope of the respective
|
||||
// graphical properties in time.
|
||||
ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f));
|
||||
ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f));
|
||||
ptemplate.setColorRange(osgParticle::rangev4(
|
||||
osg::Vec4(1, 0.5f, 0.3f, 1.5f),
|
||||
osg::Vec4(0, 0.7f, 1.0f, 0.0f)));
|
||||
// the following ranges set the envelope of the respective
|
||||
// graphical properties in time.
|
||||
ptemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f));
|
||||
ptemplate.setAlphaRange(osgParticle::rangef(0.0f, 1.5f));
|
||||
ptemplate.setColorRange(osgParticle::rangev4(
|
||||
osg::Vec4(1, 0.5f, 0.3f, 1.5f),
|
||||
osg::Vec4(0, 0.7f, 1.0f, 0.0f)));
|
||||
|
||||
// these are physical properties of the particle
|
||||
ptemplate.setRadius(0.05f); // 5 cm wide particles
|
||||
ptemplate.setMass(0.05f); // 50 g heavy
|
||||
// these are physical properties of the particle
|
||||
ptemplate.setRadius(0.05f); // 5 cm wide particles
|
||||
ptemplate.setMass(0.05f); // 50 g heavy
|
||||
|
||||
// As usual, let's create the ParticleSystem object and set its
|
||||
// default state attributes. This time we use a texture named
|
||||
// "smoke.rgb", you can find it in the data distribution of OSG.
|
||||
// We turn off the additive blending, because smoke has no self-
|
||||
// illumination.
|
||||
osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
|
||||
ps->setDefaultAttributes("Images/smoke.rgb", false, false);
|
||||
// As usual, let's create the ParticleSystem object and set its
|
||||
// default state attributes. This time we use a texture named
|
||||
// "smoke.rgb", you can find it in the data distribution of OSG.
|
||||
// We turn off the additive blending, because smoke has no self-
|
||||
// illumination.
|
||||
osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
|
||||
ps->setDefaultAttributes("Images/smoke.rgb", false, false);
|
||||
|
||||
// assign the particle template to the system.
|
||||
ps->setDefaultParticleTemplate(ptemplate);
|
||||
// assign the particle template to the system.
|
||||
ps->setDefaultParticleTemplate(ptemplate);
|
||||
|
||||
// now we have to create an emitter; this will be a ModularEmitter, for which
|
||||
// we define a RandomRateCounter as counter, a SectorPlacer as placer, and
|
||||
// a RadialShooter as shooter.
|
||||
osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
|
||||
emitter->setParticleSystem(ps);
|
||||
// now we have to create an emitter; this will be a ModularEmitter, for which
|
||||
// we define a RandomRateCounter as counter, a SectorPlacer as placer, and
|
||||
// a RadialShooter as shooter.
|
||||
osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
|
||||
emitter->setParticleSystem(ps);
|
||||
|
||||
// setup the counter
|
||||
osgParticle::RandomRateCounter *counter = new osgParticle::RandomRateCounter;
|
||||
counter->setRateRange(60, 60);
|
||||
emitter->setCounter(counter);
|
||||
// setup the counter
|
||||
osgParticle::RandomRateCounter *counter = new osgParticle::RandomRateCounter;
|
||||
counter->setRateRange(60, 60);
|
||||
emitter->setCounter(counter);
|
||||
|
||||
// setup the placer; it will be a circle of radius 5 (the particles will
|
||||
// be placed inside this circle).
|
||||
osgParticle::SectorPlacer *placer = new osgParticle::SectorPlacer;
|
||||
placer->setCenter(8, 0, 10);
|
||||
placer->setRadiusRange(2.5, 5);
|
||||
placer->setPhiRange(0, 2 * osg::PI); // 360° angle to make a circle
|
||||
emitter->setPlacer(placer);
|
||||
// setup the placer; it will be a circle of radius 5 (the particles will
|
||||
// be placed inside this circle).
|
||||
osgParticle::SectorPlacer *placer = new osgParticle::SectorPlacer;
|
||||
placer->setCenter(8, 0, 10);
|
||||
placer->setRadiusRange(2.5, 5);
|
||||
placer->setPhiRange(0, 2 * osg::PI); // 360° angle to make a circle
|
||||
emitter->setPlacer(placer);
|
||||
|
||||
// now let's setup the shooter; we use a RadialShooter but we set the
|
||||
// initial speed to zero, because we want the particles to fall down
|
||||
// only under the effect of the gravity force. Since we se the speed
|
||||
// to zero, there is no need to setup the shooting angles.
|
||||
osgParticle::RadialShooter *shooter = new osgParticle::RadialShooter;
|
||||
shooter->setInitialSpeedRange(0, 0);
|
||||
emitter->setShooter(shooter);
|
||||
// now let's setup the shooter; we use a RadialShooter but we set the
|
||||
// initial speed to zero, because we want the particles to fall down
|
||||
// only under the effect of the gravity force. Since we se the speed
|
||||
// to zero, there is no need to setup the shooting angles.
|
||||
osgParticle::RadialShooter *shooter = new osgParticle::RadialShooter;
|
||||
shooter->setInitialSpeedRange(0, 0);
|
||||
emitter->setShooter(shooter);
|
||||
|
||||
// add the emitter to the scene graph
|
||||
root->addChild(emitter);
|
||||
// add the emitter to the scene graph
|
||||
root->addChild(emitter);
|
||||
|
||||
// WELL, we got our particle system and a nice emitter. Now we want to
|
||||
// simulate the effect of the earth gravity, so first of all we have to
|
||||
// create a Program. It is a particle processor just like the Emitter
|
||||
// class, but it allows to modify particle properties *after* they have
|
||||
// been created.
|
||||
// The ModularProgram class can be thought as a sequence of operators,
|
||||
// each one performing some actions on the particles. So, the trick is:
|
||||
// create the ModularProgram object, create one or more Operator objects,
|
||||
// add those operators to the ModularProgram, and finally add the
|
||||
// ModularProgram object to the scene graph.
|
||||
// NOTE: since the Program objects perform actions after the particles
|
||||
// have been emitted by one or more Emitter objects, all instances of
|
||||
// Program (and its descendants) should be placed *after* the instances
|
||||
// of Emitter objects in the scene graph.
|
||||
// WELL, we got our particle system and a nice emitter. Now we want to
|
||||
// simulate the effect of the earth gravity, so first of all we have to
|
||||
// create a Program. It is a particle processor just like the Emitter
|
||||
// class, but it allows to modify particle properties *after* they have
|
||||
// been created.
|
||||
// The ModularProgram class can be thought as a sequence of operators,
|
||||
// each one performing some actions on the particles. So, the trick is:
|
||||
// create the ModularProgram object, create one or more Operator objects,
|
||||
// add those operators to the ModularProgram, and finally add the
|
||||
// ModularProgram object to the scene graph.
|
||||
// NOTE: since the Program objects perform actions after the particles
|
||||
// have been emitted by one or more Emitter objects, all instances of
|
||||
// Program (and its descendants) should be placed *after* the instances
|
||||
// of Emitter objects in the scene graph.
|
||||
|
||||
osgParticle::ModularProgram *program = new osgParticle::ModularProgram;
|
||||
program->setParticleSystem(ps);
|
||||
osgParticle::ModularProgram *program = new osgParticle::ModularProgram;
|
||||
program->setParticleSystem(ps);
|
||||
|
||||
// create an operator that simulates the gravity acceleration.
|
||||
osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator;
|
||||
op1->setToGravity();
|
||||
program->addOperator(op1);
|
||||
// create an operator that simulates the gravity acceleration.
|
||||
osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator;
|
||||
op1->setToGravity();
|
||||
program->addOperator(op1);
|
||||
|
||||
// now create a custom operator, we have defined it before (see
|
||||
// class VortexOperator).
|
||||
VortexOperator *op2 = new VortexOperator;
|
||||
op2->setCenter(osg::Vec3(8, 0, 0));
|
||||
program->addOperator(op2);
|
||||
// now create a custom operator, we have defined it before (see
|
||||
// class VortexOperator).
|
||||
VortexOperator *op2 = new VortexOperator;
|
||||
op2->setCenter(osg::Vec3(8, 0, 0));
|
||||
program->addOperator(op2);
|
||||
|
||||
// let's add a fluid operator to simulate air friction.
|
||||
osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator;
|
||||
op3->setFluidToAir();
|
||||
program->addOperator(op3);
|
||||
// let's add a fluid operator to simulate air friction.
|
||||
osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator;
|
||||
op3->setFluidToAir();
|
||||
program->addOperator(op3);
|
||||
|
||||
// add the program to the scene graph
|
||||
root->addChild(program);
|
||||
// add the program to the scene graph
|
||||
root->addChild(program);
|
||||
|
||||
// create a Geode to contain our particle system.
|
||||
osg::Geode *geode = new osg::Geode;
|
||||
geode->addDrawable(ps);
|
||||
// create a Geode to contain our particle system.
|
||||
osg::Geode *geode = new osg::Geode;
|
||||
geode->addDrawable(ps);
|
||||
|
||||
// add the geode to the scene graph.
|
||||
root->addChild(geode);
|
||||
// add the geode to the scene graph.
|
||||
root->addChild(geode);
|
||||
|
||||
return ps;
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
@ -312,27 +312,27 @@ osgParticle::ParticleSystem *create_complex_particle_system(osg::Group *root)
|
||||
void build_world(osg::Group *root)
|
||||
{
|
||||
|
||||
// In this function we are going to create two particle systems;
|
||||
// the first one will be very simple, based mostly on default properties;
|
||||
// the second one will be a little bit more complex, showing how to
|
||||
// create custom operators.
|
||||
// To avoid inserting too much code in a single function, we have
|
||||
// splitted the work into two functions which accept a Group node as
|
||||
// parameter, and return a pointer to the particle system they created.
|
||||
// In this function we are going to create two particle systems;
|
||||
// the first one will be very simple, based mostly on default properties;
|
||||
// the second one will be a little bit more complex, showing how to
|
||||
// create custom operators.
|
||||
// To avoid inserting too much code in a single function, we have
|
||||
// splitted the work into two functions which accept a Group node as
|
||||
// parameter, and return a pointer to the particle system they created.
|
||||
|
||||
osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root);
|
||||
osgParticle::ParticleSystem *ps2 = create_complex_particle_system(root);
|
||||
osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root);
|
||||
osgParticle::ParticleSystem *ps2 = create_complex_particle_system(root);
|
||||
|
||||
// Now that the particle systems and all other related objects have been
|
||||
// created, we have to add an "updater" node to the scene graph. This node
|
||||
// will react to cull traversal by updating the specified particles system.
|
||||
// Now that the particle systems and all other related objects have been
|
||||
// created, we have to add an "updater" node to the scene graph. This node
|
||||
// will react to cull traversal by updating the specified particles system.
|
||||
|
||||
osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
|
||||
psu->addParticleSystem(ps1);
|
||||
psu->addParticleSystem(ps2);
|
||||
osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
|
||||
psu->addParticleSystem(ps1);
|
||||
psu->addParticleSystem(ps2);
|
||||
|
||||
// add the updater node to the scene graph
|
||||
root->addChild(psu);
|
||||
// add the updater node to the scene graph
|
||||
root->addChild(psu);
|
||||
|
||||
}
|
||||
|
||||
|
@ -150,9 +150,9 @@ void build_world(osg::Group *root)
|
||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
terrainGeode->setStateSet( stateset );
|
||||
@ -168,10 +168,10 @@ void build_world(osg::Group *root)
|
||||
|
||||
for(unsigned int r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
grid->setHeight(c,r,z_scale*vertex[r+c*39][2]);
|
||||
}
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
grid->setHeight(c,r,z_scale*vertex[r+c*39][2]);
|
||||
}
|
||||
}
|
||||
terrainGeode->addDrawable(new osg::ShapeDrawable(grid));
|
||||
|
||||
|
@ -455,9 +455,9 @@ osg::Geode* SolarSystem::createPlanet( double radius, const std::string& name, c
|
||||
osg::Image* image = osgDB::readImageFile( textureName );
|
||||
if ( image )
|
||||
{
|
||||
osg::Texture2D* tex2d = new osg::Texture2D( image );
|
||||
tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
|
||||
tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
|
||||
osg::Texture2D* tex2d = new osg::Texture2D( image );
|
||||
tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
|
||||
tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
|
||||
geodePlanet->getOrCreateStateSet()->setTextureAttributeAndModes( 0, tex2d, osg::StateAttribute::ON );
|
||||
|
||||
// reset the object color to white to allow the texture to set the colour.
|
||||
@ -494,9 +494,9 @@ osg::Geode* SolarSystem::createPlanet( double radius, const std::string& name, c
|
||||
texenv->setOperand2_RGB(osg::TexEnvCombine::SRC_COLOR);
|
||||
|
||||
stateset->setTextureAttribute( 1, texenv );
|
||||
osg::Texture2D* tex2d = new osg::Texture2D( image );
|
||||
tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
|
||||
tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
|
||||
osg::Texture2D* tex2d = new osg::Texture2D( image );
|
||||
tex2d->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
|
||||
tex2d->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
|
||||
stateset->setTextureAttributeAndModes( 1, tex2d, osg::StateAttribute::ON );
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
geode->setStateSet( stateset );
|
||||
@ -81,8 +81,8 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
unsigned int r;
|
||||
for(r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
float h = vertex[r+c*39][2];
|
||||
if (h>maxHeight) maxHeight=h;
|
||||
if (h<minHeight) minHeight=h;
|
||||
@ -94,11 +94,11 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
|
||||
for(r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
float h = vertex[r+c*39][2];
|
||||
grid->setHeight(c,r,(h+hieghtOffset)*hieghtScale);
|
||||
}
|
||||
grid->setHeight(c,r,(h+hieghtOffset)*hieghtScale);
|
||||
}
|
||||
}
|
||||
|
||||
geode->addDrawable(new osg::ShapeDrawable(grid));
|
||||
|
@ -26,9 +26,9 @@ osg::Geode* createShapes( char* img_filename )
|
||||
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
geode->setStateSet( stateset );
|
||||
@ -52,10 +52,10 @@ osg::Geode* createShapes( char* img_filename )
|
||||
|
||||
for(unsigned int r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
grid->setHeight(c,r,vertex[r+c*39][2]);
|
||||
}
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
grid->setHeight(c,r,vertex[r+c*39][2]);
|
||||
}
|
||||
}
|
||||
geode->addDrawable(new osg::ShapeDrawable(grid));
|
||||
|
||||
@ -125,11 +125,11 @@ int main( int argc, char **argv )
|
||||
char* img_filename = 0;
|
||||
for( int pos = 1; pos < arguments.argc(); ++pos )
|
||||
{
|
||||
if( arguments.isString(pos) )
|
||||
{
|
||||
img_filename = arguments[pos];
|
||||
break;
|
||||
}
|
||||
if( arguments.isString(pos) )
|
||||
{
|
||||
img_filename = arguments[pos];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Node* node = createShapes( img_filename );
|
||||
|
@ -73,8 +73,8 @@ int main( int argc, char **argv )
|
||||
// draw the rendering bins.
|
||||
sceneView->draw();
|
||||
|
||||
// Swap Buffers
|
||||
renderSurface->swapBuffers();
|
||||
// Swap Buffers
|
||||
renderSurface->swapBuffers();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
|
||||
osg::Matrixd getViewMatrix()
|
||||
{
|
||||
_trackBall->input( mx(), my(), mbutton() );
|
||||
_trackBall->input( mx(), my(), mbutton() );
|
||||
return osg::Matrixd(_trackBall->getMatrix().ptr());
|
||||
}
|
||||
|
||||
|
@ -72,10 +72,10 @@ osg::Node* createEarth()
|
||||
{
|
||||
osgTerrain::DataSet::Source* source = new osgTerrain::DataSet::Source(osgTerrain::DataSet::Source::IMAGE, filename);
|
||||
|
||||
source->setCoordinateSystemPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS);
|
||||
source->setCoordinateSystemPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS);
|
||||
source->setCoordinateSystem(osgTerrain::DataSet::coordinateSystemStringToWTK("WGS84"));
|
||||
|
||||
source->setGeoTransformPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS_BUT_SCALE_BY_FILE_RESOLUTION);
|
||||
source->setGeoTransformPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS_BUT_SCALE_BY_FILE_RESOLUTION);
|
||||
source->setGeoTransformFromRange(-180.0, 180.0, -90.0, 90.0);
|
||||
|
||||
dataSet->addSource(source);
|
||||
|
@ -188,8 +188,8 @@ int main( int argc, char **argv )
|
||||
// draw the rendering bins.
|
||||
sceneView->draw();
|
||||
|
||||
// Swap Buffers
|
||||
renderSurface->swapBuffers();
|
||||
// Swap Buffers
|
||||
renderSurface->swapBuffers();
|
||||
|
||||
std::cout << "before readPixels: _r = " << sp->_image->r() << std::endl;
|
||||
|
||||
|
@ -236,9 +236,9 @@ void build_world(osg::Group *root, unsigned int testCase)
|
||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
terrainGeode->setStateSet( stateset );
|
||||
@ -271,11 +271,11 @@ void build_world(osg::Group *root, unsigned int testCase)
|
||||
float max_z = -FLT_MAX;
|
||||
for(r=0;r<numRows;++r)
|
||||
{
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
|
||||
max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
|
||||
max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
|
||||
}
|
||||
}
|
||||
|
||||
float scale_z = size.z()/(max_z-min_z);
|
||||
@ -287,14 +287,14 @@ void build_world(osg::Group *root, unsigned int testCase)
|
||||
{
|
||||
pos.x() = origin.x();
|
||||
tex.x() = 0.0f;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
tc[vi] = tex;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
|
||||
tc[vi] = tex;
|
||||
pos.x()+=columnCoordDelta;
|
||||
tex.x()+=columnTexDelta;
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
pos.y() += rowCoordDelta;
|
||||
tex.y() += rowTexDelta;
|
||||
}
|
||||
@ -309,11 +309,11 @@ void build_world(osg::Group *root, unsigned int testCase)
|
||||
osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
|
||||
geometry->addPrimitiveSet(&drawElements);
|
||||
int ei=0;
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
for(c=0;c<numColumns;++c)
|
||||
{
|
||||
drawElements[ei++] = (r+1)*numColumns+c;
|
||||
drawElements[ei++] = (r)*numColumns+c;
|
||||
}
|
||||
}
|
||||
|
||||
osgUtil::SmoothingVisitor smoother;
|
||||
|
@ -150,9 +150,9 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
|
||||
if (image)
|
||||
{
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
osg::Texture2D* texture = new osg::Texture2D;
|
||||
texture->setImage(image);
|
||||
stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
geode->setStateSet( stateset );
|
||||
@ -171,8 +171,8 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
unsigned int r;
|
||||
for(r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
float h = vertex[r+c*39][2];
|
||||
if (h>maxHeight) maxHeight=h;
|
||||
if (h<minHeight) minHeight=h;
|
||||
@ -184,11 +184,11 @@ osg::Node* createBase(const osg::Vec3& center,float radius)
|
||||
|
||||
for(r=0;r<39;++r)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
for(unsigned int c=0;c<38;++c)
|
||||
{
|
||||
float h = vertex[r+c*39][2];
|
||||
grid->setHeight(c,r,(h+hieghtOffset)*hieghtScale);
|
||||
}
|
||||
grid->setHeight(c,r,(h+hieghtOffset)*hieghtScale);
|
||||
}
|
||||
}
|
||||
|
||||
geode->addDrawable(new osg::ShapeDrawable(grid));
|
||||
|
@ -35,14 +35,14 @@ class ConstructStateCallback : public osgProducer::OsgCameraGroup::RealizeCallba
|
||||
osg::ref_ptr<osg::Image> image_3 = osgDB::readImageFile("Images/skymap.jpg");
|
||||
|
||||
if (!image_0 || !image_1 || !image_2 || !image_3)
|
||||
{
|
||||
std::cout << "Warning: could not open files."<<std::endl;
|
||||
{
|
||||
std::cout << "Warning: could not open files."<<std::endl;
|
||||
return new osg::StateSet;
|
||||
}
|
||||
|
||||
if (image_0->getPixelFormat()!=image_1->getPixelFormat() || image_0->getPixelFormat()!=image_2->getPixelFormat() || image_0->getPixelFormat()!=image_3->getPixelFormat())
|
||||
{
|
||||
std::cout << "Warning: image pixel formats not compatible."<<std::endl;
|
||||
std::cout << "Warning: image pixel formats not compatible."<<std::endl;
|
||||
return new osg::StateSet;
|
||||
}
|
||||
|
||||
|
@ -492,8 +492,8 @@ osg::Image* createTexture3D(ImageList& imageList, ProcessRow& processRow,
|
||||
int num_t = osg::minimum(image->t(), image_3d->t());
|
||||
int num_s = osg::minimum(image->s(), image_3d->s());
|
||||
|
||||
unsigned int s_offset_dest = (image->s()<s_nearestPowerOfTwo) ? s_nearestPowerOfTwo/2 - image->s()/2 : 0;
|
||||
unsigned int t_offset_dest = (image->t()<t_nearestPowerOfTwo) ? t_nearestPowerOfTwo/2 - image->t()/2 : 0;
|
||||
unsigned int s_offset_dest = (image->s()<s_nearestPowerOfTwo) ? s_nearestPowerOfTwo/2 - image->s()/2 : 0;
|
||||
unsigned int t_offset_dest = (image->t()<t_nearestPowerOfTwo) ? t_nearestPowerOfTwo/2 - image->t()/2 : 0;
|
||||
|
||||
for(int r=0;r<num_r;++r, ++curr_dest_r)
|
||||
{
|
||||
@ -1011,8 +1011,8 @@ osg::Node* createModel(osg::ref_ptr<osg::Image>& image_3d, osg::ref_ptr<osg::Ima
|
||||
|
||||
if (normalmap_3d.valid())
|
||||
{
|
||||
if (two_pass)
|
||||
{
|
||||
if (two_pass)
|
||||
{
|
||||
|
||||
// set up normal texture
|
||||
osg::Texture3D* bump_texture3D = new osg::Texture3D;
|
||||
@ -1076,7 +1076,7 @@ osg::Node* createModel(osg::ref_ptr<osg::Image>& image_3d, osg::ref_ptr<osg::Ima
|
||||
|
||||
stateset->setTextureAttributeAndModes(1,new osg::TexEnv(),osg::StateAttribute::ON);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::ref_ptr<osg::Image> normalmap_3d = createNormalMapTexture(image_3d.get());
|
||||
|
Loading…
Reference in New Issue
Block a user