/**
* Copyright Geo877 ( http://wonderfl.net/user/Geo877 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/q3Zr
*/
package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.MouseEvent;
[SWF(backgroundColor="#000000", frameRate=60)]
public class Main extends Sprite {
private var camera:view3D;
private var drawing:Sprite;
static public var pointsToDraw:Array;
private var nativeZ:Number = 100;
private var closeZ:Number = 0;
private var spinningLight:light = new light(new point3(210,-100),0.96,0.25,0.2,160000);
private var awesomeLight:light = new light(new point3(0,0,0),0.0,0.6,0.95,24000);
public function Main():void{
init();
var i:Number =1000;
while(i>0){
pointsToDraw.push(new point3(Math.random()*300 - 150,Math.random()*300 - 150,Math.random()*300-150));
i--;
}
addEventListener(Event.ENTER_FRAME,mainLoop);
}
private function mainLoop(e:Event = null):void{
camera.r.y+=0.005;
//camera.p.z+=0.5;
awesomeLight.p.x = 250-mouseX;
awesomeLight.p.y = (250-mouseY)*-1;
rotatePointY(spinningLight.p,0.04);
draw();
}
private function init():void{
pointsToDraw = new Array();
camera = new view3D(0,0,0,Math.PI/2.5,250,250,500,500);
view_ratio = Math.tan(camera.fov/2);
camera.p.z = -400;
camera.r.y=Math.PI/3;
camera.r.x=Math.PI/10;
drawing = new Sprite();
addChild(drawing);
}
private function draw():void{
var radius:Number =7;
/* Grab 2D points to order by relative Z */
var displayPointArray:Array = new Array();
var i:int = pointsToDraw.length-1;
while(i>=0){
var point3D:point3 = pointsToDraw[i];
var point2DData:displayPoint = get2DPointData(point3D);
if(point2DData.visible){
var done:Boolean = false;
var index:int = 0;
while(!done){
if(displayPointArray[index]==null){
displayPointArray[index] = point2DData;
done = true;
break;
}else
if(point2DData.relativeZ<displayPointArray[index].relativeZ){
displayPointArray.splice(index,0,point2DData);
done = true;
break;
}
index++;
}
}
i--;
}
//displayPointArray.sortOn(["relativeZ"]);
drawing.graphics.clear();
var j:int = displayPointArray.length - 1;
while(j>=0){
var dp:displayPoint = displayPointArray[j];
/* draw colour */
var red:uint = 0x00;var green:uint = 0x00;var blue:uint = 0x00;
/* Lighting Routine */
var lights:Array =light.getAllInstances();
var k:Number = lights.length-1;
//var k:Number = 0;
while(k>=0){
var cLight:light = lights[k];
//lighting stuff
var d:Number = dp.refPoint.distanceTo(cLight.p);
//magnitude
var m:Number = cLight.intensity/(4*Math.PI*d*d);
red+=m*cLight.red;
green+=m*cLight.green;
blue+=m*cLight.blue;
k--;
}
/* Check For Overflow After Lighting */
if(red>0xFF)red=0xFF; if(green>0xFF)green=0xFF; if(blue>0xFF)blue=0xFF;
drawing.graphics.beginFill(red*0x10000+green*0x100+blue,1);
drawing.graphics.drawCircle(dp.p.x,dp.p.y,(radius/dp.t_width)*view_ratio*nativeZ);
j--;
}
}
public function get2DPointData(point_3D:point3):displayPoint{
var point_2D:point2 = new point2();
var pointCopy:point3 = new point3(point_3D.x,point_3D.y,point_3D.z);
rotatePointZ(pointCopy,-camera.r.z);
rotatePointY(pointCopy,-camera.r.y);
rotatePointX(pointCopy,-camera.r.x);
pointCopy.x -= camera.p.x;
pointCopy.y -= camera.p.y;
pointCopy.z -= camera.p.z;
var t_width:Number = view_ratio*pointCopy.z;
point_2D.x = (pointCopy.x/t_width)*camera.display.width*0.5+camera.display.x;
point_2D.y = (pointCopy.y/t_width)*camera.display.height*0.5+camera.display.y;
var visible:Boolean = false;
if(pointCopy.z>=closeZ){
visible = true
}else{
visible = false;
point_2D.x*=-1;
point_2D.y*=-1;
};
return new displayPoint(point_2D,point_3D,pointCopy.z,visible,
t_width);
}
static public function rotatePointX(point:point3,angleRads:Number):void{
var tempy:Number = point.y;var tempz:Number = point.z;
point.z = tempz*Math.cos(angleRads) - tempy*Math.sin(angleRads);
point.y = tempz*Math.sin(angleRads) + tempy*Math.cos(angleRads);
}
static public function rotatePointY(point:point3,angleRads:Number):void{
var tempx:Number = point.x;var tempz:Number = point.z;
point.x = tempx*Math.cos(angleRads) - tempz*Math.sin(angleRads);
point.z = tempx*Math.sin(angleRads) + tempz*Math.cos(angleRads);
}
static public function rotatePointZ(point:point3,angleRads:Number):void{
var tempx:Number = point.x;var tempy:Number = point.y;
point.x = tempx*Math.cos(angleRads) - tempy*Math.sin(angleRads);
point.y = tempx*Math.sin(angleRads) + tempy*Math.cos(angleRads);
}
private var view_ratio:Number;
}
}
import flash.geom.Rectangle;
class view3D {
public var p:point3;
public var fov:Number;
public var r:point3;
public var display:Rectangle;
public function view3D(px:Number=0,py:Number=0,pz:Number=0, pfov:Number=45,pdx:Number=250,pdy:Number=250,pdw:Number=500,pdh:Number=500):void{
p = new point3(px,py,pz);
fov = pfov;
r = new point3();
display = new Rectangle(pdx,pdy,pdw,pdh);
}
}
class point3 {
public var x:Number;public var y:Number;public var z:Number;
public function point3(px:Number=0,py:Number=0,pz:Number=0):void{x=px;y=py;z=pz;}
public function distanceTo(point:point3):Number{
return Math.sqrt((point.x-x)*(point.x-x)+(point.y-y)*(point.y-y)+(point.z-z)*(point.z-z));
}
}
class point2 {
public var x:Number;public var y:Number;
public function point2(px:Number=0,py:Number=0):void{x=px;y=py;}
}
class displayPoint{
public var visible:Boolean;public var t_width:Number;public var refPoint:point3;
public var p:point2;public var relativeZ:Number;
public function displayPoint(pp:point2, prefPoint:point3, prelativeZ:Number,pvisible:Boolean = true,
pt_width:Number = 1){
p = pp;
relativeZ = prelativeZ;
visible = pvisible;
t_width = pt_width;
refPoint = prefPoint;
}
}
class light{
private static var allInstances:Array = new Array();
public var red:Number;public var green:Number;public var blue:Number;
public var intensity:Number;
public var p:point3;
public function light(pp:point3, pred:Number = 1,pgreen:Number=1,pblue:Number=1,
pintensity:Number=1000){
p = pp;
red = pred*0xFF;
green = pgreen*0xFF;
blue = pblue*0xFF;
intensity = pintensity;
allInstances.push(this);
}
static public function getAllInstances():Array{
return allInstances;
}
}