查看: 2251|回复: 21

为场景添加Draager,在点选的时候报错

[复制链接]

该用户从未签到

发表于 2009-10-21 10:25:04 | 显示全部楼层 |阅读模式
本帖最后由 lvzhihan 于 2009-10-21 10:27 编辑

我参照了osgmanipulator这个例子,调用函数addDraggerToScene为载入的场景添加了dragger。之后可以看到Dragger,盒式的和坐标轴的。但是当点击的时候就会报错。事件代码和出错位置如下:
                case osgGA::GUIEventAdapter:USH:
                {
                    osgUtil:ineSegmentIntersector::Intersections intersections;
                    _pointer.reset();
                    if (view->computeIntersections(ea.getX(),ea.getY(),intersections))
                    {
                        _pointer.setCamera(view->getCamera());
                        _pointer.setMousePosition(ea.getX(), ea.getY());
                        for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
                            hitr != intersections.end();
                            ++hitr)
                        {
                            _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                        }
                        for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin();
                             itr != _pointer._hitList.front().first.end();
                             ++itr)
                        {
                            osgManipulator:ragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);
                            if (dragger)
                            {
                                dragger->handle(_pointer, ea, aa);//此处报错
                                _activeDragger = dragger;
                                break;
                            }                  
                        }
                    }
                }

f11跟踪进去后
bool CompositeDragger::handle(const PointerInfo& pi, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
    // Check if the dragger node is in the nodepath.
    if (!pi.contains(this))
        return false;
    for (DraggerList::iterator itr=_draggerList.begin(); itr!=_draggerList.end(); ++itr)
    {
        if ((*itr)->handle(pi, ea, aa))//此处出错
            return true;
    }
    return false;
}
再次f11
        case (osgGA::GUIEventAdapter::PUSH):
            {
                // Get the LocalToWorld matrix for this node and set it for the projector.
                osg::NodePath nodePathToRoot;
                computeNodePathToRoot(*this,nodePathToRoot);
                osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot);
                _projector->setLocalToWorld(localToWorld);
                if (_projector->project(pointer, _startProjectedPoint))
                {
                    // Generate the motion command.
                    osg::ref_ptr<TranslateInLineCommand> cmd = new TranslateInLineCommand(_projector->getLineStart(),
                                                                                          _projector->getLineEnd());
                    cmd->setStage(MotionCommand::START);
                    cmd->setLocalToWorldAndWorldToLocal(_projector->getLocalToWorld(),_projector->getWorldToLocal());
                    // Dispatch command.
                    if (_commandManager)
                    {
                        _commandManager->addSelectionsToCommand(*cmd, *getParentDragger());//此处出错
                        _commandManager->dispatch(*cmd);
                    }
                    // Set color to pick color.
                    setMaterialColor(_pickColor,*this);
                    aa.requestRedraw();
                }
                return true;
            }
            
        // Pick move.

再次f11,CommandManager.cpp
    if (_draggerConstraintMap.count(&dragger) > 0)//此处出
    {
        // Get all the selections assoicated with this dragger.
        std::pair<DraggerConstraintMap::iterator,DraggerConstraintMap::iterator> s;
        s = _draggerConstraintMap.equal_range(&dragger);
        for (DraggerConstraintMap::iterator iter = s.first; iter != s.second; ++iter)
        {
            // Add the selection to the command.
            if (iter->second.valid())
            {
                command.applyConstraint(iter->second.get());
            }
        }
    }
再次f11,xtree
size_type count(const key_type& _Keyval) const
  { // count all elements that match _Keyval
  _Paircc _Ans = equal_range(_Keyval);//此处出错
  size_type _Num = 0;
  _Distance(_Ans.first, _Ans.second, _Num);
  return (_Num);
  }

CommandManager初始化如下:
WebVRManipulator* webvrmanipulator=new WebVRManipulator();

  osg::ref_ptr<osgManipulator::CommandManager> cmdMgr = new osgManipulator::CommandManager;
   
  m_Viewer->setSceneData(webvrmanipulator->addDraggerToScene(m_Root.get(), cmdMgr.get(), "TranslateAxisDragger"));

WebVRManipulator类如下:
class WebVRManipulator
{
public:
osgManipulator::Dragger* createDragger(const std::string& name);
osg::Node* addDraggerToScene(osg::Node* scene, osgManipulator::CommandManager* cmdMgr, const std::string& name);
};

该用户从未签到

发表于 2009-10-21 10:32:57 | 显示全部楼层
代码没有具体看,,似乎你得设置数据setDataVariance为DYNIMIC~~~~

该用户从未签到

 楼主| 发表于 2009-10-21 10:34:21 | 显示全部楼层
需要在什么位置设置?
    m_Viewer->addEventHandler(new PickModeHandler());
在这句的后面行不行?

该用户从未签到

 楼主| 发表于 2009-10-21 10:34:42 | 显示全部楼层
m_Viewer->setDataVariance(osg::Object:YNAMIC);
这样写吗?

该用户从未签到

发表于 2009-10-21 10:37:36 | 显示全部楼层
Set the data variance of this object.

Can be set to either STATIC for values that do not change over the lifetime of the object, or DYNAMIC for values that vary over the lifetime of the object. The DataVariance value can be used by routines such as optimization codes that wish to share static data. UNSPECIFIED is used to specify that the DataVariance hasn't been set yet.

请多看看文档~~~·针对数据的,,root->setDataVariance()~~~~~~

该用户从未签到

 楼主| 发表于 2009-10-21 10:43:38 | 显示全部楼层
m_Root = new osg::Group ;
        m_Root->setDataVariance(osg::Object:YNAMIC);

在这个位置设置后仍然点击报错。

该用户从未签到

发表于 2009-10-21 10:48:00 | 显示全部楼层
貌似你做的是WEB开发~~~你的太乱了,没法给你具体分析~~~~你可以跟踪一下数据试试~~~~~

该用户从未签到

 楼主| 发表于 2009-10-21 16:16:35 | 显示全部楼层
本帖最后由 lvzhihan 于 2009-10-21 16:17 编辑

for (osg::NodePath::iterator itr = _pointer._hitList.front().first.begin();
     itr != _pointer._hitList.front().first.end();
     ++itr)
    {
osgManipulator:ragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);

          if (dragger)
     {
      dragger->handle(_pointer, ea, aa);//此处出错
      _activeDragger = dragger;
      break;
     }                  
    }

在经过:
osgManipulator::Dragger* dragger = dynamic_cast<osgManipulator::Dragger*>(*itr);
这一步转换后,dragger中有一个结构体为:
_commandManager = 0x031e2b68 {_draggerSelectionMap=[18351985](...) _draggerConstraintMap=[19039](...) }
其中的属性均有问题。
而在osg自带的例子中,这一步转换后的Dragger就没有问题。

该用户从未签到

发表于 2009-10-21 20:13:05 | 显示全部楼层
本帖最后由 小行星 于 2009-10-21 20:20 编辑

我这里有同样的错误,一模一样,跟DataVariance没关系,这段代码相当乱,但不是LZ的,而是官方示例和osgManipulator下的几个文件……我的环境是MFC,总会有这不爽那不爽,过去是堆内存被破坏,现在又是这个……正在查找原因中……

该用户从未签到

 楼主| 发表于 2009-10-21 20:27:10 | 显示全部楼层
9# 小行星

有同我遇到一样问题的我就放心了。
我用的是ATL,没链接MFC库。
难道是窗口的原因?

该用户从未签到

 楼主| 发表于 2009-10-21 20:30:59 | 显示全部楼层
我直接在osgmanipulator上加参数调用模型就正常,但是在我的程序里面调用同一个模型就出问题了。

该用户从未签到

发表于 2009-10-21 20:42:18 | 显示全部楼层
是的,甚至在官方的mfc示例基础上修改也不行。

我这里的代码调试情况,文件CommandManager.cpp,86行,函数addSelectionsToCommand的第一句中,成员变量_draggerConstraintMap的数据是错误的,我暂时把问题归结为dll中标准容器的……一些毛病,抱歉,这一块暂时是我的弱项,我不知道该如何描述,等我有了更详细的结论我会发上来的。

该用户从未签到

发表于 2009-10-21 20:46:18 | 显示全部楼层
可惜我没有遇到过这个问题,我在编写新书的时候也重写了osgManipulator的代码。也许您倒是可以考虑先把MFC的依赖去掉看看

该用户从未签到

 楼主| 发表于 2009-10-21 21:08:41 | 显示全部楼层
13# array
阿Ray能否把代码在这里部分公开?

该用户从未签到

发表于 2009-10-21 22:24:40 | 显示全部楼层
新书发布之后,会随之发布代码资源网站,到时候这些源代码都有公开

该用户从未签到

 楼主| 发表于 2009-10-21 22:44:29 | 显示全部楼层
16# array

赶快出版啊,等不及了。新版本的osg都快出来了。

该用户从未签到

发表于 2009-10-22 23:26:03 | 显示全部楼层
本帖最后由 harolf 于 2009-10-22 23:50 编辑

我也曾遇到过类似的错误,但具体是怎样已经忘了,现在把早期的代码(可以正常运行)贴出来给您参考一下,希望有所帮助,注:我用的qt,里面还有一些代码牵扯到其它模块,不过可以很容易剔除,里面的itemDragger派生自osgManipulator::CompositeDragger。

class SimHandler : public QObject, public osgGA::GUIEventHandler
{
        Q_OBJECT

protected:
        osgManipulator:ragger* createDragger()
        {
                osgManipulator::Dragger* dragger =  new ItemDragger();
                dragger->setupDefaultGeometry();               

                return dragger;
        }

        osg::Node* addDraggerToScene(osgManipulator::Selection* selection)
        {
                osgManipulator::Dragger* dragger = createDragger();

                osg::Group* root = new osg::Group;
                root->addChild(dragger);
                root->addChild(selection);        

                float scale = selection->getBound().radius() * 1.6;
                dragger->setMatrix(osg::Matrix::scale(scale, scale, scale) *
                        osg::Matrix::translate(selection->getBound().center()));
                SceneEngine::instance()->commandManager()->connect(*dragger, *selection);        

                return root;
        }

public:
        SimHandler() : m_mx(0), m_my(0), _activeDragger(0), m_draggerWrap(0), m_object(0)
        {

        }
        ~SimHandler()
        {

        }

        //事件处理函数
        bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
        {
                if (m_object)
                        return draggerHandle(ea, aa);
                else
                        return pickHandle(ea, aa);               
        }

        //拾取处理
        bool pickHandle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
        {
                osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
                if (!view)
                        return false;
               

                switch(ea.getEventType())
                {
                case(osgGA::GUIEventAdapter:USH):
                        {
                                if(ea.getButtonMask() == osgGA::GUIEventAdapter:EFT_MOUSE_BUTTON)
                                {                                       

                                        SceneEngine::instance()->pick(ea, aa);        

                                        m_object = SceneEngine::instance()->selected();
                                        if (m_object)
                                        {        
                                                emit selectObject(m_object);

                                                if (!m_draggerWrap)
                                                {
                                                        m_draggerWrap = addDraggerToScene(m_object);

                                                        m_parent = m_object->getParent(0);
                                                        m_parent->replaceChild(m_object, m_draggerWrap);
                                                }
                                                
                                                return true;
                                        }
                                }
                                break;
                        }        
                }
                return false;
               
               
        }        // end of bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
        
        //拖拽处理
        bool draggerHandle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
        {
                osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
                if (!view) return false;               
        

                bool result = false;

                switch (ea.getEventType())
                {
                case osgGA::GUIEventAdapter::PUSH:
                        {
                                if(ea.getButtonMask() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
                                {
                                        osgUtil::LineSegmentIntersector::Intersections intersections;

                                        _pointer.reset();

                                        if (view->computeIntersections(ea.getX(),ea.getY(),intersections))
                                        {
                                                _pointer.setCamera(view->getCamera());
                                                _pointer.setMousePosition(ea.getX(), ea.getY());

                                                for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();
                                                        hitr != intersections.end();
                                                        ++hitr)
                                                {
                                                        _pointer.addIntersection(hitr->nodePath, hitr->getLocalIntersectPoint());
                                                }
                                                for (osg::NodePath::iterator 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;
                                                                result = true;
                                                                break;
                                                        }                                                   
                                                }                                                                        
                                        }               

                                        if (!result)
                                        {
                                                m_parent->replaceChild(m_draggerWrap, m_object);
                                                m_object->setSelectedMark(false);
                                                m_object = 0;
                                                m_draggerWrap = 0;
                                                SceneEngine::instance()->clearSelected();
                                                result = true;
                                                break;
                                        }
                                }
                                
                        }
                case osgGA::GUIEventAdapter::DRAG:                        
                case osgGA::GUIEventAdapter::RELEASE:
                        {                                
                                if (_activeDragger)
                                {
                                        _pointer._hitIter = _pointer._hitList.begin();
                                        _pointer.setCamera(view->getCamera());
                                        _pointer.setMousePosition(ea.getX(), ea.getY());

                                        emit transformObject(m_object);
                                        _activeDragger->handle(_pointer, ea, aa);

                                        result = true;
                                }
                                break;                                                               
                        }
                default:
                        break;
                }

                if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
                {
                        _activeDragger = 0;
                        _pointer.reset();
                }

                return result;
        }
private:
        osgManipulator::Dragger* _activeDragger;
        osgManipulator::PointerInfo _pointer;
        float m_mx;
        float m_my;
        SceneItem *m_object;
        osg::Node *m_draggerWrap;        
        osgManipulator::PointerInfo *m_pointer;
        osg::Group *m_parent;
signals:
        //!当拾取到对象时发送
        void selectObject(SceneItem *object);

        //! 对象变换时发送
        void transformObject(SceneItem *object);
};


#endif        //SIMHANGLER_H

该用户从未签到

 楼主| 发表于 2009-10-27 09:23:25 | 显示全部楼层
同Simbaforrest交流后得到答案,commandManager应声明为类成员,而不应仅在初始化的时候创建。

该用户从未签到

 楼主| 发表于 2009-10-27 09:37:25 | 显示全部楼层
谢谢18楼的方案。

该用户从未签到

发表于 2009-10-27 13:16:27 | 显示全部楼层
感谢harolf和lvzhihan,我已经陷在这个“为什么Win32行而MFC不行”中而忽略了问题的本质了,无论怎样,先能用就好~谢谢,我这里的问题按照上面的方法也正常了

该用户从未签到

发表于 2010-5-20 10:24:53 | 显示全部楼层
pf...我也遇到了同样的问题,谢谢楼上各位。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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