3d demo
a basic 3d engine displaying some shapes
built from scratch by me
yakir13@gmail.com
/**
* Copyright yAKIr ( http://wonderfl.net/user/yAKIr )
* GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
* Downloaded from: http://wonderfl.net/c/23GV
*/
// built by me yakir13@gmail.com
package
{
import flash.display.*;
import flash.events.*;
//import flash.filters.*;
[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]
public class display3d extends Sprite
{
private var alpha_:Number = 1;
private var screen:Shape = new Shape();
private var center_x:Number = stage.stageWidth / 2;
private var center_y:Number = stage.stageHeight / 2;
private var model1:Object = new Object();
private var model2:Object = new Object();
private var model3:Object = new Object();
private var scenePolygons:Array = [];
private var polycou:int = 0;
private var t:Number;
private var c:Number = 0;
private var resetcountdown:int=1;
// private var rad:int=20;
// private var swellup:Boolean=true;
// private var color_:Number = Math.round(Math.random() *0xFFFFFF);
//private var glowFilter:GlowFilter = new GlowFilter(0x000000, 1, 4, 4, 10, 1);
public function display3d()
{
this.addChild(screen);
//screen.filters = [glowFilter];
model1.xPos = 0;
model1.yPos = 0;
model1.zPos = 500;
model1.RotationX = 0;
model1.RotationY = 0;
// model1.Sides = makeDoughnut(300,30,7,Math.round(Math.random()*0xFFFFFF));
model1.Sides = makespiral(100, 30, 10,25);
/*model2.xPos = 0;
model2.yPos = 0;
model2.zPos = 500;
model2.RotationX = 0;
model2.RotationY = 0;
model2.Sides = makeDoughnut(220,30,5,Math.round(Math.random() * 0xFFFFFF));*/
/* model3.xPos = 0;
model3.yPos = 0;
model3.zPos = 500;
model3.RotationX = 0;
model3.RotationY = 0;
//model3.Sides = makeSphere(6, 50, -1);*/
stage.quality = "low";
addEventListener(Event.ENTER_FRAME,enterframe);
screen.addEventListener(MouseEvent.CLICK, onpress);
}
public function onpress(e:MouseEvent):Void
{
if (alpha_ == 0)
{
alpha_ = 0.5;
}
else if (alpha_==0.5)
{
alpha_ = 1;
}
else if (alpha_==1)
{
alpha_ = 0;
}
return null;
}
public function enterframe(event:Event):Void
{
/* if (swellup){
if (++rad>150){
swellup=false;
}
}else{
if (--rad<20){
swellup=true;
}
}*/
if (--resetcountdown==0){
model3.Sides = makeSphere(6, 80, -1);
resetcountdown=5;
}
polycou = 0;
model1.RotationX += ((mouseX-center_x)-model1.RotationX)/20;
model1.RotationY += ((mouseY-center_y)-model1.RotationY)/20;
//model1.RotationX = mouseX;
//model1.RotationY = mouseY;
/* model2.RotationX += ((mouseX+mouseY/2-center_x)-model2.RotationX)/20;
model2.RotationY += ((mouseY+mouseX/2-center_y)-model2.RotationY)/20;
//model2.RotationX = mouseX+mouseY/2;
//model2.RotationY = mouseY+mouseX/2;
model3.RotationX += ((mouseY*1.5-mouseX-center_x)-model3.RotationX)/20;
model3.RotationY += ((mouseX*0.5+mouseY-center_y)-model3.RotationY)/20;*/
//model3.RotationX = mouseY*1.5-mouseX;
//model3.RotationY = mouseX*0.5+mouseY;
//model1.xPos += ((mouseX-center_x)-model1.xPos)/20;
//model1.yPos += ((mouseY-center_y)-model1.yPos)/20;
var tempModel1:Object = position("model1");
//var tempModel2:Object = position("model2");
// var tempModel3:Object = position("model3");
for (var i:int=0; i<tempModel1.length; i++)
{
scenePolygons.push(tempModel1[i]);
}
/* for (i=0; i<tempModel2.length; i++)
{
scenePolygons.push(tempModel2[i]);
}
for (i=0; i<tempModel3.length; i++)
{
scenePolygons.push(tempModel3[i]);
}*/
screen.graphics.clear();
render("scenePolygons", alpha_);
scenePolygons.splice(0, scenePolygons.length);
return null;
}
public function getDistance3D(x1:Number, y1:Number, z1:Number, x2:Number, y2:Number, z2:Number):Number
{//get the distance between 2 point in the 3d space
var zdist:Number = z2 - z1;
var xdist:Number = x2 - x1;
var ydist:Number = y2 - y1;
var distancefromthis:Number = Math.round(Math.sqrt((xdist * xdist) + (ydist * ydist) + (zdist * zdist)));
return distancefromthis;
}
public function get2D(X:Number, Y:Number, Z:Number):Array
{
var fX:Number = 0 - (0 - X) / (1 + Z / 400);
var fY:Number = 0 - (0 - Y) / (1 + Z / 400);
return [fX, fY];
}
public function rotate(x_:Number, y_:Number, z_:Number, xan:Number, yan:Number):Object
{//rotate the 3d point in the 3d space by a given angle
var R:Number = Math.sqrt(y_ * y_ + z_ * z_);
var dy:Number = y_ - 0;
var dz:Number = z_ - 0;
var angle:Number = Math.atan2(dz,dy) / 1.745329E-002;
y_ = 0 + R * Math.cos((angle + yan) * 3.141593E+000 / 180);
z_ = 0 + R * Math.sin((angle + yan) * 3.141593E+000 / 180);
R = Math.sqrt(x_ * x_ + z_ * z_);
var dx:Number = x_ - 0;
dz = z_ - 0;
angle = Math.atan2(dz,dx) / 1.745329E-002;
x_ = 0 + R * Math.cos((angle + xan) * 3.141593E+000 / 180);
z_ = 0 + R * Math.sin((angle + xan) * 3.141593E+000 / 180);
return {X:x_, Y:y_, Z:z_};
}
public function getDistance(x1:Number, y1:Number, x2:Number, y2:Number):Number
{//get the distance between 2 points in the 2d space
var xdist:Number = x1 - x2;
var ydist:Number = y1 - y2;
var distancefromthis:Number = Math.round(Math.sqrt((xdist * xdist) + (ydist * ydist)));
return distancefromthis;
}
public function getAngle(x1:Number, y1:Number, x2:Number, y2:Number):Number
{
var theX:Number = x2 - x1;
var theY:Number = (y2 - y1) * -1;
var angle:Number = Math.atan(theY / theX) / (Math.PI / 180);
if (theX < 0)
{
angle += 180;
}
if (theX >= 0 && theY < 0)
{
angle += 360;
}
return (angle * -1);
}
public function makespiral(R:Number, quantity:Number, thickness:Number,turn:Number):Array{
var Sides:Array = new Array();
var angle:Number=0;
var X:Number = 0;
var Y:Number = 0;
var x1:Number = 0;
var y1:Number = 0;
var x2:Number = 0;
var y2:Number = 0;
var d:Number=0;
for (var i:int=0; i<quantity; i++){
x1 = 0 + R * Math.sin((angle) * 3.141593E+000 / 180);
y1 = 0 + R * Math.cos((angle) * 3.141593E+000 / 180);
angle+=turn;
x2 = 0 + R * Math.sin((angle) * 3.141593E+000 / 180);
y2 = 0 + R * Math.cos((angle) * 3.141593E+000 / 180);
Sides.push({X:[x1,x2,0,0], Y:[y1,y2,0,0], Z:[d*thickness, i*thickness, i*thickness,d*thickness], Color:Math.round(Math.random()*0xFFFFFF)});
d=i;
}
return Sides;
}
public function makeSphere(sliceDen:int, R:Number, color:Number):Array
{
var X0:Array = [];
var Y0:Array = [];
var X1:Array = [];
var Y1:Array = [];
var Z1:Array = [];
var X2:Array = [];
var Y2:Array = [];
var Z2:Array = [];
var slicesCou:int = sliceDen * 2;
for (var an1:int = 0; an1 < sliceDen-1; an1++)
{
X0.push(R * Math.cos((an1*(180/sliceDen)-90) * Math.PI / 180));
Y0.push(R * Math.sin((an1*(180/sliceDen)-90) * Math.PI / 180));
}
X0.push(0);
Y0.push(R);
for (var an2:int = 0; an2 < slicesCou; an2++)
{
for (var i:int = 0; i < X0.length; i++)
{
var P:Object = rotate(X0[i],Y0[i],0,an2 * (720/slicesCou),0);
X1.push(P.X);
Y1.push(P.Y);
Z1.push(P.Z);
}
}
///////////////////
var Sides:Array = [];
for (var a:int=0; a<(slicesCou/2); a++)
{
var b:Number = a * sliceDen;
for (var i4:int=0; i4<sliceDen; i4++)
{
var x1:Number = X1[b + (i4)];//
var y1:Number = Y1[b + (i4)];
var z1:Number = Z1[b + (i4)];
var x2:Number = X1[b + i4 + 1];//
var y2:Number = Y1[b + i4 + 1];
var z2:Number = Z1[b + i4 + 1];
var x3:Number = X1[b + sliceDen + i4 + 1];//
var y3:Number = Y1[b + sliceDen + i4 + 1];
var z3:Number = Z1[b + sliceDen + i4 + 1];
var x4:Number=X1[b+sliceDen+(i4)];//
var y4:Number=Y1[b+sliceDen+(i4)];
var z4:Number=Z1[b+sliceDen+(i4)];
if (color==-1){
Sides.push({X:[x1, x2, x3, x4], Y:[y1, y2, y3, y4], Z:[z1, z2, z3, z4], Color:Math.round(Math.random()*0xFFFFFF)});
}else{
Sides.push({X:[x1, x2, x3, x4], Y:[y1, y2, y3, y4], Z:[z1, z2, z3, z4], Color:color});
}
}
}
return Sides;
}
public function makeDoughnut(Radius:Number, pipeRadius:Number, complexity:Number, color:Number):Array
{
var circle3D:Array = new Array();
for (var i:int = 0; i < complexity; i++)
{
var x_:Number = 0;
var y_:Number=0 + (pipeRadius) * Math.cos((i*(360/(complexity-1))) * Math.PI / 180);
var z_:Number=-Radius + (pipeRadius) * Math.sin((i*(360/(complexity-1))) * Math.PI / 180);
circle3D.push({X:x_, Y:y_, Z:z_});
}
//
var Sides:Array = new Array();
var oldCircle3D:Array = new Array();
for (var a:int = 0; a < complexity*2; a++)
{
var newCircle3D:Array = new Array();
for (i = 0; i < complexity; i++)
{
var newPoint:Object = rotate(circle3D[i].X,circle3D[i].Y,circle3D[i].Z,360/(complexity*2-1)*a,0);
newCircle3D.push({X:newPoint.X, Y:newPoint.Y, Z:newPoint.Z});
}
for (i = 0; i < complexity-1; i++)
{
if (a > 0)
{
var x1:Number = oldCircle3D[i].X;
var y1:Number = oldCircle3D[i].Y;
var z1:Number = oldCircle3D[i].Z;
var x2:Number = oldCircle3D[i + 1].X;
var y2:Number = oldCircle3D[i + 1].Y;
var z2:Number = oldCircle3D[i + 1].Z;
var x3:Number = newCircle3D[i + 1].X;
var y3:Number = newCircle3D[i + 1].Y;
var z3:Number = newCircle3D[i + 1].Z;
var x4:Number = newCircle3D[i].X;
var y4:Number = newCircle3D[i].Y;
var z4:Number = newCircle3D[i].Z;
if (color==(-1)){
Sides.push({X:[x1,x2,x3,x4], Y:[y1,y2,y3,y4], Z:[z1, z2, z3, z4], Color:Math.round(Math.random() * 0xFFFFFF)});
}else{
Sides.push({X:[x1,x2,x3,x4], Y:[y1,y2,y3,y4], Z:[z1, z2, z3, z4], Color:color});
}
}
}
oldCircle3D = newCircle3D;
}
return Sides;
}
public function position(object:Object):Array
{
var sides:Array = new Array();
for (var i:int = 0; i < this[object].Sides.length; i++)
{
var point:Array = new Array();
for (var a:int = 0; a < this[object].Sides[i].X.length; a++)
{
point[a] = rotate(this[object].Sides[i].X[a],this[object].Sides[i].Y[a],this[object].Sides[i].Z[a],this[object].RotationX,this[object].RotationY);
}
var X:Array = new Array();
var Y:Array = new Array();
var Z:Array = new Array();
for (a = 0; a < point.length; a++)
{
X.push(this[object].xPos+point[a].X);
Y.push(this[object].yPos+point[a].Y);
Z.push(this[object].zPos+point[a].Z);
}
sides.push({x:X, y:Y, z:Z, color:this[object].Sides[i].Color});
}
return sides;
}
public function render(scene:String, Alpha:Number):Void
{
var polygons:Array = [];//sort the sides order in the array by their depth
for (var i:int = 0; i < this[scene].length; i++)
{
var midZ:Number = 0;
var minZ:Number = 99999;
for (var a:int = 0; a < this[scene][i].z.length; a++)
{
if (this[scene][i].z[a] < minZ)
{
minZ = this[scene][i].z[a];
}
midZ += this[scene][i].z[a];
}
midZ = midZ / this[scene][i].z.length;
var finalZ:Number = midZ;
polygons.push({x:this[scene][i].x, y:this[scene][i].y, z:this[scene][i].z, color:this[scene][i].color, Depth:finalZ});
}
polygons.sortOn("Depth");
polygons.reverse();
screen.graphics.lineStyle(1,0,1);
for (i = 0; i <polygons.length; i++)
{//get 2d points of side
var point:Array = new Array();
for (a = 0; a < polygons[i].x.length; a++)
{
point[a] = get2D(polygons[i].x[a],polygons[i].y[a],polygons[i].z[a]);
}//draw side
screen.graphics.beginFill(polygons[i].color,Alpha);
screen.graphics.moveTo(center_x + point[0][0],center_y + point[0][1]);
for (a = 1; a < point.length; a++)
{
screen.graphics.lineTo(center_x + point[a][0],center_y + point[a][1]);
}
screen.graphics.lineTo(center_x + point[0][0],center_y + point[0][1]);
screen.graphics.endFill();
}
polygons = null;
return null;
}
}
}