package { import away3d.containers.*; import away3d.core.base.*; import away3d.core.render.Renderer; import away3d.materials.*; import away3d.primitives.*; import away3d.test.Button; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Vector3D; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.getTimer; [SWF(width="500", height="400", frameRate="60", backgroundColor="#FFFFFF")] public class Triangles extends Sprite { private var View:View3D; private var baseObject:ObjectContainer3D; private var triangles:Array; private var numTriangles:Number = 400; private var label1:TextField; private var label2:TextField; private var lastTime:Number; private var state:String = "Single sided"; public function Triangles() { super(); triangles = new Array(); // prep for handling resizing events this.stage.scaleMode = StageScaleMode.NO_SCALE; this.stage.align = StageAlign.TOP; // create a 3D-viewport View = new View3D({x:250, y:200}); View.renderer = Renderer.BASIC; addChild(View); View.camera.position = new Vector3D(400, 500, 400); View.camera.lookAt( new Vector3D(0, 0, 0) ); // Make container object to attach other objects to baseObject = new ObjectContainer3D(); View.scene.addChild(baseObject); // Make some triangles var newTri:Triangle; for(var i:Number = 0; i < numTriangles; i++) { newTri = makeTriangle(); // Move to random position var max:Number = 120; newTri.x = (Math.random()*max)-(max/2); newTri.y = (Math.random()*max)-(max/2); newTri.z = (Math.random()*max)-(max/2); newTri.material = new ColorMaterial(); triangles.push(newTri); baseObject.addChild(newTri); } addControls(); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(e:Event):void { var fps:Number = Math.floor( 1000/(getTimer()-lastTime) ); label1.text = ""+numTriangles+" "+state+" triangles"; label2.text = ""+fps+"fps"; lastTime = getTimer(); baseObject.rotationY += 1; baseObject.rotationZ += 0.1; baseObject.rotationX -= 0.05; View.render(); } private function makeTriangle():Triangle { // Create triangle and change face var tri:Triangle = new Triangle({bothsides:false}); tri.a = getVertex(); tri.b = getVertex(); tri.c = getVertex(); return tri; } private function getVertex():Vertex { var maxSize:Number = 100; var newX:Number = (Math.random()*maxSize)-(maxSize/2); var newY:Number = (Math.random()*maxSize)-(maxSize/2); var newZ:Number = (Math.random()*maxSize)-(maxSize/2); return new Vertex(newX,newY,newZ); } private function addControls():void { var txtFormat:TextFormat = new TextFormat("_sans",12); var pad:Number = 10; label1 = new TextField(); label1.x = pad; label1.y = pad; label1.width = 140; label1.height = 30; label1.defaultTextFormat = txtFormat; var bothSidedButton:Button = new Button("Both sided", 140, 20); bothSidedButton.addEventListener(MouseEvent.CLICK, makeBothsided); bothSidedButton.x = pad; bothSidedButton.y = 30; var singleSidedButton:Button = new Button("Toggle single sided", 140, 20); singleSidedButton.addEventListener(MouseEvent.CLICK, makeSinglesided); singleSidedButton.x = pad; singleSidedButton.y = 55; label2 = new TextField(); label2.x = pad; label2.y = 75; label2.width = 140; label2.height = 20; label2.defaultTextFormat = txtFormat; addChild(label1); addChild(label2); addChild(bothSidedButton); addChild(singleSidedButton); } private function makeBothsided(e:MouseEvent):void { for(var i:Number = 0; i < triangles.length ; i++){ var tri:Triangle = triangles[i] as Triangle; tri.bothsides = true; state = "Both sided"; } } private function makeSinglesided(e:MouseEvent):void { for(var i:Number = 0; i < triangles.length ; i++){ var tri:Triangle = triangles[i] as Triangle; tri.bothsides = false; if(tri.scaleX == 1){ // This should have been tri.invertFaces() but that's been broken for so many releases now tri.scaleX = -1; } else { tri.scaleX = 1; } state = "Single sided"; } } } }