Added back in the osgimpostor example, cleaning up so that it no longer has any deprecated paths and adds stats and file output for debug purposes

This commit is contained in:
Robert Osfield 2016-08-25 11:05:30 +01:00
parent 037e8f24c6
commit 35e19b4f30
5 changed files with 575 additions and 0 deletions

View File

@ -68,6 +68,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
ADD_SUBDIRECTORY(osggpx)
ADD_SUBDIRECTORY(osggraphicscost)
ADD_SUBDIRECTORY(osgmanipulator)
ADD_SUBDIRECTORY(osgimpostor)
ADD_SUBDIRECTORY(osgmovie)
ADD_SUBDIRECTORY(osgmultiplemovies)
ADD_SUBDIRECTORY(osgmultiplerendertargets)

View File

@ -0,0 +1,8 @@
#this file is automatically generated
SET(TARGET_SRC TestManipulator.cpp osgimpostor.cpp )
SET(TARGET_H TestManipulator.h )
SET(TARGET_ADDED_LIBRARIES osgSim )
#### end var setup ###
SETUP_EXAMPLE(osgimpostor)

View File

@ -0,0 +1,292 @@
/* OpenSceneGraph example, osgimpostor.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "TestManipulator.h"
#include <osg/Notify>
using namespace osg;
using namespace osgGA;
TestManipulator::TestManipulator()
{
_modelScale = 0.01f;
_minimumZoomScale = 0.05f;
_thrown = false;
_distance = 1.0f;
}
TestManipulator::~TestManipulator()
{
}
void TestManipulator::setNode(osg::Node* node)
{
_node = node;
if (_node.get())
{
const osg::BoundingSphere& boundingSphere=_node->getBound();
_modelScale = boundingSphere._radius;
}
}
const osg::Node* TestManipulator::getNode() const
{
return _node.get();
}
osg::Node* TestManipulator::getNode()
{
return _node.get();
}
/*ea*/
void TestManipulator::home(const GUIEventAdapter& ,GUIActionAdapter& us)
{
if(_node.get())
{
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));
us.requestRedraw();
}
}
void TestManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
{
flushMouseEventStack();
}
bool TestManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
{
switch(ea.getEventType())
{
case(GUIEventAdapter::PUSH):
{
flushMouseEventStack();
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
us.requestContinuousUpdate(false);
_thrown = false;
return true;
}
case(GUIEventAdapter::RELEASE):
{
if (ea.getButtonMask()==0)
{
if (isMouseMoving())
{
if (calcMovement())
{
us.requestRedraw();
us.requestContinuousUpdate(true);
_thrown = true;
}
}
else
{
flushMouseEventStack();
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
us.requestContinuousUpdate(false);
_thrown = false;
}
}
else
{
flushMouseEventStack();
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
us.requestContinuousUpdate(false);
_thrown = false;
}
return true;
}
case(GUIEventAdapter::DRAG):
{
addMouseEvent(ea);
if (calcMovement()) us.requestRedraw();
us.requestContinuousUpdate(false);
_thrown = false;
return true;
}
case(GUIEventAdapter::MOVE):
{
return false;
}
case(GUIEventAdapter::KEYDOWN):
if (ea.getKey()==' ')
{
flushMouseEventStack();
_thrown = false;
home(ea,us);
us.requestRedraw();
us.requestContinuousUpdate(false);
return true;
}
return false;
case(GUIEventAdapter::FRAME):
if (_thrown)
{
if (calcMovement()) us.requestRedraw();
return true;
}
return false;
default:
return false;
}
}
bool TestManipulator::isMouseMoving()
{
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
static const float velocity = 0.1f;
float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
float len = sqrtf(dx*dx+dy*dy);
float dt = _ga_t0->getTime()-_ga_t1->getTime();
return (len>dt*velocity);
}
void TestManipulator::flushMouseEventStack()
{
_ga_t1 = NULL;
_ga_t0 = NULL;
}
void TestManipulator::addMouseEvent(const GUIEventAdapter& ea)
{
_ga_t1 = _ga_t0;
_ga_t0 = &ea;
}
void TestManipulator::setByMatrix(const osg::Matrixd& matrix)
{
_center = matrix.getTrans();
_rotation = matrix.getRotate();
_distance = 1.0f;
}
osg::Matrixd TestManipulator::getMatrix() const
{
return osg::Matrixd::rotate(_rotation)*osg::Matrixd::translate(_center);
}
osg::Matrixd TestManipulator::getInverseMatrix() const
{
return osg::Matrixd::translate(-_center)*osg::Matrixd::rotate(_rotation.inverse());
}
void TestManipulator::computePosition(const osg::Vec3& eye,const osg::Vec3& lv,const osg::Vec3& up)
{
osg::Vec3 f(lv);
f.normalize();
osg::Vec3 s(f^up);
s.normalize();
osg::Vec3 u(s^f);
u.normalize();
osg::Matrixd rotation_matrix(s[0], u[0], -f[0], 0.0f,
s[1], u[1], -f[1], 0.0f,
s[2], u[2], -f[2], 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
_center = eye+lv;
_distance = lv.length();
_rotation = rotation_matrix.getRotate().inverse();
}
bool TestManipulator::calcMovement()
{
// return if less then two events have been added.
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
// return if there is no movement.
if (dx==0 && dy==0) return false;
unsigned int buttonMask = _ga_t1->getButtonMask();
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
// rotate camera.
osg::Quat new_rotate;
new_rotate.makeRotate(dx / 3.0f, osg::Vec3(0.0f, 0.0f, 1.0f));
_rotation = _rotation*new_rotate;
return true;
}
else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON)
{
// pan model.
osg::Vec3 dv = osg::Vec3(0.0f, 0.0f, -500.0f) * dy;
_center += dv;
return true;
}
else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
{
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;
osg::Vec3 dv = fv*(dy*-500.0f)-sv*(dx*500.0f);
_center += dv;
return true;
}
return false;
}

View File

@ -0,0 +1,103 @@
/* -*-c++-*-
*
* OpenSceneGraph example, osgimpostor.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef OSGGA_TESTMANIPULATOR
#define OSGGA_TESTMANIPULATOR 1
#include <osgGA/CameraManipulator>
#include <osg/Quat>
class TestManipulator : public osgGA::CameraManipulator
{
public:
TestManipulator();
virtual ~TestManipulator();
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByMatrix(const osg::Matrixd& matrix);
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
/** get the position of the manipulator as 4x4 Matrix.*/
virtual osg::Matrixd getMatrix() const;
/** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
virtual osg::Matrixd getInverseMatrix() const;
/** Attach a node to the manipulator.
Automatically detaches previously attached node.
setNode(NULL) detaches previously nodes.
Is ignored by manipulators which do not require a reference model.*/
virtual void setNode(osg::Node*);
/** Return node if attached.*/
virtual const osg::Node* getNode() const;
/** Return node if attached.*/
virtual osg::Node* getNode();
/** Move the camera to the default position.
May be ignored by manipulators if home functionality is not appropriate.*/
virtual void home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
/** Start/restart the manipulator.*/
virtual void init(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
/** handle events, return true if handled, false otherwise.*/
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us);
private:
/** Reset the internal GUIEvent stack.*/
void flushMouseEventStack();
/** Add the current mouse GUIEvent to internal stack.*/
void addMouseEvent(const osgGA::GUIEventAdapter& ea);
void computePosition(const osg::Vec3& eye,const osg::Vec3& lv,const osg::Vec3& up);
/** For the give mouse movement calculate the movement of the camera.
Return true is camera has moved and a redraw is required.*/
bool calcMovement();
/** Check the speed at which the mouse is moving.
If speed is below a threshold then return false, otherwise return true.*/
bool isMouseMoving();
// Internal event stack comprising last three mouse events.
osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t1;
osg::ref_ptr<const osgGA::GUIEventAdapter> _ga_t0;
osg::ref_ptr<osg::Node> _node;
float _modelScale;
float _minimumZoomScale;
bool _thrown;
osg::Vec3 _center;
osg::Quat _rotation;
float _distance;
};
#endif

View File

@ -0,0 +1,171 @@
/* OpenSceneGraph example, osgimpostor.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <osg/Geometry>
#include <osg/Material>
#include <osg/MatrixTransform>
#include <osg/Quat>
#include <osg/Geode>
#include <osgSim/Impostor>
#include <osgSim/InsertImpostorsVisitor>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>
#include "TestManipulator.h"
#include <iostream>
#include <list>
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// construct the viewer.
osgViewer::Viewer viewer;
// set up the camera manipulators.
{
osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
// add local test manipulator more suitable for testing impostors.
keyswitchManipulator->addMatrixManipulator( '0', "Test", new TestManipulator);
keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
keyswitchManipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() );
keyswitchManipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
keyswitchManipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
std::string pathfile;
double animationSpeed = 1.0;
while(arguments.read("--speed",animationSpeed) ) {}
char keyForAnimationPath = '8';
while (arguments.read("-p",pathfile))
{
osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
if (apm || !apm->valid())
{
apm->setTimeScale(animationSpeed);
unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
keyswitchManipulator->selectMatrixManipulator(num);
++keyForAnimationPath;
}
}
viewer.setCameraManipulator( keyswitchManipulator.get() );
}
viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
std::string output_filename;
arguments.read("-o", output_filename);
// load the nodes from the commandline arguments.
osg::ref_ptr<osg::Node> model = osgDB::readRefNodeFiles(arguments);
if (!model)
{
OSG_NOTICE<<"No model loaded, please specify and model on the the command line"<<std::endl;
return 0;
}
// the osgSim::InsertImpostorsVisitor used lower down to insert impostors
// only operators on subclass of Group's, if the model top node is not
// a group then it won't be able to insert an impostor. We therefore
// manually insert an impostor above the model.
if (dynamic_cast<osg::Group*>(model.get())==0)
{
const osg::BoundingSphere& bs = model->getBound();
if (bs.valid())
{
osgSim::Impostor* impostor = new osgSim::Impostor;
// standard LOD settings
impostor->addChild(model.get());
impostor->setRange(0,0.0f,1e7f);
impostor->setCenter(bs.center());
// impostor specfic settings.
impostor->setImpostorThresholdToBound(5.0f);
model = impostor;
}
}
// we insert an impostor node above the model, so we keep a handle
// on the rootnode of the model, the is required since the
// InsertImpostorsVisitor can add a new root in automatically and
// we would know about it, other than by following the parent path
// up from model. This is really what should be done, but I'll pass
// on it right now as it requires a getRoots() method to be added to
// osg::Node, and we're about to make a release so no new features!
osg::ref_ptr<osg::Group> rootnode = new osg::Group;
rootnode->addChild(model);
// now insert impostors in the model using the InsertImpostorsVisitor.
osgSim::InsertImpostorsVisitor ov;
// traverse the model and collect all osg::Group's and osg::LOD's.
// however, don't traverse the rootnode since we want to keep it as
// the start of traversal, otherwise the insertImpostor could insert
// and Impostor above the current root, making it nolonger a root!
model->accept(ov);
// insert the Impostors above groups and LOD's
ov.insertImpostors();
if (!output_filename.empty())
{
osgDB::writeNodeFile(*rootnode, output_filename);
return 1;
}
// add model to viewer.
viewer.setSceneData(rootnode);
return viewer.run();
}