<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Richard Lord &#187; 3D</title>
	<atom:link href="http://www.richardlord.net/blog/tag/3d/feed" rel="self" type="application/rss+xml" />
	<link>http://www.richardlord.net</link>
	<description>Actionscript/Flex, PHP and Java developer</description>
	<lastBuildDate>Mon, 23 Jan 2012 17:07:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Bugs in Vector3D and Matrix3D</title>
		<link>http://www.richardlord.net/blog/bugs-in-vector3d-and-matrix3d</link>
		<comments>http://www.richardlord.net/blog/bugs-in-vector3d-and-matrix3d#comments</comments>
		<pubDate>Thu, 24 Feb 2011 18:38:49 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Coral]]></category>

		<guid isPermaLink="false">http://www.richardlord.net/?p=774</guid>
		<description><![CDATA[This is part 4 of a 4 part series comparing Coral, a derivative of the 3D math classes that used to be in the Flint Particles project, and Flash&#8217;s native 3D math classes. In the first post I introduced Coral, explaining what it is and why I&#8217;m releasing it as an open source project. The [...]]]></description>
			<content:encoded><![CDATA[<p>This is part 4 of a 4 part series comparing <a href="https://github.com/richardlord/Coral">Coral</a>, a derivative of the 3D math classes that used to be in the <a href="http://flintparticles.org/">Flint Particles</a> project, and Flash&#8217;s native 3D math classes.</p>

<p>In the first post I <a href="/blog/introducing-coral-an-actionscript-library-for-3d-math">introduced Coral</a>, explaining what it is and why I&#8217;m releasing it as an open source project. The next post looked at <a href="/blog/architecture-of-coral-vs-vector3d-and-matrix3d">the key architectural differences between Coral and the native Vector3D and Matrix3D classes</a>. The third post <a href="/blog/performance-of-coral-vs-vector3d-and-matrix3d">compared the performance of Coral and the native 3D math classes</a>. This last post is about bugs.</p>

<p>The classes in Coral are covered by <a href="https://github.com/richardlord/Coral/tree/master/test/net/richardlord/coral">unit tests</a>. I don&#8217;t write unit tests for every bit of code I write, but for classes like these 3D Math classes, which will be used in many different projects, in many different circumstances, where bugs could be hard to track down, I consider unit tests essential.</p>

<p>I adapted the unit tests from Coral to <a href="https://github.com/richardlord/Coral/tree/master/native/test">test Flash&#8217;s native Vector3D and Matrix3D classes</a>. In so doing, I discovered a number of bugs in the native classes. All the test code is <a href="https://github.com/richardlord/Coral">in the Coral project on Github</a>. This is what I found.</p>

<h2>Bugs in Vector3D</h2>

<p>Vector3D passed most of the tests. These are the tests it failed.</p>

<h3>X_AXIS, Y_AXIS &#038; Z_ AXIS are mutable.</h3>

<p>Consider this code</p>

<pre class="code">var v : Vector3D = Vector3D.X_AXIS;
v.scaleBy( 2 );
var u : Vector3D = Vector3D.X_AXIS;
trace( u );</pre>

<p>It would be natural to expect u to be the vector ( 1 0 0 ), but it isn&#8217;t. It&#8217;s ( 2 0 0 ). Because X_AXIS, Y_AXIS &#038; Z_AXIS return a reference to the same vector every time. They should return a new vector each time, so the value of the X_AXIS, Y_AXIS &#038; Z_AXIS properties can&#8217;t be changed.</p>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6244">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h3>CrossProduct sets the w coordinate to 1</h3>

<p>The default value for the w coordinate is supposed to be zero. So the w coordinate of the result of the crossProduct of two vectors should be zero. It isn&#8217;t &#8211; it&#8217;s one.</p>

<pre class="code">var u : Vector3D = new Vector3D( 1, 0, 0 );
var v : Vector3D = new Vector3D( 0, 1, 0 );
var r : Vector3D = u.crossProduct( v );
trace( u.w ); // 0
trace( v.w ); // 0
trace( r.w ); // 1</pre>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6250">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h2>Bugs in Matrix3D</h2>

<p>Matrix3D contains more serious bugs than Vector3D. Here they are.</p>

<h3>The determinant is incorrect</h3>

<p>When the Matrix3D class calculates the determinant, it gets it wrong. Every time. Consider this matrix, for example.</p>

<pre class="code">[ 1 2 3 4 ]
[ 2 3 4 5 ]
[ 3 4 5 6 ]
[ 4 5 6 7 ]</pre>

<p>The determinant of this matrix is zero. But the Matrix3D class thinks it is -36. Stranger, but reassuring, if you ask Matrix3D to calculate the inverse, it recognizes that the inverse can&#8217;t be calculated because the determinant is zero!!</p>

<pre class="code">var m : Matrix3D = new Matrix3D(Vector.<Number>([1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7]));
trace( m.determinant ); // -36
var b : Boolean = m.invert();
trace( b ); // false</pre>

<p>Matrix3D even gets the determinant of the identity matrix wrong.</p>

<pre class="code">var m : Matrix3D = new Matrix3D();
trace( m.determinant ); // -1</pre>

<p>The correct value is 1.</p>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6252">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h3>Floating point inaccuracies</h3>

<p>The Matrix3D class introduces inaccuracies in floating point numbers that far exceed the normal floating point inaccuracies. You can see this without even touching the matrix after creating it&#8230;</p>

<pre class="code">var m : Matrix3D = new Matrix3D(Vector.<Number>([1.1,0,0,0,0,1.1,0,0,0,0,1.1,0,0,0,0,1]));
trace( m.rawData );</pre>

<p>The output from this is</p>

<pre class="code">1.100000023841858,0,0,0,0,1.100000023841858,0,0,0,0,1.100000023841858,0,0,0,0,1</pre>

<p>The Matrix3D class intermittently fails some of Coral&#8217;s unit tests because the results are not within 0.0001 of what they should be. To me, that&#8217;s a big error.</p>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6253">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h3>appendRotation() and prependRotation() assume the axis is of unit length</h3>

<p>The appendRotation() and prependRotation() methods only produce the correct matrix if the axis property passed to the method is of unit length.</p>

<p>This code specifies a 90° rotation about the x-axis.</p>

<pre class="code">var m : Matrix3D = new Matrix3D();
m.appendRotation( 90, new Vector3D( 1, 0, 0 ) );
trace( m.rawData );</pre>

<p>The result is the matrix</p>

<pre class="code">[ 1 0 0 0 ]
[ 0 0-1 0 ]
[ 0 1 0 0 ]
[ 0 0 0 1 ]</pre>

<p>This code also specifies a 90° rotation about the x-axis.</p>

<pre class="code">var m : Matrix3D = new Matrix3D();
m.appendRotation( 90, new Vector3D( 2, 0, 0 ) );
trace( m.rawData );</pre>

<p>But the result is the matrix</p>

<pre class="code">[ 4 0 0 0 ]
[ 0 0-2 0 ]
[ 0 2 0 0 ]
[ 0 0 0 1 ]</pre>

<p>Which is a rotation and scale.</p>

<p>That the axis should be a unit vector isn&#8217;t specified as a requirement in the documentation and it isn&#8217;t enforced in the code. These methods should calculate a unit vector from the axis and use that to calculate the rotation.</p>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6255">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h3>appendTranslation() ignores the bottom row of the matrix</h3>

<p>The appendTranslation() method simply adds the new translation coordinates to the translation coordinates in the last column of the matrix. This is only correct if the first three numbers in the bottom row of the matrix are zero.</p>

<pre class="code">[ 1 0 0 2 ]   [ 2 1 0 0 ]   [ 2 1 0 2 ]
[ 0 1 0 3 ] . [ 3 1 2 0 ] = [ 3 1 2 3 ]
[ 0 0 1 4 ]   [ 1 0 1 0 ]   [ 1 0 1 4 ]
[ 0 0 0 1 ]   [ 0 0 0 1 ]   [ 0 0 0 1 ]</pre>

<pre class="code">[ 1 0 0 2 ]   [ 2 1 0 0 ]   [ 4 3 2 2 ]
[ 0 1 0 3 ] . [ 3 1 2 0 ] = [ 6 4 5 3 ]
[ 0 0 1 4 ]   [ 1 0 1 0 ]   [ 5 4 5 4 ]
[ 0 0 0 1 ]   [ 1 1 1 1 ]   [ 1 1 1 1 ]</pre>

<p>The Matrix3D class gets the first calculation correct and gets the second one wrong.</p>

<pre class="code">var m1 : Matrix3D = new Matrix3D(Vector.<Number>([2,3,1,0,1,1,0,0,0,2,1,0,0,0,0,1]));
m1.appendTranslation( 2, 3, 4 );
trace( m1.rawData ); // 2,3,1,0,1,1,0,0,0,2,1,0,2,3,4,1 
var m2 : Matrix3D = new Matrix3D(Vector.<Number>([2,3,1,1,1,1,0,1,0,2,1,1,0,0,0,1]));
m2.appendTranslation( 2, 3, 4 );
trace( m2.rawData ); // 2,3,1,1,1,1,0,1,0,2,1,1,2,3,4,1</pre>

<p><a href="https://bugs.adobe.com/jira/browse/FP-6261">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h3>transformVector() ignores the w coordinate</h3>

<p>The transformVector() method ignores the value of the w property of the input vector. The transformVector() method will set the w property if you define a matrix that affects the fourth coordinate of the vector, for example a perspective projection matrix. However, it assumes the w coordinate of the input vector is 1, even though the default value for the w coordinate is 0.</p>

<p><a href="https://bugs.adobe.com/jira/browse/FP-1354">Vote for this bug on Adobe&#8217;s bug tracker</a></p>

<h2>The end</h2>

<p>That&#8217;s all the bugs I found. Please vote for them in the Adobe bug tracking site.</p>

<p>That&#8217;s also the end of this series of posts about Coral and Flash&#8217;s native 3D Math classes. Please feel free to <a href="https://github.com/richardlord/Coral">use, fork and improve</a> Coral. And let me know what you think, in the comments or <a href="http://twitter.com/richard_lord">via Twitter</a>.</p>

<h2>Footnote</h2>

<p>The new <a href="http://labs.adobe.com/technologies/flashplatformruntimes/incubator/">Flash Player 11 Incubator pre-release</a> became available on 28 February. I ran the test suite using this new player and all the bugs appear to still be present. That&#8217;s not surprising since I only notified Adobe of the bugs a few days before the pre-release.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/bugs-in-vector3d-and-matrix3d/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Performance of Coral vs Vector3D and Matrix3D</title>
		<link>http://www.richardlord.net/blog/performance-of-coral-vs-vector3d-and-matrix3d</link>
		<comments>http://www.richardlord.net/blog/performance-of-coral-vs-vector3d-and-matrix3d#comments</comments>
		<pubDate>Thu, 24 Feb 2011 18:36:34 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Coral]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.richardlord.net/?p=772</guid>
		<description><![CDATA[This is part 3 of a 4 part series comparing Coral, a derivative of the 3D math classes that used to be in the Flint Particles project, and Flash&#8217;s native 3D math classes. In the first post I introduced Coral, explaining what it is and why I&#8217;m releasing it as an open source project. The [...]]]></description>
			<content:encoded><![CDATA[<p>This is part 3 of a 4 part series comparing <a href="https://github.com/richardlord/Coral">Coral</a>, a derivative of the 3D math classes that used to be in the <a href="http://flintparticles.org/">Flint Particles</a> project, and Flash&#8217;s native 3D math classes.</p>

<p>In the first post I <a href="/blog/introducing-coral-an-actionscript-library-for-3d-math">introduced Coral</a>, explaining what it is and why I&#8217;m releasing it as an open source project. The next post looked at <a href="/blog/architecture-of-coral-vs-vector3d-and-matrix3d">the key architectural differences between Coral and the native Vector3D and Matrix3D classes</a>. In a later post I will show you <a href="/blog/bugs-in-vector3d-and-matrix3d">the bugs I discovered in the native 3D math classes</a>. This post is about performance.</p>

<p>Coral is covered by <a href="https://github.com/richardlord/Coral/tree/master/performance/net/richardlord/coral">a set of performance tests</a> for measuring and optimizing it&#8217;s performance. These tests are run using Grant Skinner&#8217;s <a href="http://gskinner.com/blog/archives/2010/02/performancetest.html">performance test suite</a>. I adapted these tests to also apply to the <a href="https://github.com/richardlord/Coral/tree/master/native/performance">native 3D geometry classes</a>, for comparison. All the test code is <a href="https://github.com/richardlord/Coral">in the Coral project on Github</a>.</p>

<p>I ran these tests on my laptop, a MacBook with a 2.4GHz Core2Duo cpu, with the release version of Flash Player 10.2.152.26. All tests were over 1,000,000 iterations and each test is run four times and an average taken.</p>

<h2>Vector3d performance tests</h2>

<table>
<tr><td colspan="2">Coral Vector3d Performance tests.</td><td colspan="2">Native Vector3D Performance tests.</td><td></td></tr>
<tr><td>Description</td><td>Time (ms)</td><td>Description</td><td>Time (ms)</td><td>% diff</td></tr>
<tr><td>new Vector3d()</td><td>154.5</td><td>new Vector3D()</td><td>178</td><td>87%</td></tr>
<tr><td>new Vector3d( x, y, z )</td><td>156</td><td>new Vector3D( x, y, z )</td><td>173.5</td><td>90%</td></tr>
<tr><td>Vector3d.reset( x, y, z )</td><td>21.75</td><td>v = new Vector3D( x, y, z )</td><td>173.5</td><td>13%</td></tr>
<tr><td>Vector3d.assign( v )</td><td>17.25</td><td>u = v.clone()</td><td>183.75</td><td>9%</td></tr>
<tr><td>Vector3d.clone()</td><td>179.75</td><td>Vector3D.clone()</td><td>183.75</td><td>98%</td></tr>
<tr><td>Vector3d.add( v )</td><td>171</td><td>Vector3D.add( v )</td><td>183.25</td><td>93%</td></tr>
<tr><td>Vector3d.add( v, r )</td><td>13.5</td><td>Vector3D.add( v )</td><td>183.25</td><td>7%</td></tr>
<tr><td>Vector3d.subtract( v )</td><td>176.25</td><td>Vector3D.subtract( v )</td><td>184.25</td><td>96%</td></tr>
<tr><td>Vector3d.subtract( v, r )</td><td>13.75</td><td>Vector3D.subtract( v )</td><td>184.25</td><td>7%</td></tr>
<tr><td>Vector3d.multiply( s )</td><td>205.5</td><td>Vector3D.clone().scaleBy( s )</td><td>191.75</td><td>107%</td></tr>
<tr><td>Vector3d.multiply( s, r )</td><td>13</td><td>Vector3D.clone().scaleBy( s )</td><td>191.75</td><td>7%</td></tr>
<tr><td>Vector3d.divide( s )</td><td>207</td><td>Vector3D.clone().scaleBy( 1 / s )</td><td>199.75</td><td>104%</td></tr>
<tr><td>Vector3d.divide( s, r )</td><td>21.75</td><td>Vector3D.clone().scaleBy( 1 / s )</td><td>199.75</td><td>11%</td></tr>
<tr><td>Vector3d.incrementBy( v )</td><td>11.75</td><td>Vector3D.incrementBy( v )</td><td>11</td><td>107%</td></tr>
<tr><td>Vector3d.decrementBy( v )</td><td>12</td><td>Vector3D.decrementBy( v )</td><td>12</td><td>100%</td></tr>
<tr><td>Vector3d.scaleBy( s )</td><td>9.75</td><td>Vector3D.scaleBy( s )</td><td>10</td><td>98%</td></tr>
<tr><td>Vector3d.divideBy( s )</td><td>11</td><td>Vector3D.scaleBy( 1 / s )</td><td>12.5</td><td>88%</td></tr>
<tr><td>Vector3d.equals( v ) true</td><td>16.25</td><td>Vector3D.equals( v ) true</td><td>16.25</td><td>100%</td></tr>
<tr><td>Vector3d.equals( v ) false</td><td>12.75</td><td>Vector3D.equals( v ) false</td><td>13.25</td><td>96%</td></tr>
<tr><td>Vector3d.nearEquals( v ) true</td><td>13</td><td>Vector3D.nearEquals( v ) true</td><td>20</td><td>65%</td></tr>
<tr><td>Vector3d.nearEquals( v ) false</td><td>13</td><td>Vector3D.nearEquals( v ) false</td><td>13.5</td><td>96%</td></tr>
<tr><td>Vector3d.dotProduct( v )</td><td>12.5</td><td>Vector3D.dotProduct( v )</td><td>12</td><td>104%</td></tr>
<tr><td>Vector3d.crossProduct( v )</td><td>178</td><td>Vector3D.crossProduct( v )</td><td>186.25</td><td>96%</td></tr>
<tr><td>Vector3d.crossProduct( v, r )</td><td>18.5</td><td>Vector3D.crossProduct( v )</td><td>186.25</td><td>10%</td></tr>
<tr><td>Vector3d.length</td><td>32.75</td><td>Vector3D.length</td><td>35.25</td><td>93%</td></tr>
<tr><td>Vector3d.lengthSquared</td><td>9.25</td><td>Vector3D.lengthSquared</td><td>9</td><td>103%</td></tr>
<tr><td>Vector3d.negative()</td><td>172</td><td>Vector3D.clone().negate()</td><td>192.75</td><td>89%</td></tr>
<tr><td>Vector3d.negative( r )</td><td>13.5</td><td>Vector3D.clone().negate()</td><td>192.75</td><td>7%</td></tr>
<tr><td>Vector3d.negate()</td><td>10.75</td><td>Vector3D.negate()</td><td>11</td><td>98%</td></tr>
<tr><td>Vector3d.normalize()</td><td>47</td><td>Vector3D.normalize()</td><td>45.75</td><td>103%</td></tr>
<tr><td>Vector3d.unit()</td><td>222.75</td><td>Vector3D.clone().normalize()</td><td>240.75</td><td>93%</td></tr>
<tr><td>Vector3d.unit( r )</td><td>41.25</td><td>Vector3D.clone().normalize()</td><td>240.75</td><td>17%</td></tr>
</table>

<p>Comparing Coral&#8217;s Vector3d class to the native Vector3D class, the first thing I notice is that the majority of methods show insignificant differences. Those methods where significant differences occur are situations where Coral avoids creation of a temporary object. Thus, Coral is marginally faster when adding two vectors to produce a third new vector, but is very much quicker when it&#8217;s allowed to use an existing vector to hold the result &#8211; something which the native vector class can&#8217;t do.</p>

<h2>Point3d performance tests</h2>

<table>
<tr><td colspan="2">Coral Point3d Performance tests.</td><td colspan="2">Native Vector3D Performance tests.</td><td></td></tr>
<tr><td>Description</td><td>Time (ms)</td><td>Description</td><td>Time (ms)</td><td>% diff</td></tr>
<tr><td>new Point3d()</td><td>155</td><td>new Vector3D()</td><td>178</td><td>87%</td></tr>
<tr><td>new Point3d( x, y, z )</td><td>164</td><td>new Vector3D( x, y, z )</td><td>173.5</td><td>95%</td></tr>
<tr><td>Point3d.reset( x, y, z )</td><td>20.75</td><td>v = new Vector3D( x, y, z )</td><td>173.5</td><td>12%</td></tr>
<tr><td>Point3d.assign( v )</td><td>12.5</td><td>u = Vector3D.clone()</td><td>183.75</td><td>7%</td></tr>
<tr><td>Point3d.clone()</td><td>166.75</td><td>Vector3D.clone()</td><td>183.75</td><td>91%</td></tr>
<tr><td>Point3d.add( v )</td><td>173.5</td><td>Vector3D.add( v )</td><td>183.25</td><td>95%</td></tr>
<tr><td>Point3d.add( v, r )</td><td>13.25</td><td>Vector3D.add( v )</td><td>183.25</td><td>7%</td></tr>
<tr><td>Point3d.subtract( v )</td><td>170.75</td><td>Vector3D.subtract( v )</td><td>184.25</td><td>93%</td></tr>
<tr><td>Point3d.subtract( v, r )</td><td>14</td><td>Vector3D.subtract( v )</td><td>184.25</td><td>8%</td></tr>
<tr><td>Point3d.incrementBy( v )</td><td>11.75</td><td>Vector3D.incrementBy( v )</td><td>11</td><td>107%</td></tr>
<tr><td>Point3d.decrementBy( v )</td><td>10.75</td><td>Vector3D.decrementBy( v )</td><td>12</td><td>90%</td></tr>
<tr><td>Point3d.equals( v ) true</td><td>15.25</td><td>Vector3D.equals( v ) true</td><td>16.25</td><td>94%</td></tr>
<tr><td>Point3d.equals( v ) false</td><td>12</td><td>Vector3D.equals( v ) false</td><td>13.25</td><td>91%</td></tr>
<tr><td>Point3d.nearTo( p ) true</td><td>13.75</td><td>Vector3D.nearEquals( v ) true</td><td>20</td><td>69%</td></tr>
<tr><td>Point3d.nearTo( p ) false</td><td>13.75</td><td>Vector3D.nearEquals( v ) false</td><td>13.5</td><td>102%</td></tr>
<tr><td>Point3d.distance( v )</td><td>37</td><td>Vector3D.subtract( v ).length</td><td>214.75</td><td>17%</td></tr>
<tr><td>Point3d.distanceSquared( v )</td><td>12</td><td>Vector3D.subtract( v ).lengthSquared</td><td>194.25</td><td>6%</td></tr>
<tr><td>Point3d.project()</td><td>15.75</td><td>Vector3D.project()</td><td>16.25</td><td>97%</td></tr>
</table>

<p>As with Coral&#8217;s Vector3d class, the Point3d class has comparable (usually marginally faster) performance where functionality is identical, but is very much faster where it is able to avoid creating a temporary object.</p>

<h2>Matrix3d performance tests</h2>

<table>
<tr><td colspan="2">Coral Matrix3d Performance tests.</td><td colspan="2">Native Matrix3D Performance tests.</td><td></td></tr>
<tr><td>Description</td><td>Time (ms)</td><td>Description</td><td>Time (ms)</td><td>% diff</td></tr>
<tr><td>new Matrix3d()</td><td>185</td><td>new Matrix3D()</td><td>242.75</td><td>76%</td></tr>
<tr><td>new Matrix3d( n11, n12, &#8230; )</td><td>212</td><td>new Matrix3D( v )</td><td>255.5</td><td>83%</td></tr>
<tr><td>Matrix3d.clone()</td><td>218.75</td><td>Matrix3D.clone()</td><td>637.75</td><td>34%</td></tr>
<tr><td>Matrix3d.rawData</td><td>536.75</td><td>Matrix3D.rawData</td><td>312.5</td><td>172%</td></tr>
<tr><td>Matrix3d.rawData = v</td><td>120.75</td><td>Matrix3D.rawData = v</td><td>54.5</td><td>222%</td></tr>
<tr><td>Matrix3d.assign( m )</td><td>16.75</td><td>m1.rawData = m2.rawData</td><td>729.25</td><td>2%</td></tr>
<tr><td>Matrix3d.newScale( x, y, z )</td><td>208.25</td><td>new Matrix3D().appendScale( x, y, z )</td><td>314.5</td><td>66%</td></tr>
<tr><td>Matrix3d.newTranslation( x, y, z )</td><td>209.75</td><td>new Matrix3D().appendTranslation( x, y, z )</td><td>253.75</td><td>83%</td></tr>
<tr><td>Matrix3d.newRotation( angle, axis, point )</td><td>387.25</td><td>new Matrix3D().appendRotation( angle, axis, point )</td><td>502.5</td><td>77%</td></tr>
<tr><td>Matrix3d.newBasisTransform( v1, v2, v3 )</td><td>266.75</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.append( m )</td><td>68.5</td><td>Matrix3D.append( m )</td><td>65.75</td><td>104%</td></tr>
<tr><td>Matrix3d.appendScale( x, y, z )</td><td>14.75</td><td>Matrix3D.appendScale( x, y, z )</td><td>83.25</td><td>18%</td></tr>
<tr><td>Matrix3d.appendTranslation( x, y, z )</td><td>25.5</td><td>Matrix3D.appendTranslation( x, y, z )</td><td>21.25</td><td>120%</td></tr>
<tr><td>Matrix3d.appendRotation( angle, axis, point )</td><td>263.25</td><td>Matrix3D.appendRotation( angle, axis, point )</td><td>273.25</td><td>96%</td></tr>
<tr><td>Matrix3d.appendBasisTransform( v1, v2, v3 )</td><td>104.75</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.prepend( m )</td><td>76.5</td><td>Matrix3D.prepend( m )</td><td>65.75</td><td>116%</td></tr>
<tr><td>Matrix3d.prependScale( x, y, z )</td><td>14.75</td><td>Matrix3D.prependScale( x, y, z )</td><td>171.5</td><td>9%</td></tr>
<tr><td>Matrix3d.prependTranslation( x, y, z )</td><td>22.25</td><td>Matrix3D.prependTranslation( x, y, z )</td><td>89.5</td><td>25%</td></tr>
<tr><td>Matrix3d.prependRotation( angle, axis, point )</td><td>278.25</td><td>Matrix3D.prependRotation( angle, axis, point )</td><td>273.25</td><td>102%</td></tr>
<tr><td>Matrix3d.prependBasisTransform( v1, v2, v3 )</td><td>103.5</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.determinant</td><td>30.75</td><td>Matrix3D.determinant</td><td>84</td><td>37%</td></tr>
<tr><td>Matrix3d.invert()</td><td>138.5</td><td>Matrix3D.invert()</td><td>150.5</td><td>92%</td></tr>
<tr><td>Matrix3d.inverse()</td><td>315.75</td><td>Matrix3D.clone().invert()</td><td>821.5</td><td>38%</td></tr>
<tr><td>Matrix3d.inverse( r )</td><td>127.75</td><td>Matrix3D.clone().invert()</td><td>821.5</td><td>16%</td></tr>
<tr><td>Matrix3d.transformVector( v )</td><td>187.75</td><td>Matrix3D.deltaTransformVector( v )</td><td>542</td><td>35%</td></tr>
<tr><td>Matrix3d.transformVector( v, r )</td><td>23.75</td><td>Matrix3D.deltaTransformVector( v )</td><td>542</td><td>4%</td></tr>
<tr><td>Matrix3d.transformVectorSelf( v )</td><td>19.5</td><td>Matrix3D.deltaTransformVector( v )</td><td>542</td><td>4%</td></tr>
<tr><td>Matrix3d.transformPoint( v )</td><td>186.5</td><td>Matrix3D.transformVector( v )</td><td>537.5</td><td>35%</td></tr>
<tr><td>Matrix3d.transformPoint( v, r )</td><td>23.5</td><td>Matrix3D.transformVector( v )</td><td>537.5</td><td>4%</td></tr>
<tr><td>Matrix3d.transformPointSelf( v )</td><td>19.5</td><td>Matrix3D.transformVector( v )</td><td>537.5</td><td>4%</td></tr>
<tr><td>Matrix3d.transformVectors( v )*</td><td>903</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.transformVectors( v, r )*</td><td>182</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.transformVectorsSelf( v )*</td><td>184</td><td>-</td><td>-</td><td></td></tr>
<tr><td>Matrix3d.transformPoints( v )*</td><td>904.5</td><td>Matrix3D.transformVectors( v, r )*</td><td>129.75</td><td>697%</td></tr>
<tr><td>Matrix3d.transformPoints( v, r )*</td><td>183</td><td>Matrix3D.transformVectors( v, r )*</td><td>129.75</td><td>141%</td></tr>
<tr><td>Matrix3d.transformPointsSelf( v )*</td><td>184.5</td><td>Matrix3D.transformVectors( v, r )*</td><td>129.75</td><td>142%</td></tr>
</table>

<p><i>* collection being transformed contained 30 vectors/points</i></p>

<p>The results of the matrix tests are more diverse than the vector and point tests. Creating transformation matrices using &#8216;new&#8217; plus the various append/prepend transformation methods will usually be quicker with Coral than with the native classes. In some cases (e.g. prependScale) the difference is very large.</p>

<p>However, it could be argued that this is rarely important. The area where real speed is needed is when performing transformations on vectors and points. Here the performance profiles differ. Coral is very much faster when performing transformations on individual vectors and points, where it can produce a 25x speed improvement by avoiding creating temporary objects.</p>

<p>However, if you bundle all your points into a Vector.&lt;Number&gt; collection, the native Matrix3D class outperforms everything else.</p>

<h2>Next</h2>

<p>That&#8217;s all for performance. Overall I have found Coral to be a lot more performant than the native 3D math classes. In the final post in this series I will look at <a href="/blog/bugs-in-vector3d-and-matrix3d">the bugs in Flash&#8217;s native 3D classes that were revealed by applying Coral&#8217;s unit tests to the native 3D classes</a>.</p>

<h2>Footnote</h2>

<p>The new <a href="http://labs.adobe.com/technologies/flashplatformruntimes/incubator/">Flash Player 11 Incubator pre-release</a> became available on 28 February. This pre-release is only available as a debug version, so results from it are not comparable to the release players. Even so, I ran the tests out of interest and it looks like Matrix3D.transformVectors() has got a lot faster. There is nothing else of significance to draw from the debug version &#8211; we&#8217;ll have to wait for a release version to land to find out more.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/performance-of-coral-vs-vector3d-and-matrix3d/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Architecture of Coral vs Vector3D and Matrix3D</title>
		<link>http://www.richardlord.net/blog/architecture-of-coral-vs-vector3d-and-matrix3d</link>
		<comments>http://www.richardlord.net/blog/architecture-of-coral-vs-vector3d-and-matrix3d#comments</comments>
		<pubDate>Thu, 24 Feb 2011 18:31:40 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Coral]]></category>

		<guid isPermaLink="false">http://www.richardlord.net/?p=770</guid>
		<description><![CDATA[This is part 2 of a 4 part series comparing Coral, a derivative of the 3D math classes that used to be in the Flint Particles project, and Flash&#8217;s native 3D math classes. In the first post I introduced Coral, explaining what it is and why I&#8217;m releasing it as an open source project. In [...]]]></description>
			<content:encoded><![CDATA[<p>This is part 2 of a 4 part series comparing <a href="https://github.com/richardlord/Coral">Coral</a>, a derivative of the 3D math classes that used to be in the <a href="http://flintparticles.org/">Flint Particles</a> project, and Flash&#8217;s native 3D math classes.</p>

<p>In the first post I <a href="/blog/introducing-coral-an-actionscript-library-for-3d-math">introduced Coral</a>, explaining what it is and why I&#8217;m releasing it as an open source project. In later posts I will <a href="/blog/performance-of-coral-vs-vector3d-and-matrix3d">compare the performance of Coral with the native Vector3D &#038; Matrix3D classes</a> and will discuss <a href="/blog/bugs-in-vector3d-and-matrix3d">the bugs I discovered in the native 3D math classes</a>.</p>

<p>In this post I will look at the key architectural differences between Coral and the native Vector3D and Matrix3D classes. Code architecture is an important area to me. I find well architected code is much easier to use, leading to more rapid development and fewer bugs. So good architecture in core classes like Vector3D and Matrix3D can make a lot of difference to developers.</p>

<p>I happen to think that Coral has a much better architecture than the native classes, but then I would &#8211; I wrote it. I&#8217;d like to know what you think, in the comments below or <a href="http://twitter.com/richard_lord">on Twitter</a>.</p>

<h2>How many core classes do we need?</h2>

<p>The first thing you&#8217;ll notice when comparing the two projects is the number of core classes they have. The core 3D geometry classes in Flash are</p>

<ul>
<li><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Vector3D.html">Vector3D</a></li>
<li><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix3D.html">Matrix3D</a></li>
</ul>

<p>In Coral, the core classes are</p>

<ul>
<li><a href="https://github.com/richardlord/Coral/blob/master/src/net/richardlord/coral/Vector3d.as">Vector3d</a></li>
<li><a href="https://github.com/richardlord/Coral/blob/master/src/net/richardlord/coral/Point3d.as">Point3d</a></li>
<li><a href="https://github.com/richardlord/Coral/blob/master/src/net/richardlord/coral/Quaternion.as">Quaternion</a></li>
<li><a href="https://github.com/richardlord/Coral/blob/master/src/net/richardlord/coral/Matrix3d.as">Matrix3d</a></li>
</ul>

<p>This is because the native Vector3D class is used to represent vectors, points and quaternions. I think this is a big architectural mistake and so Coral has separate classes for each type. Here&#8217;s why&#8230;</p>

<h2>Vectors and Points</h2>

<p>A point is a location in space, like the centre of Trafalgar Square in London, or the centre of Times Square in New York. You can&#8217;t do much to a point &#8211; you can&#8217;t add points together (Times Square + Trafalgar Square = ?), you can&#8217;t multiply them by a scalar (what&#8217;s 2 x the centre of Times Square?). You can&#8217;t find the dot product of two points. Points have zero dimensions and there&#8217;s not a lot you can do with points alone, except change the coordinate system you use to represent them.</p>

<p>A vector on the other hand represents a direction and distance in space. Like 5 miles north, or 3 miles west. 5 miles north is a vector &#8211; it&#8217;s a distance and a direction. We can do lots more with vectors. For example, we can add them together: 5 miles north + 5 miles west = 7 and a bit miles north west (thanks to Pythagoras for that one). We can subtract them: 5 miles north &#8211; 5 miles west = 7 and a bit miles north east. We can multiply them by a scalar: 2 * 5 miles north = 10 miles north, and we can do a whole lot more besides, like dot product, cross product, normalize, etc.</p>

<p>We can also add a vector to a point, to get a new point &#8211; Times square + 5 miles north = somewhere in New Jersey.</p>

<p>The whole point of this is, points and vectors are different. Yes, they can both be represented in cartesian coordinate space by three coordinates, but that doesn&#8217;t make them the same.</p>

<p>Yet Actionscript uses a single class (Vector3D) to represent them both. So, in the Vector3D class we have methods like crossProduct() and properties like length that only apply to vectors, and we have methods like project() that only apply to points. It&#8217;s the developer&#8217;s responsibility to know whether the Vector3D object they&#8217;re using actually represents a point or a vector, and hence which methods are valid.</p>

<p>Coral has no such issues because in Coral points and vectors are represented by different classes.</p>

<h2>Matrix Transformations</h2>

<p>Transformations in 3D space are commonly represented by a 4&#215;4 matrix. A transformation that doesn&#8217;t move the origin can be, and often is, represented with a 3&#215;3 matrix.</p>

<pre class="code">[ a b c ]
[ d e f ]
[ g h i ]</pre>

<p>We can multiply our vector or point by this matrix to get the transformed vector or point.</p>

<pre class="code">[ a b c ]   [ x ]   [ new_x ]
[ d e f ] x [ y ] = [ new_y ]
[ g h i ]   [ z ]   [ new_z ]</pre>

<p>If we want to include translations in the transformation we use a 4&#215;4 matrix.</p>

<pre class="code">[ a b c tx ]
[ d e f ty ]
[ g h i tz ]
[ 0 0 0 1  ]</pre>

<p>Where tx, ty and tz represent the translation in the x, y and z directions. We also add a fourth value to the point or vector, often called the w coordinate, to bring the translation in to play. For a point we would use 1 for the w value.</p>

<pre class="code">[ a b c tx ]   [ x ]   [ new_x + tx ]
[ d e f ty ] x [ y ] = [ new_y + ty ]
[ g h i tz ]   [ z ]   [ new_z + tz ]
[ 0 0 0 1  ]   [ 1 ]   [     1      ]</pre>

<p>By using a 1 for the y coordinate, we ensure the translation elements are added in to the transformation of the point.</p>

<p>However, when transforming a vector, the translation part of the transformation should not be applied. This is because, unlike a point, a vector is not located in the three-d space. The vector &#8220;5 miles north&#8221; is the same whether you are in London or New York.</p>

<p>To avoid applying the translation part of the 4&#215;4 matrix when transforming a vector, we set the w coordinate of the vector to 0.</p>

<pre class="code">[ a b c tx ]   [ x ]   [ new_x ]
[ d e f ty ] x [ y ] = [ new_y ]
[ g h i tz ]   [ z ]   [ new_z ]
[ 0 0 0 1  ]   [ 0 ]   [   0   ]</pre>

<p>This is another area where vectors and points differ, and Coral takes care of the difference for you. Coral&#8217;s Vector3d and Point3d classes both have a w coordinate, which defaults to 0 in the Vector3d class and 1 in the Point3d class. You don&#8217;t usually have to change these values, but if you do that&#8217;s fine. The Matrix3d class will use whatever value of w the point or vector has when transforming it.</p>

<p>Actionscript&#8217;s Vector3D class also has a w coordinate property. the value of this property defaults to 0. Don&#8217;t bother changing it because the value of this property is ignored when applying a Matrix3D transformation to a Vector3D object. Instead, to transform your point or vector you have to choose between the radically misnamed transformVector() method, which assumes a w coordinate of 1, for transforming a point and the almost as badly named deltaTransformVector() method, which assumes a w coordinate of 0, for transforming a vector.</p>

<h2>Quaternions</h2>

<p><a href="http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation">Quaternions</a> are another object type used in 3D geometry. A quaternion represents a rotation in 3D space. Rotations can be represented using a Matrix, but sometimes it&#8217;s much easier to use a quaternion.</p>

<p>A quaternion has nothing in common with a vector or a point, although a quaternion is represented using four numbers, commonly called w, x, y &#038; z. These are not like the coordinates of a vector or point and the common methods of vectors and points don&#8217;t apply to quaternions. Despite this, in the native 3D classes quaternions are represented using the Vector3D class. This overloads the Vector3D class with yet another object to represent &#8211; an object to which methods like crossProduct() and project() are meaningless, and which can&#8217;t be transformed by a matrix.</p>

<p>This is so confusing that most 3D Actionscript libraries give up at this point and create their own class to represent a quaternion. Flint is no exception to this rule &#8211; it uses the quaternion class from Coral.</p>

<h2>More methods</h2>

<p>Coral contains many methods that are not in the native Vector3D and Matrix3D classes, ranging from simple methods like Vector3d.multiply() to more complex methods like Matrix3d.appendBasisTransform(). These are all useful additions to the classes and make 3D development simpler because it frees developers from having to implement these behaviours in their own code.</p>

<h2>Method chaining</h2>

<p>Often the code that uses classes like Vector3D is performing simple mathematical methods on vector or point objects. For example, if you have an initial position point p, an initial velocity vector u and final velocity vector v and a time number t, and you want to calculate the new position after time t. In mathematics, this would be expressed as</p>

<pre class="code">newP = p + ( u + v ) * t / 2</pre>

<p>In the absence of operator overloading, we can&#8217;t make the same calculation in Acrionscript look as concise as the mathematics, but we can do better than Flash&#8217;s native Vector3D class.</p>

<p>Using Flash&#8217;s native Vector3D class the calculation above is expressed as</p>

<pre class="code">var temp:Vector3D = u.add( v );
temp.scaleBy( t / 2 );
p.incrementBy( temp );

<i>(252 ms for 1,000,000 iterations)</i></pre>

<p>Using Coral&#8217;s classes, the same calculation is expressed as</p>

<pre class="code">p.incrementBy( u.add( v ).scaleBy( t / 2 ) );

<i>(194 ms for 1,000,000 iterations)</i></pre>

<p>In Coral, all methods that manipulate the object the method belongs to return a reference to that object (i.e. a reference to &#8216;this&#8217;). So in the example above, the scaleBy method of the Vector3d class returns a reference to the vector that has been scaled. This enables chaining of methods to produce more compact, cleaner code.</p>

<h2>Optional result objects</h2>

<p>It is common knowledge that object creation in Actionscript is slow. That&#8217;s why many speed-critical projects use object pools to reuse objects rather than create new ones. Unfortunately, it&#8217;s very difficult to use Flash&#8217;s native geometry classes without creating lots of temporary Vector3D and Matrix3D objects.</p>

<p>The previous example is a case in point. The temporary vector object is explicitly required in the native example. In the Coral example, a similar temporary object is created from the addition. But with Coral this can be avoided. In Coral, all methods that would create an object to hold the result of the method, have an optional parameter allowing you to pass in an object to hold the result and thus avoid the object creation.</p>

<p>So, if I have a temporary Vector3d available, from an object pool or elsewhere, I can rewrite the calculation above as</p>

<pre class="code">p.incrementBy( ( u.add( v, temp ).scaleBy( t / 2 ) );

<i>(35 ms for 1,000,000 iterations)</i></pre>

<p>and get a fivefold speed increase by avoiding the object creation.</p>

<h2>Conclusion</h2>

<p>It&#8217;s my opinion that the overloading of a single Vector3D class to represent vectors, points and quaternions is the worst architectural mistake in Actionscript&#8217;s native 3D math classes. That the matrix transformations also ignore the w coordinate, forcing one to choose between two badly named methods instead, compounds the problem.</p>

<p>The other architectural improvements in Coral that I mention above improve readability and performance of the code, and hence are very useful.</p>

<h2>Next</h2>

<p>That&#8217;s all for architecture. Next time I&#8217;ll <a href="/blog/performance-of-coral-vs-vector3d-and-matrix3d">compare the performance of Flash&#8217;s native 3D math classes and the classes in Coral</a>. Then I&#8217;ll finish up by describing <a href="/blog/bugs-in-vector3d-and-matrix3d">the bugs I found in the native Vector3D and Matrix3D classes</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/architecture-of-coral-vs-vector3d-and-matrix3d/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducing Coral, an Actionscript library for 3D Math</title>
		<link>http://www.richardlord.net/blog/introducing-coral-an-actionscript-library-for-3d-math</link>
		<comments>http://www.richardlord.net/blog/introducing-coral-an-actionscript-library-for-3d-math#comments</comments>
		<pubDate>Thu, 24 Feb 2011 18:28:07 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Coral]]></category>
		<category><![CDATA[Flint]]></category>

		<guid isPermaLink="false">http://www.richardlord.net/?p=768</guid>
		<description><![CDATA[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 &#8211; Away3D and Papervision3D had their own Number3D and Matrix3D classes, for example. Since the release of Flash 10, open-source projects [...]]]></description>
			<content:encoded><![CDATA[<h2>The experience of Flint</h2>

<p>I started work on <a href="http://flintparticles.org/">Flint Particles</a> before Flash 10 was launched, so back then I created my own 3D mathematics classes for Flint. At the time this was not unusual &#8211; <a href="http://away3d.com/">Away3D</a> and <a href="http://blog.papervision3d.org/">Papervision3D</a> had their own Number3D and Matrix3D classes, for example.</p>

<p>Since the release of Flash 10, open-source projects have gradually switched to use the native <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Vector3D.html">Vector3D</a> and <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix3D.html">Matrix3D</a> 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.</p>

<p>Converting Flint to use the native classes was an interesting experience. For one thing, I think the architecture of Flint&#8217;s classes was better than the native classes. That wasn&#8217;t sufficient reason to stick with Flint&#8217;s own classes; using it&#8217;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&#8217;t use the excellent <a href="https://github.com/robertpenner/as3-signals">As3-Signals</a> library by Robert Penner in Flint, even though I use it in all my other work.)</p>

<p>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 <a href="https://twitter.com/richard_lord/status/2269097639288832">one line of code using Flint&#8217;s classes had to be replaced with 3 or 4 lines of code using the native classes</a>.</p>

<p>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 &#8211; the code using the native 3D classes ran at about one quarter of the rate of the code using Flint&#8217;s own 3D classes.</p>

<p>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&#8217;s position from global coordinate space to camera coordinate space, where instead of a simple</p>

<pre class="code">pp = camera.transform.transformVector( p );</pre>

<p>Flint now does</p>

<pre class="code">var raw:Vector.<Number> = 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;</pre>

<p>for a massive performance improvement.</p>

<h2>Coral</h2>

<p>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.</p>

<p>I am calling the project &#8220;Coral&#8221; &#8211; apparently small pieces of coral are sometimes found inside larger pieces of flint. <a href="https://github.com/richardlord/Coral">Coral is available on Github</a>, including unit tests and performance tests. Please feel free to use it, fork it and improve it.</p>

<p>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.</p>

<p>In the following posts I&#8217;ll look at the results of these tests, with posts <a href="/blog/bugs-in-vector3d-and-matrix3d">about the bugs I found</a> and <a href="/blog/performance-of-coral-vs-vector3d-and-matrix3d">a performance comparison of Coral and the native classes</a>. But first, if you&#8217;ll indulge me, here&#8217;s a post <a href="/blog/architecture-of-coral-vs-vector3d-and-matrix3d">comparing the architecture of Coral and the architecture of Flash&#8217;s native 3D classes</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/introducing-coral-an-actionscript-library-for-3d-math/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flint does Papervision3D and Away3D</title>
		<link>http://www.richardlord.net/blog/flint-does-papervision3d-and-away3d</link>
		<comments>http://www.richardlord.net/blog/flint-does-papervision3d-and-away3d#comments</comments>
		<pubDate>Wed, 17 Sep 2008 09:25:04 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Away3D]]></category>
		<category><![CDATA[Flint]]></category>
		<category><![CDATA[Papervision3D]]></category>
		<category><![CDATA[Particles]]></category>

		<guid isPermaLink="false">http://www.bigroom.co.uk/blog/flint-does-papervision3d-and-away3d/</guid>
		<description><![CDATA[<p>Today I released a new alpha of version 2 of the <a href="http://flintparticles.org">Flint particle system</a>. This version adds renderers for Papervision3D and Away3D to the library, so that particle effects can be integrated with a 3D scene in these libraries...</p>]]></description>
			<content:encoded><![CDATA[<p>Today I released a new alpha of version 2 of the <a href="http://flintparticles.org">Flint particle system</a>. This version adds renderers for Papervision3D and Away3D to the library, so that particle effects can be integrated with a 3D scene in these libraries.</p>

<p>For Away3D Flint has one renderer, the Away3D renderer, that uses any Away3D Object3D type for displaying each particle inside an ObjectContainer3D. This lets you use 2D sprites or 3D objects for the particles.</p>

<p>For Papervision3D, Flint has three renderers -</p>

<ul>
<li>A pixel renderer that displays each particle as a pixel in a Papervision Pixels object.</li>
<li>A particle renderer that displays each particle in a Papervision Particles object using a Papervision particle.</li>
<li>A basic renderer that displays each particle in a DisplayObject3DContainer using a Papervision DisplayObject3D object.</li>
</ul>

<p>In all cases, the renderer sets the appropriate properties of the particle&#8217;s display object based on the state of the particle system and leaves the 3D engine to do the drawing.</p>

<p>Flint can be downloaded from the <a href="http://code.google.com/p/flint-particle-system/downloads/list">Google Code repository</a>. Along with the source download, you&#8217;ll find documentation and examples using the new features.</p>

<p>Have fun with this, and if you find any bugs or spot a better way to do something please let me know via the <a href="http://flintparticles.org/forum">Flint forum</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/flint-does-papervision3d-and-away3d/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>3D version of Flint Particle System</title>
		<link>http://www.richardlord.net/blog/3d-version-of-flint-particle-system</link>
		<comments>http://www.richardlord.net/blog/3d-version-of-flint-particle-system#comments</comments>
		<pubDate>Mon, 01 Sep 2008 11:55:39 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Flint]]></category>
		<category><![CDATA[Particles]]></category>

		<guid isPermaLink="false">http://www.bigroom.co.uk/blog/3d-version-of-flint-particle-system/</guid>
		<description><![CDATA[<p>Today I released the alpha of version 2 of Flint. This version does 3D particle effects as well as 2D effects. The alpha is fairly stable and can be downloaded from <a href="http://code.google.com/p/flint-particle-system/downloads">Google code</a>.</p>

<p>The 2D effects have some enhancements over previous versions. The 3D effects are all new, and include most of the features from 2D, along with some new stuff. At the moment, rendering is done via Flint's own new 3D renderers, but I'm developing renderers for Papervision3d, Away3d and Sandy3d so that Flint can be used as a particle system with any of these 3d libraries too.</p>]]></description>
			<content:encoded><![CDATA[<p>Today I released the alpha of version 2 of Flint. This version does 3D particle effects as well as 2D effects. The alpha is fairly stable and can be downloaded from <a href="http://code.google.com/p/flint-particle-system/downloads">Google code</a>.</p>

<p>The 2D effects have some enhancements over previous versions. The 3D effects are all new, and include most of the features from 2D, along with some new stuff. At the moment, rendering is done via Flint&#8217;s own new 3D renderers, but I&#8217;m developing renderers for Papervision3d, Away3d and Sandy3d so that Flint can be used as a particle system with any of these 3d libraries too.</p>

<p>Here&#8217;s an example.</p>

<div class="spaced"><div id="swf4f2e7fa83fc26">
<p><b>Flash required:</b> You need version 10 or later of the free Flash player from Adobe to use this content. To download and install the free player from Adobe's web site <a href="http://get.adobe.com/flashplayer/">click here</a>.</p>
</div>
<script type="text/javascript">
var params = {loop:"false",quality:"high",allowfullscreen:"true"};
var flashvars = {};
swfobject.embedSWF("/images/blog/FireworkDisplay.swf", "swf4f2e7fa83fc26", "500", "300", "10.0.0", "/swf/expressInstall.swf", flashvars, params, {} );
</script></div>

<p>Use W,A,S,D keys to track in/out and left/right. Use cursor keys to pan and tilt. Use page-up/page-down to raise and lower the camera.</p>


<p>As always, find out more about Flint from the <a href="http://flintparticle.org/">project website</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/3d-version-of-flint-particle-system/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>If I had more time</title>
		<link>http://www.richardlord.net/blog/if-i-had-more-time</link>
		<comments>http://www.richardlord.net/blog/if-i-had-more-time#comments</comments>
		<pubDate>Fri, 13 Jun 2008 10:28:28 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[All]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Physics]]></category>

		<guid isPermaLink="false">http://www.bigroom.co.uk/blog/if-i-had-more-time/</guid>
		<description><![CDATA[<p>One of the frustrations of being busy with client work is the lack of time to investigate, experiment and play with interesting stuff. One day I'll have time to try all this stuff but until then, here's a simple list of the flash/flex tools I'd like to play with. Maybe you'll find something interesting here...</p>]]></description>
			<content:encoded><![CDATA[<p>One of the frustrations of being busy with client work is the lack of time to investigate, experiment and play with interesting stuff. One day I&#8217;ll have time to try all this stuff but until then, here&#8217;s a simple list of the flash/flex tools I&#8217;d like to play with. Maybe you&#8217;ll find something interesting here.</p>

<h3>Flash Player 10 beta</h3>

<p>Lots of cool new stuff in the Flash Player 10 beta, if only I had time to try it out.</p>

<ul>
<li><a href="http://labs.adobe.com/downloads/flashplayer10.html">The player</a></li>
<li><a href="http://opensource.adobe.com/wiki/display/flexsdk/Targeting+Flash+Player+10+Beta+with+Flex+SDK+3.0.x">The Flex compiler</a></li>
<li><a href="http://download.macromedia.com/pub/labs/flashplayer10/flashplayer10_as3langref_052008.zip">The docs</a></li>
</ul>

<h3>3D engines</h3>

<p>I still haven&#8217;t had time to do much with 3D in Flash (although I need to know to get Flint working in the 3D engines). I want time to experiment with the 3D engines and discover their strengths and weaknesses.</p>

<ul>
<li><a href="http://blog.papervision3d.org/">Papervision3D</a></li>
<li><a href="http://www.flashsandy.org/blog/">Sandy3D</a></li>
<li><a href="http://away3d.com/">Away3D</a></li>
<li><a href="http://www.alternativaplatform.com/en/alternativa3d/">Alternative3D</a></li>
<li><a href="http://five3d.mathieu-badimon.com/">Five3D</a></li>
</ul>

<h3>Physics engines</h3>

<p>I also want time to try out the 2D and 3D physics engines.</p>

<ul>
<li><a href="http://sourceforge.net/projects/box2dflash">Box2DFlashAS3</a></li>
<li><a href="http://code.google.com/p/motor2/">Motor 2</a></li>
<li><a href="http://code.google.com/p/ape/">APE</a></li>
<li><a href="http://code.google.com/p/foam-as3/">FOAM</a></li>
<li><a href="http://www.fisixengine.com/">Fisix</a></li>
<li><a href="http://seraf.mediabox.fr/wow-engine/as3-3d-physics-engine-wow-engine/">Wow-engine</a></li>
</ul>

<h3>Flex tools</h3>

<p>There&#8217;s a number of Flex tools/libraries that I want to investigate. Top of the list are</p>

<ul>
<li><a href="http://mate.asfusion.com/">Mate</a></li>
<li><a href="http://code.google.com/p/openflux/">OpenFlux</a></li>
</ul>

<h3>What I&#8217;m doing now</h3>

<p>Meanwhile, I only have a little spare time, which I&#8217;m using to develop the next version of <a href="http://flintparticles.org/">Flint</a>. I have some other personal projects I want to work on but they are all on hold for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.richardlord.net/blog/if-i-had-more-time/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

