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
|
function generateCube() {
///First we need to define the Vertex, Cube have exacly 8 vertex.
points = new Array();
//Each vertex is composed from X Y and Z coordinates in the space
points.push({x:-50, y:-50, z:-50});
points.push({x:50, y:-50, z:-50});
points.push({x:50, y:50, z:-50});
points.push({x:-50, y:50, z:-50});
points.push({x:-50, y:-50, z:50});
points.push({x:50, y:-50, z:50});
points.push({x:50, y:50, z:50});
points.push({x:-50, y:50, z:50});
//Then, if we want to draw more than a point, we need to define shapes with those points
//Each shape (6) will have 4 vertex, the order is important when we want to use the draw api to fill it.
shapes = new Array();
shapes.push([0, 1, 2, 3]);
shapes.push([4, 5, 6, 7]);
shapes.push([0, 4, 7, 3]);
shapes.push([0, 1, 5, 4]);
shapes.push([1, 5, 6, 2]);
shapes.push([3, 7, 6, 2]);
}
//Lens distance
var fl:Number = 400;
//Center of the Stage
var vpX:Number = Stage.width/2;
var vpY:Number = Stage.height/2;
//Render Offsets, here you can move the 3D object
var xOffset:Number = 0;
var zOffset:Number = fl;
var yOffset:Number = 0;
//vars used to rotate the cube in the Y and X axis
var angleY:Number = 0.0;//var angleY:Number = 0.01;
var angleX:Number = 0.0;//var angleX:Number = 0.01;
var angleZ:Number = 0.0;//var angleZ:Number = 0.01;
//this._xscale += 50;
//this._yscale += 50;
//We call the cube function
generateCube();
//Simple function to detect the keys pressed by the user. We just change the offsets and angles.
function checkKeys() {
if (Key.isDown(Key.RIGHT)) {
xOffset += 4;
}
if (Key.isDown(Key.LEFT)) {
xOffset -= 4;
}
if (Key.isDown(Key.UP)) {
yOffset -= 4;
}
if (Key.isDown(Key.DOWN)) {
yOffset += 4;
}
if (Key.isDown(Key.INSERT)) {
angleY -= 0.001;
} else {
if (Key.isDown(Key.DELETEKEY)) {
angleY += 0.001;
} else {
angleY *= 0.95;
}
}
if (Key.isDown(Key.HOME)) {
angleX += 0.001;
} else {
if (Key.isDown(Key.END)) {
angleX -= 0.001;
} else {
angleX *= 0.95;
}
}
if (Key.isDown(Key.PGDN)) {
angleZ += 0.001;
} else {
if (Key.isDown(Key.PGUP)) {
angleZ -= 0.001;
} else {
angleZ *= 0.95;
}
}
if (Key.isDown(Key.SHIFT)) {
this._x -= 5;
this._y -= 5;
this._xscale += 5;
this._yscale += 5;
}
if (Key.isDown(Key.CONTROL)) {
maRotation();
}
}
function maRotation() {
angleY -= 0.0255;
}
///Start with the update, right now is just an enterframe
this.onEnterFrame = function() {
//Cosine and sin calculation from the angles
var cosY:Number = Math.cos(angleY);
var sinY:Number = Math.sin(angleY);
var cosX:Number = Math.cos(angleX);
var sinX:Number = Math.sin(angleX);
var cosZ:Number = Math.cos(angleZ);
var sinZ:Number = Math.sin(angleZ);
//We need to clear the stage to be able to draw the new cube on every frame
clear();
//This array will store the distance form the camera to each Shape
distanceArray = [];
//Ok, let's start with each shape, remember each one is made with 4 points.
for (var j:Number = 0; j<shapes.length; j++) {
//Vars to store the distance from each point in the shape, in each axis.
dx = 0;
dy = 0;
dz = 0;
//Now, we need to look inside each shape, obviously, we will find 4 points, so let's take a look to all the points, and make some calculations.
for (var i:Number = 0; i<shapes[j].length; i++) {
//Here, is where we apply the projections for each point coordinate
x1 = cosY*(sinZ*(points[shapes[j][i]].y)+cosZ*(points[shapes[j][i]].x))-sinY*(points[shapes[j][i]].z);
y1 = sinX*(cosY*(points[shapes[j][i]].z)+sinY*(sinZ*(points[shapes[j][i]].y)+cosZ*(points[shapes[j][i]].x)))+cosX*(cosZ*(points[shapes[j][i]].y)-sinZ*(points[shapes[j][i]].x));
z1 = cosX*(cosY*(points[shapes[j][i]].z)+sinY*(sinZ*(points[shapes[j][i]].y)+cosZ*(points[shapes[j][i]].x)))-sinX*(cosZ*(points[shapes[j][i]].y)-sinZ*(points[shapes[j][i]].x));
//Now we store the new point coodinates, based on the angles.
points[shapes[j][i]].x = x1;
points[shapes[j][i]].y = y1;
points[shapes[j][i]].z = z1;
//we add each point coordinate to the relative distance var
dx += x1;
dy += y1;
dz += z1;
//Next code, is the way to get the X and Y points to draw in the Stage, we take care about offsets, and distance from the camera in the Z Axis
//Each point will be scaled acording the distance to the camera. We are using the _x and _y as variables to render, not for calculations
points[shapes[j][i]]._x = vpX+(points[shapes[j][i]].x+xOffset)*(fl/(points[shapes[j][i]].z+fl+zOffset));//scale;
points[shapes[j][i]]._y = vpY+(points[shapes[j][i]].y+yOffset)*(fl/(points[shapes[j][i]].z+fl+zOffset));//scale;
}
//Ok, you have checked all the points in the shape, now is time too look at the distances
//This is important, cos the distance to the observer, will mean which shape is render on top.
//Since we have a sum of distances in X Y and Z, we need an average
//Next code is the same than dividing by four (cos the four points per shape)
dx /= shapes[j].length-1;
dy /= shapes[j].length-1;
dz /= shapes[j].length-1;
//We add an element to the distances, and is basically the distance from each point, to the camera. Note than fl is on the Z axis, and is where the camera is.
//We store and object with the distance, and also a shape ID to know which shape corresponds with the distance.
distanceArray.push({d:Math.round(Math.sqrt(Math.pow(dx-xOffset, 2)+Math.pow(dy-yOffset, 2)+Math.pow(fl-dz, 2))), index:j});
}
//Now, we need to sort the array, to know wich shape is near and need to be render on top. So a simple Sort function.
distanceArray.sortOn("d");
//Here is where the fun starts. Now is time to render each polygon
lineStyle(0,0xFF9122,40);
//for each element in the distance array (the same length than the shape array, we will render the shape.
for (w=0; w<distanceArray.length; w++) {
//Drawing sfuff to do the line and the fill color (this can be better :D)
// pas besoin de faire changer les faces de couleur
//beginFill(0xEEEEEE-(distanceArray[w].index*10),100);
beginFill(0xEEEEEE,100);
moveTo(points[shapes[distanceArray[w].index][0]]._x,points[shapes[distanceArray[w].index][0]]._y);
//Now in each shape, we draw lines to each point to close the shape.
for (var j:Number = 0; j<shapes[distanceArray[w].index].length; j++) {
lineTo(points[shapes[distanceArray[w].index][j]]._x,points[shapes[distanceArray[w].index][j]]._y);
}
//Close the shape with the endFill
endFill();
}
//Capture Keys pressed to move and rotate the cube
checkKeys();
//DONE!
}; |
Partager