首页 > 代码库 > Away3D 的实体收集器流程2

Away3D 的实体收集器流程2

带着上次的疑问我们继续探讨Away3D 的渲染流程。

在Away3D中所有的显示对象都是继承Object3D 的我们先看看显示对象和继承关系。

Object3D

  |---ObjectContainer3D  (3D显示容器)

      |---Entity (所有的3D实体对象的抽象基类)

         |---Mesh (网格对象)

         |---Camera3D (摄影机[非显示对象])

         |---SegmentSet (线段的集合可以绘制线)

         |---Sprite3D (公告板始终面向摄像机)

以上显示对象中最常用的 是 Mesh 我们想看看Mesh 的结构。

Mesh 是由多个SubMesh 组成的,每个 SubMesh 可以拥有自己的 Geometry 和 Material。很多朋友说 Away3D 的mesh不支持多材质,其实是错误的。

你可以对 Mesh进行改造单独设置他的 SubMesh 即可。Geometry 和 Material这里占时不多说了大家自己用用就知道了。 每个Mesh都有一个MeshNode。

我们要寻找的答案也就在这里面。

我们搞清楚了显示对象下面就来了解下这些显示对象是如何被addChild 到舞台的。

ObjectContainer3D 类中实现了一个 addChild 的函数。在这个函数里大部分代码都是在做对象的管理,关键一步是 child.scene = _scene;

ObjectContainer3D 只是做了赋值处理并没有真正意义上的把对象添加到场景上。Entity类重写了scene的set 函数。

override public function set scene(value : Scene3D) : void
  {
   if (value =http://www.mamicode.com/= _scene)
    return;

   if (_scene)
    _scene.unregisterEntity(this);
   
   // callback to notify object has been spawned. Casts to please FDT
   if (value)
    value.registerEntity(this);

   super.scene = value;
  }

重写的scene set 函数 调用了 registerEntity 函数 把当前对象最为参数传递给了scene3d.由scene3d调用了添加到Partition3D中了。

但是添加到 Partition3D 中的时候并不是直接的添加当前对象 而是 添加了 当前对象的 node对象。至于为什么我们后面再说。

先回过头来看看之前收集器进过Partition3D 的 traverse函数。

if (_updatesMade)
    updateEntities();

当有新的显示对象添加到了Partition3D中 Partition3D 将 _updatesMade自动设置为true了 这时候开始跟新显示对象以及该显示对象的子对象。

最后把所有要显示的对象的Node 都添加到了_rootNode中。然后开始 调用 acceptTraverser函数。前面说到了 Partition3D 中并不是直接的添加当前对象 而是 添加了 当前对象的 node对象。原因是Away3d 为了分离渲染和对象收集 把视锥剔除的逻辑在 node 中实现了。而对象本身是没有这个逻辑的。再进一步的debug 跟进发现进入了enterNode函数 开始计算视锥剔除。如果当前显示对象不在 视锥范围内 将不会被渲染。

  下面再补充一下Away3D在渲染的过程中会先检查对象是否被 visible=false;如果是false 将不会被渲染。很多人在实际开发中把TextureMaterial 中的 alpha 设置等于0;但实际上这个显示对象还是会被渲染的。