[three.js]如何判断物体之间相交 【根据拖拽的div选取物体】

异智宇宙 动手写第一个 Three.js... 最后由 huqingchao 于2016年06月15日回复

  • 7 回答
  • 3.9k 浏览

我已经丧心病狂的摸索到国外网站里去了,各种没有办法的办法都试了一边,找到唯一靠谱的具体解决方法是根据选取框的大小定义一个锥形物体,然后再通过这个锥形物体判断是否有物体在其之内

实现关键代码如下:

QQ图片20160526134731.png

而我亲自实践检测结果如下

锥形检测.jpg

锥形检测函数.jpg

锥形检测输出.jpg还请老师甄别其中问题所在,这段代码究竟问题出在哪,如何才能使其运作,临图涕零,不甚感激

  • huqingchao 2016年05月27日 回答 #1楼
  • 使用锥形体判别选中的方向本身没有问题,但是存在一定局限。首先是锥形体的范围不能保证一定涵盖所有对象,总不可能把锥形体的尺寸设为无限远吧。其次,这个计算也是比较复杂的。你的算法我没有仔细推敲,我相信思路是对的,经过一定调试应该可以做出来。不过鉴于刚才提到的缺点,并不建议用这种方法。

    我之前应该提过,我建议使用投影的方式,这种简洁高效,适用性高。现在选择框已经有了,说明已经有了2D的一个坐标范围。那么,把所有三维对象(或者包括其下所有坐标顶点)投影到2D平面,就很容易判断出是否在选择框内,剩下的就是投影的2D坐标计算的问题了,大大简化了算法的难度。应为使用了投影,把3D降低为2D,可以适用于任意深度的模型,不存在范围问题。具体算法在早先的项目中用过,经过验证没有问题,只不过项目久远,代码属于客户的,所以现在已无从共享。

    Three.js自带一个鼠标拾取的例子,思路比较新颖。虽然它是鼠标点拾取,不是框选,不过也用的是3D投影到2D的方法,也可以借鉴。http://threejs.org/examples/#webgl_interactive_cubes_gpu

    由于我最近比较忙,没有时间整理代码给你,抱歉。

  • 0 评论
  • 异智宇宙 2016年06月11日 回答 #2楼
  • #1楼  @huqingchao 老师,这里我看了下,他定义了两个场景,一个获取物体用,一个显示物体用,但他这里是通过.merge把所有物体都组合到一起,我如果要实现编辑物体的功能还得在再从中把物体剥离出来,但我找不到剥离物体的函数,重新定义顶点、面也试过了,会出现Three。js某函数未定义错误,我现今已知所要操作的物体属于组合物体中第X-y个顶点,但找不到对应函数对它进行合法的操作,还请老师解惑,拜谢

  • 0 评论
  • huqingchao 2016年06月12日 回答 #3楼
  • 那个案例只是一个思路的参考,并不能适用于复杂场景。

    请参照我上述投影的方法,这是我推荐的思路。

  • 0 评论
  • 异智宇宙 2016年06月13日 回答 #4楼
  • 他采用的方法是定义ID转换为颜色,然后从颜色转换为ID再渲染缓冲区中的颜色中查找对应ID的物体, 我经调试后可用于框选,但老师所说的投影法……我找不到例子,也不知道从何下手,他所示例地方法唯一不足目前就是不能删除已经加载的物体,但我找到了方法

    english_helper.jpg

    但实测这个方法只有在网页加载完立即执行删除面的时候才有效(具体貌似是在某段代码执行之前),之后经测试只要我延迟执行删除面,就会因其他代码的影响而无法刷新被删除面后的geometry(实测面数组已被删除)控制台显示我看来意义不明的报错

    11756.png

    现已不知所措,还请老师指明方向

  • 0 评论
  • huqingchao 2016年06月15日 回答 #6楼
  • 颜色id的案例仅供参考其思路,实用性不是很高。最大的一个问题就是如果模型被遮挡了,则渲染不出来对应颜色,当然也就拾取不到了。投影的方式不存在这个问题。

  • 0 评论
  • huqingchao 2016年06月15日 回答 #7楼
  • 按投影的方式做也不难,我给你思路,具体你自己研究:

    1)通过某种方式(如拖拽)确定屏幕范围内的2D选择框。

    2)把所有需要检测的模型的坐标(中心点或者复杂一点使用模型的所有顶点坐标)投影到屏幕,检查其投影点的2D坐标是否在选择框内。

    3)根据2)的结果确定所有模型是否被框选


    是不是也很容易实现啊,你试试吧。

  • 0 评论