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度。