/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/k8dF
*/
package {
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
myShip.cy = 100;
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public var gt:int = 0;
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
drawLine(-200,0,-200, -200,0,200);
drawLine(200,0,-200, 200,0,200);
drawSpr(cx,cy,cz, 16);
drawShad(cx,cz, 16);
// drawSpr(0,70,0, 16);
drawShip(myShip);
gt += 1;
if (gt == 1 || (gt % 90 == 0) )
{
cx = Math.random() * 300 - 150;
cy = Math.random()*200;
cz = Math.random() * 300 -150;
}//endif
}//onenter
public var cx:Number = 0;
public var cy:Number = 0;
public var cz:Number = 0;
public var myShip:xShip = new xShip();
public var temp:xQuat = new xQuat();
public function drawShip(a:xShip):void
{
var o:xQuat;
o = a.ori;
temp.lookAtXYZ(a.cx,a.cy, a.cz, cx,cy,cz);
temp.rotAxisZ(a.roll);
a.ori.nlerp(a.ori, temp, 0.05);
//a.ori.copyQuat(temp);
// a.ori.rotRoll(0.1);
//a.ori.rotYaw(0.2);
// a.ori.rotPitch(0.2);
var ax:Number; var ay:Number; var az:Number;
ax = o.getFrontVx(); ay = o.getFrontVy(); az = o.getFrontVz();
a.vx += ax*0.1;
a.vy += ay*0.1;
a.vz += az*0.1;
//a.roll += 0.02;
if (a.vy < 0 && a.cy <= 8) { a.vy *=-0.5;}
a.cx += a.vx;
a.cy += a.vy;
a.cz += a.vz;
a.vx *= 0.98;
a.vy *= 0.98;
a.vz *= 0.98;
var bx:Number; var by:Number; var bz:Number;
bx = o.getSideVx(); by = o.getSideVy(); bz = o.getSideVz();
var ux:Number; var uy:Number; var uz:Number;
ux = o.getUpVx(); uy = o.getUpVy(); uz = o.getUpVz();
var kx:Number; var ky:Number; var kz:Number;
kx = a.cx; ky = a.cy; kz = a.cz;
kx -= ax*8; ky -= ay*8; kz -= az*8;
drawSpr(kx+ax, ky+ay,kz+az, 8);
drawSpr(kx+ax*8, ky+ay*8,kz+az*8, 7);
drawSpr(kx+ax*16, ky+ay*16,kz+az*16, 6);
drawSpr(kx+ax*20, ky+ay*20,kz+az*20, 6);
drawSpr(kx+bx*16, ky+by*16,kz+bz*16, 4);
drawSpr(kx+bx*-16, ky+by*-16,kz+bz*-16, 4);
drawSpr(kx+bx*8, ky+by*8,kz+bz*8, 4);
drawSpr(kx+bx*-8, ky+by*-8,kz+bz*-8, 4);
drawSpr(kx+ux*7, ky+uy*7,kz+uz*7, 6);
drawShad(a.cx,a.cz, 12);
}//drawship
public function drawSpr(ax:Number, ay:Number, az:Number, rad:Number):void
{
var sx:Number; var sy:Number;
sx = (ax-az) + 230; sy = (ax*0.5)+(az*0.5) - ay + 230;
graphics.drawCircle(sx,sy,rad);
}//drawspr
public function drawShad(ax:Number, az:Number, rad:Number):void
{
var sx:Number; var sy:Number;
sx = (ax-az) + 230; sy = (ax*0.5)+(az*0.5) + 230;
graphics.beginFill(0,1);
graphics.drawEllipse(sx-rad,sy-rad*0.5,rad+rad,rad);
graphics.endFill();
}//drawshade
public function drawLine(ax:Number, ay:Number, az:Number, bx:Number, by:Number, bz:Number):void
{
var sx:Number; var sy:Number;
sx = (ax-az) + 230; sy = (ax*0.5)+(az*0.5) - ay + 230;
graphics.moveTo(sx,sy);
sx = (bx-bz) + 230; sy = (bx*0.5)+(bz*0.5) - by + 230;
graphics.lineTo(sx,sy);
}//drawline
}//classend
}
import flash.geom.Matrix3D;
internal class xShip
{
public var cx:Number = 0; public var cy:Number = 0; public var cz:Number = 0;
public var ori:xQuat = new xQuat();
public var vx:Number = 0; public var vy:Number = 0; public var vz:Number = 0;
public var roll:Number = 0;
}//xship
internal class xQuat
{
public var x:Number = 0; public var y:Number = 0;
public var z:Number = 0; public var 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 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
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; }
//helpers -- same as getting the matrix and extracting the vectors we need
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 ); }
//and now observe my magic: look at point without vector normalisation
public function lookAtXYZ(ax:Number, ay:Number, az:Number,
bx:Number, by:Number, bz:Number):void
{
x = 0; y = 0; z = 0; w = 1;
var yaw:Number; var pitch:Number;
var dx:Number; var dz:Number;
var am:Number;
dx = ax - bx; dz = az - bz;
yaw = Math.atan2(dz, dx);
am = Math.cos(yaw) * dx + Math.sin(yaw) * dz;
pitch = Math.atan2(ay - by, am);
rotAxisY( -yaw - 1.57);
rotAxisX(pitch);
}//lookat
}//xquat