root/OpenSceneGraph/trunk/src/osgAnimation/UpdateCallback.cpp @ 10877

Revision 10877, 5.2 kB (checked in by cedricpinson, 5 years ago)

From Cedric Pinson,
Add check in RigTransformSoftware? if bones are null
Indent TimelineAnimationManager?
Add check for NaN in UpdateCallback?.cpp
Fix TimelineAnimationManager? clear target (a refactore of Timeline is require for futur)
Fix Computation of bounding box for RigGeometry?

RevLine 
[9093]1/*  -*-c++-*-
[10518]2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
[9093]3 *
4 * This library is open source and may be redistributed and/or modified under 
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version.  The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * OpenSceneGraph Public License for more details.
[10527]13 *
14 * Authors:
15 *         Cedric Pinson <cedric.pinson@plopbyte.net>
16 *         Michael Platings <mplatings@pixelpower.com>
17 */
[9093]18
19#include <osgAnimation/UpdateCallback>
20#include <osg/MatrixTransform>
21#include <osg/PositionAttitudeTransform>
[10877]22#include <osg/Math>
[9093]23
24using namespace osgAnimation;
25
26
27UpdateTransform::UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop)
[10386]28    : osg::Object(apc, copyop),
[10518]29      AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
[9093]30{
[10386]31    _euler = new osgAnimation::Vec3Target(apc._euler->getValue());
[10390]32    _position = new osgAnimation::Vec3Target(apc._position->getValue());
33    _scale = new osgAnimation::Vec3Target(apc._scale->getValue());
[9093]34}
35
[10518]36UpdateTransform::UpdateTransform(const std::string& name):
37    AnimationUpdateCallback<osg::NodeCallback>(name)
[9093]38{
39    _euler = new osgAnimation::Vec3Target;
40    _position = new osgAnimation::Vec3Target;
41    _scale = new osgAnimation::Vec3Target(osg::Vec3(1,1,1));
42}
43
44/** Callback method called by the NodeVisitor when visiting a node.*/
45void UpdateTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
46{
47    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
48    {
49        osg::MatrixTransform* matrix = dynamic_cast<osg::MatrixTransform*>(node);
50        if (matrix)
51        {
52            update(*matrix);
53        }
54        else 
55        {
56            osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
57            if (pat)
58                update(*pat);
59        }
60    }
61    traverse(node,nv);
62}
63
64void UpdateTransform::update(osg::MatrixTransform& mat)
65{
66    float z = _euler->getValue()[2];
67    float x = _euler->getValue()[0];
68    float y = _euler->getValue()[1];
69    osg::Matrix m =
70        osg::Matrix::rotate(x,1.0,0.0,0.0) *
71        osg::Matrix::rotate(y,0.0,1.0,0.0) *
72        osg::Matrix::rotate(z,0.0,0.0,1.0);
[10877]73    m = osg::Matrix::scale(_scale->getValue()) * m * osg::Matrix::translate(_position->getValue());
74    mat.setMatrix(m);
75
76    if (!m.valid())
77        osg::notify(osg::WARN) << this << " UpdateTransform::update detected NaN" << std::endl;
[9093]78}
79
80void UpdateTransform::update(osg::PositionAttitudeTransform& pat)
81{
82    float heading = _euler->getValue()[0];
83    float pitch = _euler->getValue()[1];
84    float roll = _euler->getValue()[2];
85    osg::Matrix m = osg::Matrix::rotate(roll,0.0,1.0,0.0) * osg::Matrix::rotate(pitch,1.0,0.0,0.0) * osg::Matrix::rotate(-heading,0.0,0.0,1.0);
86    osg::Quat q = m.getRotate();
87
88    pat.setPosition(_position->getValue());
89    pat.setScale(_scale->getValue());
90    pat.setAttitude(q);
91    pat.dirtyBound();
92}
93
94bool UpdateTransform::link(osgAnimation::Channel* channel)
95{
96    if (channel->getName().find("euler") != std::string::npos)
97    {
[10527]98        return channel->setTarget(_euler.get());
[9093]99    }
100    else if (channel->getName().find("position") != std::string::npos)
101    {
[10527]102        return channel->setTarget(_position.get());
[9093]103    }
104    else if (channel->getName().find("scale") != std::string::npos)
105    {
[10527]106        return channel->setTarget(_scale.get());
[9093]107    }
108    else 
109    {
[10518]110        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
[9093]111    }
112    return false;
113}
[10518]114
115
116
117
118
119UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
120    : osg::Object(apc, copyop),
[10671]121      AnimationUpdateCallback<osg::StateAttributeCallback>(apc, copyop)
[10518]122{
123    _diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
124}
125
126UpdateMaterial::UpdateMaterial(const std::string& name):
[10671]127    AnimationUpdateCallback<osg::StateAttributeCallback>(name)
[10518]128{
[10561]129    _diffuse = new osgAnimation::Vec4Target(osg::Vec4(1,0,1,1));
[10518]130}
131
132/** Callback method called by the NodeVisitor when visiting a node.*/
133void UpdateMaterial::operator()(osg::StateAttribute* sa, osg::NodeVisitor* nv)
134{
135    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
136    {
137        osg::Material* material = dynamic_cast<osg::Material*>(sa);
138        if (material)
139            update(*material);
140    }
141}
142
[10671]143
144osgAnimation::Vec4Target* UpdateMaterial::getDiffuse() { return _diffuse.get(); }
[10518]145void UpdateMaterial::update(osg::Material& material)
146{
147    osg::Vec4 diffuse = _diffuse->getValue();
148    material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
149}
150
151bool UpdateMaterial::link(osgAnimation::Channel* channel)
152{
153    if (channel->getName().find("diffuse") != std::string::npos)
154    {
[10527]155        return channel->setTarget(_diffuse.get());
[10518]156    }
157    else 
158    {
159        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class " << className() << std::endl;
160    }
161    return false;
162}
Note: See TracBrowser for help on using the browser.