查看: 1027|回复: 0

【疑问】有关于拖拽器dragger的问题,大神请进

[复制链接]

该用户从未签到

发表于 2015-4-23 11:03:26 | 显示全部楼层 |阅读模式
最近学习【多拖拽器dragger共同操作物体】的时候遇到了一点问题,采用的是示例dragger程序,帖末有贴出。

问题:在点击Ctrl进行拖拽器操作时,后面的场景也跟着动。原理上,鼠标的相应应该传入dragger中进行操作,但同时也进入了场景中,对视口进行了操作。不知道为什么?能只操作dragger么?另外setHandleEvents(true)函数是干嘛用的。。。。如果删除ctrl相应,加入setHandleEvents(true),拖拽器确实也能工作,但是位移之后重新加载心得类型拖拽器,新拖拽器的初始化位置还是在最初的位置。比如我已经把物体通过位移拖拽器移动到了一个别的位置,如果没有按照ctrl相应而用setHandleEvents(true)函数的话,在读取旋转拖拽器,旋转拖拽器的生成位置还是在物体最初读取时的位置。不知道怎么解决。
----------------------------------------------------------------------------------------------------------------------------------------------------------------
1.操作器开函数
void CModelGraggerManager::SetTrackBallDragger()
{
        if(m_nDragger != NULL )
                m_nDraggerMatrix  = m_nDragger->getMatrix();
        SetDraggerEmpty();
        //m_nDragger = new osgManipulator::TrackballDragger();
    m_nDragger = m_nRotateDragger;
        m_nDragger->addTransformUpdating(m_nSelection);
        m_nSelection->getParent(0)->addChild(m_nDragger);
        m_nCmgr->connect( *m_nDragger, *m_nSelection );

        /*float scale =  m_nModelNode->getBound().radius() * 150.0f;
        m_nDragger->setupDefaultGeometry();
        m_nDragger->setMatrix(osg::Matrixd::scale(scale, scale, scale) * m_nMatrixNode->GetModelTranslate());*/
        m_nDragger->setupDefaultGeometry();
        m_nDragger->setMatrix(m_nDraggerMatrix);
        //m_nDragger->setHandleEvents(true); //拖拽器使能

}

------------------------------------------------------------------------------------------------------------------------------------------------------------


2.拖拽器初始化
void CModelGraggerManager::InitDragger( std::string ModelPath)
{
        //(m_nMatrixNode->GetModelMatrix(m_nModelNode))->setDataVariance(osg::Object:YNAMIC);
        //m_nSelection->addChild(m_nMatrixNode->GetModelMatrix(m_nModelNode));

        //***************************************************************

        m_nModelNode   = osgDB::readNodeFile(ModelPath);
        float scale = m_nModelNode->getBound().radius() * 1.6;
        m_nModelNode->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
        m_nSelection->addChild(m_nModelNode);
        //osg::Matrixd mtTemp;
        //osg::ref_ptr<osg::CoordinateSystemNode> m_pCoordinateNode = new osg::CoordinateSystemNode;
        //m_pCoordinateNode->setEllipsoidModel(new osg::EllipsoidModel());
        //通过经纬度及高度计算模型坐标
        //m_pCoordinateNode->getEllipsoidModel()->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(23.8212), osg::DegreesToRadians(113.4163), 360, mtTemp);
        //osg::Matrixf mt = mtTemp;
        m_nSelection->setMatrix( osg::Matrixf::scale(scale*0.05,scale*0.05,scale*0.05) *osg::Matrix::translate(m_nModelNode->getBound().center()));//默认了一个方位 和地球坐标尺寸相关,初始化修改,默认到屏幕中心?
        //****************************************************
   
        m_nDragger =  new osgManipulator::TranslateAxisDragger();//默认三维平移拖拽器
        m_nDragger->setDataVariance(osg::Object::DYNAMIC);
        m_nRoot->addChild( m_nSelection.get() );
        m_nRoot->addChild( m_nDragger );
    m_nCmgr->connect( *m_nDragger, *m_nSelection );

        //m_nDragType = drag_Translate;
        //float scale =  m_nModelNode->getBound().radius() * 150.0f;
        m_nDragger->setupDefaultGeometry();
       
        m_nDraggerMatrix = osg::Matrixd::scale(scale*3, scale*3, scale*3) *osg::Matrix::translate(m_nModelNode->getBound().center()) ;
        osg::Matrixf tempMat = osg::Matrixf::scale(scale*3, scale*1.5, scale*3) * osg::Matrix::translate(m_nModelNode->getBound().center());
        m_nDragger->setMatrix(tempMat);
        //不显示拖拽器
        SetDraggerEmpty();
         
--------------------------------------------------------------------------------------------------------------------------
3.键盘相应事件函数
bool CKeyBoardEventHandler::handle( const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa )
{
        osgViewer::Viewer* viewer =  dynamic_cast<osgViewer::Viewer*>(&aa);

        //当前消息未被处理
        if(!viewer)
                return true;

        switch(ea.getEventType())
        {
        case(osgGA::GUIEventAdapter::KEYDOWN):
                {
                        switch(ea.getKey())
                            {
                               case osgGA::GUIEventAdapter::KEY_B:
                                           {               
                                                           m_modelOp->SetTrackBallDragger();                                                 
                                           }                                          
                                           break;
                                   case osgGA::GUIEventAdapter::KEY_M:
                                           {
                                                    m_modelOp->SetScaleAxisDragger();
                                           }
                                           break;
                                   case osgGA::GUIEventAdapter::KEY_N:
                                           {
                                                   m_modelOp->SetTranslateDragger();
                                           }
                                           break;
                                   case osgGA::GUIEventAdapter::KEY_P:
                                           {
                                                   m_modelOp->SetDraggerEmpty();
                                           }
                                           break;
                                   case osgGA::GUIEventAdapter::KEY_Q:
                                           {
                                                   m_modelOp->MoveModelForDragger(m_modelOp->m_nModelNode,m_modelOp->GetModelMatrixd());
                                                   //m_cMgmr->setModelNode();
                                           }
                                           break;
                                 
                                   default: break;                                            
                            }
                }
                break;

                case osgGA::GUIEventAdapter:USH:
        {
            mX = ea.getX();
            mY = ea.getY();
        }
        break;

    case osgGA::GUIEventAdapter::RELEASE:
        {
            if (ea.getX() == mX && ea.getY() == mY)
            {
                pick(ea, aa);
            }
        }
        break;

   
       
        default:break;
        }
        return false;
}
-------------------------------------------------------------------------------------------------------------------------------------------
4.ctrl事件函数
bool CModeDraggerlHandle::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
        osgViewer::Viewer* viewer =  dynamic_cast<osgViewer::Viewer*>(&aa);

        //当前消息未被处理
        if(!viewer)
                return true;
        switch (ea.getEventType())
        {         
        case(osgGA::GUIEventAdapter::KEYDOWN):
                {
                        if(ea.getKey() ==  osgGA::GUIEventAdapter::KEY_Control_L)
                                isHandle = true;                          
                }
                 break;
        case ( osgGA::GUIEventAdapter::KEYUP):
                {
                        if(ea.getKey() ==  osgGA::GUIEventAdapter::KEY_Control_L)
                        {
                                m_ActiveDragger = NULL;
                                m_Pointer.reset();
                                isHandle = false;
                        }
                               
                }
                break;
        default:break;
        }

        switch (ea.getEventType())
        {         
        case osgGA::GUIEventAdapter::PUSH:
                {
                        //判断是否按下Ctr
                        if(!isHandle)
                                return false;

                        //当前鼠标信息重置
                        m_Pointer.reset();

                        //判断交点
                        osgUtil:ineSegmentIntersector::Intersections mouseHits;

                        //通过鼠标屏幕点进行求交,所求得的数据存放在intersections内部
                        if( viewer->computeIntersections(ea.getX(),  ea.getY(), mouseHits) )
                        {
                                //在_pointer内记录当前的相机信息,其实就是记录了几个投影矩阵
                                m_Pointer.setCamera( viewer->getCamera());
                                //记录当前鼠标位置,屏幕坐标
                                m_Pointer.setMousePosition( ea.getX(), ea.getY() );

                                //将所有相交的对象记录到_pointer内部
                                osgUtil::LineSegmentIntersector::Intersections::iterator hitIter;
                                for( hitIter = mouseHits.begin(); hitIter != mouseHits.end(); ++hitIter )
                                {
                                        m_Pointer.addIntersection( hitIter->nodePath, hitIter->getLocalIntersectPoint() );
                                }

                                //逐个分析是否点中了dragger
                                osg::NodePath::iterator pathIter;
                                for( pathIter=  m_Pointer._hitList.front().first.begin();
                                        pathIter != m_Pointer._hitList.front().first.end(); ++pathIter )
                                {
                                        osgManipulator::Dragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*pathIter);
                                        //判断点中了dragger
                                        if( dragger )
                                        {
                                                //给dragger传入事件,这里我们可以看到,pointer的作用就是记录相关拖拽信息,供dragger使用
                                                dragger->handle( m_Pointer, ea, aa );
                                                m_ActiveDragger = dragger;
                                                //isHandle = true;
                                                break;
                                        }
                                }
                        }
                }
                break;
                case  osgGA::GUIEventAdapter::DRAG :
                        {
                                //按下Ctrl建
                                if(!isHandle)
                                        return false;
                 
                                if( m_ActiveDragger )
                                {
                                        m_Pointer._hitIter = m_Pointer._hitList.begin();
                                        m_Pointer.setCamera( viewer->getCamera() );
                                        m_Pointer.setMousePosition( ea.getX(),  ea.getY());
                                        m_ActiveDragger->handle( m_Pointer, ea, aa );
                                }
                        }
                        break;
                case  osgGA::GUIEventAdapter::RELEASE :
                        {                                 
                                if( m_ActiveDragger )
                                {
                                        m_Pointer._hitIter = m_Pointer._hitList.begin();
                                        m_Pointer.setCamera( viewer->getCamera() );
                                        m_Pointer.setMousePosition( ea.getX(),  ea.getY());
                                        m_ActiveDragger->handle( m_Pointer, ea, aa );
                                }
                                m_ActiveDragger = NULL;
                                m_Pointer.reset();
                        }        
                 
                break;
                default:break;
        }


       
        return  false;
}


:'( :'(
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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