 					if (uvStream != xyzStream)
 						uvStream.unlock(false);
 				}
+				
+				if (hitNormal)
+				{
+					// length
+					var edge1Length		: Number	= Math.sqrt(edge1X * edge1X + edge1Y * edge1Y + edge1Z * edge1Z);
+					var edge2Length		: Number	= Math.sqrt(edge2X * edge2X + edge2Y * edge2Y + edge2Z * edge2Z);
+					
+					// normalize
+					edge1X /= edge1Length;
+					edge1Y /= edge1Length;
+					edge1Z /= edge1Length;
+					edge2X /= edge2Length;
+					edge2Y /= edge2Length;
+					edge2Z /= edge2Length;
+					
+					// cross product
+					hitNormal.x = edge1Y * edge2Z - edge1Z * edge2Y;
+					hitNormal.y = edge1Z * edge2X - edge1X * edge2Z;
+					hitNormal.z = edge1X * edge2Y - edge1Y * edge2X;
+				}
 			}
 			
 			_indexStream.unlock(false);

		public function cast(ray 		: Ray,
							 transform 	: Matrix4x4 = null,
							 hitXYZ 	: Vector4 	= null,
							 hitUV		: Point		= null) : int
		{
			var numVertices : uint 	= indexStream._data.length / 2;
			

		 * of the actual ray/geometry hit point.
		 * @param hitUV An optional reference to a Point object to fill with the (u, v) texture coordinates
		 * of the actual ray/geometry hit point.
		 * @param hitNormal An optional reference to a Vector4 object to fill the normal of the intersection
		 * point if any.
		 * 
		 * @return The triangle ID (the ID of the first index of the triangle in the IndexStream) that was
		 * hit by the specified ray, -1 otherwise.
