From Cedric Pinson, Pulled in osgAnimation from OpenSceneGraph-osgWidget-dev into svn/trunk.
This commit is contained in:
@@ -108,6 +108,12 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgvertexprogram)
|
||||
ADD_SUBDIRECTORY(osgvolume)
|
||||
ADD_SUBDIRECTORY(osgwindows)
|
||||
ADD_SUBDIRECTORY(osganimationtimeline)
|
||||
ADD_SUBDIRECTORY(osganimationnode)
|
||||
ADD_SUBDIRECTORY(osganimationmakepath)
|
||||
ADD_SUBDIRECTORY(osganimationskinning)
|
||||
ADD_SUBDIRECTORY(osganimationsolid)
|
||||
# ADD_SUBDIRECTORY(osganimationviewer)
|
||||
|
||||
IF (POPPLER_FOUND AND CAIRO_FOUND)
|
||||
ADD_SUBDIRECTORY(osgpdf)
|
||||
@@ -176,6 +182,7 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
ADD_SUBDIRECTORY(osgwidgetwindow)
|
||||
ENDIF(BUILD_OSGWIDGET)
|
||||
|
||||
|
||||
IF (LIBVNCSERVER_FOUND)
|
||||
ADD_SUBDIRECTORY(osgvnc)
|
||||
ENDIF(LIBVNCSERVER_FOUND)
|
||||
|
||||
3
examples/osganimationmakepath/CMakeLists.txt
Normal file
3
examples/osganimationmakepath/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
SET(TARGET_SRC osganimationmakepath.cpp )
|
||||
SET(TARGET_ADDED_LIBRARIES osgAnimation )
|
||||
SETUP_EXAMPLE(osganimationmakepath)
|
||||
337
examples/osganimationmakepath/osganimationmakepath.cpp
Normal file
337
examples/osganimationmakepath/osganimationmakepath.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Jeremy Moles <jeremy@emperorlinux.com>
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Shape>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Material>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgAnimation/Sampler>
|
||||
|
||||
class AnimtkUpdateCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
META_Object(osgAnimation, AnimtkUpdateCallback);
|
||||
|
||||
AnimtkUpdateCallback()
|
||||
{
|
||||
_sampler = new osgAnimation::Vec3CubicBezierSampler;
|
||||
_playing = false;
|
||||
_lastUpdate = 0;
|
||||
}
|
||||
AnimtkUpdateCallback(const AnimtkUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(val, copyop),
|
||||
osg::NodeCallback(val, copyop),
|
||||
_sampler(val._sampler),
|
||||
_startTime(val._startTime),
|
||||
_currentTime(val._currentTime),
|
||||
_playing(val._playing),
|
||||
_lastUpdate(val._lastUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
/** Callback method called by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR &&
|
||||
nv->getFrameStamp() &&
|
||||
nv->getFrameStamp()->getFrameNumber() != _lastUpdate)
|
||||
{
|
||||
|
||||
_lastUpdate = nv->getFrameStamp()->getFrameNumber();
|
||||
_currentTime = osg::Timer::instance()->tick();
|
||||
|
||||
if (_playing && _sampler.get() && _sampler->getKeyframeContainer())
|
||||
{
|
||||
osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);
|
||||
if (transform) {
|
||||
osg::Vec3 result;
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
float duration = _sampler->getEndTime() - _sampler->getStartTime();
|
||||
t = fmod(t, duration);
|
||||
t += _sampler->getStartTime();
|
||||
_sampler->getValueAt(t, result);
|
||||
transform->setMatrix(osg::Matrix::translate(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
// note, callback is responsible for scenegraph traversal so
|
||||
// they must call traverse(node,nv) to ensure that the
|
||||
// scene graph subtree (and associated callbacks) are traversed.
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
|
||||
void stop() { _currentTime = _startTime; _playing = false;}
|
||||
|
||||
osg::ref_ptr<osgAnimation::Vec3CubicBezierSampler> _sampler;
|
||||
osg::Timer_t _startTime;
|
||||
osg::Timer_t _currentTime;
|
||||
bool _playing;
|
||||
int _lastUpdate;
|
||||
};
|
||||
|
||||
|
||||
class AnimtkStateSetUpdateCallback : public osg::StateSet::Callback
|
||||
{
|
||||
public:
|
||||
META_Object(osgAnimation, AnimtkStateSetUpdateCallback);
|
||||
|
||||
AnimtkStateSetUpdateCallback()
|
||||
{
|
||||
_sampler = new osgAnimation::Vec4LinearSampler;
|
||||
_playing = false;
|
||||
_lastUpdate = 0;
|
||||
}
|
||||
|
||||
AnimtkStateSetUpdateCallback(const AnimtkStateSetUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(val, copyop),
|
||||
osg::StateSet::Callback(val, copyop),
|
||||
_sampler(val._sampler),
|
||||
_startTime(val._startTime),
|
||||
_currentTime(val._currentTime),
|
||||
_playing(val._playing),
|
||||
_lastUpdate(val._lastUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
/** Callback method called by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(osg::StateSet* state, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (state &&
|
||||
nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR &&
|
||||
nv->getFrameStamp() &&
|
||||
nv->getFrameStamp()->getFrameNumber() != _lastUpdate) {
|
||||
|
||||
_lastUpdate = nv->getFrameStamp()->getFrameNumber();
|
||||
_currentTime = osg::Timer::instance()->tick();
|
||||
|
||||
if (_playing && _sampler.get() && _sampler->getKeyframeContainer())
|
||||
{
|
||||
osg::Material* material = dynamic_cast<osg::Material*>(state->getAttribute(osg::StateAttribute::MATERIAL));
|
||||
if (material)
|
||||
{
|
||||
osg::Vec4 result;
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
float duration = _sampler->getEndTime() - _sampler->getStartTime();
|
||||
t = fmod(t, duration);
|
||||
t += _sampler->getStartTime();
|
||||
_sampler->getValueAt(t, result);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
|
||||
void stop() { _currentTime = _startTime; _playing = false;}
|
||||
|
||||
osg::ref_ptr<osgAnimation::Vec4LinearSampler> _sampler;
|
||||
osg::Timer_t _startTime;
|
||||
osg::Timer_t _currentTime;
|
||||
bool _playing;
|
||||
int _lastUpdate;
|
||||
};
|
||||
|
||||
// This won't really give good results in any situation, but it does demonstrate
|
||||
// on possible "fast" usage...
|
||||
class MakePathTimeCallback: public AnimtkUpdateCallback
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> _geode;
|
||||
float _lastAdd;
|
||||
float _addSeconds;
|
||||
|
||||
public:
|
||||
MakePathTimeCallback(osg::Geode* geode):
|
||||
_geode(geode),
|
||||
_lastAdd(0.0f),
|
||||
_addSeconds(0.08f) {
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
|
||||
if(_lastAdd + _addSeconds <= t && t <= 8.0f)
|
||||
{
|
||||
osg::Vec3 pos;
|
||||
|
||||
_sampler->getValueAt(t, pos);
|
||||
|
||||
_geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(pos, 0.5f)));
|
||||
_geode->dirtyBound();
|
||||
|
||||
_lastAdd += _addSeconds;
|
||||
}
|
||||
|
||||
AnimtkUpdateCallback::operator()(node, nv);
|
||||
}
|
||||
};
|
||||
|
||||
// This will give great results if you DO NOT have VSYNC enabled and can generate
|
||||
// decent FPS.
|
||||
class MakePathDistanceCallback: public AnimtkUpdateCallback
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> _geode;
|
||||
osg::Vec3 _lastAdd;
|
||||
float _threshold;
|
||||
unsigned int _count;
|
||||
|
||||
public:
|
||||
MakePathDistanceCallback(osg::Geode* geode):
|
||||
_geode(geode),
|
||||
_threshold(0.5f),
|
||||
_count(0) {}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
static bool countReported = false;
|
||||
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
|
||||
osg::Vec3 pos;
|
||||
|
||||
_sampler->getValueAt(t, pos);
|
||||
|
||||
osg::Vec3 distance = _lastAdd - pos;
|
||||
|
||||
if(t <= 8.0f && distance.length() >= _threshold)
|
||||
{
|
||||
_geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(pos, 0.25f)));
|
||||
_lastAdd = pos;
|
||||
_count++;
|
||||
}
|
||||
else if(t > 8.0f)
|
||||
{
|
||||
if(!countReported) std::cout << "Created " << _count << " nodes." << std::endl;
|
||||
countReported = true;
|
||||
}
|
||||
|
||||
AnimtkUpdateCallback::operator()(node, nv);
|
||||
}
|
||||
};
|
||||
|
||||
osg::StateSet* setupStateSet()
|
||||
{
|
||||
osg::StateSet* st = new osg::StateSet();
|
||||
|
||||
st->setAttributeAndModes(new osg::Material(), true);
|
||||
st->setMode(GL_BLEND, true);
|
||||
|
||||
AnimtkStateSetUpdateCallback* callback = new AnimtkStateSetUpdateCallback();
|
||||
osgAnimation::Vec4KeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(0, osg::Vec4(1,0,0,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(2, osg::Vec4(0.,1,0,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(4, osg::Vec4(0,0,1,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(6, osg::Vec4(0,0,1,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(8, osg::Vec4(0,1,0,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(10, osg::Vec4(1,0,0,1)));
|
||||
callback->start();
|
||||
st->setUpdateCallback(callback);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
osg::MatrixTransform* setupAnimtkNode(osg::Geode* staticGeode)
|
||||
{
|
||||
osg::Vec3 v[4];
|
||||
|
||||
v[0] = osg::Vec3( 0, 0, 0);
|
||||
v[1] = osg::Vec3(20, 40, 60);
|
||||
v[2] = osg::Vec3(40, 60, 20);
|
||||
v[3] = osg::Vec3(60, 20, 40);
|
||||
v[4] = osg::Vec3( 0, 0, 0);
|
||||
|
||||
osg::MatrixTransform* node = new osg::MatrixTransform();
|
||||
AnimtkUpdateCallback* callback = new MakePathDistanceCallback(staticGeode);
|
||||
osgAnimation::Vec3CubicBezierKeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
|
||||
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(0, osgAnimation::Vec3CubicBezier(
|
||||
v[0],
|
||||
v[0] + (v[0] - v[3]),
|
||||
v[1] - (v[1] - v[0])
|
||||
)));
|
||||
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(2, osgAnimation::Vec3CubicBezier(
|
||||
v[1],
|
||||
v[1] + (v[1] - v[0]),
|
||||
v[2] - (v[2] - v[1])
|
||||
)));
|
||||
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(4, osgAnimation::Vec3CubicBezier(
|
||||
v[2],
|
||||
v[2] + (v[2] - v[1]),
|
||||
v[3] - (v[3] - v[2])
|
||||
)));
|
||||
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(6, osgAnimation::Vec3CubicBezier(
|
||||
v[3],
|
||||
v[3] + (v[3] - v[2]),
|
||||
v[4] - (v[4] - v[3])
|
||||
)));
|
||||
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(8, osgAnimation::Vec3CubicBezier(
|
||||
v[4],
|
||||
v[4] + (v[4] - v[3]),
|
||||
v[0] - (v[0] - v[4])
|
||||
)));
|
||||
|
||||
callback->start();
|
||||
node->setUpdateCallback(callback);
|
||||
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
|
||||
geode->setStateSet(setupStateSet());
|
||||
geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 2)));
|
||||
|
||||
node->addChild(geode);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
osgViewer::Viewer viewer;
|
||||
|
||||
osgGA::TrackballManipulator* tbm = new osgGA::TrackballManipulator();
|
||||
|
||||
viewer.setCameraManipulator(tbm);
|
||||
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
|
||||
osg::Group* root = new osg::Group();
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
|
||||
geode->setStateSet(setupStateSet());
|
||||
|
||||
root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,20), 50));
|
||||
root->addChild(setupAnimtkNode(geode));
|
||||
root->addChild(geode);
|
||||
|
||||
viewer.setSceneData(root);
|
||||
|
||||
// tbm->setDistance(150);
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
3
examples/osganimationnode/CMakeLists.txt
Normal file
3
examples/osganimationnode/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
#SET(TARGET_SRC osganimationnode.cpp )
|
||||
#SET(TARGET_ADDED_LIBRARIES osgAnimation )
|
||||
#SETUP_EXAMPLE(osganimationnode)
|
||||
272
examples/osganimationnode/osganimationnode.cpp
Normal file
272
examples/osganimationnode/osganimationnode.cpp
Normal file
@@ -0,0 +1,272 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Shape>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Material>
|
||||
#include <osgAnimation/Sampler>
|
||||
|
||||
class AnimtkUpdateCallback : public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
META_Object(osgAnimation, AnimtkUpdateCallback);
|
||||
|
||||
AnimtkUpdateCallback()
|
||||
{
|
||||
_sampler = new osgAnimation::Vec3CubicBezierSampler;
|
||||
_playing = false;
|
||||
_lastUpdate = 0;
|
||||
}
|
||||
AnimtkUpdateCallback(const AnimtkUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(val, copyop),
|
||||
osg::NodeCallback(val, copyop),
|
||||
_sampler(val._sampler),
|
||||
_startTime(val._startTime),
|
||||
_currentTime(val._currentTime),
|
||||
_playing(val._playing),
|
||||
_lastUpdate(val._lastUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
/** Callback method called by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR &&
|
||||
nv->getFrameStamp() &&
|
||||
nv->getFrameStamp()->getFrameNumber() != _lastUpdate) {
|
||||
|
||||
_lastUpdate = nv->getFrameStamp()->getFrameNumber();
|
||||
_currentTime = osg::Timer::instance()->tick();
|
||||
|
||||
if (_playing && _sampler.get() && _sampler->getKeyframeContainer()) {
|
||||
osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);
|
||||
if (transform) {
|
||||
osg::Vec3 result;
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
float duration = _sampler->getEndTime() - _sampler->getStartTime();
|
||||
t = fmod(t, duration);
|
||||
t += _sampler->getStartTime();
|
||||
_sampler->getValueAt(t, result);
|
||||
transform->setMatrix(osg::Matrix::translate(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
// note, callback is responsible for scenegraph traversal so
|
||||
// they must call traverse(node,nv) to ensure that the
|
||||
// scene graph subtree (and associated callbacks) are traversed.
|
||||
traverse(node,nv);
|
||||
}
|
||||
|
||||
void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
|
||||
void stop() { _currentTime = _startTime; _playing = false;}
|
||||
|
||||
osg::ref_ptr<osgAnimation::Vec3CubicBezierSampler> _sampler;
|
||||
osg::Timer_t _startTime;
|
||||
osg::Timer_t _currentTime;
|
||||
bool _playing;
|
||||
int _lastUpdate;
|
||||
};
|
||||
|
||||
|
||||
class AnimtkStateSetUpdateCallback : public osg::StateSet::Callback
|
||||
{
|
||||
public:
|
||||
META_Object(osgAnimation, AnimtkStateSetUpdateCallback);
|
||||
|
||||
AnimtkStateSetUpdateCallback()
|
||||
{
|
||||
_sampler = new osgAnimation::Vec4LinearSampler;
|
||||
_playing = false;
|
||||
_lastUpdate = 0;
|
||||
}
|
||||
|
||||
AnimtkStateSetUpdateCallback(const AnimtkStateSetUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(val, copyop),
|
||||
osg::StateSet::Callback(val, copyop),
|
||||
_sampler(val._sampler),
|
||||
_startTime(val._startTime),
|
||||
_currentTime(val._currentTime),
|
||||
_playing(val._playing),
|
||||
_lastUpdate(val._lastUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
/** Callback method called by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(osg::StateSet* state, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (state &&
|
||||
nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR &&
|
||||
nv->getFrameStamp() &&
|
||||
nv->getFrameStamp()->getFrameNumber() != _lastUpdate)
|
||||
{
|
||||
|
||||
_lastUpdate = nv->getFrameStamp()->getFrameNumber();
|
||||
_currentTime = osg::Timer::instance()->tick();
|
||||
|
||||
if (_playing && _sampler.get() && _sampler->getKeyframeContainer())
|
||||
{
|
||||
osg::Material* material = dynamic_cast<osg::Material*>(state->getAttribute(osg::StateAttribute::MATERIAL));
|
||||
if (material)
|
||||
{
|
||||
osg::Vec4 result;
|
||||
float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
|
||||
float duration = _sampler->getEndTime() - _sampler->getStartTime();
|
||||
t = fmod(t, duration);
|
||||
t += _sampler->getStartTime();
|
||||
_sampler->getValueAt(t, result);
|
||||
material->setDiffuse(osg::Material::FRONT_AND_BACK, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
|
||||
void stop() { _currentTime = _startTime; _playing = false;}
|
||||
|
||||
osg::ref_ptr<osgAnimation::Vec4LinearSampler> _sampler;
|
||||
osg::Timer_t _startTime;
|
||||
osg::Timer_t _currentTime;
|
||||
bool _playing;
|
||||
int _lastUpdate;
|
||||
};
|
||||
|
||||
|
||||
osg::Geode* createAxis()
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry());
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 10.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 10.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 10.0));
|
||||
geometry->setVertexArray (vertices.get());
|
||||
|
||||
osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
geometry->setColorArray (colors.get());
|
||||
|
||||
geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));
|
||||
|
||||
geode->addDrawable( geometry.get() );
|
||||
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
|
||||
return geode;
|
||||
}
|
||||
|
||||
osg::StateSet* setupStateSet()
|
||||
{
|
||||
osg::StateSet* st = new osg::StateSet;
|
||||
st->setAttributeAndModes(new osg::Material, true);
|
||||
st->setMode(GL_BLEND, true);
|
||||
AnimtkStateSetUpdateCallback* callback = new AnimtkStateSetUpdateCallback;
|
||||
osgAnimation::Vec4KeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(0, osg::Vec4(0,0,0,0)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(2, osg::Vec4(0.5,0,0,0.5)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(4, osg::Vec4(0,0.5,0,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(6, osg::Vec4(0,0,0.5,1)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(8, osg::Vec4(1,1,1,0.5)));
|
||||
keys->push_back(osgAnimation::Vec4Keyframe(10, osg::Vec4(0,0,0,0)));
|
||||
callback->start();
|
||||
st->setUpdateCallback(callback);
|
||||
return st;
|
||||
}
|
||||
|
||||
osg::Node* setupCube()
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,0.0f),2)));
|
||||
geode->setStateSet(setupStateSet());
|
||||
return geode;
|
||||
}
|
||||
|
||||
osg::MatrixTransform* setupAnimtkNode()
|
||||
{
|
||||
osg::Vec3 v[4];
|
||||
v[0] = osg::Vec3(0,0,0);
|
||||
v[1] = osg::Vec3(10,-50,0);
|
||||
v[2] = osg::Vec3(30,-10,20);
|
||||
v[3] = osg::Vec3(-10,20,-20);
|
||||
v[4] = osg::Vec3(0,0,0);
|
||||
osg::MatrixTransform* node = new osg::MatrixTransform;
|
||||
AnimtkUpdateCallback* callback = new AnimtkUpdateCallback;
|
||||
osgAnimation::Vec3CubicBezierKeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(0, osgAnimation::Vec3CubicBezier(
|
||||
v[0], // pos
|
||||
v[0] + (v[0] - v[3]), // p1
|
||||
v[1] - (v[1] - v[0]) // p2
|
||||
)));
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(2, osgAnimation::Vec3CubicBezier(
|
||||
v[1], // pos
|
||||
v[1] + (v[1] - v[0]),
|
||||
v[2] - (v[2] - v[1])
|
||||
)));
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(4, osgAnimation::Vec3CubicBezier(
|
||||
v[2], // pos
|
||||
v[2] + (v[2] - v[1]),
|
||||
v[3] - (v[3] - v[2])
|
||||
)));
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(6, osgAnimation::Vec3CubicBezier(
|
||||
v[3], // pos
|
||||
v[3] + (v[3] - v[2]),
|
||||
v[4] - (v[4] - v[3])
|
||||
)));
|
||||
keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(8, osgAnimation::Vec3CubicBezier(
|
||||
v[4], // pos
|
||||
v[4] + (v[4] - v[3]),
|
||||
v[0] - (v[0] - v[4])
|
||||
)));
|
||||
|
||||
callback->start();
|
||||
node->setUpdateCallback(callback);
|
||||
node->addChild(setupCube());
|
||||
return node;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
osgViewer::Viewer viewer;
|
||||
osgGA::TrackballManipulator* manipulator = new osgGA::TrackballManipulator();
|
||||
viewer.setCameraManipulator(manipulator);
|
||||
|
||||
osg::Group* root = new osg::Group;
|
||||
root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,10), 30));
|
||||
root->addChild(createAxis());
|
||||
|
||||
osg::MatrixTransform* node = setupAnimtkNode();
|
||||
node->addChild(createAxis());
|
||||
root->addChild(node);
|
||||
|
||||
viewer.setSceneData( root );
|
||||
viewer.realize();
|
||||
|
||||
while (!viewer.done())
|
||||
{
|
||||
viewer.frame();
|
||||
}
|
||||
|
||||
}
|
||||
3
examples/osganimationskinning/CMakeLists.txt
Normal file
3
examples/osganimationskinning/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
SET(TARGET_SRC osganimationskinning.cpp )
|
||||
SET(TARGET_ADDED_LIBRARIES osgAnimation )
|
||||
SETUP_EXAMPLE(osganimationskinning)
|
||||
267
examples/osganimationskinning/osganimationskinning.cpp
Normal file
267
examples/osganimationskinning/osganimationskinning.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Geode>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgUtil/SmoothingVisitor>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include <osgAnimation/Bone>
|
||||
#include <osgAnimation/Skeleton>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <osgAnimation/Skinning>
|
||||
|
||||
osg::Geode* createAxis()
|
||||
{
|
||||
osg::Geode* geode (new osg::Geode());
|
||||
osg::Geometry* geometry (new osg::Geometry());
|
||||
|
||||
osg::Vec3Array* vertices (new osg::Vec3Array());
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 1.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 1.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 1.0));
|
||||
geometry->setVertexArray (vertices);
|
||||
|
||||
osg::Vec4Array* colors (new osg::Vec4Array());
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
geometry->setColorArray (colors);
|
||||
|
||||
geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));
|
||||
|
||||
geode->addDrawable( geometry );
|
||||
return geode;
|
||||
}
|
||||
|
||||
osgAnimation::RigGeometry* createTesselatedBox(int nsplit, float size)
|
||||
{
|
||||
osgAnimation::RigGeometry* geometry = new osgAnimation::RigGeometry;
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
|
||||
osg::ref_ptr<osg::Vec3Array> colors (new osg::Vec3Array());
|
||||
geometry->setVertexArray (vertices.get());
|
||||
geometry->setColorArray (colors.get());
|
||||
geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);
|
||||
|
||||
float step = size / nsplit;
|
||||
float s = 0.5/4.0;
|
||||
for (int i = 0; i < nsplit; i++)
|
||||
{
|
||||
float x = -1 + i * step;
|
||||
std::cout << x << std::endl;
|
||||
vertices->push_back (osg::Vec3 ( x, s, s));
|
||||
vertices->push_back (osg::Vec3 ( x, -s, s));
|
||||
vertices->push_back (osg::Vec3 ( x, -s, -s));
|
||||
vertices->push_back (osg::Vec3 ( x, s, -s));
|
||||
osg::Vec3 c (0,0,0);
|
||||
c[i%3] = 1;
|
||||
colors->push_back (c);
|
||||
colors->push_back (c);
|
||||
colors->push_back (c);
|
||||
colors->push_back (c);
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::UIntArray> array = new osg::UIntArray;
|
||||
for (int i = 0; i < nsplit - 1; i++)
|
||||
{
|
||||
int base = i * 4;
|
||||
array->push_back(base);
|
||||
array->push_back(base+1);
|
||||
array->push_back(base+4);
|
||||
array->push_back(base+1);
|
||||
array->push_back(base+5);
|
||||
array->push_back(base+4);
|
||||
|
||||
array->push_back(base+3);
|
||||
array->push_back(base);
|
||||
array->push_back(base+4);
|
||||
array->push_back(base+7);
|
||||
array->push_back(base+3);
|
||||
array->push_back(base+4);
|
||||
|
||||
array->push_back(base+5);
|
||||
array->push_back(base+1);
|
||||
array->push_back(base+2);
|
||||
array->push_back(base+2);
|
||||
array->push_back(base+6);
|
||||
array->push_back(base+5);
|
||||
|
||||
array->push_back(base+2);
|
||||
array->push_back(base+3);
|
||||
array->push_back(base+7);
|
||||
array->push_back(base+6);
|
||||
array->push_back(base+2);
|
||||
array->push_back(base+7);
|
||||
}
|
||||
|
||||
geometry->addPrimitiveSet(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, array->size(), &array->front()));
|
||||
geometry->setUseDisplayList( false );
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
void initVertexMap(osgAnimation::Bone* b0,
|
||||
osgAnimation::Bone* b1,
|
||||
osgAnimation::Bone* b2,
|
||||
osgAnimation::RigGeometry* geom,
|
||||
osg::Vec3Array* array)
|
||||
{
|
||||
osgAnimation::VertexInfluenceSet vertexesInfluences;
|
||||
osgAnimation::VertexInfluenceMap* vim = new osgAnimation::VertexInfluenceMap;
|
||||
|
||||
(*vim)[b0->getName()].setName(b0->getName());
|
||||
(*vim)[b1->getName()].setName(b1->getName());
|
||||
(*vim)[b2->getName()].setName(b2->getName());
|
||||
|
||||
for (int i = 0; i < (int)array->size(); i++)
|
||||
{
|
||||
float val = (*array)[i][0];
|
||||
std::cout << val << std::endl;
|
||||
if (val >= -1 && val <= 0)
|
||||
(*vim)[b0->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
|
||||
else if ( val > 0 && val <= 1)
|
||||
(*vim)[b1->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
|
||||
else if ( val > 1)
|
||||
(*vim)[b2->getName()].push_back(osgAnimation::VertexIndexWeight(i,1));
|
||||
}
|
||||
|
||||
geom->setInfluenceMap(vim);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
osgViewer::Viewer viewer;
|
||||
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
|
||||
|
||||
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
|
||||
osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
|
||||
{
|
||||
root->setBindMatrixInBoneSpace(osg::Matrix::identity());
|
||||
root->setBindMatrixInBoneSpace(osg::Matrix::translate(-1,0,0));
|
||||
root->setName("root");
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
|
||||
right0->setBindMatrixInBoneSpace(osg::Matrix::translate(1,0,0));
|
||||
right0->setName("right0");
|
||||
|
||||
osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
|
||||
right1->setBindMatrixInBoneSpace(osg::Matrix::translate(1,0,0));
|
||||
right1->setName("right1");
|
||||
|
||||
root->addChild(right0.get());
|
||||
right0->addChild(right1.get());
|
||||
skelroot->addChild(root.get());
|
||||
|
||||
osg::ref_ptr<osgAnimation::AnimationManager> manager = new osgAnimation::AnimationManager;
|
||||
|
||||
osgAnimation::Animation* anim = new osgAnimation::Animation;
|
||||
{
|
||||
osgAnimation::QuatKeyframeContainer* keys0 = new osgAnimation::QuatKeyframeContainer;
|
||||
osg::Quat rotate;
|
||||
rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
|
||||
keys0->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
|
||||
keys0->push_back(osgAnimation::QuatKeyframe(3,rotate));
|
||||
keys0->push_back(osgAnimation::QuatKeyframe(6,rotate));
|
||||
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
|
||||
sampler->setKeyframeContainer(keys0);
|
||||
osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right0->getUpdateCallback());
|
||||
cb->setName("right0");
|
||||
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler);
|
||||
channel->setName("quaternion");
|
||||
channel->setTargetName("right0");
|
||||
//cb->link(channel);
|
||||
anim->addChannel(channel);
|
||||
}
|
||||
|
||||
{
|
||||
osgAnimation::QuatKeyframeContainer* keys1 = new osgAnimation::QuatKeyframeContainer;
|
||||
osg::Quat rotate;
|
||||
rotate.makeRotate(osg::PI_2, osg::Vec3(0,0,1));
|
||||
keys1->push_back(osgAnimation::QuatKeyframe(0,osg::Quat(0,0,0,1)));
|
||||
keys1->push_back(osgAnimation::QuatKeyframe(3,osg::Quat(0,0,0,1)));
|
||||
keys1->push_back(osgAnimation::QuatKeyframe(6,rotate));
|
||||
osgAnimation::QuatSphericalLinearSampler* sampler = new osgAnimation::QuatSphericalLinearSampler;
|
||||
sampler->setKeyframeContainer(keys1);
|
||||
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel(sampler);
|
||||
osgAnimation::AnimationUpdateCallback* cb = dynamic_cast<osgAnimation::AnimationUpdateCallback*>(right1->getUpdateCallback());
|
||||
cb->setName("right1");
|
||||
channel->setName("quaternion");
|
||||
channel->setTargetName("right1");
|
||||
//cb->link(channel);
|
||||
anim->addChannel(channel);
|
||||
}
|
||||
manager->registerAnimation(anim);
|
||||
manager->buildTargetReference();
|
||||
|
||||
// let's start !
|
||||
manager->playAnimation(anim);
|
||||
|
||||
// we will use local data from the skeleton
|
||||
osg::Group* scene = new osg::Group;
|
||||
osg::MatrixTransform* rootTransform = new osg::MatrixTransform;
|
||||
rootTransform->setMatrix(osg::Matrix::rotate(osg::PI_2,osg::Vec3(1,0,0)));
|
||||
right0->addChild(createAxis());
|
||||
right0->setDataVariance(osg::Object::DYNAMIC);
|
||||
right1->addChild(createAxis());
|
||||
right1->setDataVariance(osg::Object::DYNAMIC);
|
||||
osg::MatrixTransform* trueroot = new osg::MatrixTransform;
|
||||
trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
|
||||
trueroot->addChild(createAxis());
|
||||
trueroot->setDataVariance(osg::Object::DYNAMIC);
|
||||
rootTransform->addChild(manager.get());
|
||||
scene->addChild(rootTransform);
|
||||
manager->addChild(skelroot.get());
|
||||
|
||||
osgAnimation::RigGeometry* geom = createTesselatedBox(4, 4.0);
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(geom);
|
||||
skelroot->addChild(geode);
|
||||
osg::ref_ptr<osg::Vec3Array> src = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
|
||||
geom->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
|
||||
geom->setDataVariance(osg::Object::DYNAMIC);
|
||||
OSGANIMATION_ASSERT(src);
|
||||
|
||||
initVertexMap(root.get(), right0.get(), right1.get(), geom, src.get());
|
||||
|
||||
geom->buildVertexSet();
|
||||
geom->buildTransformer(skelroot.get());
|
||||
|
||||
// let's run !
|
||||
viewer.setSceneData( scene );
|
||||
viewer.realize();
|
||||
|
||||
while (!viewer.done())
|
||||
{
|
||||
viewer.frame();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
3
examples/osganimationsolid/CMakeLists.txt
Normal file
3
examples/osganimationsolid/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
SET(TARGET_SRC osganimationsolid.cpp )
|
||||
SET(TARGET_ADDED_LIBRARIES osgAnimation )
|
||||
SETUP_EXAMPLE(osganimationsolid)
|
||||
118
examples/osganimationsolid/osganimationsolid.cpp
Normal file
118
examples/osganimationsolid/osganimationsolid.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Shape>
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
#include <osgAnimation/AnimationManager>
|
||||
#include <osgAnimation/Channel>
|
||||
#include <osgAnimation/UpdateCallback>
|
||||
|
||||
using namespace osgAnimation;
|
||||
|
||||
osg::ref_ptr<osg::Geode> createAxis()
|
||||
{
|
||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode());
|
||||
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry());
|
||||
|
||||
osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 10.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 10.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
|
||||
vertices->push_back (osg::Vec3 ( 0.0, 0.0, 10.0));
|
||||
geometry->setVertexArray (vertices.get());
|
||||
|
||||
osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
|
||||
geometry->setColorArray (colors.get());
|
||||
|
||||
geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));
|
||||
|
||||
geode->addDrawable( geometry.get() );
|
||||
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
osgViewer::Viewer viewer;
|
||||
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
|
||||
|
||||
osg::Group* root = new osg::Group;
|
||||
|
||||
osg::ref_ptr<osg::Geode> axe = createAxis();
|
||||
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,0.0f),0.5)));
|
||||
|
||||
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform();
|
||||
trans->setName("AnimatedNode");
|
||||
trans->setDataVariance(osg::Object::DYNAMIC);
|
||||
trans->setUpdateCallback(new osgAnimation::UpdateTransform("AnimatedCallback"));
|
||||
trans->setMatrix(osg::Matrix::identity());
|
||||
trans->addChild (geode.get());
|
||||
|
||||
root->addChild (axe.get());
|
||||
root->addChild (trans.get());
|
||||
|
||||
// Define a scheduler for our animations
|
||||
osgAnimation::AnimationManager* mng = new osgAnimation::AnimationManager();
|
||||
|
||||
|
||||
mng->addChild(root);
|
||||
|
||||
// And we finaly define our channel
|
||||
osgAnimation::Vec3LinearChannel* channelAnimation1 = new osgAnimation::Vec3LinearChannel;
|
||||
channelAnimation1->setTargetName("AnimatedCallback");
|
||||
channelAnimation1->setName("position");
|
||||
channelAnimation1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(0, osg::Vec3(0,0,0)));
|
||||
channelAnimation1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(2, osg::Vec3(1,1,0)));
|
||||
osgAnimation::Animation* anim1 = new osgAnimation::Animation;
|
||||
anim1->addChannel(channelAnimation1);
|
||||
anim1->setPlaymode(osgAnimation::Animation::PPONG);
|
||||
|
||||
|
||||
osgAnimation::Vec3LinearChannel* channelAnimation2 = new osgAnimation::Vec3LinearChannel;
|
||||
channelAnimation2->setTargetName("AnimatedCallback");
|
||||
channelAnimation2->setName("euler");
|
||||
channelAnimation2->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(0, osg::Vec3(0,0,0)));
|
||||
channelAnimation2->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(1.5, osg::Vec3(2*osg::PI,0,0)));
|
||||
osgAnimation::Animation* anim2 = new osgAnimation::Animation;
|
||||
anim2->addChannel(channelAnimation2);
|
||||
anim2->setPlaymode(osgAnimation::Animation::LOOP);
|
||||
|
||||
|
||||
// We register all animation inside the scheduler
|
||||
mng->registerAnimation(anim1);
|
||||
mng->registerAnimation(anim2);
|
||||
|
||||
mng->playAnimation(anim1);
|
||||
mng->playAnimation(anim2);
|
||||
|
||||
viewer.setSceneData( mng );
|
||||
return viewer.run();
|
||||
}
|
||||
3
examples/osganimationtimeline/CMakeLists.txt
Normal file
3
examples/osganimationtimeline/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
SET(TARGET_SRC osganimationtimeline.cpp )
|
||||
SET(TARGET_ADDED_LIBRARIES osgAnimation )
|
||||
SETUP_EXAMPLE(osganimationtimeline)
|
||||
209
examples/osganimationtimeline/osganimationtimeline.cpp
Normal file
209
examples/osganimationtimeline/osganimationtimeline.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <osgDB/ReadFile>
|
||||
#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 <osgAnimation/Bone>
|
||||
#include <osgAnimation/Skeleton>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <osgAnimation/Skinning>
|
||||
#include <osgAnimation/Timeline>
|
||||
#include <osgAnimation/AnimationManagerBase>
|
||||
|
||||
|
||||
struct NoseBegin : public osgAnimation::Action::Callback
|
||||
{
|
||||
virtual void operator()(osgAnimation::Action* action)
|
||||
{
|
||||
std::cout << "sacrebleu, it scratches my nose, let me scratch it" << std::endl;
|
||||
std::cout << "process NoseBegin call back " << action->getName() << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct NoseEnd : public osgAnimation::Action::Callback
|
||||
{
|
||||
virtual void operator()(osgAnimation::Action* action)
|
||||
{
|
||||
std::cout << "shhhrt shrrrrt shhhhhhrrrrt, haaa it's better"<< std::endl;
|
||||
std::cout << "process NoseEnd call back " << action->getName() << std::endl << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct ExampleTimelineUsage : public osgGA::GUIEventHandler
|
||||
{
|
||||
osg::ref_ptr<osgAnimation::StripAnimation> _mainLoop;
|
||||
osg::ref_ptr<osgAnimation::StripAnimation> _scratchHead;
|
||||
osg::ref_ptr<osgAnimation::StripAnimation> _scratchNose;
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerTimeline> _manager;
|
||||
|
||||
bool _releaseKey;
|
||||
|
||||
ExampleTimelineUsage(osgAnimation::AnimationManagerTimeline* manager)
|
||||
{
|
||||
_releaseKey = false;
|
||||
_manager = manager;
|
||||
|
||||
osgAnimation::AnimationMap map = _manager->getAnimationMap();
|
||||
_mainLoop = new osgAnimation::StripAnimation(map["Idle_Main"].get(),0.0,0.0);
|
||||
_mainLoop->setLoop(0); // means forever
|
||||
|
||||
_scratchHead = new osgAnimation::StripAnimation(map["Idle_Head_Scratch.02"].get(),0.2,0.3);
|
||||
_scratchHead->setLoop(1); // one time
|
||||
|
||||
map["Idle_Nose_Scratch.01"]->setDuration(10.0); // set this animation duration to 10 seconds
|
||||
_scratchNose = new osgAnimation::StripAnimation(map["Idle_Nose_Scratch.01"].get(),0.2,0.3);
|
||||
_scratchNose->setLoop(1); // one time
|
||||
|
||||
// add the main loop at priority 0 at time 0.
|
||||
|
||||
osgAnimation::Timeline* tml = _manager->getTimeline();
|
||||
tml->play();
|
||||
tml->addActionAt(0.0, _mainLoop.get(), 0);
|
||||
|
||||
|
||||
// add a scratch head priority 1 at 3.0 second.
|
||||
tml->addActionAt(5.0, _scratchHead.get(), 1);
|
||||
|
||||
// populate time with scratch head
|
||||
for (int i = 1; i < 20; i++)
|
||||
{
|
||||
// we add a scratch head priority 1 each 10 second
|
||||
// note:
|
||||
// it's possible to add the same instance more then once on the timeline
|
||||
// the only things you need to take care is if you remove it. It will remove
|
||||
// all instance that exist on the timeline. If you need to differtiate
|
||||
// it's better to create a new instance
|
||||
tml->addActionAt(5.0 + 10.0 * i, _scratchHead.get(), 1);
|
||||
}
|
||||
|
||||
// we will add the scratch nose action only when the player hit a key
|
||||
// in the operator()
|
||||
|
||||
// now we will add callback at end and begin of animation of Idle_Nose_Scratch.02
|
||||
_scratchNose->setCallback(0.0, new NoseBegin);
|
||||
_scratchNose->setCallback(_scratchNose->getNumFrames()-1, new NoseEnd);
|
||||
}
|
||||
|
||||
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
|
||||
{
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
|
||||
{
|
||||
_releaseKey = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
|
||||
{
|
||||
if (_releaseKey) // we hit a key and release it execute an action
|
||||
{
|
||||
osgAnimation::Timeline* tml = _manager->getTimeline();
|
||||
// dont play if already playing
|
||||
if (!tml->isActive(_scratchNose.get()))
|
||||
{
|
||||
// add this animation on top of two other
|
||||
// we add one to evaluate the animation at the next frame, else we
|
||||
// will miss the current frame
|
||||
tml->addActionAt(tml->getCurrentFrame() + 1, _scratchNose.get(), 2);
|
||||
}
|
||||
_releaseKey = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(nv);
|
||||
if (ev && ev->getActionAdapter() && !ev->getEvents().empty())
|
||||
{
|
||||
for(osgGA::EventQueue::Events::iterator itr = ev->getEvents().begin();
|
||||
itr != ev->getEvents().end();
|
||||
++itr)
|
||||
{
|
||||
handleWithCheckAgainstIgnoreHandledEventsMask(*(*itr), *(ev->getActionAdapter()), node, nv);
|
||||
}
|
||||
}
|
||||
}
|
||||
traverse(node, nv);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
std::cerr << "This example workd only with osgAnimation/nathan.osg" << std::endl;
|
||||
|
||||
osg::ArgumentParser psr(&argc, argv);
|
||||
|
||||
osgViewer::Viewer viewer(psr);
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group();
|
||||
|
||||
std::string file = "osgAnimation/nathan.osg";
|
||||
if(argc >= 2)
|
||||
file = psr[1];
|
||||
|
||||
// replace the manager
|
||||
osgAnimation::AnimationManagerBase* animationManager = dynamic_cast<osgAnimation::AnimationManagerBase*>(osgDB::readNodeFile(file));
|
||||
if(!animationManager)
|
||||
{
|
||||
std::cerr << "Couldn't convert the file's toplevel object into an AnimationManager." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerTimeline> tl = new osgAnimation::AnimationManagerTimeline(*animationManager);
|
||||
|
||||
animationManager->removeChildren(0, animationManager->getNumChildren());
|
||||
ExampleTimelineUsage* callback = new ExampleTimelineUsage(tl.get());
|
||||
group->addChild(tl.get());
|
||||
group->setEventCallback(callback);
|
||||
group->setUpdateCallback(callback);
|
||||
|
||||
|
||||
// add the state manipulator
|
||||
viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
|
||||
|
||||
// add the thread model handler
|
||||
viewer.addEventHandler(new osgViewer::ThreadingHandler);
|
||||
|
||||
// add the window size toggle handler
|
||||
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
|
||||
|
||||
// add the stats handler
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
// add the help handler
|
||||
viewer.addEventHandler(new osgViewer::HelpHandler(psr.getApplicationUsage()));
|
||||
|
||||
// add the LOD Scale handler
|
||||
viewer.addEventHandler(new osgViewer::LODScaleHandler);
|
||||
|
||||
// add the screen capture handler
|
||||
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
|
||||
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
|
||||
|
||||
123
examples/osganimationviewer/AnimtkViewer
Normal file
123
examples/osganimationviewer/AnimtkViewer
Normal file
@@ -0,0 +1,123 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
* jeremy Moles <jeremy@emperorlinux.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ANIMTKVIEWER_H
|
||||
#define ANIMTKVIEWER_H
|
||||
|
||||
#include <osg/Node>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgAnimation/AnimationManager>
|
||||
|
||||
class AnimtkViewerModelController
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::string> AnimationMapVector;
|
||||
|
||||
static AnimtkViewerModelController& instance()
|
||||
{
|
||||
static AnimtkViewerModelController avmc;
|
||||
return avmc;
|
||||
}
|
||||
|
||||
static bool setModel(osgAnimation::AnimationManager* model)
|
||||
{
|
||||
AnimtkViewerModelController& self = instance();
|
||||
self._model = model;
|
||||
self._map = self._model->getAnimationMap();
|
||||
|
||||
for(osgAnimation::AnimationMap::iterator it = self._map.begin(); it != self._map.end(); it++)
|
||||
self._amv.push_back(it->first);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool list()
|
||||
{
|
||||
std::cout << "Animation List:" << std::endl;
|
||||
for(osgAnimation::AnimationMap::iterator it = _map.begin(); it != _map.end(); it++)
|
||||
std::cout << it->first << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool play()
|
||||
{
|
||||
if(_focus < _amv.size())
|
||||
{
|
||||
std::cout << "Play " << _amv[_focus] << std::endl;
|
||||
_model->playAnimation(_map[_amv[_focus]].get());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool stop()
|
||||
{
|
||||
if(_focus < _amv.size())
|
||||
{
|
||||
std::cout << "Stop " << _amv[_focus] << std::endl;
|
||||
_model->stopAnimation(_map[_amv[_focus]].get());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool next()
|
||||
{
|
||||
_focus = (_focus + 1) % _map.size();
|
||||
std::cout << "Current now is " << _amv[_focus] << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool previous()
|
||||
{
|
||||
_focus = (_map.size() + _focus - 1) % _map.size();
|
||||
std::cout << "Current now is " << _amv[_focus] << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool playByName(const std::string& name)
|
||||
{
|
||||
for(unsigned int i = 0; i < _amv.size(); i++) if(_amv[i] == name) _focus = i;
|
||||
_model->playAnimation(_map[name].get());
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string& getCurrentAnimationName() const
|
||||
{
|
||||
return _amv[_focus];
|
||||
}
|
||||
|
||||
const AnimationMapVector& getAnimationMap() const
|
||||
{
|
||||
return _amv;
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osgAnimation::AnimationManager> _model;
|
||||
osgAnimation::AnimationMap _map;
|
||||
AnimationMapVector _amv;
|
||||
unsigned int _focus;
|
||||
|
||||
AnimtkViewerModelController():
|
||||
_model(0),
|
||||
_focus(0) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
116
examples/osganimationviewer/AnimtkViewer.cpp
Normal file
116
examples/osganimationviewer/AnimtkViewer.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
* jeremy Moles <jeremy@emperorlinux.com>
|
||||
*/
|
||||
|
||||
#include "AnimtkViewerKeyHandler"
|
||||
#include "AnimtkViewerGUI"
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/io_utils>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Geode>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgWidget/ViewerEventHandlers>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
const int WIDTH = 1440;
|
||||
const int HEIGHT = 900;
|
||||
|
||||
|
||||
osg::Geode* createAxis()
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
osg::Geometry* geometry = new osg::Geometry();
|
||||
osg::Vec3Array* vertices = new osg::Vec3Array();
|
||||
osg::Vec4Array* colors = new osg::Vec4Array();
|
||||
|
||||
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
|
||||
vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
|
||||
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
|
||||
vertices->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
|
||||
vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
|
||||
vertices->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
|
||||
geometry->setVertexArray(vertices);
|
||||
geometry->setColorArray(colors);
|
||||
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
|
||||
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 6));
|
||||
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
|
||||
|
||||
geode->addDrawable(geometry);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
osg::ArgumentParser psr(&argc, argv);
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
std::cerr << "usage: AnimtkViewer <file.osg>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
osgViewer::Viewer viewer(psr);
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group();
|
||||
|
||||
osgAnimation::AnimationManager* animationManager = dynamic_cast<osgAnimation::AnimationManager*>(osgDB::readNodeFile(psr[1]));
|
||||
|
||||
if(!animationManager)
|
||||
{
|
||||
std::cerr << "Couldn't convert the file's toplevel object into an AnimationManager." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set our Singleton's model.
|
||||
AnimtkViewerModelController::setModel(animationManager);
|
||||
|
||||
animationManager->addChild(createAxis());
|
||||
|
||||
AnimtkViewerGUI* gui = new AnimtkViewerGUI(&viewer, WIDTH, HEIGHT, 0x1234);
|
||||
osg::Camera* camera = gui->createParentOrthoCamera();
|
||||
|
||||
animationManager->setNodeMask(0x0001);
|
||||
|
||||
group->addChild(animationManager);
|
||||
group->addChild(camera);
|
||||
|
||||
viewer.addEventHandler(new AnimtkKeyEventHandler());
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
|
||||
viewer.addEventHandler(new osgWidget::MouseHandler(gui));
|
||||
viewer.addEventHandler(new osgWidget::KeyboardHandler(gui));
|
||||
viewer.addEventHandler(new osgWidget::ResizeHandler(gui, camera));
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
viewer.setUpViewInWindow(40, 40, WIDTH, HEIGHT);
|
||||
|
||||
return viewer.run();
|
||||
}
|
||||
46
examples/osganimationviewer/AnimtkViewerGUI
Normal file
46
examples/osganimationviewer/AnimtkViewerGUI
Normal file
@@ -0,0 +1,46 @@
|
||||
/* -*-c++-*-
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Authors:
|
||||
|
||||
Jeremy Moles <jeremy@emperorlinux.com>
|
||||
Cedric Pinson <mornifle@plopbyte.net>
|
||||
*/
|
||||
|
||||
#ifndef ANIMTKVIEWERGUI_H
|
||||
#define ANIMTKVIEWERGUI_H
|
||||
|
||||
#include <osgWidget/WindowManager>
|
||||
|
||||
class AnimtkViewerGUI: public osgWidget::WindowManager {
|
||||
osg::ref_ptr<osgWidget::Box> _buttonBox;
|
||||
osg::ref_ptr<osgWidget::Box> _listBox;
|
||||
osg::ref_ptr<osgWidget::Box> _labelBox;
|
||||
|
||||
protected:
|
||||
osgWidget::Widget* _createButton(const std::string&);
|
||||
|
||||
bool _buttonPush(osgWidget::Event&);
|
||||
bool _listMouseHover(osgWidget::Event&);
|
||||
|
||||
void _createButtonBox();
|
||||
void _createListBox();
|
||||
void _createLabelBox();
|
||||
|
||||
public:
|
||||
AnimtkViewerGUI(osgViewer::View*, float, float, unsigned int);
|
||||
};
|
||||
|
||||
#endif
|
||||
407
examples/osganimationviewer/AnimtkViewerGUI.cpp
Normal file
407
examples/osganimationviewer/AnimtkViewerGUI.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*
|
||||
* Authors:
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
* jeremy Moles <jeremy@emperorlinux.com>
|
||||
*/
|
||||
|
||||
#include "AnimtkViewer"
|
||||
#include "AnimtkViewerGUI"
|
||||
|
||||
#include <osg/Version>
|
||||
#include <osgWidget/WindowManager>
|
||||
#include <osgAnimation/EaseMotion>
|
||||
|
||||
const std::string IMAGE_PATH = "osgAnimation/Images/";
|
||||
|
||||
template <class T>
|
||||
struct Sampler: public osg::Drawable::UpdateCallback
|
||||
{
|
||||
T _motion;
|
||||
Sampler() {
|
||||
}
|
||||
};
|
||||
|
||||
typedef Sampler<osgAnimation::OutQuadMotion> WidgetSampler;
|
||||
|
||||
struct ButtonFunctor: public WidgetSampler
|
||||
{
|
||||
float _direction;
|
||||
float _previous;
|
||||
|
||||
const float _speed;
|
||||
|
||||
ButtonFunctor(): _speed(5) { _direction = -_speed; _previous = 0;}
|
||||
|
||||
bool enter(osgWidget::Event& ev)
|
||||
{
|
||||
_direction = _speed;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool leave(osgWidget::Event& ev)
|
||||
{
|
||||
_direction = -_speed;
|
||||
return true;
|
||||
}
|
||||
|
||||
void update(osg::NodeVisitor* nv , osg::Drawable* geom)
|
||||
{
|
||||
const osg::FrameStamp* f = nv->getFrameStamp();
|
||||
float dt = f->getSimulationTime() - _previous;
|
||||
_previous = f->getSimulationTime();
|
||||
update(dt,dynamic_cast<osgWidget::Widget*>(geom));
|
||||
}
|
||||
|
||||
void update(float t, osgWidget::Widget* w)
|
||||
{
|
||||
if (!w) return;
|
||||
_motion.update(t*_direction);
|
||||
float val = _motion.getValue()*0.5;
|
||||
val += 0.5;
|
||||
if (val >= 1.0)
|
||||
val = 1.0;
|
||||
w->setColor(osg::Vec4(val, val, val, 1));
|
||||
}
|
||||
};
|
||||
|
||||
struct LabelFunctor: public WidgetSampler
|
||||
{
|
||||
float _previous;
|
||||
bool _active;
|
||||
|
||||
const float _fadeOutTime;
|
||||
|
||||
osgAnimation::OutCubicMotion _scaleSampler;
|
||||
|
||||
LabelFunctor():
|
||||
_fadeOutTime(1.5f)
|
||||
{
|
||||
_previous = 0.0f;
|
||||
_active = false;
|
||||
|
||||
_scaleSampler = osgAnimation::OutCubicMotion(0.5, 1.0, 1.0);
|
||||
}
|
||||
|
||||
void setActive(bool active)
|
||||
{
|
||||
_active = active;
|
||||
|
||||
if(active) _motion.reset();
|
||||
|
||||
_scaleSampler.reset();
|
||||
}
|
||||
|
||||
void update(osg::NodeVisitor* nv , osg::Drawable* geom)
|
||||
{
|
||||
const osg::FrameStamp* f = nv->getFrameStamp();
|
||||
|
||||
float st = f->getSimulationTime();
|
||||
float dt = st - _previous;
|
||||
|
||||
_previous = st;
|
||||
|
||||
if(!_active) return;
|
||||
|
||||
update(dt, dynamic_cast<osgWidget::Label*>(geom));
|
||||
updateScale(dt, dynamic_cast<osgWidget::Label*>(geom));
|
||||
}
|
||||
|
||||
void update(float t, osgWidget::Label* w)
|
||||
{
|
||||
if(!w) return;
|
||||
|
||||
_motion.update(t / _fadeOutTime);
|
||||
|
||||
float val = _motion.getValue();
|
||||
|
||||
if(val >= 1.0f) {
|
||||
_motion.reset();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
w->setFontColor(osg::Vec4(0.0f, 0.0f, 0.0f, (1.0f - val) * 0.7f));
|
||||
}
|
||||
|
||||
void updateScale(float t, osgWidget::Label* w)
|
||||
{
|
||||
_scaleSampler.update(t);
|
||||
float val = _scaleSampler.getValue();
|
||||
osgWidget::Window* win = w->getParent();
|
||||
win->setScale(val);
|
||||
win->update();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct ListFunctor: public osg::NodeCallback
|
||||
{
|
||||
float _previous;
|
||||
int _direction;
|
||||
|
||||
osgAnimation::InQuadMotion _transformSampler;
|
||||
|
||||
ListFunctor()
|
||||
{
|
||||
_direction = 1;
|
||||
_previous = 0;
|
||||
|
||||
_transformSampler.update(1.0f);
|
||||
}
|
||||
|
||||
void toggleShown()
|
||||
{
|
||||
if(_direction == 1) _direction = -1;
|
||||
|
||||
else _direction = 1;
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
const osg::FrameStamp* f = nv->getFrameStamp();
|
||||
|
||||
float st = f->getSimulationTime();
|
||||
float dt = st - _previous;
|
||||
|
||||
_previous = st;
|
||||
|
||||
_transformSampler.update((dt * _direction) / 0.5f);
|
||||
|
||||
float val = _transformSampler.getValue();
|
||||
|
||||
if(val > 1.0f || val < 0.0f) return;
|
||||
|
||||
osgWidget::Window* win = dynamic_cast<osgWidget::Window*>(node);
|
||||
|
||||
float w = win->getWidth();
|
||||
float wmw = win->getWindowManager()->getWidth();
|
||||
|
||||
win->setX((wmw - w) + (val * w));
|
||||
win->update();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This is a temporary hack to "prevent" dragging on Widgets and Windows.
|
||||
bool eatDrag(osgWidget::Event&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AnimtkViewerGUI::AnimtkViewerGUI(osgViewer::View* view, float w, float h, unsigned int mask):
|
||||
osgWidget::WindowManager(view, w, h, mask, 0)
|
||||
{
|
||||
_createButtonBox();
|
||||
_createLabelBox();
|
||||
_createListBox();
|
||||
|
||||
_labelBox->setAnchorHorizontal(osgWidget::Window::HA_LEFT);
|
||||
_labelBox->setY(74.0f);
|
||||
_labelBox->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
|
||||
|
||||
_listBox->setOrigin(getWidth(), 74.0f);
|
||||
|
||||
addChild(_buttonBox.get());
|
||||
addChild(_labelBox.get());
|
||||
addChild(_listBox.get());
|
||||
|
||||
resizeAllWindows();
|
||||
|
||||
// Remember, you can't call resizePercent until AFTER the box is parented
|
||||
// by a WindowManager; how could it possibly resize itself if it doesn't know
|
||||
// how large it's viewable area is?
|
||||
_buttonBox->resizePercent(100.0f);
|
||||
_buttonBox->resizeAdd(0.0f, 10.0f);
|
||||
}
|
||||
|
||||
osgWidget::Widget* AnimtkViewerGUI::_createButton(const std::string& name)
|
||||
{
|
||||
osgWidget::Widget* b = new osgWidget::Widget(name, 64.0f, 64.0f);
|
||||
|
||||
if(!b) return 0;
|
||||
|
||||
b->setImage(IMAGE_PATH + name + ".png", true);
|
||||
b->setEventMask(osgWidget::EVENT_MASK_MOUSE_DRAG);
|
||||
|
||||
ButtonFunctor* bt = new ButtonFunctor();
|
||||
b->setUpdateCallback(bt);
|
||||
|
||||
b->addCallback(new osgWidget::Callback(&ButtonFunctor::enter, bt, osgWidget::EVENT_MOUSE_ENTER));
|
||||
b->addCallback(new osgWidget::Callback(&ButtonFunctor::leave, bt, osgWidget::EVENT_MOUSE_LEAVE));
|
||||
b->addCallback(new osgWidget::Callback(&AnimtkViewerGUI::_buttonPush, this, osgWidget::EVENT_MOUSE_PUSH));
|
||||
b->addCallback(new osgWidget::Callback(&eatDrag, osgWidget::EVENT_MOUSE_DRAG));
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
bool AnimtkViewerGUI::_listMouseHover(osgWidget::Event& ev)
|
||||
{
|
||||
osgWidget::Label* l = dynamic_cast<osgWidget::Label*>(ev.getWidget());
|
||||
|
||||
if(!l) return false;
|
||||
|
||||
if(ev.type == osgWidget::EVENT_MOUSE_ENTER) l->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
else if(ev.type == osgWidget::EVENT_MOUSE_LEAVE) l->setFontColor(1.0f, 1.0f, 1.0f, 0.3f);
|
||||
|
||||
else if(ev.type == osgWidget::EVENT_MOUSE_PUSH) {
|
||||
AnimtkViewerModelController::instance().playByName(ev.getWidget()->getName());
|
||||
}
|
||||
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AnimtkViewerGUI::_buttonPush(osgWidget::Event& ev)
|
||||
{
|
||||
if(!ev.getWidget()) return false;
|
||||
|
||||
osgWidget::Label* l = static_cast<osgWidget::Label*>(_labelBox->getByName("label"));
|
||||
|
||||
if(!l) return false;
|
||||
|
||||
LabelFunctor* lf = dynamic_cast<LabelFunctor*>(l->getUpdateCallback());
|
||||
|
||||
if(!lf) return false;
|
||||
|
||||
// We're safe at this point, so begin processing.
|
||||
AnimtkViewerModelController& mc = AnimtkViewerModelController::instance();
|
||||
std::string name = ev.getWidget()->getName();
|
||||
|
||||
if(name == "play") mc.play();
|
||||
|
||||
else if(name == "stop") mc.stop();
|
||||
|
||||
else if(name == "next")
|
||||
{
|
||||
mc.next();
|
||||
|
||||
l->setFontColor(osg::Vec4(0.0f, 0.0f, 0.0f, 0.7f));
|
||||
l->setLabel(mc.getCurrentAnimationName());
|
||||
lf->setActive(true);
|
||||
}
|
||||
|
||||
else if(name == "back")
|
||||
{
|
||||
mc.previous();
|
||||
|
||||
l->setFontColor(osg::Vec4(0.0f, 0.0f, 0.0f, 0.7f));
|
||||
l->setLabel(mc.getCurrentAnimationName());
|
||||
lf->setActive(true);
|
||||
}
|
||||
|
||||
else if(name == "pause")
|
||||
{
|
||||
}
|
||||
|
||||
else if(name == "open")
|
||||
{
|
||||
ListFunctor* lsf = dynamic_cast<ListFunctor*>(_listBox->getUpdateCallback());
|
||||
|
||||
if(!lsf) return false;
|
||||
|
||||
lsf->toggleShown();
|
||||
}
|
||||
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimtkViewerGUI::_createButtonBox()
|
||||
{
|
||||
_buttonBox = new osgWidget::Box("buttonBox", osgWidget::Box::HORIZONTAL);
|
||||
|
||||
osgWidget::Widget* space = new osgWidget::Widget("nullSpace", 0.0f, 0.0f);
|
||||
osgWidget::Widget* back = _createButton("back");
|
||||
osgWidget::Widget* next = _createButton("next");
|
||||
osgWidget::Widget* play = _createButton("play");
|
||||
osgWidget::Widget* pause = _createButton("pause");
|
||||
osgWidget::Widget* stop = _createButton("stop");
|
||||
osgWidget::Widget* open = _createButton("open");
|
||||
|
||||
space->setCanFill(true);
|
||||
space->setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
_buttonBox->addWidget(space);
|
||||
_buttonBox->addWidget(back);
|
||||
_buttonBox->addWidget(next);
|
||||
_buttonBox->addWidget(play);
|
||||
_buttonBox->addWidget(pause);
|
||||
_buttonBox->addWidget(stop);
|
||||
_buttonBox->addWidget(open);
|
||||
_buttonBox->addWidget(osg::clone(space, "space1", osg::CopyOp::DEEP_COPY_ALL));
|
||||
_buttonBox->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.7f);
|
||||
|
||||
_buttonBox->setEventMask(osgWidget::EVENT_MASK_MOUSE_DRAG);
|
||||
_buttonBox->addCallback(new osgWidget::Callback(&eatDrag, osgWidget::EVENT_MOUSE_DRAG));
|
||||
}
|
||||
|
||||
void AnimtkViewerGUI::_createListBox()
|
||||
{
|
||||
_listBox = new osgWidget::Box("listBox", osgWidget::Box::VERTICAL);
|
||||
|
||||
const AnimtkViewerModelController::AnimationMapVector& amv =
|
||||
AnimtkViewerModelController::instance().getAnimationMap()
|
||||
;
|
||||
|
||||
for(
|
||||
AnimtkViewerModelController::AnimationMapVector::const_iterator i = amv.begin();
|
||||
i != amv.end();
|
||||
i++
|
||||
)
|
||||
{
|
||||
osgWidget::Label* label = new osgWidget::Label(*i);
|
||||
|
||||
label->setCanFill(true);
|
||||
label->setFont("fonts/Vera.ttf");
|
||||
label->setFontSize(15);
|
||||
label->setFontColor(1.0f, 1.0f, 1.0f, 0.3f);
|
||||
label->setPadding(5.0f);
|
||||
label->setAlignHorizontal(osgWidget::Widget::HA_RIGHT);
|
||||
label->setLabel(*i);
|
||||
label->setEventMask(osgWidget::EVENT_MASK_MOUSE_DRAG);
|
||||
label->addCallback(new osgWidget::Callback(&AnimtkViewerGUI::_listMouseHover, this, osgWidget::EVENT_MOUSE_ENTER));
|
||||
label->addCallback(new osgWidget::Callback(&AnimtkViewerGUI::_listMouseHover, this, osgWidget::EVENT_MOUSE_LEAVE));
|
||||
label->addCallback(new osgWidget::Callback(&AnimtkViewerGUI::_listMouseHover, this, osgWidget::EVENT_MOUSE_PUSH));
|
||||
|
||||
_listBox->addWidget(label);
|
||||
}
|
||||
|
||||
ListFunctor* lf = new ListFunctor();
|
||||
|
||||
_listBox->setUpdateCallback(lf);
|
||||
_listBox->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.7f);
|
||||
}
|
||||
|
||||
void AnimtkViewerGUI::_createLabelBox()
|
||||
{
|
||||
_labelBox = new osgWidget::Box("labelBox", osgWidget::Box::VERTICAL);
|
||||
|
||||
osgWidget::Label* label = new osgWidget::Label("label");
|
||||
|
||||
label->setFont("fonts/Vera.ttf");
|
||||
label->setFontSize(50);
|
||||
label->setFontColor(0.0f, 0.0f, 0.0f, 0.7f);
|
||||
label->setAlignHorizontal(osgWidget::Widget::HA_LEFT);
|
||||
label->setPadding(10.0f);
|
||||
|
||||
LabelFunctor* lf = new LabelFunctor();
|
||||
label->setUpdateCallback(lf);
|
||||
|
||||
_labelBox->addWidget(label);
|
||||
_labelBox->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
53
examples/osganimationviewer/AnimtkViewerKeyHandler
Normal file
53
examples/osganimationviewer/AnimtkViewerKeyHandler
Normal file
@@ -0,0 +1,53 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ANIMTKVIEWER_KEYHANDLER_H
|
||||
#define ANIMTKVIEWER_KEYHANDLER_H
|
||||
|
||||
#include "AnimtkViewer"
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
class AnimtkKeyEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
AnimtkKeyEventHandler();
|
||||
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa,
|
||||
osg::Object*, osg::NodeVisitor*);
|
||||
void printUsage() const;
|
||||
|
||||
protected:
|
||||
|
||||
enum Binding
|
||||
{
|
||||
List,
|
||||
Help,
|
||||
Play,
|
||||
Next,
|
||||
Prev,
|
||||
};
|
||||
|
||||
std::map<Binding, int> _actionKeys;
|
||||
};
|
||||
|
||||
#endif
|
||||
63
examples/osganimationviewer/AnimtkViewerKeyHandler.cpp
Normal file
63
examples/osganimationviewer/AnimtkViewerKeyHandler.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* Cedric Pinson <mornifle@plopbyte.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AnimtkViewerKeyHandler"
|
||||
|
||||
AnimtkKeyEventHandler::AnimtkKeyEventHandler()
|
||||
{
|
||||
_actionKeys[List] = 'l';
|
||||
_actionKeys[Help] = 'h';
|
||||
_actionKeys[Play] = 'p';
|
||||
_actionKeys[Next] = ']';
|
||||
_actionKeys[Prev] = '[';
|
||||
}
|
||||
|
||||
void AnimtkKeyEventHandler::printUsage() const
|
||||
{
|
||||
std::cout << (char) _actionKeys.find(Help)->second << " for Help" << std::endl;
|
||||
std::cout << (char) _actionKeys.find(List)->second << " for List" << std::endl;
|
||||
std::cout << (char) _actionKeys.find(Play)->second << " for Play" << std::endl;
|
||||
std::cout << (char) _actionKeys.find(Next)->second << " for selext Next item" << std::endl;
|
||||
std::cout << (char) _actionKeys.find(Prev)->second << " for selext Previous item" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
bool AnimtkKeyEventHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa,
|
||||
osg::Object*, osg::NodeVisitor*)
|
||||
{
|
||||
AnimtkViewerModelController& mc = AnimtkViewerModelController::instance();
|
||||
if(ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN)
|
||||
{
|
||||
if (ea.getKey() == _actionKeys[List]) return mc.list();
|
||||
else if (ea.getKey() == _actionKeys[Play]) return mc.play();
|
||||
else if (ea.getKey() == _actionKeys[Next]) return mc.next();
|
||||
else if (ea.getKey() == _actionKeys[Prev]) return mc.previous();
|
||||
else if (ea.getKey() == _actionKeys[Help])
|
||||
{
|
||||
printUsage();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
7
examples/osganimationviewer/CMakeLists.txt
Normal file
7
examples/osganimationviewer/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
SET(TARGET_SRC
|
||||
AnimtkViewer.cpp
|
||||
AnimtkViewerKeyHandler.cpp
|
||||
AnimtkViewerGUI.cpp
|
||||
)
|
||||
SET(TARGET_ADDED_LIBRARIES osgAnimation osgWidget)
|
||||
SETUP_EXAMPLE(osganimationviewer)
|
||||
Reference in New Issue
Block a user