zoukankan      html  css  js  c++  java
  • osgAnimation例子的注释的注释

    osgAnimation例子的注释的注释

    转自:http://www.cnblogs.com/sunliming/archive/2011/12/12/2284995.html

      1 #include <osg/Notify>
      2 #include <osg/MatrixTransform>
      3 #include <osg/PositionAttitudeTransform>
      4 #include <osg/Geometry>
      5 #include <osg/Geode>
      6 
      7 #include <osgUtil/Optimizer>
      8 
      9 #include <osgDB/Registry>
     10 #include <osgDB/ReadFile>
     11 
     12 #include <osgGA/TrackballManipulator>
     13 #include <osgGA/FlightManipulator>
     14 #include <osgGA/DriveManipulator>
     15 
     16 #include <osgSim/OverlayNode>
     17 
     18 #include <osgViewer/Viewer>
     19 #include <iostream>
     20 
     21 // 创建动画路径,参数有中心点,半径,以及循环时间
     22 osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
     23 {
     24     // 实例化动画路径类
     25     // set up the animation path
     26     osg::AnimationPath* animationPath = new osg::AnimationPath;
     27     // 设置动画路径的播放模式,当前使用循环模式(SWING LOOP NO_LOOPING )SWING就是在一个区间内顺逆方向循环,LOOP是顺一个方向循环
     28     animationPath->setLoopMode(osg::AnimationPath::LOOP);
     29    
     30 
     31     // 分40个阶段 这个意思就是分为四十个控制点,犹如四十条边的多边形,沿着这个路线飞行
     32     int numSamples = 40;
     33     float yaw = 0.0f;
     34     // 偏航的分量,这是一个角度分量,算出来每一个多边形的边对应的角度分量2*PI/(n-1)
     35     float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
     36     // 旋转角度为30度
     37     float roll = osg::inDegrees(30.0f);
     38    
     39     // 时间分量
     40     double time=0.0f;
     41     //平均的两个控制点之间的时间
     42     double time_delta = looptime/(double)numSamples;
     43     // 将时间控制点与位置坐标插入到动画路径中
     44     for(int i=0;i<numSamples;++i)
     45     {
     46         //这儿是计算出来每个多边形的顶点的坐标,(sinx*r,cosx*r,0.0)是相当于中心点的增量
     47         osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
     48         //四元数表示方向,表示在3D空间中的旋转方向**四元数很复杂**这个表示,绕x轴旋转roll,y轴旋转-(yaw+90),z轴0
     49         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)));
     50        
     51         //和flash动画类似,控制点有位置和转动角度,这样控制点之间是均匀运动
     52         animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
     53 
     54         //递增yaw和time
     55         yaw += yaw_delta;
     56         time += time_delta;
     57 
     58     }
     59     return animationPath;   
     60 }
     61 
     62 
     63 // 创建底板,中心点位置在center,半径为radius
     64 osg::Node* createBase(const osg::Vec3& center,float radius)
     65 {
     66 
     67     // 一个10x10的底板
     68     int numTilesX = 10;
     69     int numTilesY = 10;
     70    
     71     // 长度与宽度的尺寸
     72     float width = 2*radius;
     73     float height = 2*radius;
     74    
     75     // 计算初始位置与x、y的分量
     76     osg::Vec3 v000(center - osg::Vec3(width*0.5f,height*0.5f,0.0f));
     77     osg::Vec3 dx(osg::Vec3(width/((float)numTilesX),0.0,0.0f));
     78     osg::Vec3 dy(osg::Vec3(0.0f,height/((float)numTilesY),0.0f));
     79    
     80     // 计算每个小格子的顶点坐标并压入数组中
     81     // fill in vertices for grid, note numTilesX+1 * numTilesY+1...
     82     osg::Vec3Array* coords = new osg::Vec3Array;
     83     int iy;
     84     for(iy=0;iy<=numTilesY;++iy)
     85     {
     86         for(int ix=0;ix<=numTilesX;++ix)
     87         {
     88             coords->push_back(v000+dx*(float)ix+dy*(float)iy);
     89         }
     90     }
     91    
     92     // 设置颜色的数组,当前为黑白色两种颜色
     93     //Just two colours - black and white.
     94     osg::Vec4Array* colors = new osg::Vec4Array;
     95     colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // white
     96     colors->push_back(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black
     97     int numColors=colors->size();
     98    
     99     // 设置绘制四边形的顶点索引与每个四边形的颜色
    100     int numIndicesPerRow=numTilesX+1;
    101     osg::UByteArray* coordIndices = new osg::UByteArray; // assumes we are using less than 256 points...
    102     osg::UByteArray* colorIndices = new osg::UByteArray;
    103     for(iy=0;iy<numTilesY;++iy)
    104     {
    105         for(int ix=0;ix<numTilesX;++ix)
    106         {
    107             // four vertices per quad.
    108             coordIndices->push_back(ix    +(iy+1)*numIndicesPerRow);
    109             coordIndices->push_back(ix    +iy*numIndicesPerRow);
    110             coordIndices->push_back((ix+1)+iy*numIndicesPerRow);
    111             coordIndices->push_back((ix+1)+(iy+1)*numIndicesPerRow);
    112            
    113             // one color per quad
    114             colorIndices->push_back((ix+iy)%numColors);
    115         }
    116     }
    117    
    118 
    119     // 设置法线向量
    120     // set up a single normal
    121     osg::Vec3Array* normals = new osg::Vec3Array;
    122     normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
    123    
    124 
    125     // 设置顶点坐标数组
    126     osg::Geometry* geom = new osg::Geometry;
    127     geom->setVertexArray(coords);
    128     geom->setVertexIndices(coordIndices);
    129    
    130     // 设置颜色数组
    131     geom->setColorArray(colors);
    132     geom->setColorIndices(colorIndices);
    133     geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);
    134    
    135     // 设置法线数组
    136     geom->setNormalArray(normals);
    137     geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
    138    
    139     // 需要绘制什么形状的图形,当前为四边形
    140     geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,coordIndices->size()));
    141    
    142     // 将绘制的的图形添加到osg::Geode中
    143     osg::Geode* geode = new osg::Geode;
    144     geode->addDrawable(geom);
    145    
    146     return geode;
    147 }
    148 
    149 // 创建移动的模型,中心点在center,半径为radius
    150 osg::Node* createMovingModel(const osg::Vec3& center, float radius)
    151 {
    152     float animationLength = 10.0f;
    153 
    154     // 创建动画路径,中心点在center,半径为radius,循环时间为10.0f
    155     osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
    156 
    157     osg::Group* model = new osg::Group;
    158 
    159     // 从外部读取一个模型glider.osg作为飞行的模型
    160     osg::Node* glider = osgDB::readNodeFile("glider.osg");
    161     if (glider)
    162     {
    163         // 根据模型的包围球来计算矩阵
    164         // 平移到原点,缩放模型,然后沿z轴旋转-90度
    165         const osg::BoundingSphere& bs = glider->getBound();
    166 
    167         float size = radius/bs.radius()*0.3f;
    168         osg::MatrixTransform* positioned = new osg::MatrixTransform;
    169         //设置这个值在对象生命周期内为静态的不可改变的数值,或者动态的在对象生命周期内变化的值
    170         positioned->setDataVariance(osg::Object::STATIC);
    171         //设置转移矩阵参数
    172         positioned->setMatrix(osg::Matrix::translate(-bs.center())*         /*表示平移物体,注意osg的坐标系是z轴是向上的*/
    173                                      osg::Matrix::scale(size,size,size)*    /*x,y,z轴的放缩比例*/
    174                                      osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));   /*x,y,z轴的旋转角度*/
    175    
    176         positioned->addChild(glider);
    177    
    178         // 设置动画路径的回调函数,使在渲染循环中不停的沿动画路径移动,设置坐标系变换
    179         osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
    180         xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
    181         xform->addChild(positioned);
    182 
    183         model->addChild(xform);
    184     }
    185 
    186     // 从外部读取一个模型cessna.osg
    187     // 操作同上,设置动画路径的回调函数,使在渲染的循环中不停的沿动画路径移动
    188     osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
    189     if (cessna)
    190     {
    191         const osg::BoundingSphere& bs = cessna->getBound();
    192 
    193         float size = radius/bs.radius()*0.3f;
    194         osg::MatrixTransform* positioned = new osg::MatrixTransform;
    195         positioned->setDataVariance(osg::Object::STATIC);
    196         positioned->setMatrix(osg::Matrix::translate(-bs.center())*
    197                                      osg::Matrix::scale(size,size,size)*
    198                                      osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
    199    
    200         positioned->addChild(cessna);
    201    
    202         osg::MatrixTransform* xform = new osg::MatrixTransform;
    203         xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
    204         xform->addChild(positioned);
    205 
    206         model->addChild(xform);
    207     }
    208    
    209     return model;
    210 }
    211 
    212 // 创建覆盖图,根据覆盖的实现技术来设置
    213 osg::Node* createModel(bool overlay, osgSim::OverlayNode::OverlayTechnique technique)
    214 {
    215     osg::Vec3 center(0.0f,0.0f,0.0f);
    216     float radius = 100.0f;
    217 
    218     osg::Group* root = new osg::Group;
    219 
    220     // 创建底板与飞行的模型
    221     float baseHeight = center.z()-radius*0.5;
    222     osg::Node* baseModel = createBase(osg::Vec3(center.x(), center.y(), baseHeight),radius);
    223     osg::Node* movingModel = createMovingModel(center,radius*0.8f);
    224 
    225     // 是否设置覆盖图
    226     if (overlay)
    227     {
    228         // 根据命令行传入的参数来设置
    229         osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
    230         overlayNode->setContinuousUpdate(true);
    231         // 需要设置的覆盖的图的模型为飞行的模型,当前为从外部加载的模型
    232         overlayNode->setOverlaySubgraph(movingModel);
    233         // 设置覆盖图距离底板的高度
    234         overlayNode->setOverlayBaseHeight(baseHeight-0.01);
    235         overlayNode->addChild(baseModel);
    236         // 将覆盖图的节点加入到根节点中
    237         root->addChild(overlayNode);
    238     }
    239     else
    240     {
    241         // 不设置覆盖图
    242         root->addChild(baseModel);
    243     }
    244    
    245     root->addChild(movingModel);
    246 
    247     return root;
    248 }
    249 
    250 
    251 int main( int argc, char **argv )
    252 {
    253     // 是否使用覆盖模拟
    254     bool overlay = false;
    255     // 使用命令行参数实例化osg::ArgumentParset类,方便以后的操作
    256     osg::ArgumentParser arguments(&argc,argv);
    257     while (arguments.read("--overlay")) overlay = true;
    258    
    259     // 获得覆盖节点采用哪种技术实现,提供三种实现技术
    260     osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    261     while (arguments.read("--object")) { technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
    262     while (arguments.read("--ortho") || arguments.read("--orthographic")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; overlay=true; }
    263     while (arguments.read("--persp") || arguments.read("--perspective")) { technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY; overlay=true; }
    264    
    265 
    266     // initialize the viewer.
    267     osgViewer::Viewer viewer;
    268 
    269     // 创建底板与飞行的物体,飞行物体通过外部读取
    270     // load the nodes from the commandline arguments.
    271     osg::Node* model = createModel(overlay, technique);
    272     if (!model)
    273     {
    274         return 1;
    275     }
    276    
    277     // 创建一个osg::MatrixTransform并设置场景沿x轴旋转30度
    278     // tilt the scene so the default eye position is looking down on the model.
    279     osg::MatrixTransform* rootnode = new osg::MatrixTransform;
    280     rootnode->setMatrix(osg::Matrix::rotate(osg::inDegrees(30.0f),1.0f,0.0f,0.0f));
    281     rootnode->addChild(model);
    282 
    283     /// 对整个场景进行优化
    284     // run optimization over the scene graph
    285     osgUtil::Optimizer optimzer;
    286     optimzer.optimize(rootnode);
    287     
    288     // 将整个节点设置到场景中进行渲染
    289     // set the scene to render
    290     viewer.setSceneData(rootnode);
    291 
    292     // 设置相机的操作器,当前使用跟踪球的模式进行操作
    293     viewer.setCameraManipulator(new osgGA::TrackballManipulator());
    294 
    295     // viewer.setUpViewOnSingleScreen(1);
    296 
    297     // 提供两中渲染的循环模式
    298     // 第一中采用老式的模式
    299     // 第二中采用封装模式
    300 #if 0
    301 
    302     // use of custom simulation time.
    303    
    304     viewer.realize();
    305    
    306     double simulationTime = 0.0;
    307    
    308     while (!viewer.done())
    309     {
    310         viewer.frame(simulationTime);
    311         simulationTime += 0.001;
    312     }
    313    
    314     return 0;
    315 #else
    316 
    317     // normal viewer usage.
    318     return viewer.run();
    319 
    320 #endif
    321 }
    View Code
  • 相关阅读:
    ERROR Function not available to this responsibility.Change responsibilities or contact your System Administrator.
    After Upgrade To Release 12.1.3 Users Receive "Function Not Available To This Responsibility" Error While Selecting Sub Menus Under Diagnostics (Doc ID 1200743.1)
    产品设计中先熟练使用铅笔 不要依赖Axure
    12.1.2: How to Modify and Enable The Configurable Home Page Delivered Via 12.1.2 (Doc ID 1061482.1)
    Reverting back to the R12.1.1 and R12.1.3 Homepage Layout
    常见Linux版本
    网口扫盲二:Mac与Phy组成原理的简单分析
    VMware 8安装苹果操作系统Mac OS X 10.7 Lion正式版
    VMware8安装MacOS 10.8
    回顾苹果操作系统Mac OS的发展历史
  • 原文地址:https://www.cnblogs.com/flylong0204/p/4616242.html
Copyright © 2011-2022 走看看