Cedric Pinson wrote:
Hi PP,

I made a simple test, i add in osganimationviewer a way to save the
loaded data to then after test the saved data from the writer.
I used nathan.osg, and it works fine to replay the saved data. My conclusion is it works. Anyway it does not give you the solution.
Maybe you could check the osganimation examples, it create stuff from
scratch not from a loaded data.

If you have problem, report the bug with a minimal example that
reproduce the problem.

Cheers,
Cedric

Hi Cedric and thx for fast answer.
I replied in the forum already, but waiting for approval.

The issue can be reconstructed with e.g. the osgAnimationNode example. I tweak the main there to write out an osg file instead of creating a viewer ( attached ). The osg file gets written, but the UpdateCallbacks Code Block stays empty. There I would expect an animationManager entry and keyframe data, as it gets exportet from your blender exporter. When I run the file with osganimationviewer it crashes and I get a error message like "no animationmanager found".

My guess is that the class AnimtkUpdateCallback should derive from BasicAnimationManager instead of NodeCallback, but am not sure, and don't get it to run anyway.

Would be great if you could look into this, thx.

By the way it might not be possible to use your trunk, as I am developing for a software build on top of osg 2.8.2, and this might change for next stable releases only, but I will discuss this, if that is a problem.

Cheers, searching for the Pivot of my soul, PP !!! ( <- ParticlePeter )

/*  -*-c++-*- 
 *  Copyright (C) 2008 Cedric Pinson <morni...@plopbyte.net>
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/

#include <iostream>
#include <osg/Geometry>
#include <osg/Shape>
#include <osg/ShapeDrawable>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <osg/MatrixTransform>
#include <osg/Material>
#include <osgAnimation/Sampler>
#include <osgAnimation/BasicAnimationManager>
#include <osgDB/WriteFile>
#include <stdio.h>

class AnimtkUpdateCallback : public osgAnimation::NodeCallback
{
public:
    META_Object(osgAnimation, AnimtkUpdateCallback);

    AnimtkUpdateCallback() 
    {
        _sampler = new osgAnimation::Vec3CubicBezierSampler;
        _playing = false;
        _lastUpdate = 0;
    }
    AnimtkUpdateCallback(const AnimtkUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
        osg::Object(val, copyop),
        osg::NodeCallback(val, copyop),
        _sampler(val._sampler),
        _startTime(val._startTime),
        _currentTime(val._currentTime),
        _playing(val._playing),
        _lastUpdate(val._lastUpdate)
    {
    }

    /** Callback method called by the NodeVisitor when visiting a node.*/
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    { 
        if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR && 
            nv->getFrameStamp() && 
            nv->getFrameStamp()->getFrameNumber() != _lastUpdate) {

            _lastUpdate = nv->getFrameStamp()->getFrameNumber();
            _currentTime = osg::Timer::instance()->tick();

            if (_playing && _sampler.get() && _sampler->getKeyframeContainer()) {
                osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node);
                if (transform) {
                    osg::Vec3 result;
                    float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
                    float duration = _sampler->getEndTime() - _sampler->getStartTime();
                    t = fmod(t, duration);
                    t += _sampler->getStartTime();
                    _sampler->getValueAt(t, result);
                    transform->setMatrix(osg::Matrix::translate(result));
                }
            }
        }
        // note, callback is responsible for scenegraph traversal so
        // they must call traverse(node,nv) to ensure that the
        // scene graph subtree (and associated callbacks) are traversed.
        traverse(node,nv);
    }

    void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
    void stop() { _currentTime = _startTime; _playing = false;}

    osg::ref_ptr<osgAnimation::Vec3CubicBezierSampler> _sampler;
    osg::Timer_t _startTime;
    osg::Timer_t _currentTime;
    bool _playing;
    int _lastUpdate;
};


class AnimtkStateSetUpdateCallback : public osg::StateSet::Callback
{
public:
    META_Object(osgAnimation, AnimtkStateSetUpdateCallback);

    AnimtkStateSetUpdateCallback() 
    {
        _sampler = new osgAnimation::Vec4LinearSampler;
        _playing = false;
        _lastUpdate = 0;
    }

    AnimtkStateSetUpdateCallback(const AnimtkStateSetUpdateCallback& val, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
        osg::Object(val, copyop),
        osg::StateSet::Callback(val, copyop),
        _sampler(val._sampler),
        _startTime(val._startTime),
        _currentTime(val._currentTime),
        _playing(val._playing),
        _lastUpdate(val._lastUpdate)
    {
    }

    /** Callback method called by the NodeVisitor when visiting a node.*/
    virtual void operator()(osg::StateSet* state, osg::NodeVisitor* nv)
    { 
        if (state && 
            nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR && 
            nv->getFrameStamp() && 
            nv->getFrameStamp()->getFrameNumber() != _lastUpdate) 
        {

            _lastUpdate = nv->getFrameStamp()->getFrameNumber();
            _currentTime = osg::Timer::instance()->tick();

            if (_playing && _sampler.get() && _sampler->getKeyframeContainer()) 
            {
                osg::Material* material = dynamic_cast<osg::Material*>(state->getAttribute(osg::StateAttribute::MATERIAL));
                if (material) 
                {
                    osg::Vec4 result;
                    float t = osg::Timer::instance()->delta_s(_startTime, _currentTime);
                    float duration = _sampler->getEndTime() - _sampler->getStartTime();
                    t = fmod(t, duration);
                    t += _sampler->getStartTime();
                    _sampler->getValueAt(t, result);
                    material->setDiffuse(osg::Material::FRONT_AND_BACK, result);
                }
            }
        }
    }

    void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;}
    void stop() { _currentTime = _startTime; _playing = false;}

    osg::ref_ptr<osgAnimation::Vec4LinearSampler> _sampler;
    osg::Timer_t _startTime;
    osg::Timer_t _currentTime;
    bool _playing;
    int _lastUpdate;
};


osg::Geode* createAxis()
{
    osg::Geode* geode  = new osg::Geode;  
    osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry());

    osg::ref_ptr<osg::Vec3Array> vertices (new osg::Vec3Array());
    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
    vertices->push_back (osg::Vec3 ( 10.0, 0.0, 0.0));
    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
    vertices->push_back (osg::Vec3 ( 0.0, 10.0, 0.0));
    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 0.0));
    vertices->push_back (osg::Vec3 ( 0.0, 0.0, 10.0));
    geometry->setVertexArray (vertices.get());

    osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array());
    colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
    colors->push_back (osg::Vec4 (1.0f, 0.0f, 0.0f, 1.0f));
    colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
    colors->push_back (osg::Vec4 (0.0f, 1.0f, 0.0f, 1.0f));
    colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
    colors->push_back (osg::Vec4 (0.0f, 0.0f, 1.0f, 1.0f));
    geometry->setColorArray (colors.get());

    geometry->setColorBinding (osg::Geometry::BIND_PER_VERTEX);    
    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,6));

    geode->addDrawable( geometry.get() );
    geode->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
    return geode;
}

osg::StateSet* setupStateSet()
{
    osg::StateSet* st = new osg::StateSet;
    st->setAttributeAndModes(new osg::Material, true);
    st->setMode(GL_BLEND, true);
    AnimtkStateSetUpdateCallback* callback = new AnimtkStateSetUpdateCallback;
    osgAnimation::Vec4KeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
    keys->push_back(osgAnimation::Vec4Keyframe(0, osg::Vec4(0,0,0,0)));
    keys->push_back(osgAnimation::Vec4Keyframe(2, osg::Vec4(0.5,0,0,0.5)));
    keys->push_back(osgAnimation::Vec4Keyframe(4, osg::Vec4(0,0.5,0,1)));
    keys->push_back(osgAnimation::Vec4Keyframe(6, osg::Vec4(0,0,0.5,1)));
    keys->push_back(osgAnimation::Vec4Keyframe(8, osg::Vec4(1,1,1,0.5)));
    keys->push_back(osgAnimation::Vec4Keyframe(10, osg::Vec4(0,0,0,0)));
    callback->start();
    st->setUpdateCallback(callback);
    return st;
}

osg::Node* setupCube()
{
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f,0.0f,0.0f),2)));
    geode->setStateSet(setupStateSet());
    return geode;
}

osg::MatrixTransform* setupAnimtkNode()
{
    osg::Vec3 v[5];
    v[0] = osg::Vec3(0,0,0);
    v[1] = osg::Vec3(10,-50,0);
    v[2] = osg::Vec3(30,-10,20);
    v[3] = osg::Vec3(-10,20,-20);
    v[4] = osg::Vec3(0,0,0);
    osg::MatrixTransform* node = new osg::MatrixTransform;
    AnimtkUpdateCallback* callback = new AnimtkUpdateCallback;
    osgAnimation::Vec3CubicBezierKeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
    keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(0, osgAnimation::Vec3CubicBezier(
                                                        v[0], // pos
                                                        v[0] + (v[0] - v[3]), // p1 
                                                        v[1] - (v[1] - v[0]) // p2
                                                        )));
    keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(2, osgAnimation::Vec3CubicBezier(
                                                        v[1], // pos
                                                        v[1] + (v[1] - v[0]),
                                                        v[2] - (v[2] - v[1])
                                                        )));
    keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(4, osgAnimation::Vec3CubicBezier(
                                                        v[2], // pos
                                                        v[2] + (v[2] - v[1]),
                                                        v[3] - (v[3] - v[2])
                                                        )));
    keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(6, osgAnimation::Vec3CubicBezier(
                                                        v[3], // pos
                                                        v[3] + (v[3] - v[2]),
                                                        v[4] - (v[4] - v[3])
                                                        )));
    keys->push_back(osgAnimation::Vec3CubicBezierKeyframe(8, osgAnimation::Vec3CubicBezier(
                                                        v[4], // pos
                                                        v[4] + (v[4] - v[3]),
                                                        v[0] - (v[0] - v[4])
                                                        )));

    callback->start();
    node->setUpdateCallback(callback);
    node->addChild(setupCube());
    return node;
}

/*
int main (int argc, char* argv[])
{
    osg::ArgumentParser arguments(&argc, argv);
    osgViewer::Viewer viewer(arguments);

    osgGA::TrackballManipulator* manipulator = new osgGA::TrackballManipulator();
    viewer.setCameraManipulator(manipulator);
  
    osg::Group* root = new osg::Group;
    root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,10), 30));
    root->addChild(createAxis());

    osg::MatrixTransform* node = setupAnimtkNode();
    node->addChild(createAxis());
    root->addChild(node);

    viewer.setSceneData( root );
    viewer.realize();

    while (!viewer.done()) 
    {
        viewer.frame();
    }

}
*/


int main( int , char** )
{
	osg::ref_ptr< osg::Group > root = new osg::Group ;
	root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,10), 30));
	root->addChild(createAxis());

	osg::MatrixTransform* node = setupAnimtkNode();
	root->addChild(node);

	if ( !root.valid() )
		osg::notify( osg::FATAL ) << "Failed in createSceneGraph() !" << std::endl ;
	bool arg = false;

	bool  result = osgDB::writeObjectFile( * ( root.get() ) , "animNode.osg" ) ;
	if ( !result ) 
		osg::notify( osg::FATAL ) << "Failed in osgDB::writeNodeFile() !" << std::endl ;
}
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to