本文讨论Papervision 3D中与鼠标互动相关的进阶问题:

  1. 3D物体的hit检测
  2. InteractiveSceneManager
  3. VirtualMouse
  4. Mouse3D

我们知道要让Papervision 3D的互动机制开始运作,必须满足以下两个条件:

  1. viewport.interactive = true;
  2. do3d.material.interactive = true;

然后我们就可以监听do3d发出的事件(InteractiveSceneEvent)。

那么Papervision 3D是怎样实现3D物体与鼠标的hit检测呢?

来看看Viewport类提供的以下实例方法:

  1. hitTestPoint2D()
  2. hitTestMouse()
  3. hitTestPointObject()

这些方法就是三维hit检测的实现(实现方法属于图形学的范畴,本文不深入讨论,有兴趣的可以研究代码)。这些方法返回一个包含了所有检测信息的RenderHitData对象实例,该实例有以下属性:

  • x,y,z:碰撞点的3D位置。
  • u,v:碰撞点的uv,通常是0~1的范围,但是MovieClipMaterial例外。
  • displayObject3D:碰撞的do3d。
  • material:碰撞的材质。
  • renderable:实现了IRenderable接口的对象,通常是Triangle3D(三角面)。
  • isHit:是否碰撞。

点击查看RenderHitData示例 | 源代码

我们知道Papervision 3D中互动事件的管理由InteractiveSceneManager类来实现,可以通过以下代码得到对该类实例的引用。

viewport.interactiveSceneManager

InteractiveSceneManager实例在每帧更新时会调用updateRenderHitData(),该方法正是调用viewport.hitTestPoint2D()来更新的renderHitData的信息,从而进行一系列的检测,并发送对应的InteractiveSceneEvent。

VirtualMouse(虚拟鼠标)

viewport.interactiveSceneManager.virtualMouse

在我们理解的MovieClip作为贴图被贴到3D物体上时,实际上是缓存的位图贴到3D物体上,所以就会失去了原来的互动特性。而虚拟鼠标就是用于触发MovieClipMaterial的互动。

Papervision 3D中的VirtualMouse原身是senocular写的类。理解虚拟鼠标的原理对我们开发时遇到的问题会有很大的帮助。

在Papervision 3D内部,对应虚拟鼠标的xy坐标的就是renderHitData的uv。

Mouse3D

viewport.interactiveSceneManager.mouse3D

Mouse3D很容易和VirtualMouse混淆起来,但其实他们是很不一样的。Mouse3D是DisplayObject3D的子类,说明它其实也是一个3D物体。Mouse3D类扩展的唯一实例方法是updatePosition(),作用是计算并对齐碰撞点的法线方向。在实际应用中,我们可以用Mouse3D帮助对齐3D物体到碰撞的表面,用copyTransform()方法就可以了。

关于OBJECT_OVER和OBJECT_OUT

InteractiveSceneManager.enableOverOut属性可以开关这两个事件的检测。特别还需注意的是如果鼠标没有移动,就不会发出OBJECT_OVER和OBJECT_OUT事件。这会在某些情况下出现问题:比如鼠标没动,而物体在动的情况。这种情况可以自行通过viewport.hitTestMouse()判断来解决。所以监听这两个事件的时候要特别注意。

« »