Writer, Choreographer, Game Developer

Introducing Coral, an Actionscript library for 3D Math

Posted on

The experience of Flint

I started work on Flint Particles before Flash 10 was launched, so back then I created my own 3D mathematics classes for Flint. At the time this was not unusual - Away3D and Papervision3D had their own Number3D and Matrix3D classes, for example.

Since the release of Flash 10, open-source projects have gradually switched to use the native Vector3D and Matrix3D classes found in the flash.geom package and recently I decided it was time for Flint to also make this change, hence the release of Flint 3.0 a few weeks ago which uses those native 3D math classes.

Converting Flint to use the native classes was an interesting experience. For one thing, I think the architecture of Flint's classes was better than the native classes. That wasn't sufficient reason to stick with Flint's own classes; using it's own 3D math classes was a barrier to entry for users who were familiar with the native classes and resulted in many questions from confused new users. (For much the same reason, I don't use the excellent As3-Signals library by Robert Penner in Flint, even though I use it in all my other work.)

So I set about converting Flint to use the native 3D classes. The initial conversion was mostly straightforward, only complicated by a lack of functionality in the native classes that sometimes meant one line of code using Flint's classes had to be replaced with 3 or 4 lines of code using the native classes.

Having made the change, however, I was surprised to find two significant issues with the new code. The first was a couple of bugs in the native classes, which were not too serious since I could find a way to work around them. The second, and far more troubling issue, was a very large drop in performance - the code using the native 3D classes ran at about one quarter of the rate of the code using Flint's own 3D classes.

I was eventually able to fix the performance loss, mostly by inlining some critical and slow methods including, for example, the code to transform every particle's position from global coordinate space to camera coordinate space, where instead of a simple

pp = camera.transform.transformVector( p );

Flint now does

var raw:Vector. = camera.transform.rawData;
pp.x = raw[0] * p.x + raw[4] * p.y + raw[8] * p.z + raw[12] * p.w;
pp.y = raw[1] * p.x + raw[5] * p.y + raw[9] * p.z + raw[13] * p.w;
pp.z = raw[2] * p.x + raw[6] * p.y + raw[10] * p.z + raw[14] * p.w;
pp.w = raw[3] * p.x + raw[7] * p.y + raw[11] * p.z + raw[15] * p.w;

for a massive performance improvement.

Coral

In light of the issues I encountered I have decided to release the 3D math classes that were formerly part of Flint as a separate open source project. I continue to use these classes in my own work (with the exception of Flint) and others may want to do so too.

I am calling the project "Coral" - apparently small pieces of coral are sometimes found inside larger pieces of flint. Coral is available on Github, including unit tests and performance tests. Please feel free to use it, fork it and improve it.

Since releasing Flint 3.0, I modified the unit tests and performance tests in Coral to also apply to the native 3D math classes, Vector3D and Matrix3D. This was out of curiosity mainly, but it revealed a number of bugs in the native classes and where the major performance weaknesses in these classes are.

In the following posts I'll look at the results of these tests, with posts about the bugs I found and a performance comparison of Coral and the native classes. But first, if you'll indulge me, here's a post comparing the architecture of Coral and the architecture of Flash's native 3D classes.


Also in the collection Coral, an Actionscript library for 3D Math