查看: 1932|回复: 5

【新手求助】『已结』点选物体后使用拖拽器,结点绑定后物体未移动。

[复制链接]

该用户从未签到

发表于 2012-8-22 11:02:15 | 显示全部楼层 |阅读模式
本帖最后由 starmessage 于 2012-9-6 15:39 编辑

主要功能是点选了物体后(包括多选),不仅仅出现类似3DMax的标识框,还出现拖拽器(用switch结点进行显示和不显示),以TranslateAxisDragger为例,但是当移动拖拽器后,物体重复添加

我的做法是每次点选的物体都放入m_gMultiNode中,计算后的标识框放入m_gMultiBox中,osgManipulator::Selection *selection=new osgManipulator::Selection;
selection->addChild(m_gMultiBox);
selection->addChild(m_gMultiNode);
dragger放入switch结点中,后放入场景结点。
manager->connect(*dragger,*selection);

但是拖动拖拽器后,物体和标识框都没有跟着移动,如何解决?看到array大侠以前发的一个例子osg editer,里面是删除结点再添加的好像,是对单结点的操作,我的包含多选,该如何操作啊,不知道怎么改了。谁帮我改改啊。
11.jpg
部分代码如下:
void CPickHandle::CreateDragger(osgManipulator:ragger* _dragger)//此函数有问题。在于selection不能及时更新,若添加到root内,则又重复的可能。
void CPickHandle::CreateDragger(osgManipulator::Dragger* _dragger)
{
        dragger=_dragger;
        osgManipulator::Selection *selection=new osgManipulator::Selection;
        selection->addChild(m_gMultiNode);//就这里的问题
        selection->addChild(m_gMultiBox);
        selection->setNodeMask(0x2);
        m_fScale=m_gMultiNode->getBound().radius()*0.6;
        m_camera->setClearMask(GL_DEPTH_BUFFER_BIT);
        m_camera->setRenderOrder(osg::Camera:OST_RENDER);
        dragger->setupDefaultGeometry();
        dragger->setNodeMask(0x2);
        osg::StateSet *stateset=dragger->getOrCreateStateSet();
        stateset->setMode(GL_DEPTH_RANGE,osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
        dragger->setMatrix(osg::Matrix::scale(m_fScale,m_fScale,m_fScale)*
                osg::Matrix::translate(m_gMultiNode->getBound().center()));
        m_camera->addChild(dragger);
        osgManipulator::CommandManager *manager=new osgManipulator::CommandManager;
        m_camera->setNodeMask(0x2);
        m_sDragger->addChild(dragger,false);
        m_sDragger->setNodeMask(0x2);
        manager->connect(*dragger,*selection);
}

osg::Switch* CPickHandle::getSwitchDragger(void)
{
        return m_sDragger;
}

bool CPickHandle::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
        viewer=dynamic_cast<osgViewer::Viewer*>(&aa);
        if ( ea.getEventType()==osgGA::GUIEventAdapter::PUSH && ea.getButton()==osgGA::GUIEventAdapter:EFT_MOUSE_BUTTON)
        {
                if (viewer && ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL){
                        pickHandle(ea,aa);//加入点选组结点,加入标识框组结点,没问题。}
                if(viewer && ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT)
                {
                        osgUtil::LineSegmentIntersector::Intersections hits;
                        _pointer.reset();               
                        osgUtil::LineSegmentIntersector *intersector =new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
                        osgUtil::IntersectionVisitor iv(intersector);
                        viewer->getCamera()->accept( iv );
                        if(viewer->computeIntersections(ea.getX(),ea.getY(),hits))
                        {
                                _pointer.setCamera(viewer->getCamera());
                                _pointer.setMousePosition(ea.getX(),ea.getY());
                                osgUtil::LineSegmentIntersector::Intersections::iterator hitr;
                                for(hitr=hits.begin();hitr!=hits.end();++hitr)
                                {
                                        _pointer.addIntersection(hitr->nodePath,hitr->getLocalIntersectPoint());
                                }
                                osg::NodePath::iterator itr;
                                for(itr=_pointer._hitList.front().first.begin();
                                        itr!=_pointer._hitList.front().first.end();
                                        ++itr)
                                {
                                        osgManipulator::Dragger* _dragger=
                                                dynamic_cast<osgManipulator::Dragger*>(*itr);
                                        if(_dragger)
                                        {
                                                _dragger->handle(_pointer,ea,aa);
                                                activedragger=_dragger;
                                                break;
                                        }
                                }
                        }
                }
        }
        if( ea.getEventType()==osgGA::GUIEventAdapter::DRAG || ea.getEventType()==osgGA::GUIEventAdapter::RELEASE)
        {
                if(viewer && ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT)
                {
                        if(activedragger)
                        {
                                _pointer._hitIter=_pointer._hitList.begin();
                                _pointer.setCamera(viewer->getCamera());
                                _pointer.setMousePosition(ea.getX(),ea.getY());
                                activedragger->handle(_pointer,ea,aa);}
                        }
                        if(ea.getEventType()==osgGA::GUIEventAdapter::RELEASE)
                        {
                                activedragger=NULL;
                                _pointer.reset();
                        }
                        return true;
                }
        }
        if(ea.getEventType()==osgGA::GUIEventAdapter::PUSH &&
                ea.getButton()==osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON &&
                !(ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT) &&
                !(ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL)){
                cancelSelection();m_sDragger->setAllChildrenOff();}
        return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
        osg::ref_ptr<osg::Node> model1 = osgDB::readNodeFile( "..\\..\\3ds\\BoA.3ds" );
    osg::ref_ptr<osg::Group> root = new osg::Group;
        osgViewer::Viewer viewer;
        osg::ref_ptr<CPickHandle> picker = new CPickHandle();
    root->addChild( model1.get() );
        root->addChild(picker->getMultiBox());
        root->addChild(picker->getSwitchDragger());
        viewer.setSceneData(root.get());
        viewer.addEventHandler(picker.get());
    return viewer.run();
}

该用户从未签到

发表于 2012-8-22 11:58:10 | 显示全部楼层
selection  没有加到场景中 当然没有效果

该用户从未签到

 楼主| 发表于 2012-8-22 17:58:10 | 显示全部楼层
我也发现了,必须加入,一开始以为用个结点挂接上就可以了,但是加入场景的话,就会出现物体重复,看到以前array大哥的例子,是要删除此结点的。问题就来了:
第一:array获取的是每个结点的父节点,在对其删除,但是这样,当场景组结点多时,点选物体的结点就会丧失掉父节点的信息,这样还需要再有一个容器来保存父节点的信息,感觉很冗余,很没必要,不知道有没有简单的解决办法。
第二:暂且删除结点来做,但是这样子,为什么我把点选的结点组m_gMultiNode加入到selection中时,发现结点的位置全变了,为啥啊。

该用户从未签到

发表于 2012-8-23 07:55:29 | 显示全部楼层
看看3.0以上的osgManipulator,操作很方便

该用户从未签到

 楼主| 发表于 2012-9-1 14:19:22 | 显示全部楼层
可以结贴了,只是还有些细节问题,不过整体上是知道怎么回事,怎么搞了。谢谢了。

该用户从未签到

发表于 2013-1-23 15:43:40 | 显示全部楼层
starmessage 发表于 2012-9-1 14:19
可以结贴了,只是还有些细节问题,不过整体上是知道怎么回事,怎么搞了。谢谢了。

你好,我也遇到的同样的需求,拾取物体后动态的添加拖拽器,能不能把你的源代码共享一下?还有array大侠以前发的一个例子osg editer能否也分享下,smengq@163.com,搞了好久了没啥进展,能否体谅下,非常感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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