From Cedric Pinson and Jeremey Moles, Changes to OpenSceneGraph-osgWidget-dev branch.

Notes from Robert Osfield, Merged changes to OpenSceneGraph-osgWidget-dev r9367 (prior to my botched attempt at merged svn/trunk into the branch).
This commit is contained in:
Robert Osfield 2008-12-16 20:29:00 +00:00
parent 3313327ab4
commit 60fc821764
36 changed files with 1218 additions and 836 deletions

View File

@ -234,10 +234,10 @@ public:
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)));
@ -248,7 +248,7 @@ osg::StateSet* setupStateSet()
keys->push_back(osgAnimation::Vec4Keyframe(10, osg::Vec4(1,0,0,1)));
callback->start();
st->setUpdateCallback(callback);
return st;
}
@ -300,10 +300,10 @@ osg::MatrixTransform* setupAnimtkNode(osg::Geode* staticGeode)
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;
@ -312,7 +312,7 @@ osg::MatrixTransform* setupAnimtkNode(osg::Geode* staticGeode)
int main(int argc, char** argv)
{
osgViewer::Viewer viewer;
osgGA::TrackballManipulator* tbm = new osgGA::TrackballManipulator();
viewer.setCameraManipulator(tbm);

View File

@ -25,6 +25,7 @@
#include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/Skinning>
#include <osgAnimation/BasicAnimationManager>
osg::Geode* createAxis()
{
@ -178,7 +179,9 @@ int main (int argc, char* argv[])
right0->addChild(right1.get());
skelroot->addChild(root.get());
osg::ref_ptr<osgAnimation::AnimationManager> manager = new osgAnimation::AnimationManager;
osg::Group* scene = new osg::Group;
osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
scene->setUpdateCallback(manager.get());
osgAnimation::Animation* anim = new osgAnimation::Animation;
{
@ -223,7 +226,6 @@ int main (int argc, char* argv[])
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());
@ -234,9 +236,9 @@ int main (int argc, char* argv[])
trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
trueroot->addChild(createAxis());
trueroot->setDataVariance(osg::Object::DYNAMIC);
rootTransform->addChild(manager.get());
// rootTransform->addChild(scene.get());
scene->addChild(rootTransform);
manager->addChild(skelroot.get());
// manager->addChild(skelroot.get());
osgAnimation::RigGeometry* geom = createTesselatedBox(4, 4.0);
osg::Geode* geode = new osg::Geode;

View File

@ -20,7 +20,7 @@
#include <osgGA/TrackballManipulator>
#include <osg/MatrixTransform>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/Channel>
#include <osgAnimation/UpdateCallback>
@ -80,10 +80,11 @@ int main (int argc, char* argv[])
root->addChild (trans.get());
// Define a scheduler for our animations
osgAnimation::AnimationManager* mng = new osgAnimation::AnimationManager();
osg::Group* grp = new osg::Group;
osgAnimation::BasicAnimationManager* mng = new osgAnimation::BasicAnimationManager();
grp->setUpdateCallback(mng);
mng->addChild(root);
grp->addChild(root);
// And we finaly define our channel
osgAnimation::Vec3LinearChannel* channelAnimation1 = new osgAnimation::Vec3LinearChannel;
@ -113,6 +114,6 @@ int main (int argc, char* argv[])
mng->playAnimation(anim1);
mng->playAnimation(anim2);
viewer.setSceneData( mng );
viewer.setSceneData( grp );
return viewer.run();
}

View File

@ -29,6 +29,7 @@
#include <osgAnimation/Skinning>
#include <osgAnimation/Timeline>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/TimelineAnimationManager>
struct NoseBegin : public osgAnimation::Action::Callback
@ -54,16 +55,20 @@ 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;
osg::ref_ptr<osgAnimation::TimelineAnimationManager> _manager;
bool _releaseKey;
ExampleTimelineUsage(osgAnimation::AnimationManagerTimeline* manager)
ExampleTimelineUsage(osgAnimation::TimelineAnimationManager* manager)
{
_releaseKey = false;
_manager = manager;
osgAnimation::AnimationMap map = _manager->getAnimationMap();
const osgAnimation::AnimationList& list = _manager->getAnimationList();
osgAnimation::AnimationMap map;
for (osgAnimation::AnimationList::const_iterator it = list.begin(); it != list.end(); it++)
map[(*it)->getName()] = *it;
_mainLoop = new osgAnimation::StripAnimation(map["Idle_Main"].get(),0.0,0.0);
_mainLoop->setLoop(0); // means forever
@ -157,27 +162,26 @@ int main (int argc, char* argv[])
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));
osg::Group* root = dynamic_cast<osg::Group*>(osgDB::readNodeFile(file));
osgAnimation::AnimationManagerBase* animationManager = dynamic_cast<osgAnimation::AnimationManagerBase*>(root->getUpdateCallback());
if(!animationManager)
{
std::cerr << "Couldn't convert the file's toplevel object into an AnimationManager." << std::endl;
std::cerr << "Did not found AnimationManagerBase updateCallback needed to animate elements" << std::endl;
return 1;
}
osg::ref_ptr<osgAnimation::AnimationManagerTimeline> tl = new osgAnimation::AnimationManagerTimeline(*animationManager);
animationManager->removeChildren(0, animationManager->getNumChildren());
osg::ref_ptr<osgAnimation::TimelineAnimationManager> tl = new osgAnimation::TimelineAnimationManager(*animationManager);
root->setUpdateCallback(tl);
ExampleTimelineUsage* callback = new ExampleTimelineUsage(tl.get());
group->addChild(tl.get());
group->setEventCallback(callback);
group->setUpdateCallback(callback);
root->setEventCallback(callback);
root->getUpdateCallback()->addNestedCallback(callback);
// add the state manipulator
@ -201,7 +205,7 @@ int main (int argc, char* argv[])
// add the screen capture handler
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer.setSceneData(group.get());
viewer.setSceneData(root);
return viewer.run();
}

View File

@ -22,7 +22,7 @@
#include <osg/Node>
#include <osgDB/ReadFile>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/BasicAnimationManager>
class AnimtkViewerModelController
{
@ -35,11 +35,12 @@ public:
return avmc;
}
static bool setModel(osgAnimation::AnimationManager* model)
static bool setModel(osgAnimation::BasicAnimationManager* model)
{
AnimtkViewerModelController& self = instance();
self._model = model;
self._map = self._model->getAnimationMap();
for (osgAnimation::AnimationList::const_iterator it = self._model->getAnimationList().begin(); it != self._model->getAnimationList().end(); it++)
self._map[(*it)->getName()] = *it;
for(osgAnimation::AnimationMap::iterator it = self._map.begin(); it != self._map.end(); it++)
self._amv.push_back(it->first);
@ -76,7 +77,7 @@ public:
return true;
}
return false;
}
}
bool next()
{
@ -110,7 +111,7 @@ public:
}
private:
osg::ref_ptr<osgAnimation::AnimationManager> _model;
osg::ref_ptr<osgAnimation::BasicAnimationManager> _model;
osgAnimation::AnimationMap _map;
AnimationMapVector _amv;
unsigned int _focus;

View File

@ -30,6 +30,7 @@
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
#include <osgDB/ReadFile>
#include <osgAnimation/AnimationManagerBase>
const int WIDTH = 1440;
const int HEIGHT = 900;
@ -41,7 +42,7 @@ osg::Geode* createAxis()
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));
@ -55,7 +56,7 @@ osg::Geode* createAxis()
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);
@ -79,26 +80,28 @@ int main(int argc, char** argv)
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)
osg::Group* node = dynamic_cast<osg::Group*>(osgDB::readNodeFile(psr[1])); //dynamic_cast<osgAnimation::AnimationManager*>(osgDB::readNodeFile(psr[1]));
if(!node)
{
std::cerr << "Couldn't convert the file's toplevel object into an AnimationManager." << std::endl;
std::cerr << "Can't read file " << psr[1]<< std::endl;
return 1;
}
// Set our Singleton's model.
AnimtkViewerModelController::setModel(animationManager);
osgAnimation::AnimationManagerBase* base = dynamic_cast<osgAnimation::AnimationManagerBase*>(node->getUpdateCallback());
osgAnimation::BasicAnimationManager* manager = new osgAnimation::BasicAnimationManager(*base);
node->setUpdateCallback(manager);
AnimtkViewerModelController::setModel(manager);
animationManager->addChild(createAxis());
node->addChild(createAxis());
AnimtkViewerGUI* gui = new AnimtkViewerGUI(&viewer, WIDTH, HEIGHT, 0x1234);
osg::Camera* camera = gui->createParentOrthoCamera();
animationManager->setNodeMask(0x0001);
node->setNodeMask(0x0001);
group->addChild(animationManager);
group->addChild(node);
group->addChild(camera);
viewer.addEventHandler(new AnimtkKeyEventHandler());

View File

@ -25,22 +25,22 @@
#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;
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&);
osgWidget::Widget* _createButton(const std::string&);
bool _buttonPush(osgWidget::Event&);
bool _listMouseHover(osgWidget::Event&);
void _createButtonBox();
void _createListBox();
void _createLabelBox();
void _createButtonBox();
void _createListBox();
void _createLabelBox();
public:
AnimtkViewerGUI(osgViewer::View*, float, float, unsigned int);
AnimtkViewerGUI(osgViewer::View*, float, float, unsigned int);
};
#endif

View File

@ -41,7 +41,7 @@ struct ButtonFunctor: public WidgetSampler
float _previous;
const float _speed;
ButtonFunctor(): _speed(5) { _direction = -_speed; _previous = 0;}
bool enter(osgWidget::Event& ev)
@ -229,7 +229,7 @@ AnimtkViewerGUI::AnimtkViewerGUI(osgViewer::View* view, float w, float h, unsign
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);
@ -237,7 +237,7 @@ osgWidget::Widget* AnimtkViewerGUI::_createButton(const std::string& name)
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));
@ -259,7 +259,7 @@ bool AnimtkViewerGUI::_listMouseHover(osgWidget::Event& ev)
else if(ev.type == osgWidget::EVENT_MOUSE_PUSH) {
AnimtkViewerModelController::instance().playByName(ev.getWidget()->getName());
}
else return false;
return true;
@ -293,11 +293,11 @@ bool AnimtkViewerGUI::_buttonPush(osgWidget::Event& ev)
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);
@ -345,7 +345,7 @@ void AnimtkViewerGUI::_createButtonBox()
_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));
}
@ -392,7 +392,7 @@ 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);

View File

@ -16,104 +16,104 @@ const unsigned int MASK_2D = 0xF0000000;
const unsigned int MASK_3D = 0x0F000000;
struct ColorWidget: public osgWidget::Widget {
ColorWidget():
osgWidget::Widget("", 256.0f, 256.0f) {
}
ColorWidget():
osgWidget::Widget("", 256.0f, 256.0f) {
}
bool mouseEnter(double, double, osgWidget::WindowManager*) {
addColor(-osgWidget::Color(0.4f, 0.4f, 0.4f, 0.0f));
// osgWidget::warn() << "enter: " << getColor() << std::endl;
bool mouseEnter(double, double, osgWidget::WindowManager*) {
addColor(-osgWidget::Color(0.4f, 0.4f, 0.4f, 0.0f));
// osgWidget::warn() << "enter: " << getColor() << std::endl;
return true;
}
return true;
}
bool mouseLeave(double, double, osgWidget::WindowManager*) {
addColor(osgWidget::Color(0.4f, 0.4f, 0.4f, 0.0f));
// osgWidget::warn() << "leave: " << getColor() << std::endl;
return true;
}
bool mouseLeave(double, double, osgWidget::WindowManager*) {
addColor(osgWidget::Color(0.4f, 0.4f, 0.4f, 0.0f));
// osgWidget::warn() << "leave: " << getColor() << std::endl;
return true;
}
bool mouseOver(double x, double y, osgWidget::WindowManager*) {
osgWidget::Color c = getImageColorAtPointerXY(x, y);
bool mouseOver(double x, double y, osgWidget::WindowManager*) {
osgWidget::Color c = getImageColorAtPointerXY(x, y);
if(c.a() < 0.001f) {
// osgWidget::warn() << "Transparent Pixel: " << x << " " << y << std::endl;
if(c.a() < 0.001f) {
// osgWidget::warn() << "Transparent Pixel: " << x << " " << y << std::endl;
return false;
}
return false;
}
return true;
}
return true;
}
bool keyUp(int key, int keyMask, osgWidget::WindowManager*) {
// osgWidget::warn() << "..." << key << " - " << keyMask << std::endl;
bool keyUp(int key, int keyMask, osgWidget::WindowManager*) {
// osgWidget::warn() << "..." << key << " - " << keyMask << std::endl;
return true;
}
return true;
}
};
osgWidget::Box* createBox(const std::string& name, osgWidget::Box::BoxType bt) {
osgWidget::Box* box = new osgWidget::Box(name, bt, true);
osgWidget::Widget* widget1 = new osgWidget::Widget(name + "_widget1", 100.0f, 100.0f);
osgWidget::Widget* widget2 = new osgWidget::Widget(name + "_widget2", 100.0f, 100.0f);
osgWidget::Widget* widget3 = new ColorWidget();
osgWidget::Box* box = new osgWidget::Box(name, bt, true);
osgWidget::Widget* widget1 = new osgWidget::Widget(name + "_widget1", 100.0f, 100.0f);
osgWidget::Widget* widget2 = new osgWidget::Widget(name + "_widget2", 100.0f, 100.0f);
osgWidget::Widget* widget3 = new ColorWidget();
widget1->setColor(0.3f, 0.3f, 0.3f, 1.0f);
widget2->setColor(0.6f, 0.6f, 0.6f, 1.0f);
widget1->setColor(0.3f, 0.3f, 0.3f, 1.0f);
widget2->setColor(0.6f, 0.6f, 0.6f, 1.0f);
widget3->setImage("osgWidget/natascha.png");
widget3->setTexCoord(0.0f, 0.0f, osgWidget::Widget::LOWER_LEFT);
widget3->setTexCoord(1.0f, 0.0f, osgWidget::Widget::LOWER_RIGHT);
widget3->setTexCoord(1.0f, 1.0f, osgWidget::Widget::UPPER_RIGHT);
widget3->setTexCoord(0.0f, 1.0f, osgWidget::Widget::UPPER_LEFT);
widget3->setImage("osgWidget/natascha.png");
widget3->setTexCoord(0.0f, 0.0f, osgWidget::Widget::LOWER_LEFT);
widget3->setTexCoord(1.0f, 0.0f, osgWidget::Widget::LOWER_RIGHT);
widget3->setTexCoord(1.0f, 1.0f, osgWidget::Widget::UPPER_RIGHT);
widget3->setTexCoord(0.0f, 1.0f, osgWidget::Widget::UPPER_LEFT);
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
return box;
return box;
}
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
wm->setPointerFocusMode(osgWidget::WindowManager::PFM_SLOPPY);
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
wm->setPointerFocusMode(osgWidget::WindowManager::PFM_SLOPPY);
osgWidget::Window* box1 = createBox("HBOX", osgWidget::Box::HORIZONTAL);
osgWidget::Window* box2 = createBox("VBOX", osgWidget::Box::VERTICAL);
osgWidget::Window* box3 = createBox("HBOX2", osgWidget::Box::HORIZONTAL);
osgWidget::Window* box4 = createBox("VBOX2", osgWidget::Box::VERTICAL);
osgWidget::Window* box1 = createBox("HBOX", osgWidget::Box::HORIZONTAL);
osgWidget::Window* box2 = createBox("VBOX", osgWidget::Box::VERTICAL);
osgWidget::Window* box3 = createBox("HBOX2", osgWidget::Box::HORIZONTAL);
osgWidget::Window* box4 = createBox("VBOX2", osgWidget::Box::VERTICAL);
box1->getBackground()->setColor(1.0f, 0.0f, 0.0f, 0.8f);
box1->attachMoveCallback();
box1->getBackground()->setColor(1.0f, 0.0f, 0.0f, 0.8f);
box1->attachMoveCallback();
box2->getBackground()->setColor(0.0f, 1.0f, 0.0f, 0.8f);
box2->attachMoveCallback();
box2->getBackground()->setColor(0.0f, 1.0f, 0.0f, 0.8f);
box2->attachMoveCallback();
box3->getBackground()->setColor(0.0f, 0.0f, 1.0f, 0.8f);
box3->attachMoveCallback();
box3->getBackground()->setColor(0.0f, 0.0f, 1.0f, 0.8f);
box3->attachMoveCallback();
wm->addChild(box1);
wm->addChild(box2);
wm->addChild(box3);
wm->addChild(box4);
wm->addChild(box1);
wm->addChild(box2);
wm->addChild(box3);
wm->addChild(box4);
box4->hide();
box4->hide();
osg::Node* model = osgDB::readNodeFile("spaceship.osg");
osg::Node* model = osgDB::readNodeFile("spaceship.osg");
model->setNodeMask(MASK_3D);
model->setNodeMask(MASK_3D);
return osgWidget::createExample(viewer, wm, model);
return osgWidget::createExample(viewer, wm, model);
}

View File

@ -8,135 +8,135 @@
const unsigned int MASK_2D = 0xF0000000;
bool colorWidgetEnter(osgWidget::Event& event) {
event.getWidget()->addColor(0.5f, 0.2f, 0.3f, 0.0f);
event.getWidget()->addColor(0.5f, 0.2f, 0.3f, 0.0f);
// osgWidget::warn() << "WIDGET mouseEnter " << event.getWidget()->getName() << std::endl;
return false;
// osgWidget::warn() << "WIDGET mouseEnter " << event.getWidget()->getName() << std::endl;
return false;
}
bool colorWidgetLeave(osgWidget::Event& event) {
event.getWidget()->addColor(-0.5f, -0.2f, -0.3f, 0.0f);
event.getWidget()->addColor(-0.5f, -0.2f, -0.3f, 0.0f);
// osgWidget::warn() << "WIDGET mouseLeave" << std::endl;
return true;
// osgWidget::warn() << "WIDGET mouseLeave" << std::endl;
return true;
}
bool windowMouseOver(osgWidget::Event& event) {
osgWidget::XYCoord xy = event.getWindow()->localXY(event.x, event.y);
osgWidget::XYCoord xy = event.getWindow()->localXY(event.x, event.y);
// osgWidget::warn() << "WINDOW " << xy.x() << " - " << xy.y() << std::endl;
// osgWidget::warn() << "WINDOW " << xy.x() << " - " << xy.y() << std::endl;
return true;
return true;
}
bool widgetMouseOver(osgWidget::Event& event) {
osgWidget::XYCoord xy = event.getWidget()->localXY(event.x, event.y);
osgWidget::XYCoord xy = event.getWidget()->localXY(event.x, event.y);
// osgWidget::warn() << "WIDGET mouseOver " << xy.x() << " - " << xy.y() << std::endl;
// osgWidget::warn() << "WIDGET mouseOver " << xy.x() << " - " << xy.y() << std::endl;
return true;
return true;
}
osgWidget::Widget* createWidget(
const std::string& name,
osgWidget::color_type col,
osgWidget::Widget::Layer layer
const std::string& name,
osgWidget::color_type col,
osgWidget::Widget::Layer layer
) {
osgWidget::Widget* widget = new osgWidget::Widget(name, 200.0f, 200.0f);
osgWidget::Widget* widget = new osgWidget::Widget(name, 200.0f, 200.0f);
widget->setEventMask(osgWidget::EVENT_ALL);
widget->addCallback(new osgWidget::Callback(&colorWidgetEnter, osgWidget::EVENT_MOUSE_PUSH));
widget->addCallback(new osgWidget::Callback(&colorWidgetLeave, osgWidget::EVENT_MOUSE_RELEASE));
widget->addCallback(new osgWidget::Callback(&colorWidgetEnter, osgWidget::EVENT_MOUSE_ENTER));
widget->addCallback(new osgWidget::Callback(&colorWidgetLeave, osgWidget::EVENT_MOUSE_LEAVE));
widget->addCallback(new osgWidget::Callback(&widgetMouseOver, osgWidget::EVENT_MOUSE_OVER));
widget->setColor(col, col, col, 0.5f);
widget->setLayer(layer);
return widget;
widget->setEventMask(osgWidget::EVENT_ALL);
widget->addCallback(new osgWidget::Callback(&colorWidgetEnter, osgWidget::EVENT_MOUSE_PUSH));
widget->addCallback(new osgWidget::Callback(&colorWidgetLeave, osgWidget::EVENT_MOUSE_RELEASE));
widget->addCallback(new osgWidget::Callback(&colorWidgetEnter, osgWidget::EVENT_MOUSE_ENTER));
widget->addCallback(new osgWidget::Callback(&colorWidgetLeave, osgWidget::EVENT_MOUSE_LEAVE));
widget->addCallback(new osgWidget::Callback(&widgetMouseOver, osgWidget::EVENT_MOUSE_OVER));
widget->setColor(col, col, col, 0.5f);
widget->setLayer(layer);
return widget;
}
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
canvas->addCallback(new osgWidget::Callback(&windowMouseOver, osgWidget::EVENT_MOUSE_OVER));
canvas->attachMoveCallback();
canvas->attachRotateCallback();
canvas->attachScaleCallback();
canvas->addCallback(new osgWidget::Callback(&windowMouseOver, osgWidget::EVENT_MOUSE_OVER));
canvas->attachMoveCallback();
canvas->attachRotateCallback();
canvas->attachScaleCallback();
canvas->addWidget(
createWidget("w1", 0.2f, osgWidget::Widget::LAYER_LOW),
0.0f,
0.0f
);
canvas->addWidget(
createWidget("w2", 0.4f, osgWidget::Widget::LAYER_MIDDLE),
200.0f,
0.0f
);
canvas->addWidget(
createWidget("w1", 0.2f, osgWidget::Widget::LAYER_LOW),
0.0f,
0.0f
);
canvas->addWidget(
createWidget("w2", 0.4f, osgWidget::Widget::LAYER_MIDDLE),
200.0f,
0.0f
);
canvas->addWidget(
createWidget("w3", 0.6f, osgWidget::Widget::LAYER_HIGH),
400.0f,
0.0f
);
canvas->addWidget(
createWidget("w3", 0.6f, osgWidget::Widget::LAYER_HIGH),
400.0f,
0.0f
);
// Add a child and then resize it relatively to the size of the parent Window.
osgWidget::Widget* relWidget = new osgWidget::Widget("relative");
// Add a child and then resize it relatively to the size of the parent Window.
osgWidget::Widget* relWidget = new osgWidget::Widget("relative");
relWidget->setLayer(osgWidget::Widget::LAYER_LOW, 1);
relWidget->setCoordinateMode(osgWidget::Widget::CM_RELATIVE);
relWidget->setSize(0.2f, 0.2f);
relWidget->setColor(0.5f, 0.5f, 0.1f, 0.9f);
relWidget->setLayer(osgWidget::Widget::LAYER_LOW, 1);
relWidget->setCoordinateMode(osgWidget::Widget::CM_RELATIVE);
relWidget->setSize(0.2f, 0.2f);
relWidget->setColor(0.5f, 0.5f, 0.1f, 0.9f);
osgWidget::warn() << canvas->getWidth() << std::endl;
osgWidget::warn() << canvas->getWidth() << std::endl;
canvas->addWidget(relWidget, 0.4f, 0.4f);
relWidget->addOrigin(0.1f, 0.1f);
relWidget->addSize(0.2f, 0.2f);
canvas->addWidget(relWidget, 0.4f, 0.4f);
relWidget->addOrigin(0.1f, 0.1f);
relWidget->addSize(0.2f, 0.2f);
canvas->resize();
canvas->resize();
// Finally, add the whole thing to the WindowManager.
wm->addChild(canvas);
// Finally, add the whole thing to the WindowManager.
wm->addChild(canvas);
return osgWidget::createExample(viewer, wm);
return osgWidget::createExample(viewer, wm);
}
/*
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
canvas->addWidget(new osgWidget::Widget("spacer", 2.0f, 300.0f), 1280.0f, 0.0f);
canvas->addWidget(new osgWidget::Widget("spacer", 2.0f, 300.0f), 1280.0f, 0.0f);
canvas->setOrigin(0.0f, 300.0f);
canvas->setOrigin(0.0f, 300.0f);
wm->addChild(canvas);
wm->addChild(canvas);
return osgWidget::createExample(viewer, wm);
return osgWidget::createExample(viewer, wm);
}
*/

View File

@ -118,6 +118,7 @@ struct EventOK : public osgWidget::Callback, osg::NodeCallback
osg::ref_ptr<osgWidget::Frame> _frame;
float _width;
float _height;
osg::Matrix _matrix;
EventOK(osgWidget::Frame* frame) : osgWidget::Callback(osgWidget::EVENT_ALL), _frame(frame)
{
_motionOver = WidgetMotion(0.0, 0.4);
@ -138,13 +139,20 @@ struct EventOK : public osgWidget::Callback, osg::NodeCallback
_width = _frame->getWidth();
_height = _frame->getHeight();
_motionOver.reset();
_matrix = _frame->getMatrix();
//_frame->setMatrix(osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
_frame->setScale(1.1f); //osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
_frame->update(); //osg::Matrix::scale(2, 2, 1) * _frame->getMatrix());
std::cout << "enter" << std::endl;
return true;
}
else if (ev.type == osgWidget::EVENT_MOUSE_LEAVE)
else if (ev.type == osgWidget::EVENT_MOUSE_LEAVE)
{
_over = false;
_motionLeave.reset();
//_frame->setMatrix(_matrix);
_frame->setScale(1.0f);
_frame->update();
std::cout << "leave" << std::endl;
return true;
}
@ -218,7 +226,9 @@ osgWidget::Frame* MessageBox::createButtonOk(const std::string& theme,
osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
box->getBackground()->setColor(colorBack);
frame->getEmbeddedWindow()->setWindow(box);
box->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
box->setEventMask(osgWidget::EVENT_NONE);
frame->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
frame->resizeFrame(box->getWidth(), box->getHeight());
frame->resizeAdd(0, 0);
@ -255,9 +265,13 @@ bool MessageBox::create(const std::string& themeMessage,
_button = createButtonOk(themeButton, buttonText, font, fontSize);
osgWidget::Widget* buttonOK = _button->embed();
_button->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
buttonOK->setColor(osgWidget::Color(0,0,0,0));
buttonOK->setCanFill(false);
labelTitle->setPadBottom(30.0f);
labelText->setPadBottom(30.0f);
box->addWidget(buttonOK);
box->addWidget(labelText);
box->addWidget(labelTitle);
@ -325,12 +339,14 @@ int main(int argc, char** argv)
osgWidget::point_type hw = message.getWindow()->getHeight();
osgWidget::point_type ox = (w - ww) / 2;
osgWidget::point_type oy = (h - hw) / 2;
message.getWindow()->setPosition(osgWidget::Point(ox, oy, message.getWindow()->getPosition()[2] ));
message.getWindow()->setPosition(osgWidget::Point(
osg::round(ox), osg::round(oy), message.getWindow()->getPosition()[2])
);
// frame->resizeAdd(30, 30);
// AlphaSetterVisitor alpha(.8f);
// frame->accept(alpha);
return osgWidget::createExample(viewer, wm, osgDB::readNodeFile("cow.osg"));
return osgWidget::createExample(viewer, wm); //osgDB::readNodeFile("cow.osg"));
}
@ -566,6 +582,7 @@ osgWidget::Window* createButtonOk(const std::string& theme, const std::string& t
osgWidget::Color colorBack = frame->getEmbeddedWindow()->getColor();
box->getBackground()->setColor(colorBack);
frame->getEmbeddedWindow()->setWindow(box);
box->setVisibilityMode(osgWidget::Window::VM_ENTIRE);
box->setEventMask(osgWidget::EVENT_NONE);
frame->resizeFrame(box->getWidth(), box->getHeight());

View File

@ -9,83 +9,83 @@
const unsigned int MASK_2D = 0xF0000000;
struct UpdateProgressNode: public osg::NodeCallback {
float start;
float done;
float start;
float done;
UpdateProgressNode():
start (0.0f),
done (5.0f) {
}
UpdateProgressNode():
start (0.0f),
done (5.0f) {
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
const osg::FrameStamp* fs = nv->getFrameStamp();
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
const osg::FrameStamp* fs = nv->getFrameStamp();
float t = fs->getSimulationTime();
float t = fs->getSimulationTime();
if(start == 0.0f) start = t;
if(start == 0.0f) start = t;
float width = ((t - start) / done) * 512.0f;
float percent = (width / 512.0f) * 100.0f;
if(width < 1.0f || width > 512.0f) return;
float width = ((t - start) / done) * 512.0f;
float percent = (width / 512.0f) * 100.0f;
if(width < 1.0f || width > 512.0f) return;
osgWidget::Window* window = dynamic_cast<osgWidget::Window*>(node);
osgWidget::Window* window = dynamic_cast<osgWidget::Window*>(node);
if(!window) return;
if(!window) return;
osgWidget::Widget* w = window->getByName("pMeter");
osgWidget::Label* l = dynamic_cast<osgWidget::Label*>(window->getByName("pLabel"));
osgWidget::Widget* w = window->getByName("pMeter");
osgWidget::Label* l = dynamic_cast<osgWidget::Label*>(window->getByName("pLabel"));
if(!w || !l) return;
if(!w || !l) return;
w->setWidth(width);
w->setTexCoordRegion(0.0f, 0.0f, width, 64.0f);
w->setWidth(width);
w->setTexCoordRegion(0.0f, 0.0f, width, 64.0f);
std::ostringstream ss;
std::ostringstream ss;
ss << osg::round(percent) << "% Done" << std::endl;
ss << osg::round(percent) << "% Done" << std::endl;
l->setLabel(ss.str());
}
l->setLabel(ss.str());
}
};
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
osgWidget::Widget* pOutline = new osgWidget::Widget("pOutline", 512.0f, 64.0f);
osgWidget::Widget* pMeter = new osgWidget::Widget("pMeter", 0.0f, 64.0f);
osgWidget::Label* pLabel = new osgWidget::Label("pLabel", "0% Done");
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Canvas* canvas = new osgWidget::Canvas("canvas");
osgWidget::Widget* pOutline = new osgWidget::Widget("pOutline", 512.0f, 64.0f);
osgWidget::Widget* pMeter = new osgWidget::Widget("pMeter", 0.0f, 64.0f);
osgWidget::Label* pLabel = new osgWidget::Label("pLabel", "0% Done");
pOutline->setImage("osgWidget/progress-outline.png", true);
pOutline->setLayer(osgWidget::Widget::LAYER_MIDDLE, 2);
pMeter->setImage("osgWidget/progress-meter.png");
pMeter->setColor(0.7f, 0.1f, 0.1f, 0.7f);
pMeter->setLayer(osgWidget::Widget::LAYER_MIDDLE, 1);
pOutline->setImage("osgWidget/progress-outline.png", true);
pOutline->setLayer(osgWidget::Widget::LAYER_MIDDLE, 2);
pMeter->setImage("osgWidget/progress-meter.png");
pMeter->setColor(0.7f, 0.1f, 0.1f, 0.7f);
pMeter->setLayer(osgWidget::Widget::LAYER_MIDDLE, 1);
pLabel->setFont("fonts/VeraMono.ttf");
pLabel->setFontSize(20);
pLabel->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
pLabel->setSize(512.0f, 64.0f);
pLabel->setLayer(osgWidget::Widget::LAYER_MIDDLE, 3);
pLabel->setFont("fonts/VeraMono.ttf");
pLabel->setFontSize(20);
pLabel->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
pLabel->setSize(512.0f, 64.0f);
pLabel->setLayer(osgWidget::Widget::LAYER_MIDDLE, 3);
canvas->setOrigin(300.0f, 300.0f);
canvas->addWidget(pMeter, 0.0f, 0.0f);
canvas->addWidget(pOutline, 0.0f, 0.0f);
canvas->addWidget(pLabel, 0.0f, 0.0f);
canvas->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
canvas->setUpdateCallback(new UpdateProgressNode());
canvas->setOrigin(300.0f, 300.0f);
canvas->addWidget(pMeter, 0.0f, 0.0f);
canvas->addWidget(pOutline, 0.0f, 0.0f);
canvas->addWidget(pLabel, 0.0f, 0.0f);
canvas->getBackground()->setColor(0.0f, 0.0f, 0.0f, 0.0f);
canvas->setUpdateCallback(new UpdateProgressNode());
wm->addChild(canvas);
wm->addChild(canvas);
return osgWidget::createExample(viewer, wm, osgDB::readNodeFile("cow.osg"));
return osgWidget::createExample(viewer, wm, osgDB::readNodeFile("cow.osg"));
}

View File

@ -9,75 +9,75 @@
const unsigned int MASK_2D = 0xF0000000;
const std::string& STYLE1 =
"color 0 0 0 128\n"
"padding 5\n"
"color 0 0 0 128\n"
"padding 5\n"
;
const std::string& STYLE2 =
"color 1.0 0.5 0.0\n"
"color 1.0 0.5 0.0\n"
;
const std::string& STYLE3 =
"fill true\n"
"fill true\n"
;
const std::string& STYLE4 =
"pos 100.0 100.0\n"
"size 600 600\n"
"pos 100.0 100.0\n"
"size 600 600\n"
;
class CustomStyled: public osgWidget::Widget {
};
class CustomStyle: public osgWidget::Style {
virtual bool applyStyle(osgWidget::Widget* w, osgWidget::Reader r) {
CustomStyled* cs = dynamic_cast<CustomStyled*>(w);
virtual bool applyStyle(osgWidget::Widget* w, osgWidget::Reader r) {
CustomStyled* cs = dynamic_cast<CustomStyled*>(w);
if(!cs) return false;
if(!cs) return false;
osgWidget::warn() << "Here, okay." << std::endl;
osgWidget::warn() << "Here, okay." << std::endl;
return true;
}
return true;
}
};
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D
);
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D
);
osgWidget::Box* box = new osgWidget::Box("box", osgWidget::Box::VERTICAL);
osgWidget::Box* box = new osgWidget::Box("box", osgWidget::Box::VERTICAL);
osgWidget::Widget* widget1 = new osgWidget::Widget("w1", 200.0f, 200.0f);
osgWidget::Widget* widget2 = new osgWidget::Widget("w2", 100.0f, 100.0f);
osgWidget::Widget* widget3 = new osgWidget::Widget("w3", 0.0f, 0.0f);
CustomStyled* cs = new CustomStyled();
osgWidget::Widget* widget1 = new osgWidget::Widget("w1", 200.0f, 200.0f);
osgWidget::Widget* widget2 = new osgWidget::Widget("w2", 100.0f, 100.0f);
osgWidget::Widget* widget3 = new osgWidget::Widget("w3", 0.0f, 0.0f);
CustomStyled* cs = new CustomStyled();
// Yep.
wm->getStyleManager()->addStyle(new osgWidget::Style("widget.style1", STYLE1));
wm->getStyleManager()->addStyle(new osgWidget::Style("widget.style2", STYLE2));
wm->getStyleManager()->addStyle(new osgWidget::Style("spacer", STYLE3));
wm->getStyleManager()->addStyle(new osgWidget::Style("window", STYLE4));
// wm->getStyleManager()->addStyle(new CustomStyle("widget", ""));
// Yep.
wm->getStyleManager()->addStyle(new osgWidget::Style("widget.style1", STYLE1));
wm->getStyleManager()->addStyle(new osgWidget::Style("widget.style2", STYLE2));
wm->getStyleManager()->addStyle(new osgWidget::Style("spacer", STYLE3));
wm->getStyleManager()->addStyle(new osgWidget::Style("window", STYLE4));
// wm->getStyleManager()->addStyle(new CustomStyle("widget", ""));
widget1->setStyle("widget.style1");
widget2->setStyle("widget.style2");
widget3->setStyle("spacer");
widget1->setStyle("widget.style1");
widget2->setStyle("widget.style2");
widget3->setStyle("spacer");
box->setStyle("window");
box->setStyle("window");
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
wm->addChild(box);
wm->addChild(box);
// box->resizePercent(0.0f, 100.0f);
// box->resizePercent(0.0f, 100.0f);
return osgWidget::createExample(viewer, wm);
return osgWidget::createExample(viewer, wm);
}

View File

@ -13,58 +13,58 @@ const unsigned int MASK_2D = 0xF0000000;
// horizontal placement cells. A Box, on the other hand, can only be vertical or horizontal.
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
osgViewer::Viewer viewer;
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Table* table = new osgWidget::Table("table", 3, 3);
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgWidget::Table* table = new osgWidget::Table("table", 3, 3);
// Here we create our "cells" manually, though it will often be convenient to
// do so algorithmically. Also, notice how we set the text name of each widget to
// correspond with it's "index" in the table. This is merely a convenience, which
// we use later...
table->addWidget(new osgWidget::Widget("0, 0", 100.0f, 25.0f), 0, 0);
table->addWidget(new osgWidget::Widget("0, 1", 100.0f, 25.0f), 0, 1);
table->addWidget(new osgWidget::Widget("0, 2", 100.0f, 75.0f), 0, 2);
table->addWidget(new osgWidget::Widget("1, 0", 200.0f, 45.0f), 1, 0);
table->addWidget(new osgWidget::Widget("1, 1", 200.0f, 45.0f), 1, 1);
table->addWidget(new osgWidget::Widget("1, 2", 200.0f, 45.0f), 1, 2);
table->addWidget(new osgWidget::Widget("2, 0", 300.0f, 65.0f), 2, 0);
table->addWidget(new osgWidget::Widget("2, 1", 300.0f, 65.0f), 2, 1);
table->addWidget(new osgWidget::Widget("2, 2", 300.0f, 65.0f), 2, 2);
// Here we create our "cells" manually, though it will often be convenient to
// do so algorithmically. Also, notice how we set the text name of each widget to
// correspond with it's "index" in the table. This is merely a convenience, which
// we use later...
table->addWidget(new osgWidget::Widget("0, 0", 100.0f, 25.0f), 0, 0);
table->addWidget(new osgWidget::Widget("0, 1", 100.0f, 25.0f), 0, 1);
table->addWidget(new osgWidget::Widget("0, 2", 100.0f, 75.0f), 0, 2);
table->addWidget(new osgWidget::Widget("1, 0", 200.0f, 45.0f), 1, 0);
table->addWidget(new osgWidget::Widget("1, 1", 200.0f, 45.0f), 1, 1);
table->addWidget(new osgWidget::Widget("1, 2", 200.0f, 45.0f), 1, 2);
table->addWidget(new osgWidget::Widget("2, 0", 300.0f, 65.0f), 2, 0);
table->addWidget(new osgWidget::Widget("2, 1", 300.0f, 65.0f), 2, 1);
table->addWidget(new osgWidget::Widget("2, 2", 300.0f, 65.0f), 2, 2);
table->getBackground()->setColor(0.0f, 0.0f, 0.5f, 1.0f);
table->attachMoveCallback();
table->getBackground()->setColor(0.0f, 0.0f, 0.5f, 1.0f);
table->attachMoveCallback();
// Use a hackish method of setting the spacing for all Widgets.
for(osgWidget::Table::Iterator i = table->begin(); i != table->end(); i++)
i->get()->setPadding(1.0f)
;
// Use a hackish method of setting the spacing for all Widgets.
for(osgWidget::Table::Iterator i = table->begin(); i != table->end(); i++)
i->get()->setPadding(1.0f)
;
// Now we fetch the very first 0, 0 Widget in the table using an awkward method.
// This is merely one way to fetch a Widget from a Window, there are many others.
// The osgWidget::Window::getByName interface will be very handy in scripting languages
// where users will want to retrieve handles to existing Windows using a useful
// textual name, such as "MainGUIParent" or something.
table->getByName("0, 0")->setAlignHorizontal(osgWidget::Widget::HA_LEFT);
table->getByName("0, 0")->setAlignVertical(osgWidget::Widget::VA_BOTTOM);
table->getByName("0, 0")->setPadLeft(50.0f);
table->getByName("0, 0")->setPadTop(3.0f);
// Change the colors a bit to differentiate this row from the others.
table->getByName("2, 0")->setColor(1.0f, 0.0f, 0.0f, 1.0f, osgWidget::Widget::LOWER_LEFT);
table->getByName("2, 1")->setColor(1.0f, 0.0f, 0.0f, 0.5f);
table->getByName("2, 2")->setColor(1.0f, 0.0f, 0.0f, 0.5f);
// Now we fetch the very first 0, 0 Widget in the table using an awkward method.
// This is merely one way to fetch a Widget from a Window, there are many others.
// The osgWidget::Window::getByName interface will be very handy in scripting languages
// where users will want to retrieve handles to existing Windows using a useful
// textual name, such as "MainGUIParent" or something.
table->getByName("0, 0")->setAlignHorizontal(osgWidget::Widget::HA_LEFT);
table->getByName("0, 0")->setAlignVertical(osgWidget::Widget::VA_BOTTOM);
table->getByName("0, 0")->setPadLeft(50.0f);
table->getByName("0, 0")->setPadTop(3.0f);
// Change the colors a bit to differentiate this row from the others.
table->getByName("2, 0")->setColor(1.0f, 0.0f, 0.0f, 1.0f, osgWidget::Widget::LOWER_LEFT);
table->getByName("2, 1")->setColor(1.0f, 0.0f, 0.0f, 0.5f);
table->getByName("2, 2")->setColor(1.0f, 0.0f, 0.0f, 0.5f);
wm->addChild(table);
wm->addChild(table);
return createExample(viewer, wm);
return createExample(viewer, wm);
}

View File

@ -15,208 +15,208 @@ const unsigned int MASK_3D = 0x0F000000;
// Here we create (and later demonstrate) the use of a simple function callback.
bool windowClicked(osgWidget::Event& ev) {
std::cout << "windowClicked: " << ev.getWindow()->getName() << std::endl;
std::cout << "windowClicked: " << ev.getWindow()->getName() << std::endl;
if(ev.getData()) {
std::string* s = static_cast<std::string*>(ev.getData());
if(ev.getData()) {
std::string* s = static_cast<std::string*>(ev.getData());
std::cout << "This is data attached to the event: " << *s << std::endl;
}
std::cout << "This is data attached to the event: " << *s << std::endl;
}
return true;
return true;
}
bool windowScrolled(osgWidget::Event& ev) {
osgWidget::warn()
<< "scrolling up? " << ev.getWindowManager()->isMouseScrollingUp()
<< std::endl
;
osgWidget::warn()
<< "scrolling up? " << ev.getWindowManager()->isMouseScrollingUp()
<< std::endl
;
return true;
return true;
}
// Here we dcreate a new class and show how to use a method callback (which differs from
// a function callback in that we are required to also pass the "this" argument).
struct Object {
bool windowClicked(osgWidget::Event& ev) {
std::cout << "Object::windowClicked " << ev.getWindow()->getName() << std::endl;
bool windowClicked(osgWidget::Event& ev) {
std::cout << "Object::windowClicked " << ev.getWindow()->getName() << std::endl;
return true;
}
return true;
}
};
// This is the more "traditional" method of creating a callback.
struct CallbackObject: public osgWidget::Callback {
CallbackObject(osgWidget::EventType evType):
osgWidget::Callback(evType) {
}
CallbackObject(osgWidget::EventType evType):
osgWidget::Callback(evType) {
}
virtual bool operator()(osgWidget::Event& ev) {
std::cout << "here" << std::endl;
return false;
}
virtual bool operator()(osgWidget::Event& ev) {
std::cout << "here" << std::endl;
return false;
}
};
int main(int argc, char** argv) {
osgViewer::Viewer viewer;
// Let's get busy! The WindowManager class is actually an osg::Switch,
// so you can add it to (ideally) an orthographic camera and have it behave as
// expected. Note that you create a WindowManager with a NodeMask--it is very important
// that this be unique for picking to work properly. This also makes it possible to have
// multiple WindowManagers each operating on their own, unique set of Window objects.
// The final bool argument is a group of flags that introduce optional functionality
// for the WindowManager. In our case we include the flags USE_PYTHON and USE_LUA,
// to demonstrate (and test) their usage. Finally, we pass the temporary WM_NO_BETA_WARN
// argument, which prevents creating the orange warning window. :) It will be shown
// in other examples...
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_USE_LUA |
osgWidget::WindowManager::WM_USE_PYTHON |
osgWidget::WindowManager::WM_PICK_DEBUG
);
osgViewer::Viewer viewer;
// Let's get busy! The WindowManager class is actually an osg::Switch,
// so you can add it to (ideally) an orthographic camera and have it behave as
// expected. Note that you create a WindowManager with a NodeMask--it is very important
// that this be unique for picking to work properly. This also makes it possible to have
// multiple WindowManagers each operating on their own, unique set of Window objects.
// The final bool argument is a group of flags that introduce optional functionality
// for the WindowManager. In our case we include the flags USE_PYTHON and USE_LUA,
// to demonstrate (and test) their usage. Finally, we pass the temporary WM_NO_BETA_WARN
// argument, which prevents creating the orange warning window. :) It will be shown
// in other examples...
osgWidget::WindowManager* wm = new osgWidget::WindowManager(
&viewer,
1280.0f,
1024.0f,
MASK_2D,
osgWidget::WindowManager::WM_USE_LUA |
osgWidget::WindowManager::WM_USE_PYTHON |
osgWidget::WindowManager::WM_PICK_DEBUG
);
// An actual osgWidget::Window is pure virtual, so we've got to use the osgWidget::Box
// implementation for now. At a later time, support for Tables and other kinds of
// advanced layout Window types will be added.
osgWidget::Window* box = new osgWidget::Box("box", osgWidget::Box::HORIZONTAL);
// An actual osgWidget::Window is pure virtual, so we've got to use the osgWidget::Box
// implementation for now. At a later time, support for Tables and other kinds of
// advanced layout Window types will be added.
osgWidget::Window* box = new osgWidget::Box("box", osgWidget::Box::HORIZONTAL);
// Now we actually attach our two types of callbacks to the box instance. The first
// uses the simple function signature, the second uses a bound method, passing "this"
// as the second argument to the Callback constructor.
Object obj;
// Now we actually attach our two types of callbacks to the box instance. The first
// uses the simple function signature, the second uses a bound method, passing "this"
// as the second argument to the Callback constructor.
Object obj;
static std::string data = "lol ur face!";
static std::string data = "lol ur face!";
/*
box->addCallback(new osgWidget::Callback(&windowClicked, osgWidget::EVENT_MOUSE_PUSH, &data));
box->addCallback(new osgWidget::Callback(&windowScrolled, osgWidget::EVENT_MOUSE_SCROLL));
box->addCallback(osgWidget::Callback(
&Object::windowClicked,
&obj,
osgWidget::EVENT_MOUSE_PUSH
));
*/
/*
box->addCallback(new osgWidget::Callback(&windowClicked, osgWidget::EVENT_MOUSE_PUSH, &data));
box->addCallback(new osgWidget::Callback(&windowScrolled, osgWidget::EVENT_MOUSE_SCROLL));
box->addCallback(osgWidget::Callback(
&Object::windowClicked,
&obj,
osgWidget::EVENT_MOUSE_PUSH
));
*/
box->addCallback(new CallbackObject(osgWidget::EVENT_MOUSE_PUSH));
box->addCallback(new CallbackObject(osgWidget::EVENT_MOUSE_PUSH));
// Create some of our "testing" Widgets; included are two Widget subclasses I made
// during testing which I've kept around for testing purposes. You'll notice
// that you cannot move the box using the NullWidget, and that the NotifyWidget
// is a bit verbose. :)
osgWidget::Widget* widget1 = new osgWidget::NotifyWidget("widget1", 300.0f, 100.0f);
osgWidget::Widget* widget2 = new osgWidget::NullWidget("widget2", 400.0f, 75.0f);
osgWidget::Widget* widget3 = new osgWidget::Widget("widget3", 100.0f, 100.0f);
// Set the colors of widget1 and widget3 to green.
widget1->setColor(0.0f, 1.0f, 0.0f, 1.0f);
widget1->setCanFill(true);
widget3->setColor(0.0f, 1.0f, 0.0f, 1.0f);
// Create some of our "testing" Widgets; included are two Widget subclasses I made
// during testing which I've kept around for testing purposes. You'll notice
// that you cannot move the box using the NullWidget, and that the NotifyWidget
// is a bit verbose. :)
osgWidget::Widget* widget1 = new osgWidget::NotifyWidget("widget1", 300.0f, 100.0f);
osgWidget::Widget* widget2 = new osgWidget::NullWidget("widget2", 400.0f, 75.0f);
osgWidget::Widget* widget3 = new osgWidget::Widget("widget3", 100.0f, 100.0f);
// Set the colors of widget1 and widget3 to green.
widget1->setColor(0.0f, 1.0f, 0.0f, 1.0f);
widget1->setCanFill(true);
widget3->setColor(0.0f, 1.0f, 0.0f, 1.0f);
widget1->setImage(osgDB::readImageFile("Images/Saturn.TGA"), true);
widget1->setImage(osgDB::readImageFile("Images/Saturn.TGA"), true);
// Set the color of widget2, to differentiate it and make it sassy. This is
// like a poor man's gradient!
widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_LEFT);
widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_RIGHT);
widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_RIGHT);
widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_LEFT);
// Set the color of widget2, to differentiate it and make it sassy. This is
// like a poor man's gradient!
widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_LEFT);
widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_RIGHT);
widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_RIGHT);
widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_LEFT);
// Now add our newly created widgets to our box.
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
// Now add our newly created widgets to our box.
box->addWidget(widget1);
box->addWidget(widget2);
box->addWidget(widget3);
// For maximum efficiency, Windows don't automatically reallocate their geometry
// and internal positioning every time a widget is added. Thus, we either have to
// call the WindowManger::resizeAllWindows method or manually call
// Window::resize when we're ready.
box->resize();
// For maximum efficiency, Windows don't automatically reallocate their geometry
// and internal positioning every time a widget is added. Thus, we either have to
// call the WindowManger::resizeAllWindows method or manually call
// Window::resize when we're ready.
box->resize();
// Now, lets clone our existing box and create a new copy of of it, also adding that
// to the WindowManager. This demonstrates the usages of OSG's ->clone() support,
// though that is abstracted by our META_UIObject macro.
osgWidget::Window* boxCopy = osg::clone(box, "newBox", osg::CopyOp::DEEP_COPY_ALL);
// Now, lets clone our existing box and create a new copy of of it, also adding that
// to the WindowManager. This demonstrates the usages of OSG's ->clone() support,
// though that is abstracted by our META_UIObject macro.
osgWidget::Window* boxCopy = osg::clone(box, "newBox", osg::CopyOp::DEEP_COPY_ALL);
// Move our copy to make it visible.
boxCopy->setOrigin(0.0f, 125.0f);
// Move our copy to make it visible.
boxCopy->setOrigin(0.0f, 125.0f);
boxCopy->getByName("widget1")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
boxCopy->getByName("widget3")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
boxCopy->getByName("widget1")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
boxCopy->getByName("widget3")->setColor(0.5f, 0.0f, 1.0f, 1.0f);
// Add the successfully created Box (if we get this far) into the WindowManager, so
// that they can receive events.
wm->addChild(box);
wm->addChild(boxCopy);
// Add the successfully created Box (if we get this far) into the WindowManager, so
// that they can receive events.
wm->addChild(box);
wm->addChild(boxCopy);
// Now, ask our new box to be 100% the width of the WindowManager.
boxCopy->resizePercent(100.0f, 0.0f);
// Now, ask our new box to be 100% the width of the WindowManager.
boxCopy->resizePercent(100.0f, 0.0f);
// Here we demonstrate the use of osgWidget/io_utils. This is really only useful for
// debugging at the moment, but later I'll make it more generic for .osg and .ive
// creation.
// std::cout << *box << std::endl << *boxCopy << std::endl;
// Here we demonstrate the use of osgWidget/io_utils. This is really only useful for
// debugging at the moment, but later I'll make it more generic for .osg and .ive
// creation.
// std::cout << *box << std::endl << *boxCopy << std::endl;
// Setup our OSG objects for our scene; note the use of the utility function
// createOrthoCamera, which is just a helper for setting up a proper viewing area.
// An alternative (and a MUCH easier alternative at that!) is to
// simply use the createParentOrthoCamera method of the WindowManager class,
// which will wrap the calls to createOrthoCamera and addChild for us! Check out
// some of the other examples to see this in action...
osg::Group* group = new osg::Group();
osg::Camera* camera = osgWidget::createOrthoCamera(1280.0f, 1024.0f);
osg::Node* model = osgDB::readNodeFile("cow.osg");
// Setup our OSG objects for our scene; note the use of the utility function
// createOrthoCamera, which is just a helper for setting up a proper viewing area.
// An alternative (and a MUCH easier alternative at that!) is to
// simply use the createParentOrthoCamera method of the WindowManager class,
// which will wrap the calls to createOrthoCamera and addChild for us! Check out
// some of the other examples to see this in action...
osg::Group* group = new osg::Group();
osg::Camera* camera = osgWidget::createOrthoCamera(1280.0f, 1024.0f);
osg::Node* model = osgDB::readNodeFile("cow.osg");
// Add our event handler; is this better as a MatrixManipulator? Add a few other
// helpful ViewerEventHandlers.
viewer.addEventHandler(new osgWidget::MouseHandler(wm));
viewer.addEventHandler(new osgWidget::KeyboardHandler(wm));
viewer.addEventHandler(new osgWidget::ResizeHandler(wm, camera));
viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera));
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgGA::StateSetManipulator(
viewer.getCamera()->getOrCreateStateSet()
));
// Add our event handler; is this better as a MatrixManipulator? Add a few other
// helpful ViewerEventHandlers.
viewer.addEventHandler(new osgWidget::MouseHandler(wm));
viewer.addEventHandler(new osgWidget::KeyboardHandler(wm));
viewer.addEventHandler(new osgWidget::ResizeHandler(wm, camera));
viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera));
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgGA::StateSetManipulator(
viewer.getCamera()->getOrCreateStateSet()
));
// Set our first non-UI node to be something other than the mask we created our
// WindowManager with to avoid picking.
// TODO: Do I need to create a mechanism for doing this automatically, or should
// that be the responsibility of the users of osgWidget?
model->setNodeMask(MASK_3D);
// Set our first non-UI node to be something other than the mask we created our
// WindowManager with to avoid picking.
// TODO: Do I need to create a mechanism for doing this automatically, or should
// that be the responsibility of the users of osgWidget?
model->setNodeMask(MASK_3D);
// Add the WindowManager instance to the 2D camera. This isn't strictly necessary,
// and you can get some cool results putting the WindowManager directly into a
// 3D scene. This is not necessary if you use WindowManager::createParentOrthoCamera.
camera->addChild(wm);
// Add the WindowManager instance to the 2D camera. This isn't strictly necessary,
// and you can get some cool results putting the WindowManager directly into a
// 3D scene. This is not necessary if you use WindowManager::createParentOrthoCamera.
camera->addChild(wm);
// Add our camera and a testing 3D model to the scene.
group->addChild(camera);
group->addChild(model);
// Add our camera and a testing 3D model to the scene.
group->addChild(camera);
group->addChild(model);
// Here we show how to both run simple strings of code AND run entire files. These
// assume that you're running the osgwidgetwindow example from the build directory,
// otherwise you'll need to adjust the file path below in the call to runFile().
wm->getLuaEngine()->eval("window = osgwidget.newWindow()");
wm->getLuaEngine()->runFile("osgWidget/osgwidgetwindow.lua");
// Here we show how to both run simple strings of code AND run entire files. These
// assume that you're running the osgwidgetwindow example from the build directory,
// otherwise you'll need to adjust the file path below in the call to runFile().
wm->getLuaEngine()->eval("window = osgwidget.newWindow()");
wm->getLuaEngine()->runFile("osgWidget/osgwidgetwindow.lua");
wm->getPythonEngine()->eval("import osgwidget");
wm->getPythonEngine()->runFile("osgWidget/osgwidgetwindow.py");
wm->getPythonEngine()->eval("import osgwidget");
wm->getPythonEngine()->runFile("osgWidget/osgwidgetwindow.py");
viewer.setUpViewInWindow(0, 0, 1280, 1024);
viewer.setSceneData(group);
viewer.setUpViewInWindow(0, 0, 1280, 1024);
viewer.setSceneData(group);
/*
osgViewer::Viewer::Cameras cameras;
viewer.getCameras(cameras);
osg::Camera* c = cameras[0];
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
c->setProjectionMatrix(s * c->getProjectionMatrix());
*/
/*
osgViewer::Viewer::Cameras cameras;
viewer.getCameras(cameras);
osg::Camera* c = cameras[0];
osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f);
c->setProjectionMatrix(s * c->getProjectionMatrix());
*/
return viewer.run();
return viewer.run();
}

View File

@ -12,78 +12,39 @@
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGANIMATION_ANIMATIONMANAGERBASE_H
#define OSGANIMATION_ANIMATIONMANAGERBASE_H
#ifndef OSGANIMATION_ANIMATION_MANAGER_BASE_H
#define OSGANIMATION_ANIMATION_MANAGER_BASE_H
#include <osgAnimation/Animation>
#include <osgAnimation/Export>
#include <osg/FrameStamp>
#include <osg/Group>
namespace osgAnimation
{
class OSGANIMATION_EXPORT AnimationManagerBase : public osg::Group
class OSGANIMATION_EXPORT AnimationManagerBase : public osg::NodeCallback
{
public:
typedef std::set<osg::ref_ptr<Target> > TargetSet;
struct UpdateCallback : public osg::NodeCallback
{
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
AnimationManagerBase* b = dynamic_cast<AnimationManagerBase*>(node);
if (b)
{
if (b->needToLink())
{
/** manager need to link, it means that an animation has been added
so we need to relink all item animated with all animations.
We apply the linker visitor on the manager node to affect
all its children.
But it should not be done here, it should be done in the
update of AnimationManager
*/
b->link();
}
const osg::FrameStamp* fs = nv->getFrameStamp();
b->update(fs->getSimulationTime());
}
}
traverse(node,nv);
}
};
AnimationManagerBase();
AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Group(b,copyop)
{
_animations = b._animations;
_targets = b._targets;
_needToLink = b._needToLink;
}
AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY);
virtual ~AnimationManagerBase();
virtual void update (double time) = 0;
virtual void buildTargetReference();
virtual void registerAnimation (Animation* animation);
virtual void link();
virtual void link(osg::Node* subgraph);
virtual void update(double t) = 0;
virtual bool needToLink() const;
const AnimationList& getAnimationList() const { return _animations;}
AnimationMap getAnimationMap() const;
void clearTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->reset();
}
void normalizeTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->normalize();
}
/** Callback method called by the NodeVisitor when visiting a node.*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
/// Operation that must be done each frame
void clearTargets();
void normalizeTargets();
protected:
@ -91,8 +52,6 @@ namespace osgAnimation
AnimationList _animations;
TargetSet _targets;
bool _needToLink;
};
}
#endif

View File

@ -0,0 +1,53 @@
/* -*-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.
*/
#ifndef OSGANIMATION_BASIC_ANIMATION_MANAGER_H
#define OSGANIMATION_BASIC_ANIMATION_MANAGER_H
#include <osg/Group>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/Export>
#include <osg/FrameStamp>
namespace osgAnimation
{
class OSGANIMATION_EXPORT BasicAnimationManager : public AnimationManagerBase
{
public:
META_Object(osgAnimation, BasicAnimationManager);
BasicAnimationManager();
BasicAnimationManager(const AnimationManagerBase& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : AnimationManagerBase(b,copyop) {}
virtual ~BasicAnimationManager();
void update (double time);
void playAnimation (Animation* pAnimation, int priority = 0, float weight = 1.0);
bool stopAnimation (Animation* pAnimation);
bool findAnimation (Animation* pAnimation);
bool isPlaying (Animation* pAnimation);
bool isPlaying (const std::string& animationName);
void stopAll();
protected:
typedef std::map<int, AnimationList > AnimationLayers;
AnimationLayers _animationsPlaying;
double _lastUpdate;
};
}
#endif

View File

@ -30,31 +30,9 @@
#include <osgAnimation/Keyframe>
#include <osgAnimation/UpdateCallback>
#include <osgAnimation/Animation>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/VertexInfluence>
namespace osgAnimation
{
inline osg::Matrix operator* (const osg::Matrix matrix, double v)
{
osg::Matrix result;
for (int i = 0; i < 16; i++)
result.ptr()[i] = matrix.ptr()[i] * v;
return result;
}
inline osg::Matrix operator+ (const osg::Matrix a, const osg::Matrix b)
{
osg::Matrix result;
for (int i = 0; i < 16; i++)
result.ptr()[i] = a.ptr()[i] + b.ptr()[i];
return result;
}
}
namespace osgAnimation
{
@ -68,19 +46,10 @@ namespace osgAnimation
typedef osg::Matrix MatrixType;
META_Node(osgAnimation, Bone);
Bone(const Bone& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Transform(b,copyop),
_position(b._position),
_rotation(b._rotation),
_scale(b._scale) {}
Bone(const std::string& name = "")
{
setName(name);
_needToRecomputeBindMatrix = false;
setUpdateCallback(new UpdateBone(name));
}
Bone(const Bone& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY);
Bone(const std::string& name = "");
void setDefaultUpdateCallback(const std::string& name = "");
struct BoneMapVisitor : public osg::NodeVisitor
{
@ -103,11 +72,18 @@ namespace osgAnimation
{
osg::ref_ptr<osgAnimation::AnimationManagerBase> _manager;
FindNearestParentAnimationManager() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_PARENTS) {}
void apply(osg::Group& node)
void apply(osg::Node& node)
{
if (_manager.valid())
return;
_manager = dynamic_cast<osgAnimation::AnimationManagerBase*>(&node);
osg::NodeCallback* callback = node.getUpdateCallback();
while (callback)
{
_manager = dynamic_cast<osgAnimation::AnimationManagerBase*>(callback);
if (_manager.valid())
return;
callback = callback->getNestedCallback();
}
traverse(node);
}
};
@ -219,25 +195,9 @@ namespace osgAnimation
}
};
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _scale;
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
// flag to recompute bind pose
bool _needToRecomputeBindMatrix;
// bind data
osg::Matrix _bindInBoneSpace;
osg::Matrix _invBindInSkeletonSpace;
// bone updated
osg::Matrix _boneInSkeletonSpace;
Bone* getBoneParent();
const Bone* getBoneParent() const;
@ -251,7 +211,7 @@ namespace osgAnimation
const osg::Matrix& getBindMatrixInBoneSpace() const { return _bindInBoneSpace; }
const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; }
const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;}
void setBoneInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
void setBindMatrixInBoneSpace(const osg::Matrix& matrix)
{
_bindInBoneSpace = matrix;
@ -262,7 +222,7 @@ namespace osgAnimation
virtual void computeBindMatrix();
bool needLink() const;
void setNeedToComputeBindMatrix(bool state) { _needToRecomputeBindMatrix = state; }
/** Add Node to Group.
@ -274,6 +234,24 @@ namespace osgAnimation
virtual bool addChild( Node *child );
BoneMap getBoneMap();
protected:
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _scale;
// flag to recompute bind pose
bool _needToRecomputeBindMatrix;
// bind data
osg::Matrix _bindInBoneSpace;
osg::Matrix _invBindInSkeletonSpace;
// bone updated
osg::Matrix _boneInSkeletonSpace;
};

View File

@ -15,6 +15,12 @@
#ifndef OSGANIMATION_EASE_MOTION_H
#define OSGANIMATION_EASE_MOTION_H
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osg/Notify>
#include <osg/Math>
#include <vector>
namespace osgAnimation {
@ -156,7 +162,7 @@ namespace osgAnimation {
class Motion
class Motion : public osg::Referenced
{
public:
typedef float value_type;
@ -165,28 +171,36 @@ namespace osgAnimation {
CLAMP,
LOOP,
};
Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _b(startValue), _c(changeValue), _d(duration), _behaviour(tb) {}
Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _startValue(startValue), _changeValue(changeValue), _duration(duration), _behaviour(tb) {}
virtual ~Motion() {}
void reset() { setTime(0);}
float getTime() const { return _time; }
void update(float dt)
float evaluateTime(float time) const
{
_time += dt;
switch (_behaviour)
{
case CLAMP:
if (_time > _d)
_time = _d;
else if (_time < 0.0)
_time = 0.0;
if (time > _duration)
time = _duration;
else if (time < 0.0)
time = 0.0;
break;
case LOOP:
_time = fmodf(_time, _d);
if (time <= 0)
time = 0;
else
time = fmodf(time, _duration);
break;
}
return time;
}
void update(float dt)
{
_time = evaluateTime(_time + dt);
}
void setTime(float time) { _time = time; update(0);}
void setTime(float time) { _time = evaluateTime(time);}
void getValue(value_type& result) const { getValueAt(_time, result); }
value_type getValue() const
{
@ -197,23 +211,24 @@ namespace osgAnimation {
void getValueAt(float time, value_type& result) const
{
getValueInNormalizedRange(time/_d, result);
result = result * _c + _b;
getValueInNormalizedRange(evaluateTime(time)/_duration, result);
result = result * _changeValue + _startValue;
}
value_type getValueAt(float time) const
{
value_type result;
getValueAt(time, result);
getValueAt(evaluateTime(time), result);
return result;
}
virtual void getValueInNormalizedRange(float t, value_type& result) const = 0;
float getDuration() const { return _duration;}
protected:
float _time;
float _b;
float _c;
float _d;
float _startValue;
float _changeValue;
float _duration;
TimeBehaviour _behaviour;
};
@ -246,6 +261,39 @@ namespace osgAnimation {
}
};
struct CompositeMotion : public Motion
{
typedef std::vector<osg::ref_ptr<Motion> > MotionList;
MotionList _motions;
MotionList& getMotionList() { return _motions; }
const MotionList& getMotionList() const { return _motions; }
CompositeMotion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
virtual void getValueInNormalizedRange(float t, value_type& result) const
{
if (_motions.empty())
{
result = 0;
osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
return;
}
for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); it++)
{
const Motion* motion = static_cast<const Motion*>(it->get());
float durationInRange = motion->getDuration() / getDuration();
if (t < durationInRange)
{
float tInRange = t/durationInRange * motion->getDuration();
motion->getValueAt( tInRange, result);
return;
} else
t = t - durationInRange;
}
osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange did find the value in range, something wrong" << std::endl;
result = 0;
}
};
// linear

View File

@ -41,9 +41,9 @@ namespace osgAnimation
};
struct UpdateVertex : public osg::Drawable::UpdateCallback
struct UpdateVertex : public osg::Drawable::UpdateCallback
{
virtual void update(osg::NodeVisitor*, osg::Drawable* drw)
virtual void update(osg::NodeVisitor*, osg::Drawable* drw)
{
RigGeometry* geom = dynamic_cast<RigGeometry*>(drw);
if (!geom)
@ -92,31 +92,9 @@ namespace osgAnimation
};
RigGeometry()
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) :
osg::Geometry(b,copyop),
_positionSource(b._positionSource),
_normalSource(b._normalSource),
_vertexInfluenceSet(b._vertexInfluenceSet),
_vertexInfluenceMap(b._vertexInfluenceMap),
_transformVertexes(b._transformVertexes),
_needToComputeMatrix(b._needToComputeMatrix) {}
RigGeometry();
RigGeometry(const osg::Geometry& b);
RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return new RigGeometry(); }
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new RigGeometry(*this,copyop); }

View File

@ -27,16 +27,18 @@ namespace osgAnimation
public:
META_Node(osgAnimation, Skeleton);
struct UpdateCallback : public osg::NodeCallback
struct UpdateSkeleton : public osg::NodeCallback
{
META_Object(osgAnimation, UpdateSkeleton);
UpdateSkeleton() {}
UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::NodeCallback(us, copyop) {}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
};
Skeleton(const Skeleton& b, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : Bone(b,copyop) {}
Skeleton();
void setDefaultUpdateCallback(void);
void computeBindMatrix() { _invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace); }
};
}

View File

@ -153,7 +153,7 @@ namespace osgAnimation
if (!_boneSetVertexSet[i].getBones().empty() &&
(sumOfWeight < 1.0 - threshold || sumOfWeight > 1.0 + threshold))
{
for (int b = 0; b < boneList.size(); b++)
for (int b = 0; b < (int)boneList.size(); b++)
boneList[b].setWeight(boneList[b].getWeight() / sumOfWeight);
}
_boneSetVertexSet[i].getVertexes() = inf.getVertexes();

View File

@ -165,9 +165,14 @@ namespace osgAnimation
typedef std::pair<unsigned int, osg::ref_ptr<Action> > FrameAction;
typedef std::vector<FrameAction> ActionList;
typedef std::map<int, ActionList> ActionLayers;
enum State
{
Play,
Stop,
};
ActionLayers _actions;
double _lastUpdate;
double _speed;
unsigned int _currentFrame;
@ -177,12 +182,6 @@ namespace osgAnimation
bool _loop;
bool _initFirstFrame;
enum State
{
Play,
Stop,
};
State _state;
// to manage pending operation
@ -240,20 +239,8 @@ namespace osgAnimation
META_Object(osgAnimation, Timeline);
Timeline()
{
_lastUpdate = 0;
_currentFrame = 0;
_fps = 25;
_speed = 1.0;
_state = Stop;
_initFirstFrame = false;
_previousFrameEvaluated = 0;
_evaluating = 0;
_numberFrame = -1; // something like infinity
setName("Timeline");
}
Timeline(const Timeline& nc,const osg::CopyOp&) {}
Timeline();
Timeline(const Timeline& nc,const osg::CopyOp& op = osg::CopyOp::SHALLOW_COPY);
State getStatus() const { return _state; }
const ActionList& getActionLayer(int i)
{
@ -541,23 +528,6 @@ namespace osgAnimation
class OSGANIMATION_EXPORT AnimationManagerTimeline : public AnimationManagerBase
{
protected:
osg::ref_ptr<Timeline> _timeline;
public:
META_Node(osgAnimation, AnimationManagerTimeline);
AnimationManagerTimeline();
AnimationManagerTimeline(const AnimationManagerBase& manager);
AnimationManagerTimeline(const AnimationManagerTimeline& nc,const osg::CopyOp&) {}
Timeline* getTimeline() { return _timeline.get(); }
void update(double time);
};
}
#endif

View File

@ -0,0 +1,44 @@
/* -*-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.
*/
#ifndef OSGANIMATION_TIMELINE_ANIMATION_MANAGER_H
#define OSGANIMATION_TIMELINE_ANIMATION_MANAGER_H
#include <osgAnimation/Export>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/Timeline>
namespace osgAnimation
{
class OSGANIMATION_EXPORT TimelineAnimationManager : public AnimationManagerBase
{
protected:
osg::ref_ptr<Timeline> _timeline;
public:
META_Object(osgAnimation, TimelineAnimationManager);
TimelineAnimationManager();
TimelineAnimationManager(const AnimationManagerBase& manager);
TimelineAnimationManager(const TimelineAnimationManager& nc,const osg::CopyOp&);
Timeline* getTimeline() { return _timeline.get(); }
const Timeline* getTimeline() const { return _timeline.get(); }
void update(double time);
};
}
#endif

View File

@ -397,7 +397,7 @@ class OSGWIDGET_EXPORT EventInterface
bool canKeyUp () const { return (_eventMask & EVENT_KEY_UP) != 0; }
private:
typedef std::list<osg::ref_ptr<Callback> > CallbackList;
typedef std::list<osg::observer_ptr<Callback> > CallbackList;
unsigned int _eventMask;
CallbackList _callbacks;

View File

@ -18,15 +18,53 @@
using namespace osgAnimation;
AnimationManagerBase::~AnimationManagerBase() {}
AnimationManagerBase::AnimationManagerBase()
{
setUpdateCallback(new UpdateCallback);
_needToLink = false;
}
void AnimationManagerBase::clearTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->reset();
}
void AnimationManagerBase::normalizeTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->normalize();
}
void AnimationManagerBase::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
if (needToLink())
{
/** manager need to link, it means that an animation has been added
so we need to relink all item animated with all animations.
We apply the linker visitor on the manager node to affect
all its children.
But it should not be done here, it should be done in the
update of AnimationManager
*/
link(node);
}
const osg::FrameStamp* fs = nv->getFrameStamp();
update(fs->getSimulationTime());
}
traverse(node,nv);
}
AnimationManagerBase::AnimationManagerBase(const AnimationManagerBase& b, const osg::CopyOp& copyop) : osg::NodeCallback(b,copyop)
{
_animations = b._animations;
_targets = b._targets;
_needToLink = b._needToLink;
}
void AnimationManagerBase::buildTargetReference()
{
_targets.clear();
@ -52,20 +90,10 @@ bool AnimationManagerBase::needToLink() const { return _needToLink; }
void AnimationManagerBase::link()
void AnimationManagerBase::link(osg::Node* subgraph)
{
LinkVisitor linker(_animations);
accept(linker);
subgraph->accept(linker);
_needToLink = false;
buildTargetReference();
}
osgAnimation::AnimationMap AnimationManagerBase::getAnimationMap() const
{
osgAnimation::AnimationMap map;
for (AnimationList::const_iterator it = _animations.begin(); it != _animations.end(); it++)
map[(*it)->getName()] = *it;
return map;
}

View File

@ -0,0 +1,138 @@
/* -*-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 <osgAnimation/BasicAnimationManager>
#include <osgAnimation/LinkVisitor>
#include <osgAnimation/Assert>
using namespace osgAnimation;
BasicAnimationManager::~BasicAnimationManager() {}
void BasicAnimationManager::stopAll()
{
// loop over all playing animation
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
(*it)->resetTargets();
}
_animationsPlaying.clear();
}
BasicAnimationManager::BasicAnimationManager()
{
_lastUpdate = 0;
}
void BasicAnimationManager::playAnimation(Animation* pAnimation, int priority, float weight)
{
bool r = findAnimation(pAnimation);
OSGANIMATION_ASSERT(r && "This animation is not registered");
if ( isPlaying(pAnimation) )
stopAnimation(pAnimation);
_animationsPlaying[priority].push_back(pAnimation);
pAnimation->setStartTime(_lastUpdate);
pAnimation->setWeight(weight);
}
bool BasicAnimationManager::stopAnimation(Animation* pAnimation)
{
// search though the layer and remove animation
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
if( (*it) == pAnimation )
{
(*it)->resetTargets();
list.erase(it);
return true;
}
}
return false;
}
void BasicAnimationManager::update (double time)
{
if (!_lastUpdate)
_lastUpdate = time;
// could filtered with an active flag
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->reset();
// update from high priority to low priority
for( AnimationLayers::reverse_iterator iterAnim = _animationsPlaying.rbegin(); iterAnim != _animationsPlaying.rend(); ++iterAnim )
{
// update all animation
std::vector<int> toremove;
AnimationList& list = iterAnim->second;
for (unsigned int i = 0; i < list.size(); i++)
{
if (! list[i]->update(time))
toremove.push_back(i);
}
// remove finished animation
while (!toremove.empty())
{
list.erase(list.begin() + toremove.back());
toremove.pop_back();
}
}
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
(*it).get()->normalize();
}
bool BasicAnimationManager::findAnimation(Animation* pAnimation)
{
for( AnimationList::const_iterator iterAnim = _animations.begin(); iterAnim != _animations.end(); ++iterAnim )
{
if ( (*iterAnim) == pAnimation )
return true;
}
return false;
}
bool BasicAnimationManager::isPlaying(Animation* pAnimation)
{
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
if ( (*it) == pAnimation )
return true;
}
return false;
}
bool BasicAnimationManager::isPlaying(const std::string& name)
{
// loop over all playing animation
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
if ( (*it)->getName() == name )
return true;
}
return false;
}

View File

@ -24,6 +24,31 @@ osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone&
{
}
osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop)
: osg::Transform(b,copyop),
_position(b._position),
_rotation(b._rotation),
_scale(b._scale)
{
}
osgAnimation::Bone::Bone(const std::string& name)
{
if (!name.empty())
setName(name);
_needToRecomputeBindMatrix = false;
}
void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
{
std::string cbName = name;
if (cbName.empty())
cbName = getName();
setUpdateCallback(new UpdateBone(cbName));
}
void osgAnimation::Bone::computeBindMatrix()
{
_invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);

View File

@ -10,26 +10,27 @@ SET(LIB_NAME osgAnimation)
SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME})
SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/Export
${HEADER_PATH}/Bone
${HEADER_PATH}/Skeleton
${HEADER_PATH}/Channel
${HEADER_PATH}/Sampler
${HEADER_PATH}/Interpolator
${HEADER_PATH}/Target
${HEADER_PATH}/Animation
${HEADER_PATH}/Keyframe
${HEADER_PATH}/Skinning
${HEADER_PATH}/CubicBezier
${HEADER_PATH}/Vec3Packed
${HEADER_PATH}/AnimationManager
${HEADER_PATH}/AnimationManagerBase
${HEADER_PATH}/UpdateCallback
${HEADER_PATH}/LinkVisitor
${HEADER_PATH}/VertexInfluence
${HEADER_PATH}/EaseMotion
${HEADER_PATH}/Assert
${HEADER_PATH}/Timeline
${HEADER_PATH}/Export
${HEADER_PATH}/Bone
${HEADER_PATH}/Skeleton
${HEADER_PATH}/Channel
${HEADER_PATH}/Sampler
${HEADER_PATH}/Interpolator
${HEADER_PATH}/Target
${HEADER_PATH}/Animation
${HEADER_PATH}/Keyframe
${HEADER_PATH}/Skinning
${HEADER_PATH}/CubicBezier
${HEADER_PATH}/Vec3Packed
${HEADER_PATH}/BasicAnimationManager
${HEADER_PATH}/TimelineAnimationManager
${HEADER_PATH}/AnimationManagerBase
${HEADER_PATH}/UpdateCallback
${HEADER_PATH}/LinkVisitor
${HEADER_PATH}/VertexInfluence
${HEADER_PATH}/EaseMotion
${HEADER_PATH}/Assert
${HEADER_PATH}/Timeline
)
@ -41,7 +42,8 @@ ADD_LIBRARY(${LIB_NAME}
Animation.cpp
Bone.cpp
RigGeometry.cpp
AnimationManager.cpp
BasicAnimationManager.cpp
TimelineAnimationManager.cpp
AnimationManagerBase.cpp
Skeleton.cpp
VertexInfluence.cpp

View File

@ -22,14 +22,45 @@
*/
#include <osgAnimation/RigGeometry>
void osgAnimation::RigGeometry::buildTransformer(Skeleton* root)
using namespace osgAnimation;
RigGeometry::RigGeometry()
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
{
setUseDisplayList(false);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
}
RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
osg::Geometry(b,copyop),
_positionSource(b._positionSource),
_normalSource(b._normalSource),
_vertexInfluenceSet(b._vertexInfluenceSet),
_vertexInfluenceMap(b._vertexInfluenceMap),
_transformVertexes(b._transformVertexes),
_needToComputeMatrix(b._needToComputeMatrix)
{
}
void RigGeometry::buildTransformer(Skeleton* root)
{
Bone::BoneMap bm = root->getBoneMap();
_transformVertexes.init(bm, _vertexInfluenceSet.getUniqVertexSetToBoneSetList());
_root = root;
}
void osgAnimation::RigGeometry::buildVertexSet()
void RigGeometry::buildVertexSet()
{
if (!_vertexInfluenceMap.valid())
{
@ -47,7 +78,7 @@ void osgAnimation::RigGeometry::buildVertexSet()
std::cout << "uniq groups " << _vertexInfluenceSet.getUniqVertexSetToBoneSetList().size() << " for " << getName() << std::endl;
}
void osgAnimation::RigGeometry::computeMatrixFromRootSkeleton()
void RigGeometry::computeMatrixFromRootSkeleton()
{
if (!_root.valid())
{
@ -60,8 +91,11 @@ void osgAnimation::RigGeometry::computeMatrixFromRootSkeleton()
_needToComputeMatrix = false;
}
void osgAnimation::RigGeometry::transformSoftwareMethod()
void RigGeometry::transformSoftwareMethod()
{
setUseDisplayList(false);
setUseVertexBufferObjects(true);
// std::cout << getName() << " _matrixFromSkeletonToGeometry" << _matrixFromSkeletonToGeometry << std::endl;
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(getVertexArray());
if (pos && _positionSource.size() != pos->size())
@ -86,8 +120,10 @@ void osgAnimation::RigGeometry::transformSoftwareMethod()
_transformVertexes.compute<osg::Vec3>(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_normalSource.front(), &normal->front());
normal->dirty();
}
if (getUseDisplayList())
dirtyDisplayList();
dirtyBound();
}
const osgAnimation::Skeleton* osgAnimation::RigGeometry::getSkeleton() const { return _root.get(); }
osgAnimation::Skeleton* osgAnimation::RigGeometry::getSkeleton() { return _root.get(); }
const osgAnimation::Skeleton* RigGeometry::getSkeleton() const { return _root.get(); }
osgAnimation::Skeleton* RigGeometry::getSkeleton() { return _root.get(); }

View File

@ -52,15 +52,15 @@ struct updateMatrixVisitor : public osg::NodeVisitor
}
if (parent)
bone->_boneInSkeletonSpace = bone->getMatrixInBoneSpace() * bone->getBoneParent()->getMatrixInSkeletonSpace();
bone->setBoneInSkeletonSpace(bone->getMatrixInBoneSpace() * bone->getBoneParent()->getMatrixInSkeletonSpace());
else
bone->_boneInSkeletonSpace = bone->getMatrixInBoneSpace();// * _skeleton;
bone->setBoneInSkeletonSpace(bone->getMatrixInBoneSpace());
traverse(node);
}
};
void Skeleton::UpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
void Skeleton::UpdateSkeleton::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
@ -72,23 +72,18 @@ void Skeleton::UpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
// process. It's important to update Bone before other things because the update
// of RigGeometry need it
updateMatrixVisitor visitor;
#if 0
visitor._skeleton = b->getMatrix();
int numChildren = b->getNumChildren();
for (int i = 0; i < numChildren; i++)
{
b->getChild(i)->accept(visitor);
}
#else
b->accept(visitor);
#endif
}
}
traverse(node,nv);
}
Skeleton::Skeleton()
Skeleton::Skeleton()
{
setUpdateCallback(new UpdateCallback());
}
void Skeleton::setDefaultUpdateCallback()
{
setUpdateCallback(new Skeleton::UpdateSkeleton );
}

View File

@ -16,34 +16,32 @@
using namespace osgAnimation;
// temporary
// the problem comes that the AnimationManagerBase should only a group
// and it's data should be in an update callback
struct TimelineAdaptator : public Timeline
{
osg::ref_ptr<AnimationManagerTimeline> _manager;
TimelineAdaptator(AnimationManagerTimeline* manager) : _manager(manager) {}
void evaluate(unsigned int frame)
{
_manager->clearTargets();
Timeline::evaluate(frame);
_manager->normalizeTargets();
}
};
AnimationManagerTimeline::AnimationManagerTimeline()
Timeline::Timeline()
{
_timeline = new TimelineAdaptator(this);
_lastUpdate = 0;
_currentFrame = 0;
_fps = 25;
_speed = 1.0;
_state = Stop;
_initFirstFrame = false;
_previousFrameEvaluated = 0;
_evaluating = 0;
_numberFrame = -1; // something like infinity
setName("Timeline");
}
AnimationManagerTimeline::AnimationManagerTimeline(const AnimationManagerBase& manager) : AnimationManagerBase(manager)
Timeline::Timeline(const Timeline& nc,const osg::CopyOp& op) : osg::Object(nc, op),
_actions(nc._actions)
{
_timeline = new TimelineAdaptator(this);
_lastUpdate = 0;
_currentFrame = 0;
_fps = 25;
_speed = 1.0;
_state = Stop;
_initFirstFrame = false;
_previousFrameEvaluated = 0;
_evaluating = 0;
_numberFrame = -1; // something like infinity
setName("Timeline");
}
void AnimationManagerTimeline::update(double time)
{
_timeline->update(time);
}

View File

@ -0,0 +1,40 @@
/* -*-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 <osgAnimation/Timeline>
#include <osgAnimation/TimelineAnimationManager>
using namespace osgAnimation;
TimelineAnimationManager::TimelineAnimationManager()
{
_timeline = new Timeline;
}
TimelineAnimationManager::TimelineAnimationManager(const AnimationManagerBase& manager) : AnimationManagerBase(manager)
{
_timeline = new Timeline;
}
TimelineAnimationManager::TimelineAnimationManager(const TimelineAnimationManager& nc,const osg::CopyOp& co) : AnimationManagerBase(nc, co)
{
_timeline = new Timeline(*nc.getTimeline());
}
void TimelineAnimationManager::update(double time)
{
clearTargets();
_timeline->update(time);
normalizeTargets();
}

View File

@ -54,9 +54,9 @@ void AnimationUpdateCallback::updateLink()
Maybe this function should be on the manager side like
_manager->linkItem(Bone);
*/
AnimationMap map = _manager->getAnimationMap();
for (AnimationMap::iterator it = map.begin(); it != map.end(); it++)
link(it->second.get());
const AnimationList& animationList = _manager->getAnimationList();
for (AnimationList::const_iterator it = animationList.begin(); it != animationList.end(); it++)
link(it->get());
_manager->buildTargetReference();
}
}

View File

@ -8,7 +8,7 @@
#include <osgAnimation/Bone>
#include <osgAnimation/Skeleton>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/BasicAnimationManager>
class BvhMotionBuilder : public osg::Referenced
{
@ -79,7 +79,7 @@ public:
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( parent->getName()+"End" );
bone->setBindMatrixInBoneSpace( osg::Matrix::translate(offsetEndSite) );
bone->setDataVariance( osg::Object::DYNAMIC );
parent->addChild( bone.get() );
parent->addChild( bone );
if ( _drawingFlag )
parent->addChild( createRefGeometry(offsetEndSite, 0.5).get() );
@ -94,11 +94,9 @@ public:
// Process JOINT section
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( fr[1].getStr() );
bone->setDefaultUpdateCallback();
bone->setDataVariance( osg::Object::DYNAMIC );
osgAnimation::AnimationUpdateCallback* cb =
dynamic_cast<osgAnimation::AnimationUpdateCallback*>( bone->getUpdateCallback() );
if ( cb ) cb->setName( bone->getName() );
parent->addChild( bone.get() );
parent->addChild( bone );
_joints.push_back( JointNode(bone, 0) );
int entry = fr[1].getNoNestedBrackets();
@ -185,7 +183,7 @@ public:
}
}
osgAnimation::AnimationManager* buildBVH( std::istream& stream, const osgDB::ReaderWriter::Options* options )
osg::Group* buildBVH( std::istream& stream, const osgDB::ReaderWriter::Options* options )
{
if ( options )
{
@ -197,6 +195,7 @@ public:
fr.attach( &stream );
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
skelroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Animation> anim = new osgAnimation::Animation;
while( !fr.eof() )
@ -234,14 +233,16 @@ public:
}
#endif
osgAnimation::AnimationManager* manager = new osgAnimation::AnimationManager;
manager->addChild( skelroot.get() );
osg::Group* root = new osg::Group;
osgAnimation::BasicAnimationManager* manager = new osgAnimation::BasicAnimationManager;
root->addChild( skelroot.get() );
root->setUpdateCallback(manager);
manager->registerAnimation( anim.get() );
manager->buildTargetReference();
manager->playAnimation( anim.get() );
_joints.clear();
return manager;
return root;
}
protected:

View File

@ -18,7 +18,9 @@
#include <osgDB/FileUtils>
#include <osgDB/ReaderWriter>
#include <osgAnimation/AnimationManager>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/TimelineAnimationManager>
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/Animation>
#include <osgAnimation/Bone>
@ -73,8 +75,8 @@ bool Bone_readLocalData(Object& obj, Input& fr)
}
bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos));
if (bone.getUpdateCallback() && bone.getUpdateCallback()->getName().empty() && bone.getUpdateCallback()->getNestedCallback())
bone.setUpdateCallback(bone.getUpdateCallback()->getNestedCallback()); // skip the default callback build in constructor of Bone
// if (bone.getUpdateCallback() && bone.getUpdateCallback()->getName().empty() && bone.getUpdateCallback()->getNestedCallback())
// bone.setUpdateCallback(bone.getUpdateCallback()->getNestedCallback()); // skip the default callback build in constructor of Bone
return iteratorAdvanced;
}
@ -297,9 +299,8 @@ RegisterDotOsgWrapperProxy g_atkAnimationProxy
bool AnimationManager_readLocalData(Object& obj, Input& fr)
bool AnimationManagerBase_readLocalData(osgAnimation::AnimationManagerBase& manager, Input& fr)
{
osgAnimation::AnimationManager& manager = dynamic_cast<osgAnimation::AnimationManager&>(obj);
int nbAnims = 0;
bool iteratorAdvanced = false;
@ -310,7 +311,7 @@ bool AnimationManager_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
for (int i = 0; i < nbAnims; i++)
for (int i = 0; i < nbAnims; i++)
{
Object* o = fr.readObject();
osgAnimation::Animation* a = dynamic_cast<osgAnimation::Animation*>(o);
@ -326,30 +327,65 @@ bool AnimationManager_readLocalData(Object& obj, Input& fr)
return iteratorAdvanced;
}
bool AnimationManager_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::AnimationManager& manager = dynamic_cast<const osgAnimation::AnimationManager&>(obj);
osgAnimation::AnimationMap map = manager.getAnimationMap();
int nbanims = map.size();
fw.indent() << "num_animations " << nbanims << std::endl;
for (osgAnimation::AnimationMap::iterator it = map.begin(); it != map.end(); it++)
bool BasicAnimationManager_readLocalData(Object& obj, Input& fr)
{
osgAnimation::BasicAnimationManager& manager = dynamic_cast<osgAnimation::BasicAnimationManager&>(obj);
return AnimationManagerBase_readLocalData(manager, fr);
}
bool TimelineAnimationManager_readLocalData(Object& obj, Input& fr)
{
osgAnimation::TimelineAnimationManager& manager = dynamic_cast<osgAnimation::TimelineAnimationManager&>(obj);
return AnimationManagerBase_readLocalData(manager, fr);
}
bool AnimationManagerBase_writeLocalData(const osgAnimation::AnimationManagerBase& manager, Output& fw)
{
const osgAnimation::AnimationList& animList = manager.getAnimationList();
fw.indent() << "num_animations " << animList.size() << std::endl;
for (osgAnimation::AnimationList::const_iterator it = animList.begin(); it != animList.end(); it++)
{
if (!fw.writeObject(*it->second))
if (!fw.writeObject(**it))
osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl;
}
return true;
}
RegisterDotOsgWrapperProxy g_atkAnimationManagerProxy
bool BasicAnimationManager_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::BasicAnimationManager& manager = dynamic_cast<const osgAnimation::BasicAnimationManager&>(obj);
return AnimationManagerBase_writeLocalData(manager, fw);
}
bool TimelineAnimationManager_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::TimelineAnimationManager& manager = dynamic_cast<const osgAnimation::TimelineAnimationManager&>(obj);
return AnimationManagerBase_writeLocalData(manager, fw);
}
RegisterDotOsgWrapperProxy g_BasicAnimationManagerProxy
(
new osgAnimation::AnimationManager,
"osgAnimation::AnimationManager",
"Object Node Group osgAnimation::AnimationManager",
&AnimationManager_readLocalData,
&AnimationManager_writeLocalData,
new osgAnimation::BasicAnimationManager,
"osgAnimation::BasicAnimationManager",
"Object NodeCallback osgAnimation::BasicAnimationManager",
&BasicAnimationManager_readLocalData,
&BasicAnimationManager_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
);
RegisterDotOsgWrapperProxy g_TimelineAnimationManagerProxy
(
new osgAnimation::TimelineAnimationManager,
"osgAnimation::TimelineAnimationManager",
"Object NodeCallback osgAnimation::TimelineAnimationManager",
&TimelineAnimationManager_readLocalData,
&TimelineAnimationManager_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool RigGeometry_readLocalData(Object& obj, Input& fr)
@ -468,6 +504,29 @@ RegisterDotOsgWrapperProxy g_atkUpdateBoneProxy
bool UpdateSkeleton_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateSkeleton_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
(
new osgAnimation::Skeleton::UpdateSkeleton,
"osgAnimation::UpdateSkeleton",
"Object osgAnimation::UpdateSkeleton",
&UpdateSkeleton_readLocalData,
&UpdateSkeleton_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateTransform_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
@ -487,5 +546,5 @@ RegisterDotOsgWrapperProxy g_atkUpdateTransformProxy
&UpdateTransform_readLocalData,
&UpdateTransform_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
);