osg的4类动画:
1.路径运动动画
2.变形动画
3.骨骼动画
4.纹理动画
骨骼动画示例:
// M23.11.W4.osgAnimation.Skeleton.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdafx.h"
#include <Windows.h>
//osg
#include <osg/Texture2D>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/Geometry>
#include <osg/Material>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGA/AnimationPathManipulator>
//osgAnimation
#include <osgAnimation/BasicAnimationManager>
#include <osgAnimation/Channel>
#include <osgAnimation/UpdateMatrixTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedRotateAxisElement>
//osgAnimation-skeleton
#include <osgAnimation/Bone>
#include <osgAnimation/Skeleton>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/UpdateBone>
#include <osgAnimation/StackedTransform>
#include <osgAnimation/StackedTranslateElement>
#include <osgAnimation/StackedRotateAxisElement>
//osglib
#pragma comment(lib,"OpenThreads_d.lib")
#pragma comment(lib,"osg_d.lib")
#pragma comment(lib,"osgDB_d.lib")
#pragma comment(lib,"osgFX_d.lib")
#pragma comment(lib,"osgGA_d.lib")
#pragma comment(lib,"osgUtil_d.lib")
#pragma comment(lib,"osgViewer_d.lib")
#pragma comment(lib,"osgShadow_d.lib")
#pragma comment(lib,"osgAnimation_d.lib")
osg::ref_ptr<osg::Geode> createBoxAndAxis(const osg::Vec3& trans)
{
osg::ref_ptr<osg::Geode> geode(new osg::Geode());
osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry());
osg::ref_ptr<osg::Vec3Array> vertices(new osg::Vec3Array());
vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(2.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 2.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 2.0));
geometry->setVertexArray(vertices.get());
osg::ref_ptr<osg::Vec4Array> colors(new osg::Vec4Array());
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
colors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
geometry->setColorArray(colors.get(), osg::Array::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 6));
geode->addDrawable(geometry.get());
osg::ref_ptr<osg::Box> pBox = new osg::Box(trans*0.5, trans.length(), 0.2, 0.2);
osg::Quat quat; quat.makeRotate(osg::Vec3(1,0,0), trans);
pBox->setRotation(quat);
geode->addChild(new osg::ShapeDrawable(pBox.get()));
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
return geode;
}
int main(int argc, char* argv[])
{
osg::ArgumentParser arguments(&argc, argv);
osgViewer::Viewer viewer(arguments);
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
osg::ref_ptr<osgAnimation::Skeleton> skelroot = new osgAnimation::Skeleton;
skelroot->setDefaultUpdateCallback();
osg::ref_ptr<osgAnimation::Bone> root = new osgAnimation::Bone;
root->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(-1.0, 0.0, 0.0)));
root->setName("root");
osgAnimation::UpdateBone* pRootUpdate = new osgAnimation::UpdateBone("root");
pRootUpdate->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(-1.0f, 0.0f, 0.0f)));
root->setUpdateCallback(pRootUpdate);
osg::ref_ptr<osgAnimation::Bone> right0 = new osgAnimation::Bone;
right0->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(0.0, 0.0, 0.0)));
right0->setName("right0");
osgAnimation::UpdateBone* pRight0Update = new osgAnimation::UpdateBone("right0");
pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1.0f, 0.0f, 0.0f)));
pRight0Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0.0f, 0.0f, 1.0f), 0.0));
right0->setUpdateCallback(pRight0Update);
osg::ref_ptr<osgAnimation::Bone> right1 = new osgAnimation::Bone;
right1->setInvBindMatrixInSkeletonSpace(osg::Matrix::inverse(osg::Matrix::translate(1.0, 0.0, 0.0)));
right1->setName("right1");
osgAnimation::UpdateBone* pRight1Update = new osgAnimation::UpdateBone("right1");
pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("translate", osg::Vec3(1.0f, 0.0f, 0.0f)));
pRight1Update->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("rotate", osg::Vec3(0.0f, 0.0f, 1.0f), 0.0));
right1->setUpdateCallback(pRight1Update);
root->addChild(right0.get());
right0->addChild(right1.get());
skelroot->addChild(root.get());
// we will use local data from the skeleton
root->addChild(createBoxAndAxis(osg::Vec3(1, 0, 0)));
root->setDataVariance(osg::Object::DYNAMIC);
right0->addChild(createBoxAndAxis(osg::Vec3(1,0,0)));
right0->setDataVariance(osg::Object::DYNAMIC);
right1->addChild(createBoxAndAxis(osg::Vec3(0,1, 0)));
right1->setDataVariance(osg::Object::DYNAMIC);
osg::MatrixTransform* rootTransform = new osg::MatrixTransform;
rootTransform->setMatrix(osg::Matrix::rotate(osg::PI_2, osg::Vec3(1.0f, 0.0f, 0.0f)));
osg::MatrixTransform* trueroot = new osg::MatrixTransform;
trueroot->setMatrix(osg::Matrix(root->getMatrixInBoneSpace().ptr()));
trueroot->addChild(skelroot.get());
trueroot->setDataVariance(osg::Object::DYNAMIC);
rootTransform->addChild(trueroot);
osg::Group* scene = new osg::Group;
scene->addChild(rootTransform);
viewer.setSceneData(scene);
osg::ref_ptr<osgAnimation::BasicAnimationManager> manager = new osgAnimation::BasicAnimationManager;
scene->setUpdateCallback(manager.get());
osgAnimation::Animation* anim = new osgAnimation::Animation;
{
osgAnimation::FloatKeyframeContainer* keys0 = new osgAnimation::FloatKeyframeContainer;
keys0->push_back(osgAnimation::FloatKeyframe(0.0, 0.0f));
keys0->push_back(osgAnimation::FloatKeyframe(3.0, osg::PI_2));
keys0->push_back(osgAnimation::FloatKeyframe(6.0, osg::PI_2));
osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
sampler->setKeyframeContainer(keys0);
osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
channel->setName("rotate");
channel->setTargetName("right0");
anim->addChannel(channel);
}
{
osgAnimation::FloatKeyframeContainer* keys1 = new osgAnimation::FloatKeyframeContainer;
keys1->push_back(osgAnimation::FloatKeyframe(0.0, 0.0f));
keys1->push_back(osgAnimation::FloatKeyframe(3.0, 0.0f));
keys1->push_back(osgAnimation::FloatKeyframe(6.0, osg::PI_2));
osgAnimation::FloatLinearSampler* sampler = new osgAnimation::FloatLinearSampler;
sampler->setKeyframeContainer(keys1);
osgAnimation::FloatLinearChannel* channel = new osgAnimation::FloatLinearChannel(sampler);
channel->setName("rotate");
channel->setTargetName("right1");
anim->addChannel(channel);
}
manager->registerAnimation(anim);
manager->buildTargetReference();
// let's start !
manager->playAnimation(anim);
// let's run !
viewer.realize();
while (!viewer.done())
{
viewer.frame();
}
return 0;
}