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

Revision 10561, 5.4 kB (checked in by cedricpinson, 5 years ago)

From Cedric Pinson, The following modification are
Update Timeline.cpp to add current layer to the ActionVisitor?, use correctly the priority
Add accessors in Action.cpp to retrieve protected data
Split files and rename them to classname
Change de default color of UpdateMaterial? to FFOOFF to detect unset value
Add accessors in LinkVisitor? instead of accessing data directly
Update osganimationtimeline example to fit the api callback

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>
22
23using namespace osgAnimation;
24
25
26UpdateTransform::UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop)
[10386]27    : osg::Object(apc, copyop),
[10518]28      AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
[9093]29{
[10386]30    _euler = new osgAnimation::Vec3Target(apc._euler->getValue());
[10390]31    _position = new osgAnimation::Vec3Target(apc._position->getValue());
32    _scale = new osgAnimation::Vec3Target(apc._scale->getValue());
[9093]33}
34
[10518]35UpdateTransform::UpdateTransform(const std::string& name):
36    AnimationUpdateCallback<osg::NodeCallback>(name)
[9093]37{
38    _euler = new osgAnimation::Vec3Target;
39    _position = new osgAnimation::Vec3Target;
40    _scale = new osgAnimation::Vec3Target(osg::Vec3(1,1,1));
41}
42
43/** Callback method called by the NodeVisitor when visiting a node.*/
44void UpdateTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
45{
46    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
47    {
48        osg::MatrixTransform* matrix = dynamic_cast<osg::MatrixTransform*>(node);
49        if (matrix)
50        {
51            update(*matrix);
52        }
53        else 
54        {
55            osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
56            if (pat)
57                update(*pat);
58        }
59    }
60    traverse(node,nv);
61}
62
63void UpdateTransform::update(osg::MatrixTransform& mat)
64{
65    float z = _euler->getValue()[2];
66    float x = _euler->getValue()[0];
67    float y = _euler->getValue()[1];
68    osg::Matrix m =
69        osg::Matrix::rotate(x,1.0,0.0,0.0) *
70        osg::Matrix::rotate(y,0.0,1.0,0.0) *
71        osg::Matrix::rotate(z,0.0,0.0,1.0);
72    mat.setMatrix(osg::Matrix::scale(_scale->getValue()) *
73                  m *
74                  osg::Matrix::translate(_position->getValue()));
75    mat.dirtyBound();
76}
77
78void UpdateTransform::update(osg::PositionAttitudeTransform& pat)
79{
80    float heading = _euler->getValue()[0];
81    float pitch = _euler->getValue()[1];
82    float roll = _euler->getValue()[2];
83    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);
84    osg::Quat q = m.getRotate();
85
86    pat.setPosition(_position->getValue());
87    pat.setScale(_scale->getValue());
88    pat.setAttitude(q);
89    pat.dirtyBound();
90}
91
92bool UpdateTransform::needLink() const
93{
94    // the idea is to return true if nothing is linked
95    return !((_position->getCount() + _euler->getCount() + _scale->getCount()) > 3);
96}
97
98bool UpdateTransform::link(osgAnimation::Channel* channel)
99{
100    if (channel->getName().find("euler") != std::string::npos)
101    {
[10527]102        return channel->setTarget(_euler.get());
[9093]103    }
104    else if (channel->getName().find("position") != std::string::npos)
105    {
[10527]106        return channel->setTarget(_position.get());
[9093]107    }
108    else if (channel->getName().find("scale") != std::string::npos)
109    {
[10527]110        return channel->setTarget(_scale.get());
[9093]111    }
112    else 
113    {
[10518]114        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
[9093]115    }
116    return false;
117}
[10518]118
119
120
121
122
123UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
124    : osg::Object(apc, copyop),
125      AnimationUpdateCallback<osg::StateAttribute::Callback>(apc, copyop)
126{
127    _diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
128}
129
130UpdateMaterial::UpdateMaterial(const std::string& name):
131    AnimationUpdateCallback<osg::StateAttribute::Callback>(name)
132{
[10561]133    _diffuse = new osgAnimation::Vec4Target(osg::Vec4(1,0,1,1));
[10518]134}
135
136/** Callback method called by the NodeVisitor when visiting a node.*/
137void UpdateMaterial::operator()(osg::StateAttribute* sa, osg::NodeVisitor* nv)
138{
139    if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
140    {
141        osg::Material* material = dynamic_cast<osg::Material*>(sa);
142        if (material)
143            update(*material);
144    }
145}
146
147void UpdateMaterial::update(osg::Material& material)
148{
149    osg::Vec4 diffuse = _diffuse->getValue();
150    material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
151}
152
153bool UpdateMaterial::needLink() const
154{
155    // the idea is to return true if nothing is linked
156    return (_diffuse->getCount() < 2);
157}
158
159bool UpdateMaterial::link(osgAnimation::Channel* channel)
160{
161    if (channel->getName().find("diffuse") != std::string::npos)
162    {
[10527]163        return channel->setTarget(_diffuse.get());
[10518]164    }
165    else 
166    {
167        osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class " << className() << std::endl;
168    }
169    return false;
170}
Note: See TracBrowser for help on using the browser.