From Cedric Pinson, "updated osgAnimation with the trunk here the update:
examples/osganimationviewer/AnimtkViewer.cpp: - add option to display bone (--drawbone) - dont crash if the file does not contains a AnimationManagerBase, display the content only examples/osganimationviewer/AnimtkViewerGUI.cpp: - adjust the path of image for the gui include/osgAnimation/Interpolator: - add warn message instead of old assert include/osgAnimation/Bone: src/osgAnimation/Skeleton.cpp: - change a method name to fit better with what it does. setMatrixInSkeletonSpace instead of setBoneInSkeletonSpace include/osgAnimation/Skinning: src/osgAnimation/RigGeometry.cpp: - add patch from Fabien Lavignotte to compute normal correctly include/osgAnimation/Sampler: - adjust behviour without assert, return 0 instead of crashing "
This commit is contained in:
@@ -237,7 +237,7 @@ int main (int argc, char* argv[])
|
||||
osg::MatrixTransform* trueroot = new osg::MatrixTransform;
|
||||
trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
|
||||
trueroot->addChild(createAxis());
|
||||
trueroot->addChild(skelroot);
|
||||
trueroot->addChild(skelroot.get());
|
||||
trueroot->setDataVariance(osg::Object::DYNAMIC);
|
||||
rootTransform->addChild(trueroot);
|
||||
scene->addChild(rootTransform);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <osgGA/StateSetManipulator>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgAnimation/AnimationManagerBase>
|
||||
#include <osgAnimation/Bone>
|
||||
|
||||
const int WIDTH = 1440;
|
||||
const int HEIGHT = 900;
|
||||
@@ -68,32 +69,86 @@ osg::Geode* createAxis()
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
struct AnimationManagerFinder : public osg::NodeVisitor
|
||||
{
|
||||
osg::ref_ptr<osgAnimation::BasicAnimationManager> _am;
|
||||
AnimationManagerFinder() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
void apply(osg::Node& node) {
|
||||
if (_am.valid())
|
||||
return;
|
||||
if (node.getUpdateCallback()) {
|
||||
osgAnimation::AnimationManagerBase* b = dynamic_cast<osgAnimation::AnimationManagerBase*>(node.getUpdateCallback());
|
||||
if (b) {
|
||||
_am = new osgAnimation::BasicAnimationManager(*b);
|
||||
return;
|
||||
}
|
||||
}
|
||||
traverse(node);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct AddHelperBone : public osg::NodeVisitor
|
||||
{
|
||||
AddHelperBone() : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
void apply(osg::Transform& node) {
|
||||
osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node);
|
||||
if (bone)
|
||||
bone->addChild(createAxis());
|
||||
traverse(node);
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
osg::ArgumentParser psr(&argc, argv);
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is a 3d poker game client");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","List command line options.");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("--drawbone","draw helps to display bones.");
|
||||
|
||||
if(argc < 2)
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
std::cerr << "usage: AnimtkViewer <file.osg>" << std::endl;
|
||||
arguments.getApplicationUsage()->write(std::cout, osg::ApplicationUsage::COMMAND_LINE_OPTION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arguments.argc()<=1)
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout, osg::ApplicationUsage::COMMAND_LINE_OPTION);
|
||||
return 1;
|
||||
}
|
||||
|
||||
osgViewer::Viewer viewer(psr);
|
||||
bool drawBone = false;
|
||||
if (arguments.read("--drawbone"))
|
||||
drawBone = true;
|
||||
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
osg::ref_ptr<osg::Group> group = new osg::Group();
|
||||
|
||||
osg::Group* node = dynamic_cast<osg::Group*>(osgDB::readNodeFile(psr[1])); //dynamic_cast<osgAnimation::AnimationManager*>(osgDB::readNodeFile(psr[1]));
|
||||
if(!node)
|
||||
osg::Group* node = dynamic_cast<osg::Group*>(osgDB::readNodeFiles(arguments)); //dynamic_cast<osgAnimation::AnimationManager*>(osgDB::readNodeFile(psr[1]));
|
||||
if(!node)
|
||||
{
|
||||
std::cerr << "Can't read file " << psr[1]<< std::endl;
|
||||
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set our Singleton's model.
|
||||
osgAnimation::AnimationManagerBase* base = dynamic_cast<osgAnimation::AnimationManagerBase*>(node->getUpdateCallback());
|
||||
osgAnimation::BasicAnimationManager* manager = new osgAnimation::BasicAnimationManager(*base);
|
||||
node->setUpdateCallback(manager);
|
||||
AnimtkViewerModelController::setModel(manager);
|
||||
AnimationManagerFinder finder;
|
||||
node->accept(finder);
|
||||
if (finder._am.valid()) {
|
||||
node->setUpdateCallback(finder._am.get());
|
||||
AnimtkViewerModelController::setModel(finder._am.get());
|
||||
} else {
|
||||
osg::notify(osg::WARN) << "no osgAnimation::AnimationManagerBase found in the subgraph, no animations available" << std::endl;
|
||||
}
|
||||
|
||||
if (drawBone) {
|
||||
osg::notify(osg::INFO) << "Add Bones Helper" << std::endl;
|
||||
AddHelperBone addHelper;
|
||||
node->accept(addHelper);
|
||||
}
|
||||
node->addChild(createAxis());
|
||||
|
||||
AnimtkViewerGUI* gui = new AnimtkViewerGUI(&viewer, WIDTH, HEIGHT, 0x1234);
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace osgAnimation
|
||||
const osg::Matrix& getBindMatrixInBoneSpace() const { return _bindInBoneSpace; }
|
||||
const osg::Matrix& getMatrixInSkeletonSpace() const { return _boneInSkeletonSpace; }
|
||||
const osg::Matrix& getInvBindMatrixInSkeletonSpace() const { return _invBindInSkeletonSpace;}
|
||||
void setBoneInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
|
||||
void setMatrixInSkeletonSpace(const osg::Matrix& matrix) { _boneInSkeletonSpace = matrix; }
|
||||
void setBindMatrixInBoneSpace(const osg::Matrix& matrix)
|
||||
{
|
||||
_bindInBoneSpace = matrix;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#ifndef OSGANIMATION_INTERPOLATOR_H
|
||||
#define OSGANIMATION_INTERPOLATOR_H
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osgAnimation/Interpolator>
|
||||
#include <osgAnimation/Keyframe>
|
||||
|
||||
@@ -38,8 +39,12 @@ namespace osgAnimation
|
||||
{
|
||||
// todo use a cache
|
||||
int key_size = keys.size();
|
||||
if (!key_size) {
|
||||
osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;;
|
||||
return -1;
|
||||
}
|
||||
const TemplateKeyframe<KeyframeType>* keysVector = &keys.front();
|
||||
for (int i = 0; i < key_size-1; i++)
|
||||
for (int i = 0; i < key_size-1; i++)
|
||||
{
|
||||
float time0 = keysVector[i].getTime();
|
||||
float time1 = keysVector[i+1].getTime();
|
||||
@@ -50,9 +55,7 @@ namespace osgAnimation
|
||||
return i;
|
||||
}
|
||||
}
|
||||
std::cout << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl;
|
||||
*((int *)0) = 0;
|
||||
|
||||
osg::notify(osg::WARN) << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,11 +64,15 @@ namespace osgAnimation
|
||||
|
||||
float getStartTime() const
|
||||
{
|
||||
if (!_keyframes)
|
||||
return 0.0f;
|
||||
return _keyframes->front().getTime();
|
||||
}
|
||||
|
||||
float getEndTime() const
|
||||
{
|
||||
if (!_keyframes)
|
||||
return 0.0f;
|
||||
return _keyframes->back().getTime();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,9 +91,9 @@ namespace osgAnimation
|
||||
ptrresult[13] += ptr[13] * weight;
|
||||
ptrresult[14] += ptr[14] * weight;
|
||||
}
|
||||
void computeMatrixForVertexSet()
|
||||
void computeMatrixForVertexSet()
|
||||
{
|
||||
if (_bones.empty())
|
||||
if (_bones.empty())
|
||||
{
|
||||
osg::notify(osg::WARN) << "TransformVertexFunctor::UniqBoneSetVertexSet no bones found" << std::endl;
|
||||
_result = MatrixType::identity();
|
||||
@@ -181,6 +181,7 @@ namespace osgAnimation
|
||||
|
||||
template <class V> void compute(const MatrixType& transform, const MatrixType& invTransform, const V* src, V* dst)
|
||||
{
|
||||
// the result of matrix mult should be cached to be used for vertexes transform and normal transform and maybe other computation
|
||||
int size = _boneSetVertexSet.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
@@ -198,6 +199,26 @@ namespace osgAnimation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class V> void computeNormal(const MatrixType& transform, const MatrixType& invTransform, const V* src, V* dst)
|
||||
{
|
||||
int size = _boneSetVertexSet.size();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
UniqBoneSetVertexSet& uniq = _boneSetVertexSet[i];
|
||||
uniq.computeMatrixForVertexSet();
|
||||
MatrixType matrix = transform * uniq.getMatrix() * invTransform;
|
||||
|
||||
const VertexList& vertexes = uniq.getVertexes();
|
||||
int vertexSize = vertexes.size();
|
||||
for (int j = 0; j < vertexSize; j++)
|
||||
{
|
||||
int idx = vertexes[j];
|
||||
dst[idx] = MatrixType::transform3x3(src[idx],matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::vector<UniqBoneSetVertexSet> _boneSetVertexSet;
|
||||
|
||||
@@ -117,7 +117,7 @@ void RigGeometry::transformSoftwareMethod()
|
||||
}
|
||||
if (!_normalSource.empty())
|
||||
{
|
||||
_transformVertexes.compute<osg::Vec3>(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_normalSource.front(), &normal->front());
|
||||
_transformVertexes.computeNormal<osg::Vec3>(_matrixFromSkeletonToGeometry, _invMatrixFromSkeletonToGeometry, &_normalSource.front(), &normal->front());
|
||||
normal->dirty();
|
||||
}
|
||||
if (getUseDisplayList())
|
||||
|
||||
@@ -52,9 +52,9 @@ struct updateMatrixVisitor : public osg::NodeVisitor
|
||||
}
|
||||
|
||||
if (parent)
|
||||
bone->setBoneInSkeletonSpace(bone->getMatrixInBoneSpace() * bone->getBoneParent()->getMatrixInSkeletonSpace());
|
||||
bone->setMatrixInSkeletonSpace(bone->getMatrixInBoneSpace() * bone->getBoneParent()->getMatrixInSkeletonSpace());
|
||||
else
|
||||
bone->setBoneInSkeletonSpace(bone->getMatrixInBoneSpace());
|
||||
bone->setMatrixInSkeletonSpace(bone->getMatrixInBoneSpace());
|
||||
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user