Oh dear! Two simple additional optional parameters for the following methods would allow you to use native performance and save memory.
Thinking of a simple 3d viewing pipeline, you have something like
- Setup geometrie, textures and lights
- Transform local coordinates to camera space
- Clipping against Frustum
- Project and render
They are a lot of helpers that helps you doing the transformation and projection, especially
I assume that Matrix3D.transformVectors and Utils3d.projectVectors are lightning fast, cause you can pass a Vector (sources and targets) to them. A single(!) Vector could contain the entire 3d world geometry as a list of (x,y,z,x,y,z,x,y,z,x,y,z,…). That is why I am thinking that the Flashplayer is able to execute this well formatted list extremely fast! Much faster than calling the methods to transform several Vector3D objects in a AS3 loop.
So far so good. Where is the problem?
The worst thing from the memorys point of view is the clipping part, cause vertices are added and just valid for a single frame (if the Camera or Geometry is moving). A big case for the garbage collection.
Trying to figure out the best data structure for a 3d engine in Flash, I thought of something like this: All 3d world vertices are stored in a single Vector. Furthermore I would also leave some extra space for the expected vertices in the clipping process (increase the Vector length). With this setup, you reserve memory space and there is no reason for the garbage collection to remove used clipping data. You can easily access the clipped vertices with an offset in the Vector.
Note: The Vector would stay fixedSized. It is on you to allocate enough space for the clipping process when you setup.
But it won’t work for now
Imagine you already clipped geometry: Next time you transform the Vector into a new coordinate space, all the clipped data from the last frames will be transformed as well. Two simple optional parameter would change that.
Matrix3D.transformVectors(vin:Vector, vout:Vector, startIndex: uint, endIndex: uint):void
Utils3D.projectVectors(m:Matrix3D, verts:Vector, projectedVerts:Vector, uvts:Vector, startIndex: uint, endIndex: uint):void
Thats it! That simple!
Now you could force the Flashplayer only to transform the necessary range. You simply overwrite the new clipped data in the Vector every frame, project and draw them. If you know the region, where a 3d-object has allocated its vertices you could use the startIndex and endIndex value to transform it at once.
Too late? I guess so. Too bad I started so late…
I created an official feature request at Adobe bugbase. It would be a great feature!
Please vote. It may not be too late.