Triangle caching

Away3D includes a feature called triangle caching, which is enabled by default. Triangle caching removes the need for 3D objects to be re-rendered if the appearance of the canvas they are rendered into has not been modified during the last frame.

By default, all 3D objects are rendered into one common canvas. In this scenario, the triangle caching system will only provide some benefit if none of the 3D objects in the scene are modified. While this results in a massive speed boost for static 3D scenes, the ability to draw a static scene at a high frame rate is actually not all that helpful—you could just as easily display a static image instead. Thankfully, triangle caching can also be separately enabled for an individual 3D object by setting its ownCanvas property to true, or enabled for a group of 3D objects by adding them as children of an ObjectConatiner3D object that has its ownCanvas property set to true. In this way, the 3D objects that are re-rendered each frame can be limited to those individual 3D objects that are modified, or to the children of a container where one of those children was modified. In all cases though, modifying the camera will cause each 3D object to be re-rendered.

Triangle caching is most useful when the camera is static and only a small number of 3D objects need to be modified for a given frame. The TriangleCachingDemo application demonstrates this by adding 75 complex 3D objects to a scene. Each of these 3D objects has its ownCanvas property set to true, enabling the triangle caching to be applied to each 3D object individually. Each 3D object also responds to the MouseEvent3D.MOUSE_OVER and MouseEevent3D.MOUSE_OUT events to animate it when it is under the mouse cursor. With a maximum of one 3D object being modified at any one time, and therefore a maximum of one 3D object being re-rendered every frame, triangle caching allows the application to run at a much higher frame rate than would be possible if every 3D object was re-rendered for every frame.

package
{
  import away3d.containers.ObjectContainer3D;
  import away3d.core.base.Mesh;
  import away3d.core.utils.Cast;
  import away3d.events.MouseEvent3D;
  import away3d.loaders.Max3DS;
  import away3d.materials.BitmapMaterial;

  import flash.events.Event;
  import flash.filters.GlowFilter;
  import flash.utils.getTimer;

  public class TriangleCachingDemo extends Away3DTemplate
  {
    [Embed(source="ship.3ds", mimeType="application/octet-stream")] 
    protected var ShipModel:Class;
    [Embed(source="ship.jpg")] 
    protected var ShipTexture:Class;

    protected static const MESH_SCALE:Number = 0.02;
    protected static const SCALE_FACTOR:Number = Math.PI / 1000;
    protected var selectedMesh:ObjectContainer3D;

    public function TriangleCachingDemo()
    {
      super();
    }

    protected override function initScene():void
    {
      super.initScene();
      this.camera.z = 0;

The initial 3D model is loaded and textured from the embedded files. We will use this as a template for all the 3D objects that will be added to the scene.

      var shipMaterial:BitmapMaterial = 
        new BitmapMaterial(Cast.bitmap(ShipTexture));
      var shipModel:ObjectContainer3D = 
        Max3DS.parse(Cast.bytearray(ShipModel),
          {
            autoLoadTextures: false,
            scale: MESH_SCALE,
            rotationY: 180,

For the triangle caching system to work we need to set the ownCanvas property to true.

            ownCanvas: true
          }
        );
      for each (var child:Mesh in shipModel.children)
        child.material = shipMaterial;

Here we use three for loops, each used to calculate either the x, y, or z position of the individual 3D objects that will be added to the scene.

      var meshClone:ObjectContainer3D
      for (var xPos:int = -40; xPos <= 40; xPos += 20)
      {
        for (var yPos:int = -40; yPos <= 40 ; yPos += 20)
        {
          for (var zPos:int = 100; zPos <= 180 ; zPos += 40)
          {

We then clone the template 3D object. This saves us the time it takes to parse the 3D model file (which, as we will see later on, can be quite significant). It also saves some memory, as each of the cloned 3D objects references the geometry of the template 3D object, instead of maintaining their own copy of that data.

            meshClone = shipModel.clone() as ObjectContainer3D;

The cloned 3D object is then repositioned and added to the scene.

            meshClone.x = xPos;
            meshClone.y = yPos;
            meshClone.z = zPos;
            scene.addChild(meshClone);

Each cloned 3D object is set to respond to the MouseEvent3D.MOUSE_OVER and MouseEvent3D.MOUSE_OUT events.

            meshClone.addEventListener(
              MouseEvent3D.MOUSE_OVER, 
              onMouseOver
            );
            meshClone.addEventListener(
              MouseEvent3D.MOUSE_OUT, 
              onMouseOut
            );
          }
        }
      }
    }

    protected function onMouseOver(event:MouseEvent3D):void
    {

We set the selectedMesh property to reflect the currently selected 3D object when the mouse is over it.

      selectedMesh = event.target as ObjectContainer3D;

The GlowFilter class is used to visually indicate which 3D object is selected.

      selectedMesh.filters = [new GlowFilter()];	
    }

    protected function onMouseOut(event:MouseEvent3D):void
    {

When the mouse has been moved off a 3D object, the selectedMesh property is set to null to reflect the fact that no 3D object is currently selected.

      selectedMesh = null;
      var mesh:ObjectContainer3D = 
        event.target as ObjectContainer3D;

The filters property of the 3D object is set to an empty array, clearing the GlowFilter object that was assigned to in the onMouseOver() function.

      mesh.filters = [];

The scale of the 3D object is set back to its default.

      mesh.scale(MESH_SCALE);
    }

    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);
      if (selectedMesh != null)
      {

If there is a 3D object under the mouse pointer, we use some simple math to bounce its scale between 1 and 2. This demonstrates how individual 3D objects can be transformed or animated, while triangle caching is used on the remaining static 3D object to maintain a high frame rate.

        var betweenNegOneAndOne:Number = 
          Math.sin(getTimer() * SCALE_FACTOR);
        var betweenZeroAndOne:Number = 
          (betweenNegOneAndOne + 1) / 2;
        var betweenOneAndTwo:Number = 
          betweenZeroAndOne + 1;
        selectedMesh.scale(betweenOneAndTwo * MESH_SCALE);
      }
    }
  }
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.57.219