flash on 2009-6-12
/**
* Copyright bigfish ( http://wonderfl.net/user/bigfish )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/h3yF
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.TriangleCulling;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.PerspectiveProjection;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
[SWF(backgroundColor="0x0000", width="800", height="600", frameRate="30")]
public class Jellyfish extends Sprite {
public var vertices:Vector.<Number>;
public var indices:Vector.<int>;
public var uvtData:Vector.<Number>;
private var radius:Number = 150;
private var detail:Number = 10;
private var bmd:BitmapData = new BitmapData(500,500,true,0xCCCCCC);
private var texture:Bitmap = new Bitmap(bmd);
private var xpos:Number = stage.stageWidth/2;
private var ypos:Number = stage.stageHeight/2;
private var zpos:Number = 10;
private var jellyfish:Sprite = new Sprite();
private var amplitude:Number = 6;
private var frequency:Number = 4;
private var pulse:Number = 0;//0-180
public function Jellyfish() {
root.transform.perspectiveProjection.fieldOfView = 80;
uvtData = new Vector.<Number>();
addChild(jellyfish);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function createMesh(radius:Number, latspacing:int, longspacing:int):void {
//reset
vertices = new Vector.<Number>();
indices = new Vector.<int>();
var _x:Number, _y:Number, _z:Number;
var a2r:Number = Math.PI/180;
//sphere
for(var lat:int = 0; lat <= 180; lat += latspacing){
var expansion:Number = amplitude*Math.sin(frequency*lat*a2r - pulse);
for(var long:int = 0; long<= 360; long += longspacing){
//get x,y,z for the point at lat, long
//x = r*cos(long)*sin(lat)
//y = r*cos(lat)
//z = r*sin(long)*sin(lat)
if(lat < 90){
//dampen down the pulsing towards the top of the head
_x = (radius + expansion*lat/90)*Math.cos(long*a2r)*Math.sin(lat*a2r);
_y = (radius + expansion*lat/90)*Math.cos(lat*a2r);
_z = (radius + expansion*lat/90)*Math.sin(long*a2r)*Math.sin(lat*a2r);
} else {
//keep at m + expansion)ax width
_x = (radius + expansion)*Math.cos(long*a2r)*Math.sin(90*a2r);
_y = (radius + expansion)*Math.cos(lat*a2r);
_z = (radius + expansion)*Math.sin(long*a2r)*Math.sin(90*a2r);
}
vertices.push(_x,_y,_z);
uvtData.push(long/360,lat/180,1);
}
}
//uvtData
//OK, now for triangles
var rows:Number = 180/latspacing;
var cols:Number = 360/longspacing + 1;
/* triangle arrangement
i--------(i+1)
| / |
| / |
| / |
|/ |
i2 ------(i2 +1)
*/
for(var row:int = 0; row < rows; row++){
for(var col:int = 0; col < cols; col++){
var i:int = row*(cols) + col;
var i2:int = (row+1)*(cols) + col;
if(col+1 != cols) {
indices.push(i, i + 1, i2);
indices.push(i2, i + 1, i2 + 1);
}
}
}
}
private function onEnterFrame(event:Event):void {
jellyfish.x = xpos;
jellyfish.y = ypos;
pulse+=0.1;
if(pulse>=180)
pulse = 0;
createMesh(radius, detail, detail);
render();
}
private function render():void {
//var sphereVerts:Vector.<Number> = new Vector.<Number>();
var projectedVerts:Vector.<Number> = new Vector.<Number>();
//sphere.transform.matrix3D.transformVectors(sphere.vertices, sphereVerts);
//drawTriangles using translated vertices
root.transform.perspectiveProjection.projectionCenter = new Point(stage.stageWidth/2, stage.stageHeight/2);
var projectionMatrix:Matrix3D = root.transform.perspectiveProjection.toMatrix3D();
//projectionMatrix.projectionCenter
projectionMatrix.prependTranslation(0,0,400);//< 20 some funny stuff happens
projectionMatrix.prependRotation(180,new Vector3D(0,0,1));
//projectionMatrix.prependRotation(turn,new Vector3D(0,1,0));
Utils3D.projectVectors(projectionMatrix, vertices, projectedVerts, new Vector.<Number>());
jellyfish.graphics.clear();
jellyfish.graphics.beginFill(0xCCFFFFFF);
jellyfish.graphics.lineStyle(1,0xcccccc,1);
//jellyfish.graphics.beginBitmapFill(texture.bitmapData,null, false, false);
jellyfish.graphics.drawTriangles(projectedVerts, indices, null, TriangleCulling.NONE);
jellyfish.graphics.endFill();
}
}
}