1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
// creates a sphere
function createSphere(radius:Number,
parallels:int,
meridians:int,
trianglePathOut:GraphicsTrianglePath,
vertices3DOut:Vector.<Number>):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<parallels; p++){
v = p/parallelStops;
pa = v*Math.PI - Math.PI/2;
y = radius*Math.sin(pa);
r = radius*Math.cos(pa);
// vertical
for (m=0; m<meridians; m++){
u = m/meridianStops;
ma = u*Math.PI*2;
x = r*Math.cos(ma);
z = r*Math.sin(ma);
// vertices
vertices3DOut.push(x,y,z);
n++;
// trianglePathOut
trianglePathOut.uvtData.push(u, v, 1);
if (m != 0){ // not first meridian (texture edge)
if (p != parallelStops){ // not last parallel (no next parallel to connect)
trianglePathOut.indices.push(n, n+meridians, n+meridians-1);
trianglePathOut.indices.push(n, n+meridians-1, n-1);
}
}
}
}
}
// creates a darker version of a bitmap
function getDarkerBitmap(source:BitmapData, darkness:Number):BitmapData {
// put source in a Bitmap display object
// and darken it using a ColorTransform
var darker:Bitmap = new Bitmap(source);
darker.transform.colorTransform = new ColorTransform(darkness, darkness, darkness);
// draw() does not take in account of
// transformations on the object you draw
// so place it in a container
var container:Sprite = new Sprite();
container.addChild(darker);
// create a new BitmapData drawing
// the darker image in the container
var bmp:BitmapData = new BitmapData(source.width, source.height, source.transparent, 0);
bmp.draw(container);
return bmp;
}
// create globe shape
var globe:Shape = new Shape();
globe.x = 0;
globe.y = 0;
globe.alpha = 0;
addChild(globe);
TweenMax.to(globe, 1, {alpha:1,ease:Circ.easeInOut,onComplete:suite_globe});
function suite_globe () {
TweenMax.to(globe, 1, {delay:2,scaleX:4,scaleY:4,y:250,ease:Circ.easeInOut});
}
// globe variables
var globeRadius:Number = 100;
var globeParallels:int = 20;
var globeMeridians:int = 20;
var globeSpinSpeed:Number = 4;
var frontFace:BitmapData = new Erf(0,0);
var backFace:BitmapData = getDarkerBitmap(frontFace, .25);
var globeTransform:Matrix3D = new Matrix3D();
globeTransform.appendTranslation(0, 0, globeRadius*4); // push back in 3D space
var globeProjection:PerspectiveProjection = new PerspectiveProjection();
var globePerspective:Matrix3D = globeProjection.toMatrix3D();
// a GraphicsTrianglePath for the path
// data to be drawn in Flash
var triangles:GraphicsTrianglePath = new GraphicsTrianglePath(
new Vector.<Number>(), new Vector.<int>(),
new Vector.<Number>(), 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.<Number> = new Vector.<Number>();
// to be non-destructive, changes to the sphere
// coordinates are added to this vector
var vertices3DTransformed:Vector.<Number> = new Vector.<Number>();
// 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.<IGraphicsData> = Vector.<IGraphicsData>([
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);
}
} |
Partager