From Cedric Pinson, Pulled in osgAnimation from OpenSceneGraph-osgWidget-dev into svn/trunk.
This commit is contained in:
491
src/osgPlugins/osgAnimation/ReaderWriter.cpp
Normal file
491
src/osgPlugins/osgAnimation/ReaderWriter.cpp
Normal file
@@ -0,0 +1,491 @@
|
||||
/* -*-c++-*-
|
||||
* Copyright (C) 2008 Cedric Pinson <mornifle@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/AnimationManager>
|
||||
#include <osgAnimation/VertexInfluence>
|
||||
#include <osgAnimation/Animation>
|
||||
#include <osgAnimation/Bone>
|
||||
#include <osgAnimation/Skeleton>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#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));
|
||||
if (bone.getUpdateCallback() && bone.getUpdateCallback()->getName().empty() && bone.getUpdateCallback()->getNestedCallback())
|
||||
bone.setUpdateCallback(bone.getUpdateCallback()->getNestedCallback()); // skip the default callback build in constructor of Bone
|
||||
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
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
bool Animation_readLocalData(Object& obj, Input& fr)
|
||||
{
|
||||
osgAnimation::Animation& anim = dynamic_cast<osgAnimation::Animation&>(obj);
|
||||
bool iteratorAdvanced = false;
|
||||
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("Channel {"))
|
||||
{
|
||||
fr += 2;
|
||||
|
||||
std::string name = "unknown";
|
||||
if (fr.matchSequence("name %s"))
|
||||
{
|
||||
name = fr[1].getStr();
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
std::string target = "unknown";
|
||||
if (fr.matchSequence("target %s"))
|
||||
{
|
||||
target = fr[1].getStr();
|
||||
fr += 2;
|
||||
iteratorAdvanced = true;
|
||||
}
|
||||
|
||||
std::string type;
|
||||
int nbKeys;
|
||||
if (fr.matchSequence("Keyframes %s %i {"))
|
||||
{
|
||||
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")
|
||||
{
|
||||
channel = new osgAnimation::Vec3LinearChannel;
|
||||
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;
|
||||
}
|
||||
|
||||
bool Animation_writeLocalData(const Object& obj, Output& fw)
|
||||
{
|
||||
const osgAnimation::Animation& anim = dynamic_cast<const osgAnimation::Animation&>(obj);
|
||||
|
||||
fw.indent() << "num_channels " << anim.getChannels().size() << std::endl;
|
||||
for (unsigned int i = 0; i < anim.getChannels().size(); i++)
|
||||
{
|
||||
fw.indent() << "Channel {" << std::endl;
|
||||
fw.moveIn();
|
||||
fw.indent() << "name \"" << anim.getChannels()[i]->getName() << "\"" << std::endl;
|
||||
fw.indent() << "target \"" << anim.getChannels()[i]->getTargetName() << "\"" << std::endl;
|
||||
|
||||
std::string type = "unknown";
|
||||
if (anim.getChannels()[i]->getName() == std::string("quaternion"))
|
||||
{
|
||||
type = "Quat";
|
||||
}
|
||||
else if (anim.getChannels()[i]->getName() == std::string("rotation"))
|
||||
{
|
||||
type = "Quat";
|
||||
}
|
||||
else if (anim.getChannels()[i]->getName() == std::string("euler"))
|
||||
{
|
||||
type = "Vec3";
|
||||
}
|
||||
else if (anim.getChannels()[i]->getName() == std::string("scale"))
|
||||
{
|
||||
type = "Vec3";
|
||||
}
|
||||
else if (anim.getChannels()[i]->getName() == std::string("position"))
|
||||
{
|
||||
type = "Vec3";
|
||||
}
|
||||
|
||||
osgAnimation::KeyframeContainer* kf = anim.getChannels()[i]->getSampler()->getKeyframeContainer();
|
||||
fw.indent() << "Keyframes \"" << type << "\" " << kf->size() << " {" << std::endl;
|
||||
fw.moveIn();
|
||||
for (unsigned int k = 0; k < kf->size(); k++)
|
||||
{
|
||||
if (type == "Vec3")
|
||||
{
|
||||
osgAnimation::Vec3KeyframeContainer* kk = dynamic_cast<osgAnimation::Vec3KeyframeContainer*>(kf);
|
||||
fw.indent() << "key " << (*kk)[k].getTime() << " " << (*kk)[k].getValue() << std::endl;
|
||||
}
|
||||
else if ( type == "Quat")
|
||||
{
|
||||
osgAnimation::QuatKeyframeContainer* kk = dynamic_cast<osgAnimation::QuatKeyframeContainer*>(kf);
|
||||
fw.indent() << "key " << (*kk)[k].getTime() << " " << (*kk)[k].getValue() << std::endl;
|
||||
}
|
||||
}
|
||||
fw.moveOut();
|
||||
fw.indent() << "}" << std::endl;
|
||||
fw.moveOut();
|
||||
fw.indent() << "}" << std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
RegisterDotOsgWrapperProxy g_atkAnimationProxy
|
||||
(
|
||||
new osgAnimation::Animation,
|
||||
"osgAnimation::Animation",
|
||||
"Object osgAnimation::Animation",
|
||||
&Animation_readLocalData,
|
||||
&Animation_writeLocalData
|
||||
);
|
||||
|
||||
|
||||
|
||||
bool AnimationManager_readLocalData(Object& obj, Input& fr)
|
||||
{
|
||||
osgAnimation::AnimationManager& manager = dynamic_cast<osgAnimation::AnimationManager&>(obj);
|
||||
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 AnimationManager_writeLocalData(const Object& obj, Output& fw)
|
||||
{
|
||||
const osgAnimation::AnimationManager& manager = dynamic_cast<const osgAnimation::AnimationManager&>(obj);
|
||||
|
||||
osgAnimation::AnimationMap map = manager.getAnimationMap();
|
||||
int nbanims = map.size();
|
||||
fw.indent() << "num_animations " << nbanims << std::endl;
|
||||
for (osgAnimation::AnimationMap::iterator it = map.begin(); it != map.end(); it++)
|
||||
{
|
||||
if (!fw.writeObject(*it->second))
|
||||
osg::notify(osg::WARN)<<"Warning: can't write an animation object"<< std::endl;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RegisterDotOsgWrapperProxy g_atkAnimationManagerProxy
|
||||
(
|
||||
new osgAnimation::AnimationManager,
|
||||
"osgAnimation::AnimationManager",
|
||||
"Object Node Group osgAnimation::AnimationManager",
|
||||
&AnimationManager_readLocalData,
|
||||
&AnimationManager_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 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 osgAnimation::UpdateBone",
|
||||
&UpdateBone_readLocalData,
|
||||
&UpdateBone_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 osgAnimation::UpdateTransform",
|
||||
&UpdateTransform_readLocalData,
|
||||
&UpdateTransform_writeLocalData,
|
||||
DotOsgWrapper::READ_AND_WRITE
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user