OSG添加自定义用户事件

在使用OSG过程中,需要用户自定义一下鼠标键盘消息,方便用户自己的控制。
用户自定义的事件必须继承osgGA::GUIEventHandler,并且实现虚函数:

virtual bool handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa);

1.定义通用的头文件

#ifndef _COMMON_H_
#define _COMMON_H_

#ifdef _DEBUG

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgTextd.lib")
#pragma comment(lib, "osgWidgetd.lib")
#pragma comment(lib, "osgManipulatord.lib")
#pragma comment(lib, "osgAnimationd.lib")
#pragma comment(lib, "osgEarthd.lib")
#pragma comment(lib, "osgEarthUtild.lib")
#pragma comment(lib, "osgTerraind.lib")
#pragma comment(lib, "osgEarthAnnotationd.lib")
#pragma comment(lib, "osgEarthFeaturesd.lib")
#pragma comment(lib, "osgEarthSymbologyd.lib")
#pragma comment(lib, "osgAnimationd.lib")
#pragma comment(lib, "osgParticled.lib")
#pragma comment(lib, "gdal_i.lib")

#endif

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgDB/ReadFile>
#include <osg/Node>
#include <osg/Switch>
#include <osg/Geode>
#include <osg/LineWidth>
#include <osg/ShapeDrawable>
#include <osg/Shape>
#include <osg/MatrixTransform>

#include <osgGA/EventHandler>
#include <osgGA/GUIEventHandler>
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIActionAdapter>

#endif // !_COMMON_H_

2.定义用户自定义事件类

#pragma once

#include "../Common.h"

class UseEventHandler : public osgGA::GUIEventHandler {
public:
    UseEventHandler();
    ~UseEventHandler();
public:
    virtual bool handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa);
};
#include "UseEventHandler.h"
UseEventHandler::UseEventHandler() {
}

UseEventHandler::~UseEventHandler() {
}

bool UseEventHandler::handle(const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa) {
    osg::ref_ptr<osgViewer::Viewer> viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
    if (!viewer) {
        return false;
    }
    switch (ea.getEventType()) {
    case osgGA::GUIEventAdapter::KEYDOWN:
    if (ea.getKey() == 0xFF51) {
        viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
        viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);
    }
    if (ea.getKey() == 0xFF53) {
        viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);
        viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
    }

    break;
    case osgGA::GUIEventAdapter::PUSH:
    if (ea.getButton() == 4) {
        viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(0);
        viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(0);
    }
    break;
    case osgGA::GUIEventAdapter::DOUBLECLICK:
    if (ea.getButton() == 1) {
        viewer->getSceneData()->asGroup()->getChild(0)->setNodeMask(1);
        viewer->getSceneData()->asGroup()->getChild(1)->setNodeMask(1);
    }
    break;

    default:
    break;
    }
    return false;
}

3.添加事件处理

//创建多节点
osg::ref_ptr<osg::Node> createMulNode() {
    osg::ref_ptr<osg::Group> root = new osg::Group();

    osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("cow.osg");
    osg::ref_ptr<osg::Node> node2 = osgDB::readNodeFile("robot.osg");

    osg::ref_ptr<osg::MatrixTransform> matrix = new osg::MatrixTransform;
    matrix->setMatrix(osg::Matrix::translate(-7, 0, 0));
    matrix->addChild(node2.get());

    osg::ref_ptr<osg::Switch> sw = new osg::Switch();
    sw->addChild(node1, true);

    root->addChild(sw);
    root->addChild(matrix.get());

    return root;
}

int main(int argc, char** argv) {
    for (int i = 0; i < argc; i++) {
        printf(argv[i]);
    }

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
    viewer->addEventHandler(new osgViewer::StatsHandler);

    viewer->addEventHandler(new UseEventHandler);

    viewer->setSceneData(createMulNode());
    viewer->realize();
    viewer->run();

    return 0;
}

4.运行结果

鼠标右键单击时牛和飞机都隐藏,鼠标左键双击时牛和机器人都显示;
按键盘上面的 LEFT 键,显示牛,
按键盘上面的 RIGHT 键显示机器人。

这里写图片描述

5.事件值

代码 事件类型
NONE 0 无事件。
PUSH 1 鼠标某键按下,在上面代码有用到。
RELEASE 2 鼠标某键弹起。
DOUBLECLICK 4 鼠标某键双击。
DRAG 8 鼠标某键拖动。
MOVE 16 鼠标移动。
KEYDOWN 32 键盘上某键按下。
KEYUP 64 键盘上某键弹起。
FRAME 128 应该是鼠标每帧。没用过。
RESIZE 256 窗口大小改变时会有的事件。
SCROLL 512 鼠标轮滚动。
PEN_PRESSURE 1024 手写板的某事件?
PEN_PROXIMITY_ENTER 2048 手写板的某事件?
PEN_PROXIMITY_LEAVE 4096 手写板的某事件?
CLOSE_WINDOWS 8192 关闭窗口。
QUIT_APPLICATION 16384 退出程序。
USER 32768 用户定义。

猜你喜欢

转载自blog.csdn.net/wb175208/article/details/80409238