From Cedric Pinson, "Here a list of changes:

Bone now inherit from MatrixTransform. It simplify a lot the update of
Bone matrix. It helps to have the bone system more generic. eg it's now
possible to have animation data with precomputed bind matrix. The other
benefit, is now the collada plugin will be able to use osgAnimation to
display skinned mesh. Michael Plating did a great work to improve this
aspect, he is working on the collada plugin and should be able to submit
a new version soon.
The RigGeometry has been refactored so now it works when you save and
reload RigGeometry because the source is not touched anymore. The
benefit with this update is that it should be now possible to use a
MorphGeometry as source for a RigGeometry.

The bad news is that the format has changed, so i have rebuild osg-data
related to osgAnimation data, updated the blender exporter to export to
the new format.
The fbx plugin could be touched about this commit, i dont compile it so
i can't give more information about it.
The bvh plugin has been updated by Wang rui so this one is fixed with
the new code of osgAnimation.
The examples has been updated to work with the new code too...

The example osg-data/example.osg should be remove, it's an old example
that does not work.

For people using blender the blender exporter up to date is here:
http://hg.plopbyte.net/osgexport2/
it will be merge to http://hg.plopbyte.net/osgexport/ as soon as the
modification will be push in the trunk.
"
This commit is contained in:
Robert Osfield
2010-01-27 12:24:55 +00:00
parent 0abf08b806
commit db4d58b01d
65 changed files with 1967 additions and 862 deletions

View File

@@ -36,7 +36,7 @@ Action::Callback* Action::getFrameCallback(unsigned int frame)
void Action::removeCallback(Callback* cb)
{
std::vector<unsigned int> keyToRemove;
for (FrameCallback::iterator it = _framesCallback.begin(); it != _framesCallback.end(); it++)
for (FrameCallback::iterator it = _framesCallback.begin(); it != _framesCallback.end(); ++it)
{
if (it->second.get())
{
@@ -52,7 +52,7 @@ void Action::removeCallback(Callback* cb)
}
}
}
for (std::vector<unsigned int>::iterator it = keyToRemove.begin(); it != keyToRemove.end(); it++)
for (std::vector<unsigned int>::iterator it = keyToRemove.begin(); it != keyToRemove.end(); ++it)
_framesCallback.erase(*it);
}

View File

@@ -24,7 +24,7 @@ Animation::Animation(const osgAnimation::Animation& anim, const osg::CopyOp& cop
_playmode(anim._playmode)
{
const ChannelList& cl = anim.getChannels();
for (ChannelList::const_iterator it = cl.begin(); it != cl.end(); it++)
for (ChannelList::const_iterator it = cl.begin(); it != cl.end(); ++it)
{
addChannel(it->get()->clone());
}

View File

@@ -28,7 +28,7 @@ AnimationManagerBase::AnimationManagerBase()
void AnimationManagerBase::clearTargets()
{
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); ++it)
(*it).get()->reset();
}
@@ -67,7 +67,7 @@ AnimationManagerBase::AnimationManagerBase(const AnimationManagerBase& b, const
const AnimationList& animationList = b.getAnimationList();
for (AnimationList::const_iterator it = animationList.begin();
it != animationList.end();
it++)
++it)
{
Animation* animation = dynamic_cast<osgAnimation::Animation*>(it->get()->clone(copyop));
_animations.push_back(animation);
@@ -85,7 +85,7 @@ void AnimationManagerBase::buildTargetReference()
Animation* anim = (*iterAnim).get();
for (ChannelList::iterator it = anim->getChannels().begin();
it != anim->getChannels().end();
it++)
++it)
_targets.insert((*it)->getTarget());
}
}

View File

@@ -38,7 +38,7 @@ void BasicAnimationManager::stopAll()
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
(*it)->resetTargets();
}
_animationsPlaying.clear();
@@ -65,7 +65,7 @@ bool BasicAnimationManager::stopAnimation(Animation* pAnimation)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if( (*it) == pAnimation )
{
(*it)->resetTargets();
@@ -82,7 +82,7 @@ void BasicAnimationManager::update (double time)
_lastUpdate = time; // keep time of last update
// could filtered with an active flag
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); it++)
for (TargetSet::iterator it = _targets.begin(); it != _targets.end(); ++it)
(*it).get()->reset();
// update from high priority to low priority
@@ -132,7 +132,7 @@ bool BasicAnimationManager::isPlaying(Animation* pAnimation)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if ( (*it) == pAnimation )
return true;
}
@@ -145,7 +145,7 @@ bool BasicAnimationManager::isPlaying(const std::string& name)
for( AnimationLayers::iterator iterAnim = _animationsPlaying.begin(); iterAnim != _animationsPlaying.end(); ++iterAnim )
{
AnimationList& list = iterAnim->second;
for (AnimationList::iterator it = list.begin(); it != list.end(); it++)
for (AnimationList::iterator it = list.begin(); it != list.end(); ++it)
if ( (*it)->getName() == name )
return true;
}

View File

@@ -14,94 +14,23 @@
#include <osgAnimation/Bone>
#include <osgAnimation/Skeleton>
#include <osgAnimation/FindParentAnimationManagerVisitor>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/ComputeBindMatrixVisitor>
using namespace osgAnimation;
osgAnimation::Bone::UpdateBone::UpdateBone(const osgAnimation::Bone::UpdateBone& apc,const osg::CopyOp& copyop) :
osg::Object(apc, copyop),
osgAnimation::AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_quaternion = new osgAnimation::QuatTarget(apc._quaternion->getValue());
_position = new osgAnimation::Vec3Target(apc._position->getValue());
_scale = new osgAnimation::Vec3Target(apc._scale->getValue());
}
bool osgAnimation::Bone::UpdateBone::link(osgAnimation::Channel* channel)
{
if (channel->getName().find("quaternion") != std::string::npos)
{
return channel->setTarget(_quaternion.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;
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void osgAnimation::Bone::UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
Bone* b = dynamic_cast<Bone*>(node);
if (!b)
{
osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl;
return;
}
if (b->needToComputeBindMatrix())
{
ComputeBindMatrixVisitor visitor;
b->accept(visitor);
}
update(*b);
Bone* parent = b->getBoneParent();
if (parent)
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace());
else
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace());
}
traverse(node,nv);
}
osgAnimation::Bone::Bone(const Bone& b, const osg::CopyOp& copyop) :
osg::Transform(b,copyop),
_position(b._position),
_rotation(b._rotation),
_scale(b._scale),
_needToRecomputeBindMatrix(true),
_bindInBoneSpace(b._bindInBoneSpace),
_invBindInSkeletonSpace(b._invBindInSkeletonSpace),
_boneInSkeletonSpace(b._boneInSkeletonSpace)
Bone::Bone(const Bone& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop), _invBindInSkeletonSpace(b._invBindInSkeletonSpace), _boneInSkeletonSpace(b._boneInSkeletonSpace)
{
}
osgAnimation::Bone::Bone(const std::string& name)
Bone::Bone(const std::string& name)
{
if (!name.empty())
setName(name);
_needToRecomputeBindMatrix = false;
}
void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
void Bone::setDefaultUpdateCallback(const std::string& name)
{
std::string cbName = name;
if (cbName.empty())
@@ -109,25 +38,12 @@ void osgAnimation::Bone::setDefaultUpdateCallback(const std::string& name)
setUpdateCallback(new UpdateBone(cbName));
}
void osgAnimation::Bone::computeBindMatrix()
{
_invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
const Bone* parent = getBoneParent();
_needToRecomputeBindMatrix = false;
if (!parent)
{
osg::notify(osg::WARN) << "Warning " << className() <<"::computeBindMatrix you should not have this message, it means you miss to attach this bone(" << getName() <<") to a Skeleton node" << std::endl;
return;
}
_invBindInSkeletonSpace = parent->getInvBindMatrixInSkeletonSpace() * _invBindInSkeletonSpace;
}
osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
Bone* Bone::getBoneParent()
{
if (getParents().empty())
return 0;
osg::Node::ParentList parents = getParents();
for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); it++)
for (osg::Node::ParentList::iterator it = parents.begin(); it != parents.end(); ++it)
{
Bone* pb = dynamic_cast<Bone*>(*it);
if (pb)
@@ -135,12 +51,12 @@ osgAnimation::Bone* osgAnimation::Bone::getBoneParent()
}
return 0;
}
const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
const Bone* Bone::getBoneParent() const
{
if (getParents().empty())
return 0;
const osg::Node::ParentList& parents = getParents();
for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); it++)
for (osg::Node::ParentList::const_iterator it = parents.begin(); it != parents.end(); ++it)
{
const Bone* pb = dynamic_cast<const Bone*>(*it);
if (pb)
@@ -148,25 +64,3 @@ const osgAnimation::Bone* osgAnimation::Bone::getBoneParent() const
}
return 0;
}
/** Add Node to Group.
* If node is not NULL and is not contained in Group then increment its
* reference count, add it to the child list and dirty the bounding
* sphere to force it to recompute on next getBound() and return true for success.
* Otherwise return false. Scene nodes can't be added as child nodes.
*/
bool osgAnimation::Bone::addChild( Node *child )
{
Bone* bone = dynamic_cast<Bone*>(child);
if (bone)
bone->setNeedToComputeBindMatrix(true);
return osg::Group::addChild(child);
}
osgAnimation::Bone::BoneMap osgAnimation::Bone::getBoneMap()
{
BoneMapVisitor mapVisitor;
this->accept(mapVisitor);
return mapVisitor.getBoneMap();
}

View File

@@ -16,20 +16,27 @@
*/
#include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/Skeleton>
osgAnimation::BoneMapVisitor::BoneMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
using namespace osgAnimation;
void osgAnimation::BoneMapVisitor::apply(osg::Node&) { return; }
void osgAnimation::BoneMapVisitor::apply(osg::Transform& node)
BoneMapVisitor::BoneMapVisitor() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
void BoneMapVisitor::apply(osg::Node&) { return; }
void BoneMapVisitor::apply(osg::Transform& node)
{
Bone* bone = dynamic_cast<Bone*>(&node);
if (bone)
if (bone)
{
_map[bone->getName()] = bone;
traverse(node);
}
Skeleton* skeleton = dynamic_cast<Skeleton*>(&node);
if (skeleton)
traverse(node);
}
const osgAnimation::Bone::BoneMap& osgAnimation::BoneMapVisitor::getBoneMap() const
const BoneMap& BoneMapVisitor::getBoneMap() const
{
return _map;
}

View File

@@ -19,13 +19,13 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/ActionVisitor
${HEADER_PATH}/Animation
${HEADER_PATH}/AnimationManagerBase
${HEADER_PATH}/AnimationUpdateCallback
${HEADER_PATH}/Assert
${HEADER_PATH}/BasicAnimationManager
${HEADER_PATH}/Bone
${HEADER_PATH}/BoneMapVisitor
${HEADER_PATH}/Channel
${HEADER_PATH}/CubicBezier
${HEADER_PATH}/ComputeBindMatrixVisitor
${HEADER_PATH}/EaseMotion
${HEADER_PATH}/Export
${HEADER_PATH}/FindParentAnimationManagerVisitor
@@ -40,12 +40,21 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/RigTransformSoftware
${HEADER_PATH}/Sampler
${HEADER_PATH}/Skeleton
${HEADER_PATH}/StackedMatrixElement
${HEADER_PATH}/StackedQuaternionElement
${HEADER_PATH}/StackedRotateAxisElement
${HEADER_PATH}/StackedScaleElement
${HEADER_PATH}/StackedTransformElement
${HEADER_PATH}/StackedTranslateElement
${HEADER_PATH}/StackedTransform
${HEADER_PATH}/StatsVisitor
${HEADER_PATH}/StatsHandler
${HEADER_PATH}/Target
${HEADER_PATH}/Timeline
${HEADER_PATH}/TimelineAnimationManager
${HEADER_PATH}/UpdateCallback
${HEADER_PATH}/UpdateBone
${HEADER_PATH}/UpdateMaterial
${HEADER_PATH}/UpdateMatrixTransform
${HEADER_PATH}/Vec3Packed
${HEADER_PATH}/VertexInfluence
)
@@ -74,12 +83,20 @@ ADD_LIBRARY(${LIB_NAME}
RigTransformHardware.cpp
RigTransformSoftware.cpp
Skeleton.cpp
StackedMatrixElement.cpp
StackedQuaternionElement.cpp
StackedRotateAxisElement.cpp
StackedScaleElement.cpp
StackedTransform.cpp
StackedTranslateElement.cpp
StatsVisitor.cpp
StatsHandler.cpp
Target.cpp
TimelineAnimationManager.cpp
Timeline.cpp
UpdateCallback.cpp
UpdateBone.cpp
UpdateMaterial.cpp
UpdateMatrixTransform.cpp
VertexInfluence.cpp
${OPENSCENEGRAPH_VERSIONINFO_RC}
)

View File

@@ -13,7 +13,7 @@
*/
#include <osgAnimation/LinkVisitor>
#include <osgAnimation/UpdateCallback>
#include <osgAnimation/AnimationUpdateCallback>
#include <osg/Notify>
#include <osg/Geode>
@@ -33,7 +33,7 @@ AnimationList& LinkVisitor::getAnimationList()
{
return _animations;
}
void LinkVisitor::link(osgAnimation::AnimationUpdateCallbackBase* cb)
void LinkVisitor::link(AnimationUpdateCallbackBase* cb)
{
int result = 0;
for (int i = 0; i < (int)_animations.size(); i++)
@@ -49,7 +49,7 @@ void LinkVisitor::handle_stateset(osg::StateSet* stateset)
if (!stateset)
return;
osg::StateSet::AttributeList& attr = stateset->getAttributeList();
for (osg::StateSet::AttributeList::iterator it = attr.begin(); it != attr.end(); it++)
for (osg::StateSet::AttributeList::iterator it = attr.begin(); it != attr.end(); ++it)
{
osg::StateAttribute* sattr = it->second.first.get();
osgAnimation::AnimationUpdateCallbackBase* cb = dynamic_cast<osgAnimation::AnimationUpdateCallbackBase*>(sattr->getUpdateCallback());

View File

@@ -261,18 +261,13 @@ bool UpdateMorph::link(osgAnimation::Channel* channel)
if (weightIndex >= 0)
{
osgAnimation::FloatLinearChannel* fc = dynamic_cast<osgAnimation::FloatLinearChannel*>(channel);
if (fc)
osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get();
if (!ft)
{
osgAnimation::FloatTarget* ft = _weightTargets[weightIndex].get();
if (ft == 0)
{
ft = new osgAnimation::FloatTarget;
_weightTargets[weightIndex] = ft;
}
fc->setTarget(ft);
return true;
ft = new osgAnimation::FloatTarget;
_weightTargets[weightIndex] = ft;
}
return channel->setTarget(ft);
}
else
{

View File

@@ -12,6 +12,7 @@
* OpenSceneGraph Public License for more details.
*/
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/RigTransformSoftware>
#include <sstream>
@@ -71,21 +72,10 @@ RigGeometry::RigGeometry()
setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
}
RigGeometry::RigGeometry(const osg::Geometry& b) : osg::Geometry(b, osg::CopyOp::SHALLOW_COPY)
{
_supportsDisplayList = false;
setUseVertexBufferObjects(true);
setUpdateCallback(new UpdateVertex);
setDataVariance(osg::Object::DYNAMIC);
_needToComputeMatrix = true;
_matrixFromSkeletonToGeometry = _invMatrixFromSkeletonToGeometry = osg::Matrix::identity();
// disable the computation of boundingbox for the rig mesh
setComputeBoundingBoxCallback(new RigComputeBoundingBoxCallback);
}
RigGeometry::RigGeometry(const RigGeometry& b, const osg::CopyOp& copyop) :
osg::Geometry(b,copyop),
_geometry(b._geometry),
_vertexInfluenceSet(b._vertexInfluenceSet),
_vertexInfluenceMap(b._vertexInfluenceMap),
_needToComputeMatrix(b._needToComputeMatrix)
@@ -114,7 +104,7 @@ void RigGeometry::buildVertexInfluenceSet()
_vertexInfluenceSet.clear();
for (osgAnimation::VertexInfluenceMap::iterator it = _vertexInfluenceMap->begin();
it != _vertexInfluenceMap->end();
it++)
++it)
_vertexInfluenceSet.addVertexInfluence(it->second);
_vertexInfluenceSet.buildVertex2BoneList();
@@ -130,7 +120,8 @@ void RigGeometry::computeMatrixFromRootSkeleton()
return;
}
osg::MatrixList mtxList = getParent(0)->getWorldMatrices(_root.get());
_matrixFromSkeletonToGeometry = mtxList[0];
osg::Matrix notRoot = _root->getMatrix();
_matrixFromSkeletonToGeometry = mtxList[0] * osg::Matrix::inverse(notRoot);
_invMatrixFromSkeletonToGeometry = osg::Matrix::inverse(_matrixFromSkeletonToGeometry);
_needToComputeMatrix = false;
}
@@ -142,10 +133,67 @@ void RigGeometry::update()
_rigTransformImplementation = new RigTransformSoftware;
}
if (getRigTransformImplementation()->needInit())
if (!getRigTransformImplementation()->init(*this))
return;
getRigTransformImplementation()->update(*this);
RigTransform& implementation = *getRigTransformImplementation();
(implementation)(*this);
}
void RigGeometry::copyFrom(osg::Geometry& from)
{
bool copyToSelf = (this==&from);
osg::Geometry& target = *this;
if (!copyToSelf) target.setStateSet(from.getStateSet());
// copy over primitive sets.
if (!copyToSelf) target.getPrimitiveSetList() = from.getPrimitiveSetList();
if (from.getVertexArray())
{
if (!copyToSelf) target.setVertexArray(from.getVertexArray());
}
target.setNormalBinding(from.getNormalBinding());
if (from.getNormalArray())
{
if (!copyToSelf) target.setNormalArray(from.getNormalArray());
}
target.setColorBinding(from.getColorBinding());
if (from.getColorArray())
{
if (!copyToSelf) target.setColorArray(from.getColorArray());
}
target.setSecondaryColorBinding(from.getSecondaryColorBinding());
if (from.getSecondaryColorArray())
{
if (!copyToSelf) target.setSecondaryColorArray(from.getSecondaryColorArray());
}
target.setFogCoordBinding(from.getFogCoordBinding());
if (from.getFogCoordArray())
{
if (!copyToSelf) target.setFogCoordArray(from.getFogCoordArray());
}
for(unsigned int ti=0;ti<from.getNumTexCoordArrays();++ti)
{
if (from.getTexCoordArray(ti))
{
if (!copyToSelf) target.setTexCoordArray(ti,from.getTexCoordArray(ti));
}
}
ArrayDataList& arrayList = from.getVertexAttribArrayList();
for(unsigned int vi=0;vi< arrayList.size();++vi)
{
ArrayData& arrayData = arrayList[vi];
if (arrayData.array.valid())
{
if (!copyToSelf) target.setVertexAttribData(vi,arrayData);
}
}
}
const VertexInfluenceSet& RigGeometry::getVertexInfluenceSet() const { return _vertexInfluenceSet;}
@@ -155,3 +203,7 @@ Skeleton* RigGeometry::getSkeleton() { return _root.get(); }
void RigGeometry::setSkeleton(Skeleton* root) { _root = root;}
RigTransform* RigGeometry::getRigTransformImplementation() { return _rigTransformImplementation.get(); }
void RigGeometry::setRigTransformImplementation(RigTransform* rig) { _rigTransformImplementation = rig; }
osg::Geometry* RigGeometry::getSourceGeometry() { return _geometry.get(); }
const osg::Geometry* RigGeometry::getSourceGeometry() const { return _geometry.get(); }
void RigGeometry::setSourceGeometry(osg::Geometry* geometry) { _geometry = geometry; }

View File

@@ -14,10 +14,19 @@
#include <osgAnimation/RigTransformHardware>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/BoneMapVisitor>
#include <sstream>
using namespace osgAnimation;
RigTransformHardware::RigTransformHardware()
{
_needInit = true;
_bonesPerVertex = 0;
_nbVertexes = 0;
}
osg::Vec4Array* RigTransformHardware::getVertexAttrib(int index)
{
if (index >= (int)_boneWeightAttribArrays.size())
@@ -67,12 +76,12 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
vertexIndexWeight.resize(nbVertexes);
int maxBonePerVertex = 0;
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); it++)
for (VertexInfluenceSet::VertexIndexToBoneWeightMap::const_iterator it = vertexIndexToBoneWeightMap.begin(); it != vertexIndexToBoneWeightMap.end(); ++it)
{
int vertexIndex = it->first;
const VertexInfluenceSet::BoneWeightList& boneWeightList = it->second;
int bonesForThisVertex = 0;
for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); it++)
for (VertexInfluenceSet::BoneWeightList::const_iterator it = boneWeightList.begin(); it != boneWeightList.end(); ++it)
{
const VertexInfluenceSet::BoneWeight& bw = *it;
if (boneNameCountMap.find(bw.getBoneName()) != boneNameCountMap.end())
@@ -85,7 +94,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
{
if (boneMap.find(bw.getBoneName()) == boneMap.end())
{
osg::notify(osg::WARN) << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
osg::notify(osg::INFO) << "RigTransformHardware::createPalette can't find bone " << bw.getBoneName() << " skip this influence" << std::endl;
continue;
}
boneNameCountMap[bw.getBoneName()] = 1; // for stats
@@ -104,7 +113,7 @@ bool RigTransformHardware::createPalette(int nbVertexes, BoneMap boneMap, const
osg::notify(osg::INFO) << "RigTransformHardware::createPalette maximum number of bone per vertex is " << maxBonePerVertex << std::endl;
osg::notify(osg::INFO) << "RigTransformHardware::createPalette matrix palette has " << boneNameCountMap.size() << " entries" << std::endl;
for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); it++)
for (BoneNameCountMap::iterator it = boneNameCountMap.begin(); it != boneNameCountMap.end(); ++it)
{
osg::notify(osg::INFO) << "RigTransformHardware::createPalette Bone " << it->first << " is used " << it->second << " times" << std::endl;
}
@@ -186,20 +195,30 @@ void RigTransformHardware::setShader(osg::Shader* shader)
bool RigTransformHardware::init(RigGeometry& geom)
{
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
if (!pos) {
osg::Geometry& source = *geom.getSourceGeometry();
osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray());
if (!positionSrc)
{
osg::notify(osg::WARN) << "RigTransformHardware no vertex array in the geometry " << geom.getName() << std::endl;
return false;
}
if (!geom.getSkeleton()) {
osg::notify(osg::WARN) << "RigTransformHardware no skeleting set in geometry " << geom.getName() << std::endl;
if (!geom.getSkeleton())
{
osg::notify(osg::WARN) << "RigTransformHardware no skeleton set in geometry " << geom.getName() << std::endl;
return false;
}
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
if (!createPalette(pos->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
// copy shallow from source geometry to rig
geom.copyFrom(source);
BoneMapVisitor mapVisitor;
geom.getSkeleton()->accept(mapVisitor);
BoneMap bm = mapVisitor.getBoneMap();
if (!createPalette(positionSrc->size(),bm, geom.getVertexInfluenceSet().getVertexToBoneList()))
return false;
osg::ref_ptr<osg::Program> program = new osg::Program;
@@ -244,7 +263,10 @@ bool RigTransformHardware::init(RigGeometry& geom)
_needInit = false;
return true;
}
void RigTransformHardware::update(RigGeometry& geom)
void RigTransformHardware::operator()(RigGeometry& geom)
{
if (_needInit)
if (!init(geom))
return;
computeMatrixPaletteUniform(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry());
}

View File

@@ -13,49 +13,92 @@
*/
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/RigTransformSoftware>
#include <osgAnimation/BoneMapVisitor>
#include <osgAnimation/RigGeometry>
using namespace osgAnimation;
RigTransformSoftware::RigTransformSoftware()
{
_needInit = true;
}
bool RigTransformSoftware::init(RigGeometry& geom)
{
if (!geom.getSkeleton())
return false;
Bone::BoneMap bm = geom.getSkeleton()->getBoneMap();
BoneMapVisitor mapVisitor;
geom.getSkeleton()->accept(mapVisitor);
BoneMap bm = mapVisitor.getBoneMap();
initVertexSetFromBones(bm, geom.getVertexInfluenceSet().getUniqVertexSetToBoneSetList());
geom.copyFrom(*geom.getSourceGeometry());
geom.setVertexArray(0);
geom.setNormalArray(0);
_needInit = false;
return true;
}
void RigTransformSoftware::update(RigGeometry& geom)
void RigTransformSoftware::operator()(RigGeometry& geom)
{
osg::Vec3Array* pos = dynamic_cast<osg::Vec3Array*>(geom.getVertexArray());
if (pos && _positionSource.size() != pos->size())
if (_needInit)
if (!init(geom))
return;
osg::Geometry& source = *geom.getSourceGeometry();
osg::Geometry& destination = geom;
osg::Vec3Array* positionSrc = dynamic_cast<osg::Vec3Array*>(source.getVertexArray());
osg::Vec3Array* positionDst = dynamic_cast<osg::Vec3Array*>(destination.getVertexArray());
if (positionSrc && (!positionDst || (positionDst->size() != positionSrc->size()) ) )
{
_positionSource = std::vector<osg::Vec3>(pos->begin(),pos->end());
geom.getVertexArray()->setDataVariance(osg::Object::DYNAMIC);
if (!positionDst)
{
positionDst = new osg::Vec3Array;
positionDst->setDataVariance(osg::Object::DYNAMIC);
destination.setVertexArray(positionDst);
}
*positionDst = *positionSrc;
}
osg::Vec3Array* normal = dynamic_cast<osg::Vec3Array*>(geom.getNormalArray());
if (normal && _normalSource.size() != normal->size())
osg::Vec3Array* normalSrc = dynamic_cast<osg::Vec3Array*>(source.getNormalArray());
osg::Vec3Array* normalDst = dynamic_cast<osg::Vec3Array*>(destination.getNormalArray());
if (normalSrc && (!normalDst || (normalDst->size() != normalSrc->size()) ) )
{
_normalSource = std::vector<osg::Vec3>(normal->begin(),normal->end());
geom.getNormalArray()->setDataVariance(osg::Object::DYNAMIC);
if (!normalDst)
{
normalDst = new osg::Vec3Array;
normalDst->setDataVariance(osg::Object::DYNAMIC);
destination.setNormalArray(normalDst);
destination.setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
}
*normalDst = *normalSrc;
}
if (!_positionSource.empty())
if (positionDst && !positionDst->empty())
{
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_positionSource.front(), &pos->front());
pos->dirty();
compute<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&positionSrc->front(),
&positionDst->front());
positionDst->dirty();
}
if (!_normalSource.empty())
if (normalDst && !normalDst->empty())
{
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(), geom.getInvMatrixFromSkeletonToGeometry(), &_normalSource.front(), &normal->front());
normal->dirty();
computeNormal<osg::Vec3>(geom.getMatrixFromSkeletonToGeometry(),
geom.getInvMatrixFromSkeletonToGeometry(),
&normalSrc->front(),
&normalDst->front());
normalDst->dirty();
}
}
void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence)
void RigTransformSoftware::initVertexSetFromBones(const BoneMap& map, const VertexInfluenceSet::UniqVertexSetToBoneSetList& influence)
{
_boneSetVertexSet.clear();
@@ -72,7 +115,7 @@ void RigTransformSoftware::initVertexSetFromBones(const Bone::BoneMap& map, cons
{
const std::string& bname = inf.getBones()[b].getBoneName();
float weight = inf.getBones()[b].getWeight();
Bone::BoneMap::const_iterator it = map.find(bname);
BoneMap::const_iterator it = map.find(bname);
if (it == map.end())
{
osg::notify(osg::WARN) << "RigTransformSoftware Bone " << bname << " not found, skip the influence group " <<bname << std::endl;

View File

@@ -14,14 +14,15 @@
#include <osgAnimation/Skeleton>
#include <osgAnimation/Bone>
#include <osg/Notify>
using namespace osgAnimation;
Skeleton::Skeleton() {}
Skeleton::Skeleton(const Skeleton& b, const osg::CopyOp& copyop) : Bone(b,copyop) {}
Skeleton::Skeleton(const Skeleton& b, const osg::CopyOp& copyop) : osg::MatrixTransform(b,copyop) {}
Skeleton::UpdateSkeleton::UpdateSkeleton() : _needValidate(true) {}
Skeleton::UpdateSkeleton::UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop)
Skeleton::UpdateSkeleton::UpdateSkeleton(const UpdateSkeleton& us, const osg::CopyOp& copyop= osg::CopyOp::SHALLOW_COPY) : osg::Object(us, copyop), osg::NodeCallback(us, copyop)
{
_needValidate = true;
}
@@ -45,7 +46,7 @@ public:
bool foundNonBone = false;
for (unsigned i = 0; i < bone->getNumChildren(); ++i)
for (unsigned int i = 0; i < bone->getNumChildren(); ++i)
{
if (dynamic_cast<Bone*>(bone->getChild(i)))
{
@@ -76,11 +77,13 @@ void Skeleton::UpdateSkeleton::operator()(osg::Node* node, osg::NodeVisitor* nv)
if (_needValidate && skeleton)
{
ValidateSkeletonVisitor visitor;
node->accept(visitor);
for (unsigned int i = 0; i < skeleton->getNumChildren(); ++i)
{
osg::Node* child = skeleton->getChild(i);
child->accept(visitor);
}
_needValidate = false;
}
if (skeleton->needToComputeBindMatrix())
skeleton->computeBindMatrix();
}
traverse(node,nv);
}
@@ -89,9 +92,3 @@ void Skeleton::setDefaultUpdateCallback()
{
setUpdateCallback(new Skeleton::UpdateSkeleton );
}
void Skeleton::computeBindMatrix()
{
_invBindInSkeletonSpace = osg::Matrix::inverse(_bindInBoneSpace);
_needToRecomputeBindMatrix = false;
}

View File

@@ -0,0 +1,40 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedMatrixElement>
using namespace osgAnimation;
StackedMatrixElement::StackedMatrixElement() {}
StackedMatrixElement::StackedMatrixElement(const std::string& name, const osg::Matrix& matrix) : StackedTransformElement(), _matrix(matrix) { setName(name); }
StackedMatrixElement::StackedMatrixElement(const osg::Matrix& matrix) : _matrix(matrix) { setName("matrix"); }
StackedMatrixElement::StackedMatrixElement(const StackedMatrixElement& rhs, const osg::CopyOp& c) : StackedTransformElement(rhs, c), _matrix(rhs._matrix)
{
if (rhs._target.valid())
_target = new MatrixTarget(*rhs._target);
}
Target* StackedMatrixElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new MatrixTarget(_matrix);
return _target.get();
}
void StackedMatrixElement::update()
{
if (_target.valid())
_matrix = _target->getValue();
}

View File

@@ -0,0 +1,53 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedQuaternionElement>
using namespace osgAnimation;
StackedQuaternionElement::StackedQuaternionElement(const std::string& name, const osg::Quat& quaternion) : _quaternion(quaternion) { setName(name); }
StackedQuaternionElement::StackedQuaternionElement(const StackedQuaternionElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _quaternion(rhs._quaternion)
{
if (rhs._target.valid())
_target = new QuatTarget(*rhs._target);
}
StackedQuaternionElement::StackedQuaternionElement(const osg::Quat& quat) : _quaternion(quat) { setName("quaternion"); }
StackedQuaternionElement::StackedQuaternionElement()
{
}
const osg::Quat& StackedQuaternionElement::getQuaternion() const { return _quaternion; }
void StackedQuaternionElement::setQuaternion(const osg::Quat& q) { _quaternion = q; }
void StackedQuaternionElement::applyToMatrix(osg::Matrix& matrix) const {matrix.preMultRotate(_quaternion);}
osg::Matrix StackedQuaternionElement::getAsMatrix() const { return osg::Matrix(_quaternion); }
bool StackedQuaternionElement::isIdentity() const { return (_quaternion[0] == 0 && _quaternion[1] == 0 && _quaternion[2] == 0 && _quaternion[3] == 1.0); }
void StackedQuaternionElement::update()
{
if (_target.valid())
_quaternion = _target->getValue();
}
Target* StackedQuaternionElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new QuatTarget(_quaternion);
return _target.get();
}
Target* StackedQuaternionElement::getTarget() {return _target.get();}
const Target* StackedQuaternionElement::getTarget() const {return _target.get();}

View File

@@ -0,0 +1,55 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedRotateAxisElement>
using namespace osgAnimation;
StackedRotateAxisElement::StackedRotateAxisElement(const std::string& name, const osg::Vec3& axis, double angle) : StackedTransformElement(), _axis(axis), _angle(angle) { setName(name); }
StackedRotateAxisElement::StackedRotateAxisElement(const osg::Vec3& axis, double angle) : _axis(axis), _angle(angle) { setName("rotateaxis"); }
StackedRotateAxisElement::StackedRotateAxisElement() {}
StackedRotateAxisElement::StackedRotateAxisElement(const StackedRotateAxisElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _axis(rhs._axis), _angle(rhs._angle)
{
if (rhs._target.valid())
_target = new FloatTarget(*rhs._target);
}
osg::Matrix StackedRotateAxisElement::getAsMatrix() const { return osg::Matrix::rotate(osg::Quat(_angle, _axis)); }
void StackedRotateAxisElement::update()
{
if (_target.valid())
_angle = _target->getValue();
}
const osg::Vec3& StackedRotateAxisElement::getAxis() const { return _axis; }
const double StackedRotateAxisElement::getAngle() const { return _angle; }
void StackedRotateAxisElement::setAxis(const osg::Vec3& axis)
{
_axis = axis;
}
void StackedRotateAxisElement::setAngle(const double& angle)
{
_angle = angle;
}
Target* StackedRotateAxisElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new FloatTarget(_angle);
return _target.get();
}
void StackedRotateAxisElement::applyToMatrix(osg::Matrix& matrix) const { matrix.preMultRotate(osg::Quat(_angle, _axis)); }

View File

@@ -0,0 +1,56 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedScaleElement>
using namespace osgAnimation;
StackedScaleElement::StackedScaleElement(const std::string& name, const osg::Vec3& scale) : _scale(scale) { setName(name); }
StackedScaleElement::StackedScaleElement(const osg::Vec3& scale) : _scale(scale) { setName("scale"); }
StackedScaleElement::StackedScaleElement(const StackedScaleElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _scale(rhs._scale)
{
if (rhs._target.valid())
_target = new Vec3Target(*rhs._target);
}
const osg::Vec3& StackedScaleElement::getScale() const { return _scale; }
void StackedScaleElement::setScale(const osg::Vec3& scale) { _scale = scale; }
Target* StackedScaleElement::getTarget() {return _target.get();}
const Target* StackedScaleElement::getTarget() const {return _target.get();}
bool StackedScaleElement::isIdentity() const { return (_scale.x() == 1 && _scale.y() == 1 && _scale.z() == 1); }
osg::Matrix StackedScaleElement::getAsMatrix() const { return osg::Matrix::scale(_scale); }
void StackedScaleElement::applyToMatrix(osg::Matrix& matrix) const { matrix.preMultScale(_scale); }
StackedScaleElement::StackedScaleElement()
{
_scale = osg::Vec3(1,1,1);
}
void StackedScaleElement::update()
{
if (_target.valid())
_scale = _target->getValue();
}
Target* StackedScaleElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new Vec3Target(_scale);
return _target.get();
}

View File

@@ -0,0 +1,66 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedTransform>
using namespace osgAnimation;
StackedTransform::StackedTransform() {}
StackedTransform::StackedTransform(const StackedTransform& rhs, const osg::CopyOp& co)
{
reserve(rhs.size());
for (StackedTransform::const_iterator it = rhs.begin(); it != rhs.end(); ++it)
{
const StackedTransformElement* element = *it;
if (element)
push_back(osg::clone(element,co));
}
}
void StackedTransform::update()
{
int dirty = 0;
for (StackedTransform::iterator it = begin(); it != end(); ++it)
{
StackedTransformElement* element = *it;
if (!element)
continue;
// update and check if there are changes
element->update();
if (element->isIdentity())
continue;
dirty++;
}
if (!dirty)
return;
// dirty update matrix
_matrix.makeIdentity();
for (StackedTransform::iterator it = begin(); it != end(); ++it)
{
StackedTransformElement* element = *it;
if (!element || element->isIdentity())
continue;
element->applyToMatrix(_matrix);
}
}
const osg::Matrix& StackedTransform::getMatrix() const
{
return _matrix;
}

View File

@@ -0,0 +1,50 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedTranslateElement>
using namespace osgAnimation;
StackedTranslateElement::StackedTranslateElement(const std::string& name, const osg::Vec3& translate) : _translate(translate) { setName(name); }
StackedTranslateElement::StackedTranslateElement(const osg::Vec3& translate) : _translate(translate) { setName("translate"); }
StackedTranslateElement::StackedTranslateElement() {}
StackedTranslateElement::StackedTranslateElement(const StackedTranslateElement& rhs, const osg::CopyOp&) : StackedTransformElement(rhs), _translate(rhs._translate)
{
if (rhs._target.valid())
_target = new Vec3Target(*rhs._target);
}
void StackedTranslateElement::applyToMatrix(osg::Matrix& matrix) const {matrix.preMultTranslate(_translate);}
osg::Matrix StackedTranslateElement::getAsMatrix() const { return osg::Matrix::translate(_translate); }
bool StackedTranslateElement::isIdentity() const { return (_translate[0] == 0 && _translate[1] == 0 && _translate[2] == 0); }
const osg::Vec3& StackedTranslateElement::getTranslate() const { return _translate; }
void StackedTranslateElement::setTranslate(const osg::Vec3& value) { _translate = value; }
Target* StackedTranslateElement::getOrCreateTarget()
{
if (!_target.valid())
_target = new Vec3Target(_translate);
return _target.get();
}
Target* StackedTranslateElement::getTarget() {return _target.get();}
const Target* StackedTranslateElement::getTarget() const {return _target.get();}
void StackedTranslateElement::update()
{
if (_target.valid())
_translate = _target->getValue();
}

View File

@@ -424,7 +424,7 @@ struct ValueTextDrawCallback : public virtual osg::Drawable::DrawCallback
osg::Vec3 pos(leftPos, _statsHeight-24.0f,0.0f);
pos.y() -= characterSize *2 + backgroundMargin;
for (std::map<std::string, StatAction >::iterator it = _actions.begin(); it != _actions.end(); it++) {
for (std::map<std::string, StatAction >::iterator it = _actions.begin(); it != _actions.end(); ++it) {
(*it).second._group->setNodeMask(~osg::Node::NodeMask(1));
}

View File

@@ -210,7 +210,7 @@ void Timeline::processPendingOperation()
void Timeline::internalRemoveAction(Action* action)
{
for (ActionLayers::iterator it = _actions.begin(); it != _actions.end(); it++)
for (ActionLayers::iterator it = _actions.begin(); it != _actions.end(); ++it)
{
ActionList& fa = it->second;
for (unsigned int i = 0; i < fa.size(); i++)

View File

@@ -0,0 +1,54 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osg/NodeVisitor>
#include <osgAnimation/Bone>
#include <osgAnimation/UpdateBone>
using namespace osgAnimation;
UpdateBone::UpdateBone(const std::string& name) : UpdateMatrixTransform(name)
{
}
UpdateBone::UpdateBone(const UpdateBone& apc,const osg::CopyOp& copyop) : osg::Object(apc,copyop), UpdateMatrixTransform(apc, copyop)
{
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
Bone* b = dynamic_cast<Bone*>(node);
if (!b)
{
osg::notify(osg::WARN) << "Warning: UpdateBone set on non-Bone object." << std::endl;
return;
}
// here we would prefer to have a flag inside transform stack in order to avoid update and a dirty state in matrixTransform if it's not require.
_transforms.update();
const osg::Matrix& matrix = _transforms.getMatrix();
b->setMatrix(matrix);
Bone* parent = b->getBoneParent();
if (parent)
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace());
else
b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace());
}
traverse(node,nv);
}

View File

@@ -1,162 +0,0 @@
/* -*-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>
#include <osg/Math>
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);
m = osg::Matrix::scale(_scale->getValue()) * m * osg::Matrix::translate(_position->getValue());
mat.setMatrix(m);
if (!m.valid())
osg::notify(osg::WARN) << this << " UpdateTransform::update detected NaN" << std::endl;
}
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::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::StateAttributeCallback>(apc, copyop)
{
_diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
}
UpdateMaterial::UpdateMaterial(const std::string& name):
AnimationUpdateCallback<osg::StateAttributeCallback>(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);
}
}
osgAnimation::Vec4Target* UpdateMaterial::getDiffuse() { return _diffuse.get(); }
void UpdateMaterial::update(osg::Material& material)
{
osg::Vec4 diffuse = _diffuse->getValue();
material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
}
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;
}

View File

@@ -0,0 +1,63 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/UpdateMaterial>
#include <osg/NodeVisitor>
using namespace osgAnimation;
UpdateMaterial::UpdateMaterial(const UpdateMaterial& apc,const osg::CopyOp& copyop)
: osg::Object(apc, copyop),
AnimationUpdateCallback<osg::StateAttributeCallback>(apc, copyop)
{
_diffuse = new osgAnimation::Vec4Target(apc._diffuse->getValue());
}
UpdateMaterial::UpdateMaterial(const std::string& name):
AnimationUpdateCallback<osg::StateAttributeCallback>(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);
}
}
osgAnimation::Vec4Target* UpdateMaterial::getDiffuse() { return _diffuse.get(); }
void UpdateMaterial::update(osg::Material& material)
{
osg::Vec4 diffuse = _diffuse->getValue();
material.setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
}
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;
}

View File

@@ -0,0 +1,67 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/UpdateMatrixTransform>
#include <osg/NodeVisitor>
#include <osg/MatrixTransform>
using namespace osgAnimation;
UpdateMatrixTransform::UpdateMatrixTransform( const UpdateMatrixTransform& apc,const osg::CopyOp& copyop) : osg::Object(apc,copyop), AnimationUpdateCallback<osg::NodeCallback>(apc, copyop)
{
_transforms = StackedTransform(apc.getStackedTransforms(), copyop);
}
UpdateMatrixTransform::UpdateMatrixTransform(const std::string& name) : AnimationUpdateCallback<osg::NodeCallback>(name)
{
}
/** Callback method called by the NodeVisitor when visiting a node.*/
void UpdateMatrixTransform::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (nv && nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
{
osg::MatrixTransform* matrixTransform = dynamic_cast<osg::MatrixTransform*>(node);
if (matrixTransform)
{
// here we would prefer to have a flag inside transform stack in order to avoid update and a dirty state in matrixTransform if it's not require.
_transforms.update();
const osg::Matrix& matrix = _transforms.getMatrix();
matrixTransform->setMatrix(matrix);
}
}
traverse(node,nv);
}
bool UpdateMatrixTransform::link(osgAnimation::Channel* channel)
{
const std::string& channelName = channel->getName();
// check if we can link a StackedTransformElement to the current Channel
for (StackedTransform::iterator it = _transforms.begin(); it != _transforms.end(); ++it)
{
StackedTransformElement* element = *it;
if (element && !element->getName().empty() && channelName == element->getName())
{
Target* target = element->getOrCreateTarget();
if (target && channel->setTarget(target))
return true;
}
}
osg::notify(osg::INFO) << "UpdateMatrixTransform::link Channel " << channel->getName() << " does not contain a symbolic name that can be linked to a StackedTransformElement." << std::endl;
return false;
}

View File

@@ -26,7 +26,7 @@ const VertexInfluenceSet::VertexIndexToBoneWeightMap& VertexInfluenceSet::getVer
void VertexInfluenceSet::buildVertex2BoneList()
{
_vertex2Bones.clear();
for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); it++)
for (BoneToVertexList::const_iterator it = _bone2Vertexes.begin(); it != _bone2Vertexes.end(); ++it)
{
const VertexInfluence& vi = (*it);
int size = vi.size();
@@ -42,7 +42,7 @@ void VertexInfluenceSet::buildVertex2BoneList()
}
// normalize weight per vertex
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++)
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it)
{
BoneWeightList& bones = it->second;
int size = bones.size();
@@ -116,7 +116,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
typedef std::map<BoneWeightList,UniqVertexSetToBoneSet, SortByBoneWeightList> UnifyBoneGroup;
UnifyBoneGroup unifyBuffer;
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); it++)
for (VertexIndexToBoneWeightMap::iterator it = _vertex2Bones.begin(); it != _vertex2Bones.end(); ++it)
{
BoneWeightList bones = it->second;
int vertexIndex = it->first;
@@ -132,7 +132,7 @@ void VertexInfluenceSet::buildUniqVertexSetToBoneSetList()
}
_uniqVertexSetToBoneSet.reserve(unifyBuffer.size());
for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); it++)
for (UnifyBoneGroup::iterator it = unifyBuffer.begin(); it != unifyBuffer.end(); ++it)
{
_uniqVertexSetToBoneSet.push_back(it->second);
}

View File

@@ -8,6 +8,10 @@
#include <osgAnimation/Bone>
#include <osgAnimation/Skeleton>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedQuaternionElement>
#include <osgAnimation/BasicAnimationManager>
class BvhMotionBuilder : public osg::Referenced
@@ -39,7 +43,17 @@ public:
if ( fr.readSequence(offset) )
{
// Process OFFSET section
parent->setBindMatrixInBoneSpace( osg::Matrix::translate(offset) );
parent->setMatrixInSkeletonSpace( osg::Matrix::translate(offset) *
parent->getMatrixInSkeletonSpace() );
osgAnimation::UpdateBone* updateBone =
static_cast<osgAnimation::UpdateBone*>( parent->getUpdateCallback() );
if ( updateBone )
{
osgAnimation::StackedTransform& stack = updateBone->getStackedTransforms();
stack.push_back( new osgAnimation::StackedTranslateElement("position", offset) );
stack.push_back( new osgAnimation::StackedQuaternionElement("quaternion", osg::Quat()) );
}
if ( _drawingFlag && parent->getNumParents() && level>0 )
parent->getParent(0)->addChild( createRefGeometry(offset, 0.5).get() );
}
@@ -77,9 +91,10 @@ public:
{
// Process End Site section
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( parent->getName()+"End" );
bone->setBindMatrixInBoneSpace( osg::Matrix::translate(offsetEndSite) );
bone->setMatrixInSkeletonSpace( osg::Matrix::translate(offsetEndSite) *
bone->getMatrixInSkeletonSpace() );
bone->setDataVariance( osg::Object::DYNAMIC );
parent->addChild( bone.get() );
parent->insertChild( 0, bone.get() );
if ( _drawingFlag )
parent->addChild( createRefGeometry(offsetEndSite, 0.5).get() );
@@ -94,9 +109,9 @@ public:
// Process JOINT section
osg::ref_ptr<osgAnimation::Bone> bone = new osgAnimation::Bone( fr[1].getStr() );
bone->setDefaultUpdateCallback();
bone->setDataVariance( osg::Object::DYNAMIC );
parent->addChild( bone.get() );
bone->setDefaultUpdateCallback();
parent->insertChild( 0, bone.get() );
_joints.push_back( JointNode(bone, 0) );
int entry = fr[1].getNoNestedBrackets();
@@ -194,8 +209,13 @@ public:
osgDB::Input fr;
fr.attach( &stream );
osg::ref_ptr<osgAnimation::Bone> boneroot = new osgAnimation::Bone( "Root" );
boneroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
skelroot->setDefaultUpdateCallback();
skelroot->insertChild( 0, boneroot.get() );
osg::ref_ptr<osgAnimation::Animation> anim = new osgAnimation::Animation;
while( !fr.eof() )
@@ -203,7 +223,7 @@ public:
if ( fr.matchSequence("HIERARCHY") )
{
++fr;
buildHierarchy( fr, 0, skelroot.get() );
buildHierarchy( fr, 0, boneroot.get() );
}
else if ( fr.matchSequence("MOTION") )
{

View File

@@ -5,5 +5,3 @@ FILE(GLOB TARGET_H *.h)
SET(TARGET_ADDED_LIBRARIES osgAnimation )
#### end var setup ###
SETUP_PLUGIN(osganimation)

View File

@@ -0,0 +1,51 @@
#include "Matrix.h"
bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword)
{
bool iteratorAdvanced = false;
if (fr[0].matchWord(keyword) && fr[1].isOpenBracket())
{
int entry = fr[0].getNoNestedBrackets();
fr += 2;
int row=0;
int col=0;
double v;
while (!fr.eof() && fr[0].getNoNestedBrackets()>entry)
{
if (fr[0].getFloat(v))
{
matrix(row,col)=v;
++col;
if (col>=4)
{
col = 0;
++row;
}
++fr;
}
else fr.advanceOverCurrentFieldOrBlock();
}
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword)
{
fw.indent() << keyword <<" {" << std::endl;
fw.moveIn();
fw.indent() << matrix(0,0) << " " << matrix(0,1) << " " << matrix(0,2) << " " << matrix(0,3) << std::endl;
fw.indent() << matrix(1,0) << " " << matrix(1,1) << " " << matrix(1,2) << " " << matrix(1,3) << std::endl;
fw.indent() << matrix(2,0) << " " << matrix(2,1) << " " << matrix(2,2) << " " << matrix(2,3) << std::endl;
fw.indent() << matrix(3,0) << " " << matrix(3,1) << " " << matrix(3,2) << " " << matrix(3,3) << std::endl;
fw.moveOut();
fw.indent() << "}"<< std::endl;
return true;
}

View File

@@ -0,0 +1,13 @@
#ifndef DOTOSG_MATRIX
#define DOTOSG_MATRIX
#include <osg/Matrix>
#include <osgDB/Input>
#include <osgDB/Output>
extern bool readMatrix(osg::Matrix& matrix, osgDB::Input& fr, const char* keyword="Matrix");
extern bool writeMatrix(const osg::Matrix& matrix, osgDB::Output& fw, const char* keyword="Matrix");
#endif

View File

@@ -10,24 +10,30 @@
* 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 <osg/io_utils>
#include <osgAnimation/AnimationManagerBase>
#include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/TimelineAnimationManager>
#include <osgAnimation/VertexInfluence>
#include <osgAnimation/Animation>
#include <osgAnimation/Bone>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/UpdateMatrixTransform>
#include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/MorphGeometry>
#include <osgAnimation/UpdateCallback>
#include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedRotateAxisElement>
#include <osgAnimation/StackedMatrixElement>
#include <osgAnimation/StackedScaleElement>
#include "Matrix.h"
#include <osgDB/Registry>
#include <osgDB/Input>
@@ -42,7 +48,7 @@ bool Bone_readLocalData(Object& obj, Input& fr)
osg::Quat att;
bool iteratorAdvanced = false;
if (fr.matchSequence("bindQuaternion %f %f %f %f"))
if (fr.matchSequence("bindQuaternion %f %f %f %f"))
{
fr[1].getFloat(att[0]);
fr[2].getFloat(att[1]);
@@ -51,10 +57,11 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 5;
iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
}
osg::Vec3d pos(0,0,0);
if (fr.matchSequence("bindPosition %f %f %f"))
if (fr.matchSequence("bindPosition %f %f %f"))
{
fr[1].getFloat(pos[0]);
fr[2].getFloat(pos[1]);
@@ -62,10 +69,11 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 4;
iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
}
osg::Vec3d scale(1,1,1);
if (fr.matchSequence("bindScale %f %f %f"))
if (fr.matchSequence("bindScale %f %f %f"))
{
fr[1].getFloat(scale[0]);
fr[2].getFloat(scale[1]);
@@ -73,31 +81,45 @@ bool Bone_readLocalData(Object& obj, Input& fr)
fr += 4;
iteratorAdvanced = true;
osg::notify(osg::WARN) << "Old osgAnimation file format update your data file" << std::endl;
}
bone.setBindMatrixInBoneSpace( osg::Matrix(att) * osg::Matrix::translate(pos));
if (fr.matchSequence("InvBindMatrixInSkeletonSpace {"))
{
Matrix matrix;
if (readMatrix(matrix,fr, "InvBindMatrixInSkeletonSpace"))
{
bone.setInvBindMatrixInSkeletonSpace(matrix);
iteratorAdvanced = true;
}
}
if (fr.matchSequence("MatrixInSkeletonSpace {"))
{
Matrix matrix;
if (readMatrix(matrix,fr, "MatrixInSkeletonSpace"))
{
bone.setMatrixInSkeletonSpace(matrix);
iteratorAdvanced = true;
}
}
return iteratorAdvanced;
}
bool Bone_writeLocalData(const Object& obj, Output& fw)
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;
bool res1 = writeMatrix(bone.getInvBindMatrixInSkeletonSpace(), fw, "InvBindMatrixInSkeletonSpace");
// write this field for debug only
// because it's recompute at each update
bool res2 = writeMatrix(bone.getMatrixInSkeletonSpace(), fw, "MatrixInSkeletonSpace");
return (res1 || res2);
}
RegisterDotOsgWrapperProxy g_atkBoneProxy
RegisterDotOsgWrapperProxy g_BoneProxy
(
new osgAnimation::Bone,
"osgAnimation::Bone",
"Object Node Transform osgAnimation::Bone Group",
"Object Node MatrixTransform osgAnimation::Bone Group",
&Bone_readLocalData,
&Bone_writeLocalData
);
@@ -112,11 +134,11 @@ bool Skeleton_writeLocalData(const Object& obj, Output& fr)
{
return true;
}
RegisterDotOsgWrapperProxy g_atkRootSkeletonProxy
RegisterDotOsgWrapperProxy g_SkeletonProxy
(
new osgAnimation::Skeleton,
"osgAnimation::Skeleton",
"Object Node Transform osgAnimation::Bone osgAnimation::Skeleton Group",
"Object Node MatrixTransform osgAnimation::Skeleton Group",
&Skeleton_readLocalData,
&Skeleton_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
@@ -723,7 +745,7 @@ bool AnimationManagerBase_writeLocalData(const osgAnimation::AnimationManagerBas
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++)
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;
@@ -816,6 +838,13 @@ bool RigGeometry_readLocalData(Object& obj, Input& fr)
if (!vmap->empty())
geom.setInfluenceMap(vmap.get());
if (fr.matchSequence("Geometry {"))
{
osg::Geometry* source = dynamic_cast<osg::Geometry*>(fr.readObject());
geom.setSourceGeometry(source);
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
@@ -827,7 +856,7 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw)
return true;
fw.indent() << "num_influences " << vm->size() << std::endl;
fw.moveIn();
for (osgAnimation::VertexInfluenceMap::const_iterator it = vm->begin(); it != vm->end(); it++)
for (osgAnimation::VertexInfluenceMap::const_iterator it = vm->begin(); it != vm->end(); ++it)
{
std::string name = it->first;
if (name.empty())
@@ -843,6 +872,8 @@ bool RigGeometry_writeLocalData(const Object& obj, Output& fw)
fw.indent() << "}" << std::endl;
}
fw.moveOut();
fw.writeObject(*geom.getSourceGeometry());
return true;
}
@@ -850,7 +881,7 @@ RegisterDotOsgWrapperProxy g_atkRigGeometryProxy
(
new osgAnimation::RigGeometry,
"osgAnimation::RigGeometry",
"Object Drawable osgAnimation::RigGeometry Geometry",
"Object osgAnimation::RigGeometry Drawable Geometry",
&RigGeometry_readLocalData,
&RigGeometry_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
@@ -975,7 +1006,10 @@ RegisterDotOsgWrapperProxy g_osgAnimationMorphGeometryProxy
);
bool UpdateBone_readLocalData(Object& obj, Input& fr)
bool UpdateBone_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
return iteratorAdvanced;
@@ -986,11 +1020,11 @@ bool UpdateBone_writeLocalData(const Object& obj, Output& fw)
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateBoneProxy
RegisterDotOsgWrapperProxy g_UpdateBoneProxy
(
new osgAnimation::Bone::UpdateBone,
new osgAnimation::UpdateBone,
"osgAnimation::UpdateBone",
"Object NodeCallback osgAnimation::UpdateBone",
"Object NodeCallback osgAnimation::UpdateMatrixTransform osgAnimation::UpdateBone",
&UpdateBone_readLocalData,
&UpdateBone_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
@@ -1009,7 +1043,7 @@ bool UpdateSkeleton_writeLocalData(const Object& obj, Output& fw)
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
RegisterDotOsgWrapperProxy g_UpdateSkeletonProxy
(
new osgAnimation::Skeleton::UpdateSkeleton,
"osgAnimation::UpdateSkeleton",
@@ -1020,51 +1054,6 @@ RegisterDotOsgWrapperProxy g_atkUpdateSkeletonProxy
);
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;
@@ -1076,7 +1065,7 @@ bool UpdateMorph_writeLocalData(const Object& obj, Output& fw)
return true;
}
RegisterDotOsgWrapperProxy g_atkUpdateMorphProxy
RegisterDotOsgWrapperProxy g_UpdateMorphProxy
(
new osgAnimation::UpdateMorph,
"osgAnimation::UpdateMorph",

View File

@@ -0,0 +1,228 @@
/* -*-c++-*-
* Copyright (C) 2009 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 <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedMatrixElement>
#include <osgAnimation/StackedScaleElement>
#include <osgAnimation/StackedRotateAxisElement>
#include <osgAnimation/StackedQuaternionElement>
#include <osgDB/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include "Matrix.h"
using namespace osgDB;
using namespace osg;
bool readStackedTranslateElement(Object& obj, Input& fr)
{
osgAnimation::StackedTranslateElement& element = dynamic_cast<osgAnimation::StackedTranslateElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("translate %f %f %f"))
{
++fr;
osg::Vec3 translate;
fr[0].getFloat(translate.x());
fr[1].getFloat(translate.y());
fr[2].getFloat(translate.z());
element.setTranslate(translate);
fr += 3;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedTranslateElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedTranslateElement& element = dynamic_cast<const osgAnimation::StackedTranslateElement&>(obj);
fw.indent() << "translate " << element.getTranslate() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedTranslateElementProxy
(
new osgAnimation::StackedTranslateElement,
"osgAnimation::StackedTranslateElement",
"Object osgAnimation::StackedTranslateElement",
&readStackedTranslateElement,
&writeStackedTranslateElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedScaleElement(Object& obj, Input& fr)
{
osgAnimation::StackedScaleElement& element = dynamic_cast<osgAnimation::StackedScaleElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("scale %f %f %f"))
{
++fr;
osg::Vec3 scale;
fr[0].getFloat(scale.x());
fr[1].getFloat(scale.y());
fr[2].getFloat(scale.z());
element.setScale(scale);
fr += 3;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedScaleElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedScaleElement& element = dynamic_cast<const osgAnimation::StackedScaleElement&>(obj);
fw.indent() << "scale " << element.getScale() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedScaleElementProxy
(
new osgAnimation::StackedScaleElement,
"osgAnimation::StackedScaleElement",
"Object osgAnimation::StackedScaleElement",
&readStackedScaleElement,
&writeStackedScaleElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedMatrixElement(Object& obj, Input& fr)
{
osgAnimation::StackedMatrixElement& element = dynamic_cast<osgAnimation::StackedMatrixElement&>(obj);
bool iteratorAdvanced = false;
if (fr[0].matchWord("Matrix"))
{
osg::Matrix matrix;
matrix.makeIdentity();
iteratorAdvanced = readMatrix(matrix, fr);
element.setMatrix(matrix);
}
return iteratorAdvanced;
}
bool writeStackedMatrixElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedMatrixElement& element = dynamic_cast<const osgAnimation::StackedMatrixElement&>(obj);
writeMatrix(element.getMatrix(), fw);
return true;
}
RegisterDotOsgWrapperProxy g_StackedMatrixElementProxy
(
new osgAnimation::StackedMatrixElement,
"osgAnimation::StackedMatrixElement",
"Object osgAnimation::StackedMatrixElement",
&readStackedMatrixElement,
&writeStackedMatrixElement,
DotOsgWrapper::READ_AND_WRITE
);
bool writeStackedRotateAxisElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedRotateAxisElement& element = dynamic_cast<const osgAnimation::StackedRotateAxisElement&>(obj);
fw.indent() << "axis " << element.getAxis() << std::endl;
fw.indent() << "angle " << element.getAngle() << std::endl;
return true;
}
bool readStackedRotateAxisElement(Object& obj, Input& fr)
{
osgAnimation::StackedRotateAxisElement& element = dynamic_cast<osgAnimation::StackedRotateAxisElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("axis %f %f %f"))
{
++fr;
osg::Vec3 axis;
fr[0].getFloat(axis.x());
fr[1].getFloat(axis.y());
fr[2].getFloat(axis.z());
element.setAxis(axis);
fr += 3;
iteratorAdvanced = true;
}
if (fr.matchSequence("angle %f"))
{
++fr;
double angle = 0;
fr[0].getFloat(angle);
++fr;
element.setAngle(angle);
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
RegisterDotOsgWrapperProxy g_StackedRotateAxisElementProxy
(
new osgAnimation::StackedRotateAxisElement,
"osgAnimation::StackedRotateAxisElement",
"Object osgAnimation::StackedRotateAxisElement",
&readStackedRotateAxisElement,
&writeStackedRotateAxisElement,
DotOsgWrapper::READ_AND_WRITE
);
bool readStackedQuaternionElement(Object& obj, Input& fr)
{
osgAnimation::StackedQuaternionElement& element = dynamic_cast<osgAnimation::StackedQuaternionElement&>(obj);
bool iteratorAdvanced = false;
if (fr.matchSequence("quaternion %f %f %f %f"))
{
++fr;
osg::Quat quaternion;
fr[0].getFloat(quaternion[0]);
fr[1].getFloat(quaternion[1]);
fr[2].getFloat(quaternion[2]);
fr[3].getFloat(quaternion[3]);
element.setQuaternion(quaternion);
fr += 4;
iteratorAdvanced = true;
}
return iteratorAdvanced;
}
bool writeStackedQuaternionElement(const Object& obj, Output& fw)
{
const osgAnimation::StackedQuaternionElement& element = dynamic_cast<const osgAnimation::StackedQuaternionElement&>(obj);
fw.indent() << "quaternion " << element.getQuaternion() << std::endl;
return true;
}
RegisterDotOsgWrapperProxy g_StackedQuaternionElementProxy
(
new osgAnimation::StackedQuaternionElement,
"osgAnimation::StackedQuaternionElement",
"Object osgAnimation::StackedQuaternionElement",
&readStackedQuaternionElement,
&writeStackedQuaternionElement,
DotOsgWrapper::READ_AND_WRITE
);

View File

@@ -0,0 +1,47 @@
/* -*-c++-*-
* Copyright (C) 2009 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/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include <osgAnimation/UpdateMaterial>
using namespace osg;
using namespace osgDB;
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
);

View File

@@ -0,0 +1,70 @@
/* -*-c++-*-
* Copyright (C) 2009 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/Input>
#include <osgDB/Output>
#include <osgDB/Registry>
#include <osgDB/ReaderWriter>
#include <osg/io_utils>
#include <osgAnimation/StackedTransformElement>
#include <osgAnimation/UpdateMatrixTransform>
using namespace osg;
using namespace osgDB;
bool UpdateMatrixTransform_readLocalData(Object& obj, Input& fr)
{
bool iteratorAdvanced = false;
osgAnimation::UpdateMatrixTransform& updateCallback = dynamic_cast<osgAnimation::UpdateMatrixTransform&>(obj);
osgAnimation::StackedTransform& stackedTransform = updateCallback.getStackedTransforms();
int entry = fr[0].getNoNestedBrackets();
while (!fr.eof() && fr[0].getNoNestedBrackets() == entry && fr.matchSequence("%w {"))
{
osgAnimation::StackedTransformElement* element = dynamic_cast<osgAnimation::StackedTransformElement*>(fr.readObject());
if (element)
stackedTransform.push_back(element);
}
return iteratorAdvanced;
}
bool UpdateMatrixTransform_writeLocalData(const Object& obj, Output& fw)
{
const osgAnimation::UpdateMatrixTransform* uc = dynamic_cast<const osgAnimation::UpdateMatrixTransform*>(&obj);
const osgAnimation::StackedTransform& transforms = uc->getStackedTransforms();
for (osgAnimation::StackedTransform::const_iterator it = transforms.begin(); it != transforms.end(); ++it)
{
osgAnimation::StackedTransformElement* element = *it;
if (element)
fw.writeObject(*element);
}
return true;
}
RegisterDotOsgWrapperProxy g_UpdateMatrixTransformProxy
(
new osgAnimation::UpdateMatrixTransform,
"osgAnimation::UpdateMatrixTransform",
"Object NodeCallback osgAnimation::UpdateMatrixTransform",
&UpdateMatrixTransform_readLocalData,
&UpdateMatrixTransform_writeLocalData,
DotOsgWrapper::READ_AND_WRITE
);