In the comments of this post, Emanuele Cipolloni put forth the idea that Flash 10 3D is simply done behind the scenes using drawTriangles. That was a interesting realization for me. Made sense, so I decided to test it out. Basically, how would I create a 3D engine like Flash 10 3D using drawTriangles?
1. I’d get the bounds of an object as a rectangle.
2. Create a bitmap of that width and height and draw the object into it.
3. Transform the four corner points of the bounds using standard 3D formulas.
4. Use these transformed points as vertices for triangle drawing, and the bitmap as a bitmap fill.
Here’s what I came up with. The image on the left (the only image you can see at first) is simply an imported bitmap in a movie clip sitting on stage. Click on it, and I do steps 1-4 repeatedly, drawing the triangles in the right part of the stage. The rotationY is increased on each frame.
Essentially, the same thing. The built in version is a lot smoother and cleaner looking, but I’m only using two triangles. And I think they are throwing some smoothing into the mix somewhere. (Perhaps even a slight blur???)
Here’s the code. Beware, it’s crappy, crappy, crappy code. Done on the train and bus on the way to work. Begs to be cleaned up, but I’ve proved my point and probably won’t do much more with it unless I can think of some practical use for it.
[as]var r:Rectangle = box.getBounds(box);
var bmpd:BitmapData = new BitmapData(r.width, r.height, true, 0);
//var bmp:Bitmap = addChild(new Bitmap(bmpd)) as Bitmap;
bmpd.draw(box, new Matrix(1, 0, 0, 1, -r.x, -r.y));
var rotY:Number = 0;
root.transform.perspectiveProjection.projectionCenter = new Point(200, 140);
var running:Boolean = false;
running = !running;
var ry:Number = -rotY * Math.PI / 180;
scales = new Array();
var p0:Point = rotateY(r.top, r.left, ry);
var p1:Point = rotateY(r.top, r.right, ry);
var p2:Point = rotateY(r.bottom, r.right, ry);
var p3:Point = rotateY(r.bottom, r.left, ry);
vertices.push(p0.x + 600, p0.y + 140);
vertices.push(p1.x + 600, p1.y + 140);
vertices.push(p2.x + 600, p2.y + 140);
vertices.push(p3.x + 600, p3.y + 140);
indices.push(0, 1, 3);
indices.push(1, 2, 3);
uvtData.push(0, 0, scales);
uvtData.push(0, 1, scales);
uvtData.push(1, 1, scales);
uvtData.push(1, 0, scales);
graphics.drawTriangles(vertices, indices, uvtData);
rotY += 3;
box.rotationY = rotY;
function rotateY(xpos:Number, ypos:Number, a:Number):Point
var x1:Number = xpos * Math.cos(a);
var z1:Number = xpos * Math.sin(a);
var foc:Number = root.transform.perspectiveProjection.focalLength;
var scale:Number = foc / (foc + z1);
return new Point(x1 * scale, ypos * scale);