查看: 2400|回复: 10

Manipulator or Mouse Event?

[复制链接]

该用户从未签到

发表于 2009-3-31 21:43:39 | 显示全部楼层 |阅读模式
在什么情况下需要重写一个manipulator
什么情况下只需要写鼠标键盘事件就好了?
有谁有这样的经历么?

该用户从未签到

发表于 2009-3-31 21:46:40 | 显示全部楼层
看您的需求,如果需要交互控制场景摄像机,那么最好重写MatrixManipulator,一般的用户交互操作只要使用GUIEventHandler就可以了

该用户从未签到

 楼主| 发表于 2009-3-31 22:10:00 | 显示全部楼层
你好,王锐!
我需要有多点输入,类似iphone的效果。

该用户从未签到

发表于 2009-3-31 22:41:48 | 显示全部楼层
我并不知道iphone是什么效果,不过多点输入对于osg的GUIEventHandler来说应该不是什么问题,它内部使用一个事件收集器来收集窗口系统的事件,并允许用户在handle函数中对其进行响应

该用户从未签到

 楼主| 发表于 2009-4-1 00:00:47 | 显示全部楼层
哦,好的,我试试看!

该用户从未签到

 楼主| 发表于 2009-4-1 01:40:02 | 显示全部楼层
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This application is open source and may be redistributed and/or modified   
* freely and without restriction, both in commericial and non commericial applications,
* as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>
#include <osg/MatrixTransform>

#include <osg/Switch>
#include <osgText/Text>

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

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>

class IpodlikeEventHandler : public osgGA::GUIEventHandler
{
public:
        IpodlikeEventHandler(osg::Group* root)
        {
                _root = root;
        }
        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
        {
                switch(ea.getEventType())
                {
                case(osgGA::GUIEventAdapter:RAG):
                        {
                                rotate(ea.getXnormalized(), ea.getYnormalized());
                                break;
                        }
                case(osgGA::GUIEventAdapter::MOVE):
                        {
                                _prevX = ea.getXnormalized();
                                _prevY = ea.getYnormalized();
                                break;
                        }
                default:
                        break;
                }
                return false;
        }
        void registerModelGroupTransform(osg::MatrixTransform* modelGroupTransform)
        {
                _modelGroupTransform = modelGroupTransform;
                _rotCenter = modelGroupTransform->getBound().center();
        }
private:
  void rotate(float x, float y)
  {
    osg::Matrix baseMatrix = _modelGroupTransform->getMatrix();
   
    baseMatrix.preMultTranslate(_rotCenter);
    baseMatrix.preMultRotate(osg:uat((x - _prevX) * 3, osg::Vec3d(0.0, 0.0, 1.0)));
    baseMatrix.preMultRotate(osg::Quat(-(y - _prevY) * 3, (baseMatrix * osg::Vec3d(1.0, 0.0, 0.0))));
    baseMatrix.preMultTranslate(-_rotCenter);
   
    _modelGroupTransform->setMatrix(baseMatrix);

    _prevX = x;
    _prevY = y;
  };

  osg::Group* _root;
  
  float _prevX;
  float _prevY;
  
  osg::Vec3 _rotCenter;
  osg::MatrixTransform* _modelGroupTransform;
};

int main(int argc, char** argv)
{
    osg::ref_ptr<osg::Node> loadedModel;
   
    // load the scene.
    if (argc>1) loadedModel = osgDB::readNodeFile(argv[1]);
   
    // if not loaded assume no arguments passed in, try use default mode instead.
    if (!loadedModel) loadedModel = osgDB::readNodeFile("dumptruck.osg");
   
    if (!loadedModel)
    {
        std::cout << argv[0] <<": No data loaded." << std::endl;
        return 1;
    }
   
    // create the window to draw to.
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->x = 200;
    traits->y = 200;
    traits->width = 800;
    traits->height = 600;
    traits->windowDecoration = true;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
    osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
    if (!gw)
    {
        osg::notify(osg::NOTICE)<<"Error: unable to create graphics window."<<std::endl;
        return 1;
    }

    // create the view of the scene.
    osgViewer::Viewer viewer;
    viewer.getCamera()->setGraphicsContext(gc.get());
    viewer.getCamera()->setViewport(0,0,800,600);
    viewer.setSceneData(loadedModel.get());
   
    // create a tracball manipulator to move the camera around in response to keyboard/mouse events
    //viewer.setCameraManipulator( new osgGA::TrackballManipulator );

    osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator(viewer.getCamera()->getStateSet());
    viewer.addEventHandler(statesetManipulator.get());

        osg::MatrixTransform* modelGroupTransform = new osg::MatrixTransform;
        osg::Group* modelGroup = new osg::Group;
        modelGroupTransform->addChild(modelGroup);
        modelGroup->addChild(loadedModel.get());
        IpodlikeEventHandler* mouseEventHandler = new IpodlikeEventHandler(modelGroup);
        mouseEventHandler->registerModelGroupTransform(modelGroupTransform);
        viewer.addEventHandler(mouseEventHandler);


    viewer.realize();
    osg::Matrix homePosition;
    homePosition.makeLookAt(osg::Vec3(0.0f,0.0f,0.0f),osg::Vec3(0.0f,1.0f,0.0f),osg::Vec3(0.0f,0.0f,1.0f));
    while(!viewer.done())
    {
        viewer.getCamera()->setViewMatrix(homePosition);
        viewer.frame();
    }

    return 0;
}


为什么这样就什么也显示不了了呢?

该用户从未签到

发表于 2009-4-1 09:11:10 | 显示全部楼层
要注意viewer.getCamera()->setViewMatrix(homePosition)所表达的摄像机位置能否显示出物体;
此外您的IpodlikeEventHandler是否用addEventHandler加入到viewer中了?

该用户从未签到

 楼主| 发表于 2009-4-1 16:37:56 | 显示全部楼层
viewer.addEventHandler(mouseEventHandler);
已经加了。
  //viewer.setCameraManipulator( new osgGA::TrackballManipulator );
如果我不注释的话,是可以看见物体的。
默认的模型位置应该在什么地方呢?

该用户从未签到

 楼主| 发表于 2009-4-1 16:39:24 | 显示全部楼层
现在的效果是,整个屏幕都是全黑的

该用户从未签到

发表于 2009-4-1 19:14:43 | 显示全部楼层
默认的模型位置在世界原点,而默认的摄像机位置也在世界原点。因此您的视野可能被模型的内部面给遮挡住了,看起来仿佛全都是黑的一样

该用户从未签到

 楼主| 发表于 2009-4-1 22:50:13 | 显示全部楼层
是的,已经修改好了。谢谢!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表