查看: 1981|回复: 3

请大家过来看看这个invisibleDragger为何不能实现呢?

[复制链接]

该用户从未签到

发表于 2011-4-15 11:43:34 | 显示全部楼层 |阅读模式
本帖最后由 baco_n 于 2011-4-15 12:18 编辑

各位OSG达人,大家好。我想实现一个invisibleDragger,也就是不要在物体上出现由于使用TabPlaneDragger或TabBoxDragger等类时出现的带tab的小平面或小包围盒。查看Dragger头文件,有以下代码:

  1. /**
  2. * Culls the drawable all the time. Used by draggers to have invisible geometry
  3. * around lines and points so that they can be picked. For example, a dragger
  4. * could have a line with an invisible cylinder around it to enable picking on
  5. * that line.
  6. */
  7. void OSGMANIPULATOR_EXPORT setDrawableToAlwaysCull(osg::Drawable& drawable);
复制代码


这个函数虽在Dragger头文件中声明,本身却不属于class Dragger 或compositDragger,所以,我想使用Nodevisitor去遍历使用TabBoxDragger时挂在场景中的drawable对象,以提供形参供上述函数使用。

  1. osg::ref_ptr<osgManipulator::TabBoxDragger>dragger=
  2.   new osgManipulator::TabBoxDragger;
  3. dragger->setupDefaultGeometry();
  4. GetDraggerDrawablesVisitor getDraggerDrawablesVisitor;
  5. dragger->accept(getDraggerDrawablesVisitor);
复制代码

其中第五行的具体定义如下,为了完整性有点长,但是可以只看有注释的那一行,那里使用了上述的函数。

  1. class GetDraggerDrawablesVisitor:public osg::NodeVisitor
  2. {
  3. public:
  4. GetDraggerDrawablesVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),_iNumNode(0){}
  5. virtual void apply(osg::Node& node)
  6. {
  7.   unsigned int i,n;
  8.   if((node.asGroup())!=0)
  9.   {
  10.    n=((osg::Group&)node).getNumChildren();
  11.    for(i=0;i<n;i++)
  12.    {
  13.     osg::Node*node1=((osg::Group&)node).getChild(i);
  14.     apply(*node1);
  15.    }
  16.   }
  17.   if(node.asGeode()!=0)
  18.   {
  19.    for( i=0;i<(((osg::Geode&)node).getNumDrawables());++i)
  20.    {
  21.     osg::Drawable*drawable=((osg::Geode&)node).getDrawable(i);
  22.     osgManipulator::setDrawableToAlwaysCull(*drawable);   //这里添加函数使得每个被找到的绘制对象都invisible
  23.     if(!drawable)continue;
  24.    }
  25.    traverse((osg::Geode&)node);
  26.       }
  27. }
  28. private:
  29.   int _iNumNode;
  30. };
复制代码

问题是,当上述程序运行时,原有的拖拽器是看不见了,但是也无法实现拖拽功能了。但setDrawableToAlwaysCull函数的解释不是说绘制对象仅仅是不可见,而拖拽功能还是可以实现的吗?
   谢谢!

该用户从未签到

发表于 2011-4-15 13:16:28 | 显示全部楼层
setDrawableToAlwaysCull()的意义是这样的:某些拖曳器的几何形状可能很简单,比如只有一条线;此时想要通过和这条线求交来判断用户是否选中拖曳器是不合适的,因为它本身就很难被选中。这种时候,我们可以沿着这条线构建一个圆柱体,这样选中圆柱体我们就认为拖曳器被选中了。而这个圆柱体事实上是不可见的,因此设置它为setDrawableToAlwaysCull()

我没有仔细看您后面的实现,不过您可以对照我的解释看一看您的用法是否正确?我不认为在访问器里使用它是正确的做法

该用户从未签到

 楼主| 发表于 2011-4-16 13:57:44 | 显示全部楼层
本帖最后由 baco_n 于 2011-4-16 14:00 编辑

回复 2# array
锐哥,这是OSG maillist中的一个问题与回答,请您过目。

问题:
Hi Paul,

>
I've got the same thing working with OSG with the osgmanipulators
>
however these manipulators (seem to?) rely on setupDefaultGeometry()
>
to create handles. I would rather have the original subtle approach,
>
where the object itself acts as the "handle" and the scene is not
>
cluttered with other objects.
>
> Is there an easy way to do this or will I have to create my own
>
specialised dragger?

回答:

Check out the code for createDefaultGeometry() for your selected
dragger. You will see that it essentially creates some geometry under
the dragger (geodes as children of the dragger, which is a subclass of
MatrixTransform). Often, there is additional geometry created only to
make picking easier, but never displayed - for example:


   
  1. // Create an invisible cylinder for picking the line.
  2. {
  3. osg::Cylinder* cylinder =
  4. new osg::Cylinder (osg::Vec3(0.0f,0.0f,0.5f), 0.015f, 1.0f);
  5. osg::Drawable* geometry = new osg::ShapeDrawable(cylinder);
  6. setDrawableToAlwaysCull(*geometry);
  7. geode->addDrawable(geometry);
  8. }
复制代码

The important part is setDrawableToAlwaysCull(), which is a protected
method of osgManipulator:: Dragger. So if, for example, you want to
create a TranslatePlaneDragger which does not display its geometry
, you
could just subclass TranslatePlaneDragger, and then in
createDefaultGeometry() you would only create an invisible quad which
would align with the plane you want to translate along, using is
setDrawableToAlwaysCull(). That way, intersections would be found on
that plane and the dragger would behave as you want, but it would not
display any geometry for the dragger itself.

Hope this helps,

J-S

他的回答中的createDefaultGeometry()应该指的就是setUpDaultGeometry(),按照他的意思,就是说可以在某个拖拽器类中写入setDrawableToAlwaysCull(),从而使得拖拽器不可见。这好像与您昨天的回答不一样。愿听ARRAY详解。谢谢!





该用户从未签到

发表于 2011-4-18 08:41:24 | 显示全部楼层
setDrawableToAlwaysCull()的代码很少,最好的验证方法就是阅读一下它的实现内容,我就是这么做的。此外J-S的说法很明显和我的是一样的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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