Files
OpenSceneGraph/src/osgAnimation/UpdateCallback.cpp
Cedric Pinson b6ab5bbe27 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
2009-08-31 09:40:56 +00:00

171 lines
5.4 KiB
C++

/* -*-c++-*-
* Copyright (C) 2008 Cedric Pinson <cedric.pinson@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.
*
* Authors:
* Cedric Pinson <cedric.pinson@plopbyte.net>
* Michael Platings <mplatings@pixelpower.com>
*/
#include <osgAnimation/UpdateCallback>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
using namespace osgAnimation;
UpdateTransform::UpdateTransform(const UpdateTransform& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_euler = new osgAnimation::Vec3Target(apc._euler->getValue());
_position = new osgAnimation::Vec3Target(apc._position->getValue());
_scale = new osgAnimation::Vec3Target(apc._scale->getValue());
}
UpdateTransform::UpdateTransform(const std::string& name):
AnimationUpdateCallback<osg::NodeCallback>(name)
{
_euler = new osgAnimation::Vec3Target;
_position = new osgAnimation::Vec3Target;
_scale = new osgAnimation::Vec3Target(osg::Vec3(1,1,1));
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::MatrixTransform* matrix = dynamic_cast<osg::MatrixTransform*>(node);
if (matrix)
{
update(*matrix);
}
else
{
osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
if (pat)
update(*pat);
}
}
traverse(node,nv);
}
void UpdateTransform::update(osg::MatrixTransform& mat)
{
float z = _euler->getValue()[2];
float x = _euler->getValue()[0];
float y = _euler->getValue()[1];
osg::Matrix m =
osg::Matrix::rotate(x,1.0,0.0,0.0) *
osg::Matrix::rotate(y,0.0,1.0,0.0) *
osg::Matrix::rotate(z,0.0,0.0,1.0);
mat.setMatrix(osg::Matrix::scale(_scale->getValue()) *
m *
osg::Matrix::translate(_position->getValue()));
mat.dirtyBound();
}
void UpdateTransform::update(osg::PositionAttitudeTransform& pat)
{
float heading = _euler->getValue()[0];
float pitch = _euler->getValue()[1];
float roll = _euler->getValue()[2];
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);
osg::Quat q = m.getRotate();
pat.setPosition(_position->getValue());
pat.setScale(_scale->getValue());
pat.setAttitude(q);
pat.dirtyBound();
}
bool UpdateTransform::needLink() const
{
// the idea is to return true if nothing is linked
return !((_position->getCount() + _euler->getCount() + _scale->getCount()) > 3);
}
bool UpdateTransform::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("euler") != std::string::npos)
{
return channel->setTarget(_euler.get());
}
else if (channel->getName().find("position") != std::string::npos)
{
return channel->setTarget(_position.get());
}
else if (channel->getName().find("scale") != std::string::npos)
{
return channel->setTarget(_scale.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class" << className() << std::endl;
}
return false;
}
UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::StateAttribute::Callback>(apc, copyop)
{
_diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
}
UpdateMaterial::UpdateMaterial(const std::string& name):
AnimationUpdateCallback<osg::StateAttribute::Callback>(name)
{
_diffuse = new osgAnimation::Vec4Target(osg::Vec4(1,0,1,1));
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateMaterial::operator()(osg::StateAttribute* sa, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::Material* material = dynamic_cast<osg::Material*>(sa);
if (material)
update(*material);
}
}
void UpdateMaterial::update(osg::Material& material)
{
osg::Vec4 diffuse = _diffuse->getValue();
material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
}
bool UpdateMaterial::needLink() const
{
// the idea is to return true if nothing is linked
return (_diffuse->getCount() < 2);
}
bool UpdateMaterial::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("diffuse") != std::string::npos)
{
return channel->setTarget(_diffuse.get());
}
else
{
osg::notify(osg::WARN) << "Channel " << channel->getName() << " does not contain a valid symbolic name for this class " << className() << std::endl;
}
return false;
}