查看: 3319|回复: 8

geode 拾取时崩溃 [Triangle Functor does not support Vec3d* vertex arrays]

[复制链接]

该用户从未签到

发表于 2010-7-12 09:22:08 | 显示全部楼层 |阅读模式
本帖最后由 gaoqian506 于 2010-7-12 10:09 编辑

如题,请问我该如何解决呢?是我设定的问题,还是osg目前不支持自定义网格的拾取呢?我用的是2.8.2版本。

该用户从未签到

发表于 2010-7-12 09:44:57 | 显示全部楼层
您需要提供更多的信息,此外您的TriangleFunctor是否没有被正确使用,您定义自己的结构体并重写函数operator()了吗?

该用户从未签到

 楼主| 发表于 2010-7-12 10:08:21 | 显示全部楼层
本帖最后由 gaoqian506 于 2010-7-12 10:12 编辑

//以下是拾取代码
osg::ref_ptr<osgUtil:ineSegmentIntersector> picker = CreateLsIntersector(lParam);
osgUtil::IntersectionVisitor iv(picker);
m_viewer.getCameraWithFocus()->accept(iv);  // 就在调用这个函数的时候出现错误

当拾取对象是从osg模型文件导入的节点时不会产生错误,而拾取自定义的osg::Geode节点是就会出现以下错误:
Triangle Functor does not support Vec3d* vertex arrays
Tz3Dv1.0.exe 中的 0x0685784a 处最可能的异常: 0xC0000005: 读取位置 0x0000000c 时发生访问冲突在 System.AccessViolationException

中第一次偶然出现的“System.Windows.Forms.dll”类型的异常未处理的“System.AccessViolationException”类型的异常出现在

System.Windows.Forms.dll 中。
其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。


我是将osg渲染窗口以ActiveX的形式嵌入到C#窗体中的。


经查找,在文件:
..\OpenSceneGraph-2.8.2\include\osg\TemplatePrimitiveFunctor中有这样的函数:
template<class T>

class TemplatePrimitiveFunctor : public PrimitiveFunctor, public T
   
{
public:
    ...
    virtual void setVertexArray(unsigned int,const Vec3d*)
    {
        notify(WARN)<<"Triangle Functor does not support Vec3d* vertex arrays"<<std::endl;
    }
    ....
};

该用户从未签到

发表于 2010-7-12 10:50:17 | 显示全部楼层
而拾取自定义的osg::Geode节点是就会出现以下错误
您恰恰没有把这个重要的信息给出来,这样没有办法帮助您进行排查

该用户从未签到

 楼主| 发表于 2010-7-12 10:56:48 | 显示全部楼层
4# array

谢谢Array,我再检查下我的代码。

该用户从未签到

 楼主| 发表于 2010-7-12 11:44:46 | 显示全部楼层
以下是发生错误是的调用堆栈

>        osg55-osgUtild.dll!osg::Vec3f:perator==(const osg::Vec3f & v={...})  行50 + 0x1a 字节        C++
        osg55-osgUtild.dll!LineSegmentIntersectorUtils::TriangleIntersector::operator()(const osg::Vec3f & v1={...}, const osg::Vec3f &

v2={...}, const osg::Vec3f & v3={...}, bool treatVertexDataAsTemporary=false)  行93 + 0xc 字节        C++
        osg55-osgUtild.dll!osg::TriangleFunctor<LineSegmentIntersectorUtils::TriangleIntersector>::drawElements(unsigned int

mode=0x00000008, int count=0x00000200, const unsigned int * indices=0x06f2bb28)  行327        C++
        osg55-osgd.dll!osg:rawElementsUInt::accept(osg:rimitiveFunctor & functor={...})  行251 + 0x40 字节        C++
        osg55-osgd.dll!osg::Geometry::accept(osg::PrimitiveFunctor & functor={...})  行2241 + 0x2e 字节        C++
        osg55-osgUtild.dll!osgUtil:ineSegmentIntersector::intersect(osgUtil::IntersectionVisitor & iv={...}, osg::Drawable *

drawable=0x06f35d80)  行357 + 0x16 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::intersect(osg::Drawable * drawable=0x06f35d80)  行245 + 0x44 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::apply(osg::Geode & geode={...})  行237        C++
        osg55-osgd.dll!osg::Geode::accept(osg::NodeVisitor & nv={...})  行39 + 0x41 字节        C++
        osg55-osgd.dll!osg::Group::traverse(osg::NodeVisitor & nv={...})  行62 + 0x25 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::traverse(osg::Node & node={...})  行191 + 0x1c 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::apply(osg::Transform & transform={...})  行400 + 0xf 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::apply(osg::MatrixTransform & node={...})  行136 + 0x13 字节        C++
        osg55-osgd.dll!osg::MatrixTransform::accept(osg::NodeVisitor & nv={...})  行37 + 0x41 字节        C++
        osg55-osgd.dll!osg::Group::traverse(osg::NodeVisitor & nv={...})  行62 + 0x25 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::traverse(osg::Node & node={...})  行191 + 0x1c 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::apply(osg::Transform & transform={...})  行400 + 0xf 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::apply(osg::MatrixTransform & node={...})  行136 + 0x13 字节        C++
        osg55-osgd.dll!osg::MatrixTransform::accept(osg::NodeVisitor & nv={...})  行37 + 0x41 字节        C++
        osg55-osgd.dll!osg::Group::traverse(osg::NodeVisitor & nv={...})  行62 + 0x25 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::traverse(osg::Node & node={...})  行191 + 0x1c 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::apply(osg::Transform & transform={...})  行400 + 0xf 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::apply(osg::MatrixTransform & node={...})  行136 + 0x13 字节        C++
        osg55-osgd.dll!osg::MatrixTransform::accept(osg::NodeVisitor & nv={...})  行37 + 0x41 字节        C++
        osg55-osgd.dll!osg::Group::traverse(osg::NodeVisitor & nv={...})  行62 + 0x25 字节        C++
        osg55-osgd.dll!osg::NodeVisitor::traverse(osg::Node & node={...})  行191 + 0x1c 字节        C++
        osg55-osgUtild.dll!osgUtil::IntersectionVisitor::apply(osg::Camera & camera={...})  行476 + 0xf 字节        C++
        osg55-osgd.dll!osg::Camera::accept(osg::NodeVisitor & nv={...})  行46 + 0x41 字节        C++
        TzScene.dll!CScene::PickModel(long lParam=0x011401cd, NodeAttributeMask mask=NodeAttAll, SceneObjectType *

objtype=0x0012e4b8)  行1193 + 0x3a 字节        C++
        TzScene.dll!CScene::OnLButtonDown(unsigned int wParam=0x00000001, long lParam=0x011401cd)  行1239 + 0x15 字节       

C++
        TE_ActiveX.dll!CSceneControl::OnLButtonDown(unsigned int __formal=0x00000201, unsigned int wParam=0x00000001, long

lParam=0x011401cd, unsigned int __formal=0x00000201)  行108 + 0x35 字节        C++
        TE_ActiveX.dll!CSceneControl::ProcessWindowMessage(HWND__ * hWnd=0x0004114c, unsigned int uMsg=0x00000201,

unsigned int wParam=0x00000001, long lParam=0x011401cd, long & lResult=0xcccccccc, unsigned long dwMsgMapID=0x00000000)  行

159 + 0x2e 字节        C++
        TE_ActiveX.dll!ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<1442840576,0> >::WindowProc(HWND__ *

hWnd=0x05615b54, unsigned int uMsg=0x00000201, unsigned int wParam=0x00000001, long lParam=0x011401cd)  行3073 + 0x27 字

节        C++


出错时的语句为:
    inline bool operator == (const Vec3f& v) const { return _v[0]==v._v[0] && _v[1]==v._v[1] && _v[2]==v._v[2]; }
此时:this 与 v._v 都为空指针

从上面可以看出osg相交检测的执行过程,首先IntersectionVisitor对Camera下的所有(mask 匹配的)节点遍历, 当发现
是Geode节点时,则对Geode中包含的Geometry的所有图元进行相交检测, 我的图元类型是矩形带(GL_QUAD_STRIP), 所以osg对
组成矩形的两个三角形进行相交检测,正如osg::TriangleFunctor::drawElements中的代码(292行)


case(GL_QUADS):

{
    IndexPointer iptr = indices;

    for(GLsizei i=3;i<count;i+=4,iptr+=4)

    {
        this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+1)],_vertexArrayPtr[*(iptr+2)],_treatVertexDataAsTemporary);
      

        this->operator()(_vertexArrayPtr[*(iptr)],_vertexArrayPtr[*(iptr+2)],_vertexArrayPtr[*(iptr+3)],_treatVertexDataAsTemporary);

    }

    break;

}

可是当引用组成图元的顶点时为什么是无效的数据呢?如果真的无效,那为什么又能正常显示呢?多谢指点。

该用户从未签到

 楼主| 发表于 2010-7-12 15:07:57 | 显示全部楼层
把文件 OpenSceneGraph-2.8.2\include\osg\TriangleFunctor中的setVertexArray函数修改一下就没有错误了,并且返回了焦点。请大家指点


//原有函数
virtual void setVertexArray(unsigned int,const Vec3d)
{
    notify(WARN)<<"Triangle Functor does not support Vec3d* vertex arrays"<<std::endl;
}

//修改结果
virtual void setVertexArray(unsigned int count,const Vec3d* vertices)
{
    _vertexArraySize = count;
    _vertexArrayPtr = (const Vec3*)vertices;
}

该用户从未签到

发表于 2010-7-12 15:38:07 | 显示全部楼层
我不理解您使用Vec3d来表达几何体的原因——在OpenGL中这并没有功用,因为硬件浮点数运算的性质,使得传入的double数组最终和float数据的结果和表达形式一致。

我也不推荐直接改写TriangleFunctor的内容,不过您也可以向osg-submissions上提交您的更改,看一看官方的说法是什么

此外您的代码中存在致命的地方:
_vertexArrayPtr = (const Vec3*)vertices;

这足以让您的程序在某些时候崩溃掉

该用户从未签到

 楼主| 发表于 2010-7-13 10:38:03 | 显示全部楼层
非常感谢,还是用Vec3Array定义Geode顶点数组吧,强制类型转换还是不用为妙。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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