OSG Example parsing osganimationmorph (1)

Source: Internet
Author: User
Introduction

This lesson mainly demonstrates the deformation animation in Osganimation, which is also known as the vertex-by-pixel animation (Per-vertex Animation), which is a representation of three-dimensional animation. It consumes a lot of computing resources of computer, usually it is appropriate to calculate and apply the position of 4000~9000 vertex at each frame, otherwise the system can not withstand the updating and rendering of other scene objects. Deformation animation in the osganimation through the morphgeometry and updatemorph to achieve, the specific implementation can refer to my other article osganimation of the role of the relevant introduction. Example

The example first implements a nodevisitor to find the Geometry object in the Geode node:

struct Geometryfinder:public osg::nodevisitor
{
    osg::ref_ptr<osg::geometry> _geom;
    Geometryfinder (): Osg::nodevisitor (Osg::nodevisitor::traverse_all_children) {}
    void apply (osg::geode& Geode) 
    {
        if (_geom.valid ())
            return;
        for (unsigned int i = 0; i < geode.getnumdrawables (); i++) 
        {
            osg::geometry* geom = dynamic_cast<osg::geome Try*> (Geode.getdrawable (i));
            if (geom) {
                _geom = Geom;
                return;}}}
;
It saves the first geometry node in the Geode, and the subsequent function uses the accessor

Osg::ref_ptr<osg::geometry> getshape (const std::string& name)
{
    osg::ref_ptr<osg::node> SHAPE0 = osgdb::readnodefile (name);
    if (SHAPE0)
    {
        Geometryfinder finder;
        Shape0->accept (finder);
        return finder._geom;
    }
    else
    {
        return NULL;
    }
}
Returns the first geometry node in a file name

Let's look at the implementation process in the main function, which should be clearer: first create a channel

    osganimation::animation* Animation = new Osganimation::animation;
    osganimation::floatlinearchannel* channel0 = new Osganimation::floatlinearchannel;
    Channel0->getorcreatesampler ()->getorcreatekeyframecontainer ()->push_back (osgAnimation::FloatKeyframe (0,0.0));
    Channel0->getorcreatesampler ()->getorcreatekeyframecontainer ()->push_back (osgAnimation::FloatKeyframe (1,1.0));
    Channel0->settargetname ("Morphnodecallback");
    Channel0->setname ("0");
It is important to note that the name of the channel is set to a nonnegative integer string of 0, 1, 2, which corresponds to the geometry object added to the morphgeometry. In addition, the channel targetname to be the same as the name of Updatemorph, so that the link can be successful. You need to be aware of these two points about channel settings.

Next create animation and animation manager

    Animation->addchannel (channel0);
    Animation->setname ("Morph");
    Animation->computeduration ();
    Animation->setplaymode (osganimation::animation::P pong);
    osganimation::basicanimationmanager* bam = new Osganimation::basicanimationmanager;
    Bam->registeranimation (animation);
The animated object adds the channel to it, and the animation manager needs to be on top of the Geode node (the parent node of the Geode), which is guaranteed to go into the animation manager's callback before entering the Updatemorph callback.

Re-create the geometry and target geometry that need to be deformed

    osg::ref_ptr<osg::geometry> geom0 = Getshape ("MORPHTARGET_SHAPE0.OSG");
    if (!geom0) {
        std::cerr << "can ' t read morphtarget_shape0.osg" << Std::endl;
        return 0;
    }

    osg::ref_ptr<osg::geometry> geom1 = Getshape ("MORPHTARGET_SHAPE1.OSG");
    if (!geom1) {
        std::cerr << "can ' t read morphtarget_shape1.osg" << Std::endl;
        return 0;
    }

    Original shape
    osganimation::morphgeometry* morph = new Osganimation::morphgeometry (*GEOM0);
   Shapes that need to be deformed are added to the Morph, which can be multiple, and the results will be added as weights
   morph->addmorphtarget (Geom1.get ());

Finally add Updatemorph to Geode

    osg::geode* Geode = new Osg::geode;
    Geode->adddrawable (morph);
    Geode->addupdatecallback (New Osganimation::updatemorph ("Morphnodecallback"));

This ensures that the weights of the geometry are updated into the Geode callback before entering Morphgeometry's drawable update callback, ensuring that subsequent vertices are calculated using the latest interpolated weights in the channel.

Operation Result:



Written in the following: In the subsequent Osgnehe course Lesson25 will be based on the vertex deformation, you can refer to the implementation of this lesson using the Osganimation library to achieve, in the implementation of the process I encountered:

When the drawing geometry is OSG::P rimitiveset: The program crashes when you:P oints, and the description is similar to the post in Osgchina. Later, after viewing the discovery is because there is no normalarray caused by the problem, the solution is to apply for a normal vector array, arbitrarily set up to add to the geometry can solve the problem. This may be a bug,osganimation requirement in the Osganimation code that must have Normalarray.




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.