/**
* Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/aiP6
*/
package {
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public function FlashTest() {
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMdown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMup);
stage.addEventListener(Event.ENTER_FRAME, onEnter);
}//ctor
public function onMdown(e:MouseEvent):void { mdown = 1; }
public function onMup(e:MouseEvent):void { mdown = 0; }
public var mdown:int = 0;
public function onEnter(e:Event):void
{
graphics.clear();
graphics.lineStyle(2, 0);
var mx:Number; var my:Number;
mx = stage.mouseX; my = stage.mouseY;
mx -= rendw;
wmz = (2*my - mx)*0.5; wmx = mx + wmz;
wmx += camx; wmz += camz;
drawBox(0,0,0, 512 ,1, 512);
drawLine(wmx, 0, wmz, wmx, 8, wmz);
drawCirc(wmx, 0, wmz, 16);
graphics.lineStyle(2, 0x808080,0.5);
drawBox2(cx-rad,cy-rad,cz-rad,rad*2,rad*2,rad*2);
drawCirc(cx,0,cz, rad*0.5);
graphics.lineStyle(2, 0);
drawBall(ori, cx,cy,cz, rad);
drawSphere(cx,cy,cz,rad+5);
vx*=0.98; vz*=0.98;
vy -= 0.2;
if (cy < rad) { if (vy >-0.5) {vy=0;} vy *=-0.5; }
cx+=vx; cy+=vy;cz+=vz;
ori.ballRot(vx,vz, rad*2);
if (mdown > 0)
{
var ang:Number; var ms:Number;
ms=0.22;
ang = Math.atan2(wmz-cz,wmx-cx);
vx+=Math.cos(ang)*ms;
vz+=Math.sin(ang)*ms;
}
gt += 1;
}//onenter
public var wmx:Number = 0;
public var wmz:Number = 0;
public var gt:int = 0;
public var rendw:Number = 465 * 0.5;
public var rendh:Number = 465 * 0.5;
public var camx:Number = 0;
public var camy:Number = 0;
public var camz:Number = 0;
public var ori:xQuat = new xQuat();
public var cx:Number = 256;
public var cy:Number = 64;
public var cz:Number = 256;
public var rad:Number = 32;
public var vx:Number = 0;
public var vy:Number = 0;
public var vz:Number = 0;
public function drawLine(ax:Number, ay:Number, az:Number,
bx:Number, by:Number, bz:Number):void
{
var sx:Number; var sy:Number;
ax -= camx; ay -= camy; az -= camz;
bx -= camx; by -= camy; bz -= camz;
sx = ax - az + rendw;
sy = (ax * 0.5) + (az * 0.5) - ay;
graphics.moveTo(sx,sy);
sx = bx - bz + rendw;
sy = (bx * 0.5) + (bz * 0.5) - by;
graphics.lineTo(sx, sy);
}//drawline
public function drawSphere(ax:Number,ay:Number,az:Number, r:Number):void
{
var sx:Number; var sy:Number;
ax -= camx; ay -= camy; az -= camz;
sx = ax - az + rendw;
sy = (ax * 0.5) + (az * 0.5) - ay;
graphics.drawCircle(sx,sy, r);
}//drawsphere
public function drawCirc(ax:Number, ay:Number, az:Number, r:Number):void
{
var u:Number; var t:Number; t = 0.314;
for (u = 0; u < 6.28; u+= t)
{
drawLine(ax + Math.cos(u) * r, ay, az + Math.sin(u) * r,
ax + Math.cos(u+t)*r, ay, az + Math.sin(u+t)*r);
}//nextu
}//drawcircle
public function drawBox2(ax:Number, ay:Number, az:Number,
aw:Number, ah:Number, ad:Number):void
{ drawBox(ax,ay,az,ax+aw,ay+ah,az+ad); }
public function drawBox(ax:Number, ay:Number, az:Number,
bx:Number, by:Number, bz:Number):void
{
drawLine(ax, ay, az, bx, ay, az);
drawLine(ax, by, az, bx, by, az);
drawLine(ax, ay, bz, bx, ay, bz);
drawLine(ax, by, bz, bx, by, bz);
drawLine(ax, ay, az, ax, by, az);
drawLine(bx, ay, az, bx, by, az);
drawLine(ax, ay, bz, ax, by, bz);
drawLine(bx, ay, bz, bx, by, bz);
drawLine(ax, ay, az, ax, ay, bz);
drawLine(bx, ay, az, bx, ay, bz);
drawLine(ax, by, az, ax, by, bz);
drawLine(bx, by, az, bx, by, bz);
}//drawbox
public var tempq:xQuat = new xQuat();
public function drawBall(o:xQuat, ax:Number,ay:Number,az:Number, r:Number=32):void
{
var tq:xQuat; tq = tempq;
var kx:Number; var ky:Number; var kz:Number;
var kx2:Number; var ky2:Number; var kz2:Number;
var u:Number; var t:Number;
t = 0.628;
var i:int;
for (i = 0; i < 3; i += 1)
{
tq.copyQuat(o); if (i == 2) { tq.rotYaw(1.57); }
kx2 = ax + tq.getFrontVx() * r; ky2 = ay + tq.getFrontVy() * r; kz2 = az + tq.getFrontVz() * r;
for (u = 0; u < 6.28; u += t)
{
tq.rotAxis(t, i%2);
kx = ax + tq.getFrontVx() * r; ky = ay + tq.getFrontVy() * r; kz = az + tq.getFrontVz() * r;
drawLine(kx2, ky2, kz2, kx, ky, kz);
kx2 = kx; ky2 = ky; kz2 = kz;
}//nextu
}
}//drawball
}//classend
}
import flash.geom.Matrix3D;
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 ); }
public function fromAxisAngle(ang:Number, ax:Number, ay:Number, az:Number):void
{ var sina:Number; ang * 0.5; sina = Math.sin(ang);
x = ax * sina; y = ay * sina; z = az * sina; w = Math.cos(ang);
normalise();
}//fromaxis
public static var tempq:xQuat = new xQuat();
public function ballRot(vx:Number, vz:Number, rad:Number):void
{
rad *= -1;
var rot:Number; var mag:Number;
mag = Math.sqrt(vx * vx + vz * vz); if (mag <= 0) { return; }
rot = mag / rad; //rad*deltatime
vx /= mag; vz /= mag; //also cross vel with up (0,1,0)
tempq.fromAxisAngle(rot, -vz, 0, vx);
tempq.mul(this); this.copyQuat(tempq);
}//ballrot
}//xquat