Fl020_DotsDemo.as (Main)
/**
* @date 05/11/2008
* @author borealkiss
* @see http://boreal-kiss.com/flash/ex/51/
*/
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.geom.PerspectiveProjection;
import com.borealkiss.display.dots.Dots;
import com.borealkiss.display.dots.PerlinNoiseSphere;
[SWF(width="700",height="500",backgroundColor="0x0")]
public class Fl020_DotsDemo extends Sprite{
private var _projectionMatrix:Matrix3D;
private var _primitive:Dots;
private var _scene:Sprite;
private var _canvasBitmap:BitmapData;
/**
* Constructor
*/
public function Fl020_DotsDemo(){
init();
}
private function init():void{
_canvasBitmap = new BitmapData(stage.stageWidth,stage.stageHeight,false,0x0);
addChild(new Bitmap(_canvasBitmap));
_scene = new Sprite();
_scene.transform.matrix3D = new Matrix3D();
_primitive = new PerlinNoiseSphere(0.8,10000);
var pp:PerspectiveProjection= new PerspectiveProjection();
pp.fieldOfView = 100;
_projectionMatrix = pp.toMatrix3D();
addEventListener(Event.ENTER_FRAME,drawBitmap);
}
private function drawBitmap(e:Event):void{
rotate(_scene);
var world:Matrix3D = _scene.transform.matrix3D.clone();
world.append(_projectionMatrix);
var projectedVerts:Array = project3D(_primitive.vertices,world);
_canvasBitmap.fillRect(_canvasBitmap.rect,0x0);
for (var i:int=0; i<projectedVerts.length; i++){
var v:Vector3D = projectedVerts[i];
var x:Number = _canvasBitmap.width/2 + v.x;
var y:Number = _canvasBitmap.height/2 + v.y;
_canvasBitmap.setPixel(x,y,getColor(x,y));
}
}
private function project3D(verts:Array,world:Matrix3D):Array{
var results:Array = new Array();
for (var i:int=0; i<verts.length; i++){
var v:Vector3D = world.transformVector(verts[i]);
results.push(v);
}
return results;
}
private function rotate(target:Sprite):void{
var dx:Number = (mouseX - stage.stageWidth/2);
var dy:Number = (mouseY - stage.stageHeight/2);
target.rotationX = 0.5*dy;
target.rotationY = -0.8*dx;
}
private function getColor(x:Number,y:Number):uint{
var r:int = 255 * Math.random();
var g:int = 255*x/_canvasBitmap.width;
var b:int = 255*y/_canvasBitmap.height;
return r << 16 | g << 8 | b;
}
}
}
com.borealkis.display.dots.Dots.as (Abstract)
package com.borealkiss.display.dots{
import flash.errors.IllegalOperationError;
/**
* Abstract class.
*/
public dynamic class Dots{
protected var _vertices:Array;
public function get vertices():Array{
return _vertices;
}
public function set vertices(value:Array):void{
_vertices = value
}
/**
* Constructor
*/
public function Dots(){
if(Object(this).constructor == Dots){
throw new IllegalOperationError("Abstract class must be inherited in a subclass.");
}
}
}
}
com.borealkis.display.dots.PerlinNoiseSphere.as
package com.borealkiss.display.dots{
import flash.display.BitmapData;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import com.borealkiss.display.dots.Dots;
import com.borealkiss.display.PerlinNoiseData;
public class PerlinNoiseSphere extends Dots{
protected var _totalPoints:int;
protected var _bitmapData:BitmapData;
protected var _topography:Array;
protected var _referenceRadius:Number;
private const BITMAP_WIDTH:int = 90;
private const BITMAP_HEIGHT:int = 90;
private const SCALE_RAD:Number = 0.2;
/**
* Constructor
*/
public function PerlinNoiseSphere(referenceRadius:Number,totalPoints:int){
_referenceRadius = referenceRadius;
_totalPoints = totalPoints;
_bitmapData = new PerlinNoiseData(BITMAP_WIDTH,BITMAP_HEIGHT,BITMAP_WIDTH/5,BITMAP_HEIGHT/5);
init();
}
protected function init():void{
setTopographyData();
this.vertices = new Array();
for (var i:int=0; i<_totalPoints; i++){
var vertex:Vector3D = randomPlot();
this.vertices.push(vertex);
}
}
protected function randomPlot():Vector3D{
var w:int = BITMAP_WIDTH;
var h:int = BITMAP_HEIGHT;
var i:int = Math.floor(w*Math.random());
var j:int = Math.floor(h*Math.random());
var phi:Number = Math.PI*(2*i - w)/w; var theta:Number = Math.PI*(j - h/2)/h; var rad:Number = _referenceRadius*(1 + _topography[i][j]*SCALE_RAD);
var x:Number = rad*Math.cos(theta)*Math.cos(phi);
var y:Number = rad*Math.cos(theta)*Math.sin(phi);
var z:Number = rad*Math.sin(theta);
return new Vector3D(x,y,z);
}
protected function setTopographyData():void{
_topography = new Array();
for (var i:int=0; i<BITMAP_WIDTH; i++){
var topo:Array = new Array();
for (var j:int=0; j<BITMAP_HEIGHT; j++){
topo.push(getHeight(i,j));
}
_topography.push(topo);
}
}
/**
* @return Number Ranges from -1 to 1.
*/
protected function getHeight(x:int,y:int):Number{
var color:uint = _bitmapData.getPixel(x,y);
var r:Number = color >> 16;
return 2*(r - 255)/255 + 1; }
}
}
com.borealkis.display.PerlinNoiseData.as
package com.borealkiss.display{
import flash.display.BitmapData;
/**
* Create BitmapData filled with a specific perlin noise.
*/
public class PerlinNoiseData extends BitmapData{
protected var _width:int;
protected var _height:int;
protected var _baseX:Number;
protected var _baseY:Number;
protected var _numOctaves:uint;
protected var _randomSeed:int;
protected var _stitch:Boolean;
protected var _fractalNoise:Boolean;
protected var _channelOptions:uint;
protected var _grayScale:Boolean;
/**
* Constructor
*/
public function PerlinNoiseData(width:int,height:int,baseX:Number,baseY:Number,
numOctaves:uint=1,randomSeed:int=1,stitch:Boolean=true,
fractalNoise:Boolean=false,channelOptions:uint=7,grayScale:Boolean=true){
_width = width;
_height = height;
_baseX = baseX;
_baseY = baseY;
_numOctaves = numOctaves;
_randomSeed = randomSeed;
_stitch = stitch;
_fractalNoise = fractalNoise;
_channelOptions = channelOptions;
_grayScale = grayScale;
super(_width,_height,false,0x0);
init();
}
protected function init():void{
this.perlinNoise(_baseX,_baseY,_numOctaves,_randomSeed,_stitch,_fractalNoise,_channelOptions,_grayScale);
}
/**
* @param red Use red channel.
* @param green User green channel.
* @param blue Use blue channel.
* @return uint ChanneOptions for BitmapData.perlinNoise().
*/
public static function getChannelOptions(red:Boolean,green:Boolean,blue:Boolean):uint{
return uint(red) + 2*uint(green) + 4*uint(blue);
}
}
}
Powered by blog Boreal Kiss 2008.