Implementing enterprise solutions into “cool shit” application

This is series of articles called “Behind The Scenes”, where we describe particular project in different ways. this time it will be our fist one. Think360.


Series Articles:

1) Planning, Platforms, Frameworks, Workspace
2) Architecting, Folder structures, Backend
3) Away3D vs Papervision3D, 3D Modelling, Physics, Sound, Optimization

Away3D vs Papervision3D

away3dWe started to build this project on top of papervision3d engine. But somewhere in the middle of project we hit the wall (or roof better say) what was technically possible to do. So I had to find some way. One of them was to risk it and swap engine to another one and hope for better performance. After few days intensive researches there were few choices. Sandy3D, Away3D and Alternativa3D. As our main issue was performance it was hard choice. There are not lot of performance comparisons on high poly objects.

On the end of the day, I decided to go for Away3D.  There few reasons for that.

Engine is continually evolving. Guys around engine development are very clever and open to community. Engine has surprisingly loads of features. Support for Flash Player 10.

Last one was probably biggest advantage.

We made few performance tests and engine seemed to be pretty fast. Actually our first full scene un-optimized test was as fast as maximum optimized papervision3d one.

Away3d engine is surprisingly easy to set up. Actually you need just 2 lines of code to set it up:

view = new View3D();


Because Away3D is actually a branch of Papervision3D it has similar API.
Only difference between PV3D and Away3D is way how you set up objects. While in PV3D you pass parameters in constructors:

var plane:Plane = new Plane(200,200);

In Away3D you pass object with {name: value} pairs:

var plane:Plane = new Plane({width:200,height:200});


var plane:Plane = new Plane();
plane.width = 200;
plane.height = 200;

I think this is down to own preference. However I found PV3D way little bit more clean and more safe as values are strong typed. But it has its drawbacks when you need to setup just particular properties.

Away3DLite has instniation based on strong typed parameters as PV3D:
var plane:Plane = new Plane(null,200,200);

For game itself we used just one main Scene in Away3D and every other scene (Main Hall, Office etc) was just Object3DContainer with additional Meshes and 3DObjects.

Image shows how effective can be proper 3D design combined with Away3D. With first tests we were able to walk around hall without noticeable loss of frame rate with nearly 17000 triangles in the scene!



Keep It Simple Stupid. That was main goal in order to build all scenes with this size. No light. No special effects. No reflections. No shades. With all that in mind, everything had to look realistic.


Funny thing is that just few days before we finished our project, guys from Away3D released lightweight version called Away3DLite.

3D Modelling

3D modelling for flash player is artistic fight rather modelling itself. Because flash player is so idiotically slow in compare with any today’s 3d capable environment that every little polygon makes difference. Model optimization is one of crucial factors when creating 3d content for flash.

Scene modelling

-scenes had to be modelled in way that triangles are spread out in balanced way
- we also used 2 versioned models:

  • High-poly for modelling and baking
  • Low-poly for Flash Player export

Hi-poly vs Low-poly triangle count difference



In order to keep up with speed we use pre-baked materials (you create lighting in 3D modelling tool and export materials with all effects already on them)
Baking was applied on high-poly mesh and then implemented on low poly in flash player.

Baking procedure



One of biggest issues we had was z-sorting. To spare every possible frame we couldn’t use built-in z-sorting camera. So we had to optimize again.

Objects sitting on floor had to be sitting on holes.

Object always in front could be forced to front with:
obj.ownCanvas = true;

For example in the office scene there is document on wall as additional element. Without obj.ownCanvas there would be issue with picture disappearing occasionally. On other hand obj.ownCanvas = true, 3d object is always in front. So solution was to set  obj.ownCanvas = false while moving into office and after camera finish movement set it to obj.ownCanvas = true and vice versa.

Implementation of ownCanvas in the Office


Without z-sorting you have to be very careful while modeling your 3D content. There are few simple rules to help this issue:

  • If model sits on floor put floor into different View or merge object with floor
  • On places where are more “triangle flicking” chance put little bit more triangles.

Example of merged objects to avoid flicking of triangles:

3D Optimization

As exporter

Because we went pretty wild with all 3d stuff on this project we had to find way how not to kill flash and browser while parsing all that data. And there is when brilliant as3 exporter comes to play. It allows you to export any 3d object from blender into as class. So instead of loading dae or other format into flash it’s already compiled into actionscript and available immediately. We used great blender plugin AS3 Blender Exporter to export 3D models as plain actionscript class.

Video material

We had 2 options here. Use video material or use AnimatedBitmapMaterial. First is small but it also affecting performance. Second perform very well but it is very big in size (especially on large or longer videos). So we applied animated material on short and small sequences and Video on longer and bigger ones. Video Material was created as movieclip in flash and exported as swc.

Example on this one can be found in main hall and office. Videos in “default” mode are Animated bitmaps. After you click on them it swaps to video.


Real video animation

To get realistic effect inside office scene. We shoot several team members on green screen with camera positioned and angled as it would be in virtual office. Then members were cut out and colorized to match colour tone of office. Then video was attached on planes. Again, all planes copy camera y rotation.

Step 1:

We shoot one of our members on green screen and then cut him out. After that we published video with alpha channel.


Step 2:

We imported video into Flash IDE, recompile it into timeline based video and then exported it as SWC.
Then we attached video into scene as Plane with AnimatedBitmapMaterial.



Fire in gallery scene was great for AnimatedBitmapMaterial. It is just small plane. All planes are stored in vector array and copy rotation of camera on y axis.

Videos has been created in Flash IDE as timeline videos and exported as swc files.



Because we had to keep frame rate high in every corner of scene we had to come up also with solution for physics. We tried jiglib but it was too slow for such a huge number of polygons and complexity of scene. Also WOW was better but still slow. So instead of using 3d physics I decided to go for 2d physics and excellent library called Box2D. It is blazingly fast in compare with jig lib and because our scenes floor was flat I could implement this 2d approach into 3d world.

We created something similar to mapping tool. It was interface responsible for creating physics objects on the fly.

Something like this:

var map:Map = new Map();

Image shows how 2D physics map is directly related to 3D world



This was another place where I found PureMVC extremely useful. We created SoundMediator responsible for sound management. Then we added list of notification interests.

Now we could play sound from any location by sending notification.

sendNotification(AppConstants.PLAY_SOUND,{volume:1,repeat:3}, AppConstants.SOUND_WALK)

Because Flash Player has issues with looping Mp3 files, we used Flash IDE to conver all sounds and export them as swf file.

Additional Performance Optimization:

So after all that there was still room to optimize few bits. These optimizations should be done always as last with relevant “stable” version saved. On top of general optimizations for flash player we’ve done these:

  • Simplify unused events to base Event. Instead of (e:MouseEvent) use (e:Event)
  • Test wmode=”gpu/direct” and use fastest one
  • Simplify classes. Instead of var myMesh:MyMesh use var myMesh:Mesh/Object3D (depends on which functions you need to use)
  • Cast to interfaces instead of Classes
  • Mark heavily used classes as “final”
  • PNG files optimization. More find here
  • Exclude unused classes
  • Remove unused conditions in cpu intensive places (especially Away3D)

As I said before, these changes must be done on the end and you should do them if you really need squeeze every bit from your application (our case). Otherwise they are not worth of invested time.


As we found by ourselves, pushing flash to its boundaries is quite hard task and we just hope that we won’t need to spend so much hours by doing tasks which shouldn’t be necessary for general mortal person in future. We hope that Flash Player will evolve into something where these tasks will be thing of past. But till then we will rely on ourselvs and amazing work of flash community and its projects inluding Away3D,PV3D,PureMVC and many others.

  1. [...] 1) Planning, Platforms, Frameworks, Workspace 2) Architecting, Folder structures, Backend 3) Away3D vs Papervision3D, 3D Modelling, Physics, Sound, Optimization [...]

  2. [...] 2) Architecting, Folder structures, Backend 3) Away3D vs Papervision3D, 3D Modelling, Physics, Sound, Optimization [...]

  3. [...] My last article about creation of Think360 is finally out. I the last one I went through 3D and interactive part of project development. Check it out here. [...]

  4. Thanks for this excellent review! Just a few days ago I was a speaker at 3d flash event in
    Israel (Tel Aviv ) where I talked at length about Away3D advantages .Here in your article you are proving exactly the same points I was talking about !!!!
    Well Done ,
    Keep it up.