// creates a sphere function createSphere(radius:Number, parallels:int, meridians:int, trianglePathOut:GraphicsTrianglePath, vertices3DOut:Vector.):void { if (parallels < 3) parallels = 3; if (meridians < 3) meridians = 3; meridians++; // texture edge meridian duplicated var parallelStops:int = parallels-1; // for determining u var meridianStops:int = meridians-1; // for determining v // local variables var r:Number; // radius var x:Number, y:Number, z:Number; // coordinates var p:int, pi:int, pa:Number; // parallel vars var m:int, mi:int, ma:Number; // meridian vars var u:Number, v:Number; // u, v of uvt var n:int = -1; // vertices index // horizontal for (p=0; p(), new Vector.(), new Vector.(), TriangleCulling.NEGATIVE); // a new GraphicsTrianglePath container using the // same vector data as triangles is created to draw // the backside of the sphere once the darker version // of the bitmap is added to the drawing state var trianglesBack:GraphicsTrianglePath = new GraphicsTrianglePath( triangles.vertices, triangles.indices, triangles.uvtData, TriangleCulling.POSITIVE); // stroke for when mouse is pressed // start with a NaN width (no stroke) var stroke:GraphicsStroke = new GraphicsStroke(NaN, false, "normal", "none", "round", 3, new GraphicsSolidFill(0xFF0000)); // create a vector of Number objects to store // 3D locations of sphere coordinates var vertices3D:Vector. = new Vector.(); // to be non-destructive, changes to the sphere // coordinates are added to this vector var vertices3DTransformed:Vector. = new Vector.(); // populate triangles and vertices3D and with // sphere data; note that the triangles vector data // is being modified but this also affects trianglesBack // since it uses those same vectors createSphere(globeRadius, globeParallels, globeMeridians, // in triangles, vertices3D); // out // IGraphicsData list of drawing commands, drawing back face // first (dark), followed by front face (light) var globeData:Vector. = Vector.([ stroke, new GraphicsBitmapFill(backFace, null, false, true), trianglesBack, new GraphicsBitmapFill(frontFace, null, false, true), triangles ]); // rotate globe in frame loop addEventListener(Event.ENTER_FRAME, draw); function draw(event:Event):void { // rotate the globe transform around the y axis // using prepend allows this to be applied // "before" the previous translation in z globeTransform.prependRotation(-globeSpinSpeed, Vector3D.Y_AXIS); // apply the transform to the globe vertices // to make the globe points actually rotated // (as well as pushed back in z) globeTransform.transformVectors(vertices3D, // in vertices3DTransformed); // out // convert the 3D points to 2D points and update // the T data in the UVT to coorectly account for // the translation of 2D to 3D for the bitmaps Utils3D.projectVectors(globePerspective, vertices3DTransformed, // in triangles.vertices, triangles.uvtData); // out // draw the triangles globe.graphics.clear(); globe.graphics.drawGraphicsData(globeData); } // show outlines when pressing the mouse stage.addEventListener(MouseEvent.MOUSE_DOWN, toggleStroke); stage.addEventListener(MouseEvent.MOUSE_UP, toggleStroke); function toggleStroke(event:MouseEvent):void { stroke.thickness = (event.type == MouseEvent.MOUSE_DOWN) ? 1 : NaN; }