osg解析系列-[osg::osgAnimation]-路径运动动画/变形动画/骨骼动画/纹理动画

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;
}


运行效果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值