osg的四类动画的实现细节及示例:
1.路径运动动画
2.变形动画
3.骨骼动画
4.纹理动画
路径运动动画示例:
// M23.11.W4.osgAnimation.UpdateTransform.cpp : 定义控制台应用程序的入口点。
//
#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>
//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> createAxis()
{
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(10.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 10.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 0.0));
vertices->push_back(osg::Vec3(0.0, 0.0, 10.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());
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::Group* root = new osg::Group;
viewer.setSceneData(root);
osg::ref_ptr<osg::Geode> axe = createAxis();
if (axe) root->addChild(axe.get());
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0.0f, 0.0f, 0.0f), 0.5)));
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform(osg::Matrix::identity());
trans->setName("AnimatedNode");
trans->setDataVariance(osg::Object::DYNAMIC);
trans->addChild(geode.get());
//仅*Tranform节点、Camera节点可设置更新回调(*UpdateCallback)
//链接:osg::Node的回调类型
//https://blog.csdn.net/qq_42531872/article/details/134247411?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170071711716800184179487%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170071711716800184179487&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-3-134247411-null-null.nonecase&utm_term=M23.11-W2&spm=1018.2226.3001.4450
osgAnimation::UpdateMatrixTransform* updatecb = new osgAnimation::UpdateMatrixTransform("AnimatedCallback");
updatecb->getStackedTransforms().push_back(new osgAnimation::StackedTranslateElement("position"));
updatecb->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement("euler", osg::Vec3(1, 1, 0), 0));
trans->setUpdateCallback(updatecb);
root->addChild(trans.get());
//动画管理器
osgAnimation::BasicAnimationManager* mng = new osgAnimation::BasicAnimationManager();
//channel1(动画频道1:负责平移)
osgAnimation::Vec3LinearChannel* channelAnimation1 = new osgAnimation::Vec3LinearChannel;
channelAnimation1->setTargetName("AnimatedCallback");
channelAnimation1->setName("position");
channelAnimation1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(0, osg::Vec3(0, 0, 0)));
channelAnimation1->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::Vec3Keyframe(2, osg::Vec3(10, 10, 0)));
osgAnimation::Animation* anim1 = new osgAnimation::Animation;
anim1->addChannel(channelAnimation1);
anim1->setPlayMode(osgAnimation::Animation::PPONG);
//channel2(负责旋转)
osgAnimation::FloatLinearChannel* channelAnimation2 = new osgAnimation::FloatLinearChannel;
channelAnimation2->setTargetName("AnimatedCallback");
channelAnimation2->setName("euler");
channelAnimation2->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(0, 0));
channelAnimation2->getOrCreateSampler()->getOrCreateKeyframeContainer()->push_back(osgAnimation::FloatKeyframe(3.5, 2 * osg::PI));
osgAnimation::Animation* anim2 = new osgAnimation::Animation;
anim2->addChannel(channelAnimation2);
anim2->setPlayMode(osgAnimation::Animation::LOOP);
// We register all animation inside the scheduler
mng->registerAnimation(anim1);
mng->registerAnimation(anim2);
//start the animation
mng->playAnimation(anim1,0,0.3);
mng->playAnimation(anim2, 0, 0.7);
root->setUpdateCallback(mng);
viewer.run();
return 0;
}
运行效果: