flash on 2015-2-8
/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3IP6
*/
package {
import flash.text.TextField;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.display.StageQuality;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
deb = new TextField();
deb.width =320; deb.height=240;
deb.mouseEnabled=false;
addChild(deb);
ori.rotYaw(0.5);
cori.copyQuat(ori);
stage.quality = StageQuality.LOW;
stage.addEventListener(KeyboardEvent.KEY_UP, onKup);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKdown);
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var vecKey:Vector.<Boolean> = new Vector.<Boolean>(512, false);
public function onKdown(e:KeyboardEvent):void { vecKey[e.keyCode] = true; }
public function onKup(e:KeyboardEvent):void { vecKey[e.keyCode] = false; }
public function isKeyDown(k:int):Boolean { return vecKey[k]; }
public var myDraw:xVertDraw = new xVertDraw();
public var gt:int = 0;
public var projMat:Vector.<Number> = new Vector.<Number>(16,false);
public var viewMat:Vector.<Number> = new Vector.<Number>(16,false);
public var deb:TextField;
public var cx:Number = 0;
public var cy:Number = 0;
public var cz:Number = 1000;
public var vx:Number = 0;
public var vy:Number = 0;
public var vz:Number = 0;
public var ori:xQuat = new xQuat();
public var cori:xQuat = new xQuat();
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
var ts:Number; ts = 0.06;
var ms:Number; ms = 8;
if (isKeyDown(Keyboard.UP)) { cori.rotPitch(ts); }
if (isKeyDown(Keyboard.DOWN)) { cori.rotPitch(-ts); }
if (isKeyDown(Keyboard.LEFT)) { cori.rotYaw(ts); }
if (isKeyDown(Keyboard.RIGHT)) { cori.rotYaw(-ts); }
// cx += ori.getFrontVx() * -ms;
// cy += ori.getFrontVy() * -ms;
// cz += ori.getFrontVz() * -ms;
var dec:Number; dec =0.98;
vx *= dec; vy*= dec; vz *= dec;
ms = 0.3;
vx += ori.getFrontVx() * -ms;
vy += ori.getFrontVy() * -ms;
vz += ori.getFrontVz() * -ms;
cx+=vx; cy+=vy; cz+=vz;
deb.text = ""+vx+"\n"+vy+"\n"+vz+"\n";
ori.nlerp(ori, cori, 0.2);
xVertDraw.setProjMat(projMat, 90, 1, 1, 16000);
xVertDraw.setViewMat(viewMat, cx, cy, cz, ori.x, ori.y, ori.z, ori.w);
xVertDraw.multMatrix(projMat, viewMat, myDraw.projMat);
var ang:Number;
ang = Math.sin(gt*0.05)*256;
myDraw.drawBox(graphics, -10240,-10240,-10240, 10240, 10240, 10240);
myDraw.drawBox(graphics, -1024,-1024,-1024, 1024, 1024, 1024);
myDraw.drawBox(graphics, -124,-124,-124, 124, 124, 124);
var d:Number; d = 1024;
var i:int; var k:int; var w:int;
for (i =-4; i < 4; i+=1)
for (k =-4; k < 4; k+=1)
for (w =-4; w < 4; w+=1)
{ myDraw.addVert(k*d,i*d,w*d, 16); }
myDraw.renderVert(graphics);
gt += 1;
}//onenter
}//classend
}
import flash.geom.Matrix3D;
import flash.display.Graphics;
internal class xVert
{
public var sx:Number = 0; public var sy:Number = 0;
public var sr:Number = 0;
public var sw:Number = 1;
public var sortCode:int = 0;
}//xvert
internal class xVertDraw
{
public var vecVert:Vector.<xVert>;
public var it:int = 0;
public var projMat:Vector.<Number> = Vector.<Number>([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
public var scrw:Number = 465;
public var scrh:Number = 465;
public var rendw:Number = 465 * 0.5;
public var rendh:Number = 465 * 0.5;
public function xVertDraw()
{
init(1024);
setProjMat(projMat, 90, 1, 1, 1000);
}//ctor
public function init(num:int):void
{
vecVert = new Vector.<xVert>(num, false);
var i:int; for (i = 0; i < num; i++) { vecVert[i] = new xVert(); }
}//init
public function drawBox(g:Graphics, minx:Number, miny:Number, minz:Number,
maxx:Number, maxy:Number, maxz:Number):void
{
drawLine(g,minx, miny, minz, maxx, miny, minz);
drawLine(g,minx, maxy, minz, maxx, maxy, minz);
drawLine(g,minx, miny, maxz, maxx, miny, maxz);
drawLine(g,minx, maxy, maxz, maxx, maxy, maxz);
drawLine(g,minx, miny, minz, minx, maxy, minz);
drawLine(g,maxx, miny, minz, maxx, maxy, minz);
drawLine(g,minx, miny, maxz, minx, maxy, maxz);
drawLine(g,maxx, miny, maxz, maxx, maxy, maxz);
drawLine(g,minx, miny, minz, minx, miny, maxz);
drawLine(g,maxx, miny, minz, maxx, miny, maxz);
drawLine(g,minx, maxy, minz, minx, maxy, maxz);
drawLine(g,maxx, maxy, minz, maxx, maxy, maxz);
}//drawbox
public function drawLine(g:Graphics, ax:Number, ay:Number, az:Number,
bx:Number, by:Number, bz:Number):void
{
var mat:Vector.<Number>;
var sx0:Number, sy0:Number, sz0:Number, w0:Number;
var sx1:Number, sy1:Number, sz1:Number, w1:Number;
mat = projMat;
w0 = ax * mat[3] + ay * mat[7] + az * mat[11] + mat[15];
w1 = bx * mat[3] + by * mat[7] + bz * mat[11] + mat[15];
if (w0 <= 0 && w1 <= 0) { return; }
sx0 = ax * mat[0] + ay * mat[4] + az * mat[8] + mat[12];
sy0 = ax * mat[1] + ay * mat[5] + az * mat[9] + mat[13];
//sz0 = ax * mat[2] + ay * mat[6] + az * mat[10] + mat[14];
sx1 = bx * mat[0] + by * mat[4] + bz * mat[8] + mat[12];
sy1 = bx * mat[1] + by * mat[5] + bz * mat[9] + mat[13];
//sz1 = bx * mat[2] + by * mat[6] + bz * mat[10] + mat[14];
sx0 /= w0; sy0 /= w0;
//projection fix
if (w0 < 0.0)
{ if (sx0 > 0) { sx0 = -1.0 - sx0; } else { sx0 = 1.0 - sx0; }
if (sy0 > 0) { sy0 = -1.0 - sy0; } else { sy0 = 1.0 - sy0; }
}//endif
sx0 *= rendw; sy0 *= -rendh; sx0 += rendw; sy0 += rendh;
sx1 /= w1; sy1 /= w1;
//projection fix
if (w1 < 0.0)
{ if (sx1 > 0) { sx1 = -1.0 - sx1; } else { sx1 = 1.0 - sx1; }
if (sy1 > 0) { sy1 = -1.0 - sy1; } else { sy1 = 1.0 - sy1; }
}//endif
sx1 *= rendw; sy1 *= -rendh; sx1 += rendw; sy1 += rendh;
//my pathetic attempt at optimisation
if (sx0 < 0 && sx1 < 0) { return; } if (sy0 < 0 && sy1 < 0) { return; }
if (sx0 > scrw && sx1 > scrw) { return; } if (sy0 > scrh && sy1 > scrh) { return; }
g.moveTo(sx0, sy0); g.lineTo(sx1, sy1);
}//drawline
public function addVert(ax:Number, ay:Number, az:Number, rad:Number):void
{
var a:xVert; var mat:Vector.<Number>; var m:Number;
var sx:Number; var sy:Number; var sz:Number;
var w:Number;
mat = projMat;
w = ax * mat[3] + ay * mat[7] + az * mat[11] + mat[15];
if (w <= 0) { return; }
sx = ax * mat[0] + ay * mat[4] + az * mat[8] + mat[12];
sy = ax * mat[1] + ay * mat[5] + az * mat[9] + mat[13];
sz = ax * mat[2] + ay * mat[6] + az * mat[10] + mat[14];
sx /= w; sy /= w;
sx *= rendw; sy *= -rendh;
sx += rendw; sy += rendh;
m = (1 / w) * rendh * rad;
a = vecVert[it]; it += 1; if (it >= vecVert.length) { it = vecVert.length - 1; }
a.sx = sx; a.sy = sy; a.sw = w; a.sr = m;
a.sortCode = 0x0FffFFff - int(sz);
}//addvert
public function renderVert(g:Graphics):void
{
//g.lineStyle(2, 0);
var i:int; var num:int; var a:xVert;
num = it; sortVert(vecVert, num);
for (i = 0; i < num; i++)
{ a = vecVert[i];
g.beginFill(0x808080, 1);
g.drawCircle(a.sx, a.sy, a.sr);
g.endFill();
}//nexti
it = 0;
}//rendervert
public function sortVert(vec:Vector.<xVert>, num:int):void
{ radixSortVert(vec, num); }//sortvert
public var tempVec:Vector.<xVert> = new Vector.<xVert>(8192, false);
public var tempBuck:Vector.<int> = new Vector.<int>(256, false);
public function radixSortVert(vec:Vector.<xVert>, num:int):void
{
var a:xVert; var temp:Vector.<xVert>; var buck:Vector.<int>;
var i:int; var k:uint; var shift:int; var g:int;
if (vec.length < num) { num = vec.length; }
temp = tempVec; if (temp.length < num) { return; }
buck = tempBuck; shift = 0;
while (shift < 32) {
for (k = 0; k < 256; k++) { buck[k] = 0; } //reset bucket
for (i = 0; i < num; i++) { g = (vec[i].sortCode >> shift) &0xFF; buck[g]++; }
for (i = 1; i < 256; i++) { buck[i] += buck[i - 1]; }
for (i = num - 1; i >= 0; i--) { g = (vec[i].sortCode >> shift) &0xFF; temp[--buck[g] ] = vec[i]; }
for (i = 0; i < num; i++) { vec[i] = temp[i]; }
shift += 8;
}//wend
}//radixsort
public static function setProjMat(vec:Vector.<Number>,
fovdeg:Number = 60.0, aspect:Number=1.0, nearp:Number = 1.0, farp:Number=1000.0):void
{ var f:Number; var i:int;
for (i = 0; i < 16; i++) { vec[i] = 0.0; }
f = 1.0 / Math.tan( (fovdeg * (3.1415 / 180.0)) * 0.5 );
if (nearp == 0) { nearp = 0.0001; }
if (farp == 0) { farp = 0.0001; }
vec[0] = f / aspect; vec[5] = f;
vec[10] = (farp + nearp) / (nearp - farp);
vec[14] = (2.0 * farp * nearp) / (nearp - farp);
vec[11] = -1.0; vec[15] = 0.0;
}//projmatrix
public static function setViewMat(vec:Vector.<Number>,
cx:Number, cy:Number, cz:Number, qx:Number, qy:Number, qz:Number, qw:Number):void
{
var forwx:Number; var forwy:Number; var forwz:Number;
var sidex:Number; var sidey:Number; var sidez:Number;
var upx:Number; var upy:Number; var upz:Number;
var i:int;
for (i = 0; i < 16; i++) { vec[i] = 0.0; }
vec[0] = vec[5] = vec[10] = vec[15] = 1.0;
forwx = 2.0 * ( qx*qz + qy*qw );
forwy = 2.0 * ( qy*qz - qx*qw );
forwz = 1.0 - 2.0 * ( qx*qx + qy*qy );
upx = 2.0 * ( qx*qy - qz*qw );
upy = 1.0 - 2.0 * ( qx*qx + qz*qz );
upz = 2.0 * ( qy * qz + qx * qw );
sidex = 1.0 - 2.0 * ( qy*qy + qz*qz );
sidey = 2.0 * ( qx*qy + qz*qw );
sidez = 2.0 * ( qx * qz - qy * qw );
vec[0] = sidex; vec[4] = sidey; vec[8] = sidez;
vec[1] = upx; vec[5] = upy; vec[9] = upz;
//forwx = -forwx; forwy = -forwy; forwz = -forwz;
vec[2] = forwx; vec[6] = forwy; vec[10] = forwz;
vec[12] = (sidex *-cx) + (sidey * -cy) + (sidez * -cz);
vec[13] = (upx *-cx) + (upy * -cy) + (upz * -cz);
vec[14] = (forwx *-cx) + (forwy * -cy) + (forwz * -cz);
}//setlookat
//only works of 4x4 matrices
public static function multMatrix(a:Vector.<Number>, b:Vector.<Number>, r:Vector.<Number>):void
{ var i:int; for (i = 0; i < 16; i += 4)
{
r[i] = a[0] * b[i] + a[4] * b[i + 1] + a[8] * b[i + 2] + a[12] * b[i + 3];
r[i + 1] = a[1] * b[i] + a[5] * b[i + 1] + a[9] * b[i + 2] + a[13] * b[i + 3];
r[i + 2] = a[2] * b[i] + a[6] * b[i + 1] + a[10] * b[i + 2] + a[14] * b[i + 3];
r[i + 3] = a[3] * b[i] + a[7] * b[i + 1] + a[11] * b[i + 2] + a[15] * b[i + 3];
}//nexti
}//multmat
}//vertdraw
internal class xQuat
{
public var x:Number = 0, y:Number = 0, z:Number = 0, w:Number = 1;
public function reset():void { x = 0; y = 0; z = 0; w = 1; }
public function copyQuat(a:xQuat):void { x = a.x; y = a.y; z = a.z; w = a.w; }
public function setValue(ax:Number, ay:Number, az:Number, aw:Number):void { x = ax; y = ay; z = az; w = aw; }
public function invert():void { x = -x; y = -y; z = -z; } //aka negate, conjugate
public function normalise():void
{ var mag:Number; mag = (x * x) + (y * y) + (z * z) + (w * w);
if (mag == 1.0) return; //already normal
if (mag == 0) { x = 0; y = 0; z = 0; w = 1; return; }
mag = 1.0 / Math.sqrt(mag);
x *= mag; y *= mag; z *= mag; w *= mag;
}//norm
public function mul(a:xQuat):void
{ var tx:Number; var ty:Number; var tz:Number; var tw:Number;
tx = (w * a.x + x * a.w + y * a.z - z * a.y); ty = (w * a.y + y * a.w + z * a.x - x * a.z);
tz = (w * a.z + z * a.w + x * a.y - y * a.x); tw = (w * a.w - x * a.x - y * a.y - z * a.z);
x = tx; y = ty; z = tz; w = tw;
}//mul
//0 x 1 y 2 z
public function rotAxis(ang:Number, xyz:int=0):void
{
ang *= 0.5;
var ax:Number; var ay:Number; var az:Number; var aw:Number;
var tx:Number; var ty:Number; var tz:Number; var tw:Number;
ax = xyz==0? Math.sin(ang):0; ay = xyz==1? Math.sin(ang):0; az = xyz==2? Math.sin(ang):0; aw = Math.cos(ang);
tx = (w * ax + x * aw + y * az - z * ay); ty = (w * ay + y * aw + z * ax - x * az);
tz = (w * az + z * aw + x * ay - y * ax); tw = (w * aw - x * ax - y * ay - z * az);
x = tx; y = ty; z = tz; w = tw;
normalise();
}//rotaxis
//backwards compatibility with older xQuat
public function rotPitch(ang:Number):void { rotAxis(ang, 0); }
public function rotYaw(ang:Number):void { rotAxis(ang, 1); }
public function rotRoll(ang:Number):void { rotAxis(ang, 2); }
public function rotAxisX(ang:Number):void { rotAxis(ang, 0); }
public function rotAxisY(ang:Number):void { rotAxis(ang, 1); }
public function rotAxisZ(ang:Number):void { rotAxis(ang, 2); }
public function nlerp(q1:xQuat, q2:xQuat, t:Number):void
{
var dot:Number; var b:Number; var rx:Number; var ry:Number; var rz:Number; var rw:Number;
dot = q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z * q2.z;
b = 1.0 - t; if (dot < 0) { t = -t;}
w = b * q1.w + t * q2.w; x = b * q1.x + t * q2.x; y = b * q1.y + t * q2.y; z = b * q1.z + t * q2.z;
}//nlerp
public function setVec(vec:Vector.<Number>):void
{
var xx:Number = x * x; var xy:Number = x * y; var xz:Number = x * z; var xw:Number = x * w;
var yy:Number = y * y; var yz:Number = y * z; var yw:Number = y * w;
var zz:Number = z * z; var zw:Number = z * w;
vec[3] = vec[7] = vec[11] = vec[12] = vec[13] = vec[14] = 0.0; vec[15] = 1.0;
vec[0] = 1.0 - 2.0 * ( yy + zz ); vec[4] = 2.0 * ( xy - zw ); vec[8] = 2.0 * ( xz + yw );
vec[1] = 2.0 * ( xy + zw ) ; vec[5] = 1.0 - 2.0 * ( xx + zz ) ; vec[9] = 2.0 * ( yz - xw ) ;
vec[2] = 2.0 * ( xz - yw ); vec[6] = 2.0 * ( yz + xw ); vec[10] = 1.0 - 2.0 * ( xx + yy );
}//setvec
public static var tempVec:Vector.<Number> = new Vector.<Number>(16, false);
public function setMatrix(m:Matrix3D):void { setVec(tempVec); m.rawData = tempVec; }
public function lookAtXYZ(ax:Number, ay:Number, az:Number, bx:Number, by:Number, bz:Number):void
{ var yaw:Number, pitch:Number; var dx:Number, dz:Number;
var am:Number;
x = 0; y = 0; z = 0; w = 1;
dx = bx - ax; dz = bz - az;
yaw = Math.atan2(dz, dx);
am = Math.cos(yaw) * dx + Math.sin(yaw) * dz;
pitch = Math.atan2(by - ay, am);
rotAxisY( -yaw - 1.57); rotAxisX(pitch);
}//lookat
public function getSideVx():Number { return 1.0 - 2.0 * ( y * y + z * z ); }
public function getSideVy():Number { return 2.0 * ( x * y + z * w ); }
public function getSideVz():Number { return 2.0 * ( x * z - y * w ); }
public function getUpVx():Number { return 2.0 * ( x*y - z*w ); }
public function getUpVy():Number { return 1.0 - 2.0 * ( x*x + z*z ); }
public function getUpVz():Number { return 2.0 * ( y*z + x*w ); }
public function getFrontVx():Number { return 2.0 * ( x*z + y*w ); }
public function getFrontVy():Number { return 2.0 * ( y*z - x*w ); }
public function getFrontVz():Number { return 1.0 - 2.0 * ( x*x + y*y ); }
}//xquat