package { import flash.display.* import flash.events.*; import flash.geom.*; import flash.utils.*; [SWF(backgroundColor = 0x000000, width=500, height=500)] public class World3D extends Sprite { // standard Vectors for using drawTriangles private var _verts:Vector.<Number> = new Vector.<Number>(); private var _pVerts:Vector.<Number>; private var _uvts:Vector.<Number> = new Vector.<Number>(); private var _indices:Vector.<int> = new Vector.<int>(); // needed for z-sorting private var _sortedIndices:Vector.<int>; private var _faces:Array = []; // we'll use this for tranforming points // and as the transformation matrix for our render private var _m:Matrix3D = new Matrix3D(); private var _boxIndex:int = 0; private var _tex:BitmapData; private var _persp:PerspectiveProjection; private var _proj:Matrix3D; private var _dx:Number = 0; private var _dy:Number = 0; public function World3D(){ init(); } private function init():void{ x = stage.stageWidth / 2; y = stage.stageHeight / 2; // create geometry and populate Vectors addBox(0,0,0, 20, 20, 20); addBox(0,0,50, 10, 10, 10); addBox(30,0,50, 3, 3, 3); addBox(30,0,55, 3, 3, 3); addBox(30,0,60, 3, 3, 3); addBox(0,0,-50, 10, 10, 10); addBox(0,-40,0, 10, 10, 10); addBox(14,-40,0, 10, 10, 5); addBox(0,0,15, 10, 10, 3); addBox(0,0,25, 10, 10, 3); addBox(-22,0,0, 15, 15, 15); addBox(-37,0,0, 10, 10, 10); addBox(5,30,5, 10, 5, 10); addBox(-5,35,-5, 10, 5, 10); addBox(0,20,0, 5, 5, 5); addBox(20,0,0, 5, 5, 5); addBox(30,0,0, 5, 5, 5); addBox(40,0,0, 5, 5, 5); addBox(30,20,0, 25, 5, 5); _sortedIndices = new Vector.<int>(_indices.length, true); _verts.fixed = true, _uvts.fixed = true, _indices.fixed = true _pVerts = new Vector.<Number>(_verts.length / 3 * 2, true); // create texture _tex = new BitmapData(400,400,false, 0x000000); var grad:Sprite = new Sprite(); var mat:Matrix = new Matrix(); mat.createGradientBox(400,400,0,0,0); with (grad.graphics){ beginGradientFill(GradientType.LINEAR, [0xFFFFFF,0x002244], [1, 1], [0, 255], mat); drawRect(0,0,400,400); } _tex.perlinNoise(500,500,2,100,false,false,1,true); _tex.draw(grad,null, null, BlendMode.HARDLIGHT); // perspective _persp = new PerspectiveProjection(); _persp.fieldOfView = 45; // projection matrix _proj = _persp.toMatrix3D(); addEventListener(Event.ENTER_FRAME, onLoop); } private function addBox(xp:Number, yp:Number, zp:Number, w:Number, h:Number, leng:Number):void{ var hw:Number = w * 0.5; var hh:Number = h * 0.5; var hl:Number = leng * 0.5; _verts.push(-hw + xp, -hh + yp, -hl + zp, hw + xp, -hh + yp, -hl + zp, -hw + xp, hh + yp, -hl + zp, hw + xp, hh + yp, -hl + zp, -hw + xp, -hh + yp, hl + zp, hw + xp, -hh + yp, hl + zp, -hw + xp, hh + yp, hl + zp, hw + xp, hh + yp, hl + zp); var i8:int = _boxIndex * 8; _indices.push(0 + i8, 1 + i8, 2 + i8, 1 + i8, 3 + i8, 2 + i8, 6 + i8, 7 + i8, 4 + i8, 7 + i8, 5 + i8, 4 + i8, 1 + i8, 5 + i8, 3 + i8, 7 + i8, 3 + i8, 5 + i8, 4 + i8, 5 + i8, 0 + i8, 1 + i8, 0 + i8, 5 + i8, 2 + i8, 6 + i8, 0 + i8, 0 + i8, 6 + i8, 4 + i8, 2 + i8, 3 + i8, 6 + i8, 3 + i8, 7 + i8, 6 + i8); _faces.push(new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face(), new Face()); _uvts.push(Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0, Math.random(), Math.random(), 0); _boxIndex++; } private function onLoop(evt:Event):void { _dx += (mouseX - _dx) / 4; _dy += (mouseY - _dy) / 4; _m.identity(); _m.appendRotation(_dy, Vector3D.X_AXIS); _m.appendRotation(_dx, Vector3D.Y_AXIS); _m.appendTranslation(0,0,100); _m.append(_proj); Utils3D.projectVectors(_m, _verts, _pVerts, _uvts); var face:Face; var inc:int = 0; for (var i:int = 0; i<_indices.length; i+=3){ face = _faces[inc]; face.i0 = _indices[i]; face.i1 = _indices[int(i + 1)]; face.i2 = _indices[int(i + 2)]; var i3:int = i * 3; face.z = (_uvts[int(face.i0*3 + 2)] + _uvts[int(face.i1*3 + 2)] + _uvts[int(face.i2*3 + 2)]) * 0.333333; inc++; } _faces.sortOn("z", Array.NUMERIC); inc = 0; for each (face in _faces){ _sortedIndices[inc++] = face.i0; _sortedIndices[inc++] = face.i1; _sortedIndices[inc++] = face.i2; } graphics.clear(); //graphics.lineStyle(0,0xFF0000); graphics.beginBitmapFill(_tex, null, false, false); graphics.drawTriangles(_pVerts, _sortedIndices, _uvts, TriangleCulling.NEGATIVE); } } } class Face{ public var i0:Number; public var i1:Number; public var i2:Number; public var z:Number; } drawTraingles() Cubes