Files
OpenSceneGraph/src/osgPlugins/osgAnimation/ReaderWriter.cpp
Cedric Pinson 3c45fb1e6c From Michael Platings,
- Animations with equal priority are now weighted correctly relative to each other
- (minor) Channels no longer store their weight as the only time it's used is in update() when Animation can pass in the weight directly
From Cedric Pinson,
- I adjusted the quaternion blending to keep the commutativy property
2009-08-26 09:24:02 +00:00

1089 lines
35 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.
*/
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgDB/ReaderWriter>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/TimelineAnimationManager>
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/Animation>
#include <osgAnimation/Bone>
#include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/MorphGeometry>
#include <osgAnimation/UpdateCallback>
#include <osgDB/Registry>
#include <osgDB/Input>
#include <osgDB/Output>
using namespace osgDB;
using namespace osg;
bool Bone_readLocalData(Object& obj, Input& fr)
{
osgAnimation::Bone& bone = dynamic_cast<osgAnimation::Bone&>(obj);
osg::Quat att;
bool iteratorAdvanced = false;
if (fr.matchSequence("bindQuaternion %f %f %f %f"))
{
fr[1].getFloat(att[0]);
fr[2].getFloat(att[1]);
fr[3].getFloat(att[2]);
fr[4].getFloat(att[3]);
fr += 5;
iteratorAdvanced = true;
}
osg::Vec3d pos(0,0,0);
if (fr.matchSequence("bindPosition %f %f %f"))
{
fr[1].getFloat(pos[0]);
fr[2].getFloat(pos[1]);
fr[3].getFloat(pos[2]);
fr += 4;
iteratorAdvanced = true;
}
osg::Vec3d scale(1,1,1);
if (fr.matchSequence("bindScale %f %f %f"))
{
fr[1].getFloat(scale[0]);
fr[2].getFloat(scale[1]);
fr[3].getFloat(scale[2]);
fr += 4;
iteratorAdvanced = true;
}
bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos));
return iteratorAdvanced;
}
bool Bone_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::Bone& bone = dynamic_cast<const osgAnimation::Bone&>(obj);
osg::Vec3 t;
osg::Quat r;
osg::Vec3 s;
osg::Quat rs;
bone.getBindMatrixInBoneSpace().decompose(t,r,s,rs);
fw.indent() << "bindQuaternion " << r << std::endl;
fw.indent() << "bindPosition " << t << std::endl;
fw.indent() << "bindScale " << s << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_atkBoneProxy
(
new osgAnimation::Bone,
"osgAnimation::Bone",
"Object Node Transform osgAnimation::Bone Group",
&Bone_readLocalData,
&Bone_writeLocalData
);
bool Skeleton_readLocalData(Object& obj, Input& fr)
{
return false;
}
bool Skeleton_writeLocalData(const Object& obj, Output& fr)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkRootSkeletonProxy
(
new osgAnimation::Skeleton,
"osgAnimation::Skeleton",
"Object Node Transform osgAnimation::Bone osgAnimation::Skeleton Group",
&Skeleton_readLocalData,
&Skeleton_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
// Helper method for reading channels
bool Animation_readChannel(osgAnimation::Channel* pChannel, Input& fr)
{
bool iteratorAdvanced = false;
std::string name = "unknown";
if (fr.matchSequence("name %s"))
{
if (fr[1].getStr())
name = fr[1].getStr();
fr += 2;
iteratorAdvanced = true;
}
pChannel->setName(name);
std::string target = "unknown";
if (fr.matchSequence("target %s"))
{
if (fr[1].getStr())
target = fr[1].getStr();
fr += 2;
iteratorAdvanced = true;
}
pChannel->setTargetName(target);
// we dont need this info
float weight = 1.0;
if (fr.matchSequence("weight %f"))
{
fr[1].getFloat(weight);
fr += 2;
iteratorAdvanced = true;
}
// pChannel->setWeight(weight);
return iteratorAdvanced;
}
bool Animation_readLocalData(Object& obj, Input& fr)
{
osgAnimation::Animation& anim = dynamic_cast<osgAnimation::Animation&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("playmode %w"))
{
if (fr[1].matchWord("ONCE")) anim.setPlaymode(osgAnimation::Animation::ONCE);
else if (fr[1].matchWord("STAY")) anim.setPlaymode(osgAnimation::Animation::STAY);
else if (fr[1].matchWord("LOOP")) anim.setPlaymode(osgAnimation::Animation::LOOP);
else if (fr[1].matchWord("PPONG")) anim.setPlaymode(osgAnimation::Animation::PPONG);
fr += 2;
iteratorAdvanced = true;
}
if (fr.matchSequence("weight %f"))
{
float weight;
fr[1].getFloat(weight);
fr += 2;
iteratorAdvanced = true;
anim.setWeight(weight);
}
if (fr.matchSequence("duration %f"))
{
float duration;
fr[1].getFloat(duration);
fr += 2;
iteratorAdvanced = true;
anim.setDuration(duration);
}
if (fr.matchSequence("starttime %f"))
{
float starttime;
fr[1].getFloat(starttime);
fr += 2;
iteratorAdvanced = true;
anim.setStartTime(starttime);
}
int nbChannels = 0;
if (fr.matchSequence("num_channels %i"))
{
fr[1].getInt(nbChannels);
fr += 2;
iteratorAdvanced = true;
}
for (int i = 0; i < nbChannels; i++)
{
if (fr.matchSequence("DoubleLinearChannel {"))
{
fr += 2;
osgAnimation::DoubleLinearChannel* channel = new osgAnimation::DoubleLinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
double v;
float time;
if (fr.matchSequence("key %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(v);
fr += 3;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::DoubleKeyframe(time, v));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
else if (fr.matchSequence("FloatLinearChannel {"))
{
fr += 2;
osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
float v;
float time;
if (fr.matchSequence("key %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(v);
fr += 3;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(time, v));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
else if (fr.matchSequence("Vec2LinearChannel {"))
{
fr += 2;
osgAnimation::Vec2LinearChannel* channel = new osgAnimation::Vec2LinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
osg::Vec2 v;
float time;
if (fr.matchSequence("key %f %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(v[0]);
fr[3].getFloat(v[1]);
fr += 4;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec2Keyframe(time, v));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
else if (fr.matchSequence("Vec3LinearChannel {"))
{
fr += 2;
osgAnimation::Vec3LinearChannel* channel = new osgAnimation::Vec3LinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
osg::Vec3 v;
float time;
if (fr.matchSequence("key %f %f %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(v[0]);
fr[3].getFloat(v[1]);
fr[4].getFloat(v[2]);
fr += 5;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(time, v));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
else if (fr.matchSequence("Vec4LinearChannel {"))
{
fr += 2;
osgAnimation::Vec4LinearChannel* channel = new osgAnimation::Vec4LinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
osg::Vec4 v;
float time;
if (fr.matchSequence("key %f %f %f %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(v[0]);
fr[3].getFloat(v[1]);
fr[4].getFloat(v[2]);
fr[5].getFloat(v[3]);
fr += 6;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec4Keyframe(time, v));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
else if (fr.matchSequence("QuatSphericalLinearChannel {"))
{
fr += 2;
osgAnimation::QuatSphericalLinearChannel* channel = new osgAnimation::QuatSphericalLinearChannel;
if (Animation_readChannel(channel, fr))
iteratorAdvanced = true;
int nbKeys;
if (fr.matchSequence("Keyframes %i {"))
{
fr[1].getInt(nbKeys);
fr += 3;
iteratorAdvanced = true;
for (int k = 0; k < nbKeys; k++)
{
osg::Quat q;
float time;
if (fr.matchSequence("key %f %f %f %f %f"))
{
fr[1].getFloat(time);
fr[2].getFloat(q[0]);
fr[3].getFloat(q[1]);
fr[4].getFloat(q[2]);
fr[5].getFloat(q[3]);
fr += 6;
channel->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::QuatKeyframe(time, q));
iteratorAdvanced = true;
}
}
anim.addChannel(channel);
if (fr.matchSequence("}")) // keyframes
fr += 1;
}
if (fr.matchSequence("}")) // channel
fr += 1;
}
// Deprecated
// Reading of old channel info
// Kept here for easy conversion of old .osg data to new format
else if (fr.matchSequence("Channel {"))
{
fr += 2;
std::string name = "unknown";
if (fr.matchSequence("name %s"))
{
if (fr[1].getStr())
name = fr[1].getStr();
fr += 2;
iteratorAdvanced = true;
}
std::string target = "unknown";
if (fr.matchSequence("target %s"))
{
if (fr[1].getStr())
target = fr[1].getStr();
fr += 2;
iteratorAdvanced = true;
}
std::string type = "unknown";
int nbKeys;
if (fr.matchSequence("Keyframes %s %i {"))
{
if (fr[1].getStr())
type = fr[1].getStr();
fr[2].getInt(nbKeys);
fr += 4;
iteratorAdvanced = true;
osgAnimation::Channel* channel = 0;
if (type == "Quat")
{
osgAnimation::QuatSphericalLinearChannel* c = new osgAnimation::QuatSphericalLinearChannel;
c->getOrCreateSampler()->getOrCreateKeyframeContainer();
channel = c;
}
else if (type == "Vec3")
{
osgAnimation::Vec3LinearChannel* c = new osgAnimation::Vec3LinearChannel;
c->getOrCreateSampler()->getOrCreateKeyframeContainer();
channel = c;
}
if (channel)
{
for (int k = 0; k < nbKeys; k++)
{
if (type == "Quat")
{
osg::Quat q;
float time;
fr.matchSequence("key %f %f %f %f %f");
fr[1].getFloat(time);
fr[2].getFloat(q[0]);
fr[3].getFloat(q[1]);
fr[4].getFloat(q[2]);
fr[5].getFloat(q[3]);
fr += 6;
osgAnimation::QuatSphericalLinearChannel* c = dynamic_cast<osgAnimation::QuatSphericalLinearChannel*>(channel);
c->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::QuatKeyframe(time, q));
iteratorAdvanced = true;
}
else if (type == "Vec3")
{
osg::Vec3 v;
float time;
fr.matchSequence("key %f %f %f %f");
fr[1].getFloat(time);
fr[2].getFloat(v[0]);
fr[3].getFloat(v[1]);
fr[4].getFloat(v[2]);
fr += 5;
osgAnimation::Vec3LinearChannel* c = dynamic_cast<osgAnimation::Vec3LinearChannel*>(channel);
c->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(time, v));
iteratorAdvanced = true;
}
}
channel->setName(name);
channel->setTargetName(target);
anim.addChannel(channel);
}
if (fr.matchSequence("}")) // keyframes
fr += 1;
if (fr.matchSequence("}")) // channel
fr += 1;
}
}
}
return iteratorAdvanced;
}
// Helper method for writing channels
template <typename ChannelType, typename ContainerType>
void Animation_writeChannel(const std::string& channelString, ChannelType* pChannel, Output& fw)
{
fw.indent() << channelString.c_str() << " {" << std::endl;
fw.moveIn();
fw.indent() << "name \"" << pChannel->getName() << "\"" << std::endl;
fw.indent() << "target \"" << pChannel->getTargetName() << "\"" << std::endl;
// fw.indent() << "weight " << pChannel->getWeight() << std::endl;
ContainerType* kfc = pChannel->getSamplerTyped()->getKeyframeContainerTyped();
if (kfc)
{
fw.indent() << "Keyframes " << kfc->size() << " {" << std::endl;
fw.moveIn();
for (unsigned int k = 0; k < kfc->size(); k++)
{
fw.indent() << "key " << (*kfc)[k].getTime() << " " << (*kfc)[k].getValue() << std::endl;
}
fw.moveOut();
fw.indent() << "}" << std::endl;
fw.moveOut();
fw.indent() << "}" << std::endl;
}
}
bool Animation_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::Animation& anim = dynamic_cast<const osgAnimation::Animation&>(obj);
switch (anim.getPlayMode())
{
case osgAnimation::Animation::ONCE:
fw.indent() << "playmode ONCE" << std::endl;
break;
case osgAnimation::Animation::STAY:
fw.indent() << "playmode STAY" << std::endl;
break;
case osgAnimation::Animation::LOOP:
fw.indent() << "playmode LOOP" << std::endl;
break;
case osgAnimation::Animation::PPONG:
fw.indent() << "playmode PPONG" << std::endl;
break;
default:
break;
}
fw.indent() << "weight " << anim.getWeight() << std::endl;
fw.indent() << "duration " << anim.getDuration() << std::endl;
fw.indent() << "starttime " << anim.getStartTime() << std::endl;
fw.indent() << "num_channels " << anim.getChannels().size() << std::endl;
for (unsigned int i = 0; i < anim.getChannels().size(); i++)
{
osgAnimation::Channel* pChannel = anim.getChannels()[i].get();
osgAnimation::DoubleLinearChannel* pDlc = dynamic_cast<osgAnimation::DoubleLinearChannel*>(pChannel);
if (pDlc)
{
Animation_writeChannel<osgAnimation::DoubleLinearChannel, osgAnimation::DoubleKeyframeContainer>("DoubleLinearChannel", pDlc, fw);
continue;
}
osgAnimation::FloatLinearChannel* pFlc = dynamic_cast<osgAnimation::FloatLinearChannel*>(pChannel);
if (pFlc)
{
Animation_writeChannel<osgAnimation::FloatLinearChannel, osgAnimation::FloatKeyframeContainer>("FloatLinearChannel", pFlc, fw);
continue;
}
osgAnimation::Vec2LinearChannel* pV2lc = dynamic_cast<osgAnimation::Vec2LinearChannel*>(pChannel);
if (pV2lc)
{
Animation_writeChannel<osgAnimation::Vec2LinearChannel, osgAnimation::Vec2KeyframeContainer>("Vec2LinearChannel", pV2lc, fw);
continue;
}
osgAnimation::Vec3LinearChannel* pV3lc = dynamic_cast<osgAnimation::Vec3LinearChannel*>(pChannel);
if (pV3lc)
{
Animation_writeChannel<osgAnimation::Vec3LinearChannel, osgAnimation::Vec3KeyframeContainer>("Vec3LinearChannel", pV3lc, fw);
continue;
}
osgAnimation::Vec4LinearChannel* pV4lc = dynamic_cast<osgAnimation::Vec4LinearChannel*>(pChannel);
if (pV4lc)
{
Animation_writeChannel<osgAnimation::Vec4LinearChannel, osgAnimation::Vec4KeyframeContainer>("Vec4LinearChannel", pV4lc, fw);
continue;
}
osgAnimation::QuatSphericalLinearChannel* pQslc = dynamic_cast<osgAnimation::QuatSphericalLinearChannel*>(pChannel);
if (pQslc)
{
Animation_writeChannel<osgAnimation::QuatSphericalLinearChannel, osgAnimation::QuatKeyframeContainer>("QuatSphericalLinearChannel", pQslc, fw);
continue;
}
osgAnimation::FloatCubicBezierChannel* pFcbc = dynamic_cast<osgAnimation::FloatCubicBezierChannel*>(pChannel);
if (pFcbc)
{
Animation_writeChannel<osgAnimation::FloatCubicBezierChannel, osgAnimation::FloatCubicBezierKeyframeContainer>("FloatCubicBezierChannel", pFcbc, fw);
continue;
}
osgAnimation::DoubleCubicBezierChannel* pDcbc = dynamic_cast<osgAnimation::DoubleCubicBezierChannel*>(pChannel);
if (pDcbc)
{
Animation_writeChannel<osgAnimation::DoubleCubicBezierChannel, osgAnimation::DoubleCubicBezierKeyframeContainer>("DoubleCubicBezierChannel", pDcbc, fw);
continue;
}
osgAnimation::Vec2CubicBezierChannel* pV2cbc = dynamic_cast<osgAnimation::Vec2CubicBezierChannel*>(pChannel);
if (pV2cbc)
{
Animation_writeChannel<osgAnimation::Vec2CubicBezierChannel, osgAnimation::Vec2CubicBezierKeyframeContainer>("Vec2CubicBezierChannel", pV2cbc, fw);
continue;
}
osgAnimation::Vec3CubicBezierChannel* pV3cbc = dynamic_cast<osgAnimation::Vec3CubicBezierChannel*>(pChannel);
if (pV3cbc)
{
Animation_writeChannel<osgAnimation::Vec3CubicBezierChannel, osgAnimation::Vec3CubicBezierKeyframeContainer>("Vec3CubicBezierChannel", pV3cbc, fw);
continue;
}
osgAnimation::Vec4CubicBezierChannel* pV4cbc = dynamic_cast<osgAnimation::Vec4CubicBezierChannel*>(pChannel);
if (pV4cbc)
{
Animation_writeChannel<osgAnimation::Vec4CubicBezierChannel, osgAnimation::Vec4CubicBezierKeyframeContainer>("Vec4CubicBezierChannel", pV4cbc, fw);
continue;
}
}
return true;
}
RegisterDotOsgWrapperProxy g_atkAnimationProxy
(
new osgAnimation::Animation,
"osgAnimation::Animation",
"Object osgAnimation::Animation",
&Animation_readLocalData,
&Animation_writeLocalData
);
bool AnimationManagerBase_readLocalData(osgAnimation::AnimationManagerBase& manager, Input& fr)
{
int nbAnims = 0;
bool iteratorAdvanced = false;
if (fr.matchSequence("num_animations %i"))
{
fr[1].getInt(nbAnims);
fr += 2;
iteratorAdvanced = true;
}
for (int i = 0; i < nbAnims; i++)
{
Object* o = fr.readObject();
osgAnimation::Animation* a = dynamic_cast<osgAnimation::Animation*>(o);
if (a)
{
manager.registerAnimation(a);
iteratorAdvanced = true;
}
else
osg::notify(osg::WARN)<<"Warning: can't read an animation object"<< std::endl;
}
return iteratorAdvanced;
}
bool BasicAnimationManager_readLocalData(Object& obj, Input& fr)
{
osgAnimation::BasicAnimationManager& manager = dynamic_cast<osgAnimation::BasicAnimationManager&>(obj);
return AnimationManagerBase_readLocalData(manager, fr);
}
bool TimelineAnimationManager_readLocalData(Object& obj, Input& fr)
{
osgAnimation::TimelineAnimationManager& manager = dynamic_cast<osgAnimation::TimelineAnimationManager&>(obj);
return AnimationManagerBase_readLocalData(manager, fr);
}
bool AnimationManagerBase_writeLocalData(const osgAnimation::AnimationManagerBase& manager, Output& fw)
{
const osgAnimation::AnimationList& animList = manager.getAnimationList();
fw.indent() << "num_animations " << animList.size() << std::endl;
for (osgAnimation::AnimationList::const_iterator it = animList.begin(); it != animList.end(); it++)
{
if (!fw.writeObject(**it))
osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl;
}
return true;
}
bool BasicAnimationManager_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::BasicAnimationManager& manager = dynamic_cast<const osgAnimation::BasicAnimationManager&>(obj);
return AnimationManagerBase_writeLocalData(manager, fw);
}
bool TimelineAnimationManager_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::TimelineAnimationManager& manager = dynamic_cast<const osgAnimation::TimelineAnimationManager&>(obj);
return AnimationManagerBase_writeLocalData(manager, fw);
}
RegisterDotOsgWrapperProxy g_BasicAnimationManagerProxy
(
new osgAnimation::BasicAnimationManager,
"osgAnimation::BasicAnimationManager",
"Object NodeCallback osgAnimation::BasicAnimationManager",
&BasicAnimationManager_readLocalData,
&BasicAnimationManager_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
RegisterDotOsgWrapperProxy g_TimelineAnimationManagerProxy
(
new osgAnimation::TimelineAnimationManager,
"osgAnimation::TimelineAnimationManager",
"Object NodeCallback osgAnimation::TimelineAnimationManager",
&TimelineAnimationManager_readLocalData,
&TimelineAnimationManager_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool RigGeometry_readLocalData(Object& obj, Input& fr)
{
osgAnimation::RigGeometry& geom = dynamic_cast<osgAnimation::RigGeometry&>(obj);
osg::ref_ptr<osgAnimation::VertexInfluenceMap> vmap = new osgAnimation::VertexInfluenceMap;
int nbGroups = 0;
bool iteratorAdvanced = false;
if (fr.matchSequence("num_influences %i"))
{
fr[1].getInt(nbGroups);
fr += 2;
iteratorAdvanced = true;
}
for (int i = 0; i < nbGroups; i++)
{
int nbVertexes = 0;
std::string name;
if (fr.matchSequence("osgAnimation::VertexInfluence %s %i {"))
{
name = fr[1].getStr();
fr[2].getInt(nbVertexes);
fr += 4;
iteratorAdvanced = true;
}
osgAnimation::VertexInfluence vi;
vi.setName(name);
vi.reserve(nbVertexes);
for (int j = 0; j < nbVertexes; j++)
{
int index = -1;
float weight = 1;
if (fr.matchSequence("%i %f"))
{
fr[0].getInt(index);
fr[1].getFloat(weight);
fr += 2;
iteratorAdvanced = true;
}
vi.push_back(osgAnimation::VertexIndexWeight(index, weight));
}
if (fr.matchSequence("}"))
{
fr+=1;
}
(*vmap)[name] = vi;
}
if (!vmap->empty())
geom.setInfluenceMap(vmap.get());
return iteratorAdvanced;
}
bool RigGeometry_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::RigGeometry& geom = dynamic_cast<const osgAnimation::RigGeometry&>(obj);
const osgAnimation::VertexInfluenceMap* vm = geom.getInfluenceMap();
if (!vm)
return true;
fw.indent() << "num_influences " << vm->size() << std::endl;
fw.moveIn();
for (osgAnimation::VertexInfluenceMap::const_iterator it = vm->begin(); it != vm->end(); it++)
{
std::string name = it->first;
if (name.empty())
name = "Empty";
fw.indent() << "osgAnimation::VertexInfluence \"" << name << "\" " << it->second.size() << " {" << std::endl;
fw.moveIn();
const osgAnimation::VertexInfluence& vi = it->second;
for (osgAnimation::VertexInfluence::const_iterator itv = vi.begin(); itv != vi.end(); itv++)
{
fw.indent() << itv->first << " " << itv->second << std::endl;
}
fw.moveOut();
fw.indent() << "}" << std::endl;
}
fw.moveOut();
return true;
}
RegisterDotOsgWrapperProxy g_atkRigGeometryProxy
(
new osgAnimation::RigGeometry,
"osgAnimation::RigGeometry",
"Object Drawable osgAnimation::RigGeometry Geometry",
&RigGeometry_readLocalData,
&RigGeometry_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool MorphGeometry_readLocalData(Object& obj, Input& fr)
{
osgAnimation::MorphGeometry& geom = dynamic_cast<osgAnimation::MorphGeometry&>(obj);
bool iteratorAdvanced = false;
if (fr[0].matchWord("method"))
{
if (fr[1].matchWord("NORMALIZED"))
{
geom.setMethod(osgAnimation::MorphGeometry::NORMALIZED);
fr+=2;
iteratorAdvanced = true;
}
else if (fr[1].matchWord("RELATIVE"))
{
geom.setMethod(osgAnimation::MorphGeometry::RELATIVE);
fr+=2;
iteratorAdvanced = true;
}
}
if (fr[0].matchWord("morphNormals"))
{
if (fr[1].matchWord("TRUE"))
{
geom.setMorphNormals(true);
fr+=2;
iteratorAdvanced = true;
}
else if (fr[1].matchWord("FALSE"))
{
geom.setMorphNormals(false);
fr+=2;
iteratorAdvanced = true;
}
}
int num_morphTargets = 0;
if (fr.matchSequence("num_morphTargets %i"))
{
fr[1].getInt(num_morphTargets);
fr += 2;
iteratorAdvanced = true;
}
for (int i = 0; i < num_morphTargets; i++)
{
if (fr.matchSequence("MorphTarget {"))
{
int entry = fr[0].getNoNestedBrackets();
fr += 2;
iteratorAdvanced = true;
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
float weight = 1.0;
if (fr.matchSequence("weight %f"))
{
fr[1].getFloat(weight);
fr += 2;
}
osg::Drawable* drawable = NULL;
drawable = fr.readDrawable();
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(drawable);
if (geometry)
geom.addMorphTarget(geometry, weight);
}
if (fr.matchSequence("}"))
fr += 1;
}
}
return iteratorAdvanced;
}
bool MorphGeometry_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::MorphGeometry& geom = dynamic_cast<const osgAnimation::MorphGeometry&>(obj);
switch(geom.getMethod())
{
case(osgAnimation::MorphGeometry::NORMALIZED): fw.indent() << "method NORMALIZED"<<std::endl; break;
case(osgAnimation::MorphGeometry::RELATIVE): fw.indent() << "method RELATIVE"<<std::endl; break;
}
fw.indent() << "morphNormals ";
if (geom.getMorphNormals())
fw << "TRUE" << std::endl;
else
fw << "FALSE" << std::endl;
const osgAnimation::MorphGeometry::MorphTargetList& morphTargets = geom.getMorphTargetList();
fw.indent() << "num_morphTargets " << morphTargets.size() << std::endl;
for (unsigned int i = 0; i < morphTargets.size(); i++)
{
fw.indent() << "MorphTarget {" << std::endl;
fw.moveIn();
fw.indent() << "weight " << morphTargets[i].getWeight() <<std::endl;
fw.writeObject(*morphTargets[i].getGeometry());
fw.moveOut();
fw.indent() << "}" << std::endl;
}
return true;
}
RegisterDotOsgWrapperProxy g_osgAnimationMorphGeometryProxy
(
new osgAnimation::MorphGeometry,
"osgAnimation::MorphGeometry",
"Object Drawable osgAnimation::MorphGeometry Geometry",
&MorphGeometry_readLocalData,
&MorphGeometry_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateBone_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateBone_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateBoneProxy
(
new osgAnimation::Bone::UpdateBone,
"osgAnimation::UpdateBone",
"Object NodeCallback osgAnimation::UpdateBone",
&UpdateBone_readLocalData,
&UpdateBone_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateSkeleton_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateSkeleton_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
(
new osgAnimation::Skeleton::UpdateSkeleton,
"osgAnimation::UpdateSkeleton",
"Object NodeCallback osgAnimation::UpdateSkeleton",
&UpdateSkeleton_readLocalData,
&UpdateSkeleton_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateTransform_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateTransform_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateTransformProxy
(
new osgAnimation::UpdateTransform,
"osgAnimation::UpdateTransform",
"Object NodeCallback osgAnimation::UpdateTransform",
&UpdateTransform_readLocalData,
&UpdateTransform_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateMaterial_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateMaterial_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_UpdateMaterialProxy
(
new osgAnimation::UpdateMaterial,
"osgAnimation::UpdateMaterial",
"Object StateAttribute::Callback osgAnimation::UpdateMaterial",
&UpdateMaterial_readLocalData,
&UpdateMaterial_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);
bool UpdateMorph_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
}
bool UpdateMorph_writeLocalData(const Object& obj, Output& fw)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy
(
new osgAnimation::UpdateMorph,
"osgAnimation::UpdateMorph",
"Object NodeCallback osgAnimation::UpdateMorph",
&UpdateMorph_readLocalData,
&UpdateMorph_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);