Model formats

Away3D can load 3D models from a variety of formats. The decision on which format to use in your published application is sometimes determined by the features that each format provides. If you require bones animation, you may choose to use the Collada format, while the Quake2 MD2 format supports vertex animation. However, for static models any of the formats can be used.

Differences in these formats can lead to significant differences in the time it takes them to be loaded and parsed, as well as factors such as model complexity, animation, UV data, and external materials. When your choice of model format is not dictated by their functionality, these differences can have a significant impact on your applications' loading times. Under certain circumstances, one model format may load as much as ten times faster than another.

Take a look at the following graph. The values represent the average time it took to load a common sphere from seven different model formats supported by Away3D, using the 3DS format as a baseline. The sphere was made up of 3,970 triangles, did not include any animation or bones, was not textured, and contained no UV data. The models were embedded into the SWF, removing any variation that may have arisen from loading the files externally across the network.

Model formats

As you can see, the time it took to load this sample 3D model varies quite significantly. The MD2, 3DS, and OBJ formats all load relatively quickly, while the ASE, DAE, AWD, and AS formats take significantly more time.

Now, take a look at the graph for loading times for a more complex sphere that is made up of 7,922 triangles (again without any textures, bones, animations, or UV data). Again, the values are relative to the time it takes to load the 3DS model. The MD2 format was not included because it is limited to 4,092 triangles.

Model formats

The situation here is different, with 3DS clearly being the fastest format to load.

What is important to take from these graphs are not the specific numbers themselves, but the fact that under different circumstances some model formats can load significantly faster than the others. Finding the best model format does have to be done on a case by case basis, but it is worth doing as there is a huge potential to reduce the time it takes to load 3D model files.

The following ModelLoadingSpeedTest application is an example of how the loading times of different formats can be measured. It loads a number of 3D models in different formats five times each in random order, and displays the averaged loading times on the screen. It is a quick way to judge which formats will perform the best.

package
{
  import away3d.loaders.AWData;
  import away3d.loaders.Ase;
  import away3d.loaders.Collada;
  import away3d.loaders.Max3DS;
  import away3d.loaders.Md2;
  import away3d.loaders.Obj;
  import away3d.materials.WireColorMaterial;

  import flash.events.Event;
  import flash.text.TextField;
  import flash.utils.getTimer;

  public class ModelLoadingSpeedTest extends Away3DTemplate
  {

Sample models saved in the various formats are embedded. When using this class to test your own 3D models, you will have to update the src parameter to reflect the names of your 3D model files.

    [Embed(source="TestSphere.3ds", mimeType="application/octet-stream")] 
    protected var TestModel3DS:Class;
    [Embed(source="TestSphere.ase", mimeType="application/octet-stream")] 
   protected var TestModelASE:Class;
   [Embed(source="TestSphere.dae", mimeType="application/octet-stream")] 
   protected var TestModelDAE:Class;
    [Embed(source="TestSphere.obj", mimeType="application/octet-stream")] 
    protected var TestModelOBJ:Class;
    [Embed(source="TestSphere.awd", mimeType="application/octet-stream")] 
   protected var TestModelAWD:Class;
    [Embed(source="TestSphere.md2", mimeType="application/octet-stream")] 
    protected var TestModelMD2:Class;

The following six Array objects are used to hold the loading times for the various 3D model formats we are testing.

    protected var ThreeD3LoadTimes:Array = new Array();
    protected var MD2LoadTimes:Array = new Array();
    protected var ASELoadTimes:Array = new Array();
    protected var DAELoadTimes:Array = new Array();
    protected var OBJLoadTimes:Array = new Array();
    protected var AWDLoadTimes:Array = new Array();
    protected var ASLoadTimes:Array = new Array();

Each embedded 3D model will be loaded, and the loading process timed, by a separate function. These functions will be added to the functionCalls collection, which we will then use to randomly select the next model loading operation.

    protected var functionCalls:Array = new Array();

The TextField object referenced by the results property will be used to display the status of the application, and the results when the test is completed.

    protected var results:TextField;

    public function ModelLoadingSpeedTest()
    {
      super();

Each of the six functions used to load a 3D model is added to the functionCalls collection five times. This means that each of these functions will be called five times each, allowing us to get an average loading time for each of the 3D model formats.

      for (var i:int = 0; i < 5; ++i)
      {
        functionCalls.push(load3DS);
        functionCalls.push(loadASE);
        functionCalls.push(loadOBJ);
        functionCalls.push(loadDAE);
        functionCalls.push(loadAWD);
        functionCalls.push(loadAS);
        functionCalls.push(loadMD2);
      }
    }

    protected override function initUI():void 
    {
      super.initUI();
      results = new TextField();
      results.x = 10;
      results.y = 10;
      results.width = 300;
      addChild(results);
    }

    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);

As we call each of the functions, they are removed from the functionCalls collection. If the functionCalls collection has no more elements, we don't need to do any more processing.

      if (functionCalls.length != 0)
      {

The status text on the screen is updated to show how many function calls remain.

        results.text = 
          functionCalls.length + 
          " model loading operations remaining";

Here we get a reference to and remove a random function from the functionCalls collection.

        var randomPos:int = 
          Math.round(
            Math.random() * (functionCalls.length - 1)
          );
        var func:Function = functionCalls[randomPos];
        functionCalls.splice(randomPos, 1);

The function is then called, which will record the time it takes to load a 3D model.

        func();

If there are no more functions left in the functionCalls collection we have run through all the tests, we can now display the results.

        if (functionCalls.length == 0)
        {

The average loading time is calculated for each of the different 3D model formats.

          var avg3DS:Number = 
            getAverage(ThreeD3LoadTimes); 
          var avgASE:Number = getAverage(ASELoadTimes);
          var avgDAE:Number = getAverage(DAELoadTimes);
          var avgOBJ:Number = getAverage(OBJLoadTimes);
          var avgAWD:Number = getAverage(AWDLoadTimes);
          var avgAS:Number = getAverage(ASLoadTimes);
          var avgMD2:Number = getAverage(MD2LoadTimes);

The results are then displayed on the screen.

          results.text = 
            "MD2: " + 
            avgMD2.toPrecision(4) + 
            " seconds
" +
            "3DS: " + 
            avg3DS.toPrecision(4) + 
            " seconds
" +
            "ASE: " + 
            avgASE.toPrecision(4) + " 
            seconds
" + 
            "DAE: " + 
            avgDAE.toPrecision(4) + 
            " seconds
" + 
            "OBJ: " + 
            avgOBJ.toPrecision(4) + 
            " seconds
" + 
            "AWD: " + 
            avgAWD.toPrecision(4) + 
            " seconds
" + 
            "AS: " + 
            avgAS.toPrecision(4) + 
            " seconds";
        }
      }
    }

The getAverage() function simply returns the average value of an Array containing a collection of Number.

    protected function getAverage(array:Array):Number
    {
      var average:Number = 0;
      for each (var time:Number in array)
        average += time;
      return average / array.length;
    }

Each of the six functions below are used to load a 3D model of a particular format. You can get more information on loading 3D models in Chapter 6, Models and Animations.

    protected function loadMD2():void
    {

We make a note of the current time before the 3D model is loaded. The value returned by the getTimer() function is in milliseconds.

      var start:int = getTimer();

The 3D model is loaded.

      Md2.parse(TestModelMD2);

We make a note of the current time after the 3D model is loaded.

      var stop:int = getTimer();

The time it took to load the 3D model is calculated in seconds.

      var time:Number = (stop - start) / 1000;

This loading time is then stored in the appropriate Array object.

      MD2LoadTimes.push(time);
    }

All the following functions use the same logic as the loadMD2() function described above to store the time it takes to load a 3D object from a given model format.

    protected function load3DS():void
    {
      var start:int = getTimer();
      Max3DS.parse(
        TestModel3DS, 
        {
          autoLoadTextures: false
        }
      );
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      ThreeD3LoadTimes.push(time);
    }

    protected function loadASE():void
    {
      var start:int = getTimer();
      Ase.parse(TestModelASE, {scaling: 1});
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      ASELoadTimes.push(time);
    }

    protected function loadDAE():void
    {
      var start:int = getTimer();
      Collada.parse(TestModelDAE);
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      DAELoadTimes.push(time);
    }

    protected function loadOBJ():void
    {
      var start:int = getTimer();
      Obj.parse(
        TestModelOBJ, 
        {
          useMtl:false, 
          material: new WireColorMaterial()
        }
      );
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      OBJLoadTimes.push(time);
    }

    protected function loadAWD():void
    {
      var start:int = getTimer();
      AWData.parse(TestModelAWD, {});
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      AWDLoadTimes.push(time);
    }

    protected function loadAS():void
    {
      var start:int = getTimer();
      new TestSphere();
      var stop:int = getTimer();
      var time:Number = (stop - start) / 1000;
      ASLoadTimes.push(time);

  }
}

Another issue to consider is the size of the 3D model files. The test sphere model used in the first loading test ranged in size from 55 KB for the MD2 file all the way up to 1.47 MB for the ASE file. That means the ASE file would take over 20 times as long to download once the application was launched if it were not embedded in the SWF file.

..................Content has been hidden....................

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