osganimationeasemotion例子

来源:互联网 发布:java字符文件乱码 编辑:程序博客网 时间:2024/05/17 02:02
osgWidget是通过HUD来实现的一个嵌入OSG中的响应界面,和功能更加强大的CEGUI类似。
WindowManager 是osgWidget管理类,继承自Switch,可以识别事件的响应,添加各种窗体,例如button

、label等。WindowManager还可以支持Lua、Python等脚本文件,通过ScriptEngine进行脚本解析。
Event定义事件,EventInterface定义响应事件的接口。
通过StyleManager来定义窗体的样式。

接下来在main中通过osgWidget::Box定义了一个容器,加载了ColorLabelMenu

osgWidget可能是参考Qt进行设计的,设计的方法类似Qt,widget是基类,label等从widget继承,,之

前说过osgWidget是通过HUD加入到OSG场景中的,那么这个HUD在什么地方呢?
找到osgWidget::Util中的createOrthoCamera 很熟悉,创建了一个平行投影的相机,

camera->getOrCreateStateSet()->setMode(
        GL_LIGHTING,
        

osg::StateAttribute::PROTECTED | osg::StateAttribute::OFF
    );

    camera-

>setProjectionMatrix(osg::Matrix::ortho2D(0.0, width, 0.0f, height));
    camera-

>setReferenceFrame(osg::Transform::ABSOLUTE_RF);
    camera->setViewMatrix

(osg::Matrix::identity());
    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
    camera-

>setRenderOrder(osg::Camera::POST_RENDER);

来看看非常熟悉的这几句,这几句代码经常会用到,
创建HUD首先关闭光照,做一个平行投影,设置转换为绝对坐标,这个ABSOLUTE_RF说明了当前的相机节

点是相对于世界坐标的,设置相机矩阵为单位矩阵,清空深度缓存(因为这个HUD是要显示在显示器上,

因此不需要和场景中其他物体进行深度计算,干脆就清空,这样这个相机节点不进行深度测试,完全绘

制),POST_RENDER设置相机最后渲染。

当相机作为一个HUD节点使用的时候,我们就可以理解它是一个可以变换自身的普通节点,与相机的其它

功能区分开。

走的有些远了,来看看Label,继承Widget,可以设置样式、位置、文字等,ColorLabel继承Label
主要为了重新mousePush mouseEnter mouseLeave事件。
ColorLabelMenu继承了ColorLabel添加了更多的ColorLabel,addWidget的几个参数就是加入的窗体,在

table中的位置。ColorLabelMenu中的其它方法设计了简单的交互,显隐等,不多说了。

这里一直涉及到EaseMotionSampler,来看看EaseMotionSampler是什么:
createEaseMotionGeometry函数中根据传进来的Motion绘制了一条曲线。EaseMotionSampler继承了

NodeCallback,重写了operator()函数,在这个函数中对Callback的节点进行了setMatrix操作,也就是

根据motion进行运动,再来看main函数
 geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 4.0f)));

    

EASE_MOTION_SAMPLER = new EaseMotionSampler(osg::Vec3(50.0f, 0.0f, 0.0f));
    

EASE_MOTION_GEODE   = new osg::Geode();

    mt->addChild(geode);
    mt->setUpdateCallback

(EASE_MOTION_SAMPLER);
    mt->setNodeMask(MASK_3D);
这几行代码,把一个球,一条曲线加入到mt中,mt设置了callback,没一帧都调用operator方法更新自

身的位置,实现根据motion进行移动。

接下来
viewer.setCameraManipulator(new osgGA::TrackballManipulator());
    

viewer.getCameraManipulator()->setHomePosition(
        osg::Vec3d(0.0f, 0.0f, 200.0f),
      

  osg::Vec3d(20.0f, 0.0f, 0.0f),
        osg::Vec3d(0.0f, 1.0f, 0.0f)
        );
    

viewer.home();
设置了操作器,设置了操作器的初始位置,设置view的初始位置,执行createExample,createExample

中就是设置了窗体大小位置,根节点加入场景,eventhandler等。
createExample中的代码可以拿出来修改来实现自己的场景。

到目前唯一还有一点没有进行解析,那就是osgAnimation::Motion
来看看他是什么吧,在easeMotion(缓和的移动)类中,EaseMotion中定义了好多的移动方式,

TimeBehaviour执行一次还是循环,
Motion中三个重要的变量float _startValue;
        float _changeValue;
        float _duration;
开始值,改变值,持续时间。

MathMotionTemplate继承了Motion重写了getValueInNormalizedRange,MathMotionTemplate是一个模板

类,通过不同的模板实现不同的效果,看看getValueInNormalizedRange中干了什么,没错,调用了模板

的getValueAt方法,这样不同的模板就产生了不同的效果,而EaseMotion中实现了很多的数学方法。各

种曲线函数,如果想实现自己的算法可以重写getValueAt方法,想参考不同的曲线算法都可以参考

EaseMotion中的实现。
原创粉丝点击