osg示例程序解析2---osganimationeasemotion_inoutexpomotion-程序员宅基地

技术标签: osg示例程序解析  

本文参考文章http://blog.csdn.net/yungis/article/details/8463077

#include <osg/Geode>
#include <osg/MatrixTransform>
#include <osg/ShapeDrawable>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgAnimation/EaseMotion>
#include <osgWidget/WindowManager>
#include <osgWidget/Box>
#include <osgWidget/Table>
#include <osgWidget/Label>
#include <iostream>

class EaseMotionSampler;

const unsigned int WINDOW_WIDTH  = 800;
const unsigned int WINDOW_HEIGHT = 600;
const unsigned int MASK_2D       = 0xF0000000;
const unsigned int MASK_3D       = 0x0F000000;
const float        M_START       = 0.0f;
const float        M_DURATION    = 2.0f;
const float        M_CHANGE      = 1.0f;

EaseMotionSampler* EASE_MOTION_SAMPLER = 0;
osg::Geode*        EASE_MOTION_GEODE   = 0;


//根据传进来的Motion绘制了一条曲线----绘制的为物体的运动路程
osg::Geometry* createEaseMotionGeometry(osgAnimation::Motion* motion) {
    osg::Geometry*  geom = new osg::Geometry();
    osg::Vec4Array* cols = new osg::Vec4Array();
    osg::Vec3Array* v    = new osg::Vec3Array();
 int j=0;
    for(float i = 0.0f; i < M_DURATION; i += M_DURATION / 256.0f)
 {
  j++;
  std::cout<<(motion->getValueAt(i))<<" ";
  if (j%10==0)
  {
   std::cout<<std::endl;
  }
  
  v->push_back(osg::Vec3(i * 30.0f, motion->getValueAt(i) * 30.0f, 0.0f));
 }

    cols->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));

    geom->setUseDisplayList(false);
    geom->setVertexArray(v);
    geom->setColorArray(cols);
    geom->setColorBinding(osg::Geometry::BIND_OVERALL);
    geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, v->size()));

    return geom;
}


//EaseMotionSampler继承了NodeCallback,重写了operator()函数,在这个函数中对Callback的节点进行了setMatrix操作,也就是根据motion进行运动
class EaseMotionSampler: public osg::NodeCallback
{
public:
    float     _previous;
    osg::Vec3 _pos;

    osg::ref_ptr<osgAnimation::Motion> _motion;

    EaseMotionSampler(const osg::Vec3& pos):
        _previous (0.0f),
        _pos      (pos) {
    }

    void operator()(osg::Node* node, osg::NodeVisitor* nv) {
        if(!_motion.valid()) return;

        osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>(node);

        if(!mt) return;

        double t = nv->getFrameStamp()->getSimulationTime();

  //这避免了应用开始但是动画不能用的故障
        if(_previous == 0.0f) _previous = t;

        _motion->update(t - _previous);

        _previous = t;

        mt->setMatrix(osg::Matrix::translate(_pos * _motion->getValue()));
    }
 //osgAnimation::Motion来看看他是什么吧,在easeMotion(缓和的移动)类中,EaseMotion中定义了好多的移动方式,TimeBehaviour执行一次还是循环,Motion中三个重要的变量:开始值,改变值,持续时间。
 float _startValue;
 float _changeValue;
 float _duration;
 

 //MathMotionTemplate继承了Motion重写了getValueInNormalizedRange,MathMotionTemplate是一个模板类,通过不同的模板实现不同的效果,看看getValueInNormalizedRange中干了什么,没错,调用了模板
    //的getValueAt方法,这样不同的模板就产生了不同的效果,而EaseMotion中实现了很多的数学方法。各
    //种曲线函数,如果想实现自己的算法可以重写getValueAt方法,想参考不同的曲线算法都可以参考EaseMotion中的实现。
    template<typename T>
    void setMotion() {
        _motion = new T(M_START, M_DURATION, M_CHANGE, osgAnimation::Motion::LOOP);

        EASE_MOTION_GEODE->removeDrawables(0, EASE_MOTION_GEODE->getNumDrawables());
        EASE_MOTION_GEODE->addDrawable(createEaseMotionGeometry(_motion.get()));
    }
};


//鼠标操作的一系列响应
struct ColorLabel: public osgWidget::Label {
    ColorLabel(const char* label):
        osgWidget::Label(label, "") {
        setFont("fonts/VeraMono.ttf");
        setFontSize(14);
        setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
  
        setColor(0.3f, 0.3f, 0.3f, 1.0f);
        setPadding(2.0f);
        setCanFill(true);
  
        addSize(150.0f, 25.0f);

        setLabel(label);
        setEventMask(osgWidget::EVENT_MOUSE_PUSH | osgWidget::EVENT_MASK_MOUSE_MOVE);
    }

    bool mousePush(double, double, const osgWidget::WindowManager*) {
        osgWidget::Table* p = dynamic_cast<osgWidget::Table*>(_parent);
 
        if(!p) return false;
  
        p->hide();

        const std::string& name = getName();

        if(!name.compare("OutQuadMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutQuadMotion>()
                ;

        else if(!name.compare("InQuadMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InQuadMotion>()
                ;

        else if(!name.compare("InOutQuadMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutQuadMotion>()
                ;

        else if(!name.compare("OutCubicMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutCubicMotion>()
                ;

        else if(!name.compare("InCubicMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InCubicMotion>()
                ;

        else if(!name.compare("InOutCubicMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutCubicMotion>()
                ;

        else if(!name.compare("OutQuartMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutQuartMotion>()
                ;

        else if(!name.compare("InQuartMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InQuartMotion>()
                ;

        else if(!name.compare("InOutQuartMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutQuartMotion>()
                ;

        else if(!name.compare("OutBounceMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutBounceMotion>()
                ;

        else if(!name.compare("InBounceMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InBounceMotion>()
                ;

        else if(!name.compare("InOutBounceMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutBounceMotion>()
                ;

        else if(!name.compare("OutElasticMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutElasticMotion>()
                ;

        else if(!name.compare("InElasticMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InElasticMotion>()
                ;

        else if(!name.compare("InOutElasticMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutElasticMotion>()
                ;

        else if(!name.compare("OutSineMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutSineMotion>()
                ;

        else if(!name.compare("InSineMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InSineMotion>()
                ;

        else if(!name.compare("InOutSineMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutSineMotion>()
                ;

        else if(!name.compare("OutBackMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutBackMotion>()
                ;

        else if(!name.compare("InBackMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InBackMotion>()
                ;

        else if(!name.compare("InOutBackMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutBackMotion>()
                ;

        else if(!name.compare("OutCircMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutCircMotion>()
                ;

        else if(!name.compare("InCircMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InCircMotion>()
                ;

        else if(!name.compare("InOutCircMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutCircMotion>()
                ;

        else if(!name.compare("OutExpoMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::OutExpoMotion>()
                ;

        else if(!name.compare("InExpoMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InExpoMotion>()
                ;

        else if(!name.compare("InOutExpoMotion"))
            EASE_MOTION_SAMPLER->setMotion<osgAnimation::InOutExpoMotion>()
                ;
  
        else EASE_MOTION_SAMPLER->setMotion<osgAnimation::LinearMotion>();

        return true;
    }

    bool mouseEnter(double, double, const osgWidget::WindowManager*) {
        setColor(0.9f, 0.6f, 0.1f, 1.0f);
  
        return true;
    }

    bool mouseLeave(double, double, const osgWidget::WindowManager*) {
        setColor(0.3f, 0.3f, 0.3f, 1.0f);
  
        return true;
    }
};

//添加响应组件,ColorLabelMenu设计了简单的交互,显隐
class ColorLabelMenu: public ColorLabel {
    osg::ref_ptr<osgWidget::Table> _window;

public:
    ColorLabelMenu(const char* label):
        ColorLabel(label) {
        _window = new osgWidget::Table(std::string("Menu_") + label, 6, 5);

        _window->addWidget(new ColorLabel("OutQuadMotion"), 0, 0);
        _window->addWidget(new ColorLabel("InQuadMotion"), 1, 0);
        _window->addWidget(new ColorLabel("InOutQuadMotion"), 2, 0);
        _window->addWidget(new ColorLabel("OutCubicMotion"), 3, 0);
        _window->addWidget(new ColorLabel("InCubicMotion"), 4, 0);
        _window->addWidget(new ColorLabel("InOutCubicMotion"), 5, 0);

        _window->addWidget(new ColorLabel("OutQuartMotion"), 0, 1);
        _window->addWidget(new ColorLabel("InQuartMotion"), 1, 1);
        _window->addWidget(new ColorLabel("InOutQuartMotion"), 2, 1);
        _window->addWidget(new ColorLabel("OutBounceMotion"), 3, 1);
        _window->addWidget(new ColorLabel("InBounceMotion"), 4, 1);
        _window->addWidget(new ColorLabel("InOutBounceMotion"), 5, 1);

        _window->addWidget(new ColorLabel("OutElasticMotion"), 0, 2);
        _window->addWidget(new ColorLabel("InElasticMotion"), 1, 2);
        _window->addWidget(new ColorLabel("InOutElasticMotion"), 2, 2);
        _window->addWidget(new ColorLabel("OutSineMotion"), 3, 2);
        _window->addWidget(new ColorLabel("InSineMotion"), 4, 2);
        _window->addWidget(new ColorLabel("InOutSineMotion"), 5, 2);

        _window->addWidget(new ColorLabel("OutBackMotion"), 0, 3);
        _window->addWidget(new ColorLabel("InBackMotion"), 1, 3);
        _window->addWidget(new ColorLabel("InOutBackMotion"), 2, 3);
        _window->addWidget(new ColorLabel("OutCircMotion"), 3, 3);
        _window->addWidget(new ColorLabel("InCircMotion"), 4, 3);
        _window->addWidget(new ColorLabel("InOutCircMotion"), 5, 3);
  
        _window->addWidget(new ColorLabel("OutExpoMotion"), 0, 4);
        _window->addWidget(new ColorLabel("InExpoMotion"), 1, 4);
        _window->addWidget(new ColorLabel("InOutExpoMotion"), 2, 4);
        _window->addWidget(new ColorLabel("Linear"), 3, 4);

        _window->resize();
    }

    void managed(osgWidget::WindowManager* wm) {
        osgWidget::Label::managed(wm);

        wm->addChild(_window.get());

        _window->hide();
    }

    void positioned() {
        osgWidget::Label::positioned();

        _window->setOrigin(_parent->getX(), _parent->getY() +  _parent->getHeight());
    }

    bool mousePush(double, double, const osgWidget::WindowManager*) {
        if(!_window->isVisible()) _window->show();

        else _window->hide();

        return true;
    }
};

int main(int argc, char** argv) {
    osgViewer::Viewer viewer;

 //osgWidget是通过HUD来实现的一个嵌入OSG中的响应界面
 //WindowManager 是osgWidget管理类,继承自Switch,可以识别事件的响应,添加各种窗体
 //WindowManager还可以支持Lua、Python等脚本文件,通过ScriptEngine进行脚本解析。Event定义事件,EventInterface定义响应事件的接口。通过StyleManager来定义窗体的样式。
    osgWidget::WindowManager* wm = new osgWidget::WindowManager(
        &viewer,
        WINDOW_WIDTH,
        WINDOW_HEIGHT,
        MASK_2D
        );

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

 //创建窗口菜单,水平对齐
    osgWidget::Window* menu = new osgWidget::Box("menu", osgWidget::Box::HORIZONTAL);
    menu->addWidget(new ColorLabelMenu("Choose EaseMotion"));
    menu->getBackground()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
    menu->setPosition(15.0f, 15.0f, 0.0f);

    wm->addChild(menu);

    osg::Group*           group = new osg::Group();
    osg::Geode*           geode = new osg::Geode();
    osg::MatrixTransform* mt    = new osg::MatrixTransform();


 //这几行代码,把一个球,一条曲线加入到mt中,mt设置了callback,每一帧都调用operator方法更新自身的位置,实现根据motion进行移动。
    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);

 

    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();

    group->addChild(mt);
    group->addChild(EASE_MOTION_GEODE);

    return osgWidget::createExample(viewer, wm, group);
}

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/J1101460678/article/details/50503826

智能推荐

matplotlib画饼状图时,数据重叠避免方法_python matplotlib 绘制的饼状图,有的数据很小全部挤在一起影响效果图-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏10次。项目开发的报表展示模块,需要展示具体的数据库中的内容。遇到一个问题,就是画饼状图的时候,存在数据堆叠的情况。废话少说,首先看个例子:但是我想要的是这种情况:于是我就找方法,找到了一种方法是生成html文件格式的情况:参考https://blog.csdn.net/qq_42467563/article/details/82812340这种方法是使用pyecharts。所..._python matplotlib 绘制的饼状图,有的数据很小全部挤在一起影响效果图

再谈Thunderbird(雷鸟)的地址簿与Microsoft 活动目录(AD)关联_thunderbird 添加ldap通讯录-程序员宅基地

文章浏览阅读606次。最近将工作用的操作系统换成了深度Linux,邮件使用Thunderbird(雷鸟),但是公司的内部地址簿是在Microsoft 活动目录(AD)中保存和维护的,这样就涉及到如何将Microsoft 活动目录(AD)和Thunderbird(雷鸟)地址簿关联的问题,网上有很多的文章介绍,但是对于“基准标示名”和“使用用户名和密码登录”没有说的很清楚,在此补充下。1、首先在主页面的上方打开“通讯录”2、点击“编辑”,选择“首选项”菜单3、选择“目录服务器”旁的“编辑目录”按钮4、在弹_thunderbird 添加ldap通讯录

UE4不使用屏幕后处理实现人物外轮廓描边效果_ue4 不是后处理的描边方案-程序员宅基地

文章浏览阅读3.3k次,点赞4次,收藏30次。UE4不使用屏幕后处理实现人物外轮廓描边效果项目涉及卡通渲染风格,需要人物描边效果,之前在网上有大量的通过post process volume来实现的描边效果,但是问题在于屏幕后处理无法控制只对特定对象生效。post process volume的机制是:通过框调整作用范围,当相机进入范围内显示后处理效果(这种效果还是全屏的,只是进入范围内才生效)因此放弃后处理,改为在人物材质上直接描边。..._ue4 不是后处理的描边方案

uni开发手写板功能 弹框 完整代码 舒适应用!!!_uniapp手写板-程序员宅基地

文章浏览阅读519次。成品展示如上图所示首先在项目的componts文件夹里引入cc-signature.vue```javascript<template> <view v-if="canvasVisiable"> <view class="canvas-container"> <canvas canvas-id="canvas" id="canvas" :disable-scroll="true" style="width: 100%; height: 200p._uniapp手写板

Apache Tomcat 8.0.9下载、安装、配置和部署(不是最新版本)_tomcat8.0.9安装-程序员宅基地

文章浏览阅读8.1k次。Apache Tomcat 8.0.8下载、安装、配置和部署_tomcat8.0.9安装

10大最受欢迎的国外业务流程管理(BPM)软件_bpm业务流程管理软件-程序员宅基地

文章浏览阅读1w次。最好的BPM软件是最重要的大型业务解决方案,因为业务竞争力取决于流程管理。业务流程管理(BPM)是使组织的工作流程更加高效,有效并适应业务环境变化的系统化过程。业务流程是为达到特定组织目的和价值目标而由不同的人分别共同完成的一系列活动。活动之间不仅有严格的先后顺序限定,而且活动的内容、方式、责任等也都必须有明确的安排和界定,以使不同活动在不同岗位角色之间进行转手交接成为可能。活动与活动之间在时间和..._bpm业务流程管理软件

随便推点

必备工具:使用Pentaho进行数据迁移_pentaho已有的任务如何备份-程序员宅基地

文章浏览阅读532次,点赞2次,收藏3次。pentaho下载地址:https://sourceforge.net/projects/pentaho/files/Data%20Integration/pentaho解压缩,win下点击Spoon.bat就可以启动了。新建数据库连接,有了数据库连接就可以在多个数据源之间进行数据迁移了,注意这里把数据库连接设置为共享的(右击数据库连接设置共享即可),否则每次都提示选择配置数据库连接。新建oracle数据库连接:新建mysql数据库连接一样,注意驱动包,如果提示找不到驱动类:org.gjt.mm._pentaho已有的任务如何备份

希望陈坚们能活下去_陈坚 电力电子-程序员宅基地

文章浏览阅读116次。陈坚这个名字,可以被google到。而下面的话,在新浪搜狐等多处看到,不管是不是真的。我不是专家,不过我相信对垂死之人而言,生理盐水绝对是无害的。  希望尽快组织大量生理盐水到救援现场! 女孩被救出10分钟去世,是可以避免的. 肢体被挤压超过24小时后开始出现肌肉坏死.一旦移开重压,坏死肌肉会释放大量的肌红素,蛋白,钾等电解质.迅速引起心肾衰竭而死.这就是很多被救人员在被挤压中还能说话,而..._陈坚 电力电子

即插即用 | 5行代码实现NAM注意力机制让ResNet、MobileNet轻松涨点(超越CBAM)-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏54次。点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达识别不显著特征是模型压缩的关键。然而,这一点在注意力机制中却没有得到研究。在这项工作中提出了一种新的基于规范化的注意力模块(NAM),它抑制了较少显著性的权值。它对注意力模块应用一个权重稀疏惩罚,因此,在保持类似性能的同时,使它们更有效地计算。通过与ResNet和MobileNet上其他三种注意力机制的..._nam注意力机制

uniapp添加顶部导航栏颜色渐变_uniapp navigationbarbackgroundcolor 颜色渐变-程序员宅基地

文章浏览阅读1.5w次,点赞2次,收藏12次。在uniapp文件夹的pages.json文件中添加如下代码即可实现"backgroundImage":"linear-gradient(to right, #FFDE28,#FF3228)"{ "path": "pages/mySuccessOrder/mySuccessOrder", "style": { "navigationBarTitleText": "支付", "app-plus": { "titleNView": { _uniapp navigationbarbackgroundcolor 颜色渐变

数据存储之SQLCipher数据库解密访问踩坑:net.sqlcipher.database.SQLiteException: file is not a databaseAndroid-程序员宅基地

文章浏览阅读5.1k次。Android解密db文件失败_net.sqlcipher.database.sqliteexception: file is not a database: , while comp

SNORT3规则编写_snort规则编写-程序员宅基地

文章浏览阅读8.6k次,点赞6次,收藏12次。Snort3 IPS规则编写1.规则基础Snort规则被分为两个逻辑部分,规则头和规则选项。规则头包含规则的操作、协议、源和目标IP地址,以及源和目标端口信息。规则选项部分包含警报消息和应该检查数据包的哪些部分的信息,以确定是否应该采取规则操作。规则举例:注:第一个括号之前的文本是规则标题,括号中包含的部分包含规则选项。规则选项部分中冒号前的单词称为选项关键字。选项部分关键字可选。2.规则头规则头包含规则的操作、协议、源和目标IP地址和网掩码,以及源和.._snort规则编写

推荐文章

热门文章

相关标签