Learning OSG programing---osgAnimation(1)

 1 osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
 2 {
 3     // set up the animation path
 4     osg::AnimationPath* animationPath = new osg::AnimationPath;
 5     animationPath->setLoopMode(osg::AnimationPath::LOOP);
 6 
 7     int numSamples = 40;
 8     float yaw = 0.0f;
 9     float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
10     float roll = osg::inDegrees(30.0f);
11 
12     double time=0.0f;
13     double time_delta = looptime/(double)numSamples;
14     for(int i=0;i<numSamples;++i)
15     {
16         osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
17         osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
18 
19         animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
20 
21         yaw += yaw_delta;
22         time += time_delta;
23 
24     }
25     return animationPath;
26 }

  第一个函数:createAnimationPath,创建仿真路径。接受一个中心点坐标参数,和一个循环时间参数。(猜测后一个参数的作用是确定每次回环持续的秒数。)函数中用到了四元数表达旋转。其构造函数为osg::Quat quat(float radians, const Vec3f& axis),其中radians是旋转弧度, 后面的axis是旋转轴向量。根据其构造函数的含义不难看出,一个四元数表示围绕轴axis旋转radians弧度。其中的旋转分量, x轴是俯仰(pitch), y轴是横滚(roll), z轴是航向角度(yaw)。根据以上知识,不难看出以下这条语句的含义:

osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));

上语句可表达为:先绕y轴旋转roll弧度,再绕z轴旋转逆时针(俯视)(yaw+π/2)弧度。经过这两次旋转,组成rotation变换矩阵。每次循环都更新横滚量yaw和时间。整个循环会使模型旋转一周。

  注意第19行代码向模拟路径中添加控制点,函数原型为:

void osg::AnimationPath::insert( double time,const ControlPoint &controlPoint )     

而ControlPoint具有构造函数:

ControlPoint (const osg::Vec3d &position, const osg::Quat &rotation)

所以第19行代码在向模拟路径中添加元素,控制time时刻模型的位置 position 和姿态 rotation.

  第7行中,变量numSamples决定模型在looptime(即旋转一周)内所细分的次数,其值越大,模拟效果越平滑。

  第10行中,变量roll被设定为30度,并在此后的程序中不会改变,以使飞机模型始终向运动中心侧倾斜30度。

原文地址:https://www.cnblogs.com/SupremeGIS-Developer/p/10666556.html