In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Closest point between sphere and rotating box

Move sphere with arrow keys and WASD
Get Adobe Flash player
by mutantleg 23 Oct 2012
/**
 * Copyright mutantleg ( http://wonderfl.net/user/mutantleg )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oVV5
 */

package {
    import flash.geom.Matrix3D;
    import flash.display.BlendMode;
    import flash.display.BitmapData;
    import flash.events.KeyboardEvent;
    import flash.events.Event;
    //import flash.media.Camera;
    
    //http://alternativaplatform.com/en/docs/7.7.0/index.html
    
    import alternativ7.engine3d.containers.ConflictContainer;
    import alternativ7.engine3d.containers.BSPContainer;
    import alternativ7.engine3d.core.Camera3D;
    import alternativ7.engine3d.primitives.Plane;
    import alternativ7.engine3d.primitives.Box;
    import alternativ7.engine3d.primitives.Sphere;
    import alternativ7.engine3d.core.View;
     import alternativ7.engine3d.materials.Material;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.materials.TextureMaterial;
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.types.Texture;
    import flash.display.Sprite;
    
    public class FlashTest extends Sprite {
        
        public var cam:Camera3D;
        public var cont:BSPContainer = new BSPContainer();
       // public var gBox:Object3D;
        public var sph:Object3D;
        public var rad:Number = 128;
        public var testOb:cObst;
        
        public var closep:Object3D;
        
        
        public function FlashTest() {
            // write as3 code here..
               cam = new Camera3D();
                cam.view = new View(500,500); 
                cam.z = -1000;
                cam.y = -500
                cam.lookAt(0,0,0);
                
               addChild(cam.view);
                cont.addChild(cam);
                
                var bm:BitmapData;
                bm = new BitmapData(64,64,false,0);
                bm.noise(123213,0,16,3,true);
                
                
                
                
                var p:Plane;
                
                p = new Plane(1024, 1024, 8, 8);
                p.setMaterialToAllFaces( new FillMaterial(0,0,1,0) );
                p.rotationX = 1.57;
                p.y = 200;
                 cont.addChild(p);
                
                bm = new BitmapData(64,64,false,0);
                bm.noise(123123);
                
                var box:Sphere; //Box;
                //box = new Box(200,200,200,1,1,1);
                  box = new Sphere(rad,12,8);
               // box.setMaterialToAllFaces( new FillMaterial(0) );
                box.x = -384;
                box.setMaterialToAllFaces( new TextureMaterial( bm) );
               
                  cont.addChild(box);
                  sph = box;
                  
                testOb = new cObst();
                cont.addChild(testOb.obj);  
                  
                var s:Sphere;
                s = new Sphere(12,8,8);
                s.setMaterialToAllFaces( new FillMaterial(0,0.5,1,0) );
                    cont.addChild(s);
                    closep = s;   
                  
                  
                  stage.addEventListener(Event.ENTER_FRAME, onEnter);  
                  stage.addEventListener(KeyboardEvent.KEY_DOWN, kdown);
                  stage.addEventListener(KeyboardEvent.KEY_UP, kup);    
               
               
        }//ctor
        
        public function kdown(e:KeyboardEvent):void
        {  cKeyMan.setKey(e.keyCode, true);     }//kdown
        
        public function kup(e:KeyboardEvent):void
        {  cKeyMan.setKey(e.keyCode, false);    }//kup
        
                
        
        public function onEnter(e:Event):void
        {
            //ref
         //http://www.dakmm.com/?p=272
            if (cKeyMan.isKeyDown(39) ) { sph.x += 20;}
            if (cKeyMan.isKeyDown(37) ) { sph.x -= 20;}
            if (cKeyMan.isKeyDown(87) ) { sph.y -= 20;}
            if (cKeyMan.isKeyDown(83) ) { sph.y += 20;}
            if (cKeyMan.isKeyDown(38) ) { sph.z += 20;}
            if (cKeyMan.isKeyDown(40) ) { sph.z -= 20;}
 
 
             testOb.ori.rotYaw(0.01);
             testOb.ori.rotPitch(0.01);
             testOb.ori.rotRoll(0.01);
             
             testOb.update();           
            //gBox.rotationY += 0.1;
           // checkCol(testOb);
           testClosest(testOb);
            
             cam.render();
             
        }//onenter
        
        
        public static var tmat:Matrix3D = new Matrix3D(); //temp matrix
        public function testClosest(a:cObst):void
        {
            var ix:Number; var iy:Number; var iz:Number;
            var rx:Number; var ry:Number; var rz:Number;
            var kx:Number; var ky:Number; var kz:Number;
            var dx:Number; var dy:Number; var dz:Number;
            
            //convert the sphere coordinates into the box's coordinate space
            rx = sph.x - a.cx;
            ry = sph.y - a.cy;
            rz = sph.z - a.cz;
            
            a.ori.setMatrix(tmat);
            var raw:Vector.<Number> = tmat.rawData;
            
            kx = raw[0] * rx + raw[1] * ry + raw[2] * rz;
            ky = raw[4] * rx + raw[5] * ry + raw[6] * rz;
            kz = raw[8] * rx + raw[9] * ry + raw[10] * rz;
            
            //do the coordinate test in the box's space (its origin is at the 0,0,0 now)
            if (kx <  -a.xrad) { ix = -a.xrad; }
            else if (kx >  a.xrad) { ix =  a.xrad; }
            else { ix = kx; }
            
            if (ky < -a.yrad) { iy =  -a.yrad; }
            else if (ky >  a.yrad) { iy =  a.yrad; }
            else { iy = ky; }
            
            if (kz <  -a.zrad) { iz =  -a.zrad; }
            else if (kz > a.zrad) { iz =  a.zrad; }
            else { iz = kz; }
            
            //now transform the closest point back into world space
            rx = ix; ry = iy; rz = iz;
            
            kx = raw[0] * rx + raw[4] * ry + raw[8] * rz;
            ky = raw[1] * rx + raw[5] * ry + raw[9] * rz;
            kz = raw[2] * rx + raw[6] * ry + raw[10] * rz;
            
            ix = kx + a.cx;
            iy = ky + a.cy;
            iz = kz + a.cz;
            
            closep.x = ix;
            closep.y = iy;
            closep.z = iz;
            
            
                var mag:Number;
            
                 dx = sph.x - ix; 
                dy = sph.y - iy;
                dz = sph.z - iz;
                
                mag = Math.sqrt(dx * dx + dy * dy + dz *dz);
                if (mag == 0) {mag = 0.0001;}
                if (rad < mag) { return; }
                
                dx /= mag;
                dy /= mag;
                dz /= mag;
                
                var diff:Number = rad - mag;
                
                sph.x += dx * diff;
                sph.y += dy * diff;
                sph.z += dz * diff;
        }//testclose
      
        
        
    }//flashtest
}//package



import flash.geom.Matrix3D;

import alternativ7.engine3d.containers.ConflictContainer;
    import alternativ7.engine3d.containers.BSPContainer;
    import alternativ7.engine3d.core.Camera3D;
    import alternativ7.engine3d.primitives.Plane;
    import alternativ7.engine3d.primitives.Box;
    import alternativ7.engine3d.primitives.Sphere;
    import alternativ7.engine3d.core.View;
     import alternativ7.engine3d.materials.Material;
    import alternativ7.engine3d.materials.FillMaterial;
    import alternativ7.engine3d.materials.TextureMaterial;
    import alternativ7.engine3d.core.Object3D;
    import alternativ7.types.Texture;
    import alternativ7.engine3d.core.Sorting;
    
internal class cObst
{
    
    public function cObst()
    {
       initDisp(); 
       }//ctor
    
    public var cx:Number = 0;
    public var cy:Number = -80;
    public var cz:Number = 0;
    
    public var xrad:Number = 110;
    public var yrad:Number = 80;
    public var zrad:Number = 300;
    
    public var ori:cQuat = new cQuat();
    public var obj:Object3D;
    
    public function initDisp():void
    {
        var b:Box = new Box(xrad*2,yrad*2,zrad*2,3,2,6);
        b.setMaterialToAllFaces( new FillMaterial(0xFFFF0000,0.75,1,0) );
        b.sorting = Sorting.DYNAMIC_BSP;
        obj = b;
        
    }//indisp
    
    public static var tmat:Matrix3D = new Matrix3D();
    public function update():void
    {
        ori.setMatrix(tmat);
        tmat.appendTranslation(cx,cy,cz);
        obj.matrix = tmat;
        
        
    }//update
    
    
}//cobst


internal class cQuat
{
    
    public var x:Number = 0;
    public var y:Number = 0;
    public var z:Number = 0;
    public var w:Number = 1;
    
    public function cQuat()
    {}//ctor
    
    public function reset():void
    { x = 0; y = 0; z = 0; w = 1; }
    
    public function copyQuat(q:cQuat):void
    { x = q.x; y = q.y; z = q.z; w = q.w; }
    
    public function invert():void
    { x = -x; y = -y; z = -z; }
    
    public function normalise():void
    {
        var mag:Number;
        
        mag = x*x + y*y + z*z + w*w;
        if (mag == 1.0) {return;}
        if (mag == 0.0) {x=0;y=0;z=0;w=1; return;}
        
        mag = 1.0 / Math.sqrt(mag);
        
        x*= mag;
        y*= mag;
        z*= mag;
        w*= mag;
        
    }//normal
    
    //multiply with other quaternion
    public function mul(b:cQuat):void
    {
            var tx:Number;
            var ty:Number;
            var tz:Number;
            var tw:Number;
            
            tx =    (w*b.x + x*b.w + y*b.z - z*b.y),
            ty =    (w*b.y + y*b.w + z*b.x - x*b.z),
            tz =    (w*b.z + z*b.w + x*b.y - y*b.x),
            tw =    (w*b.w - x*b.x - y*b.y - z*b.z);

            x = tx;
            y = ty;
            z = tz;
            w = tw; 
    }//mul
    
    public function mulq(px:Number, py:Number, pz:Number, pw:Number):void
    {
            var tx:Number;
            var ty:Number;
            var tz:Number;
            var tw:Number;
            
            tx =    (w*px + x*pw + y*pz - z*py),
            ty =    (w*py + y*pw + z*px - x*pz),
            tz =    (w*pz + z*pw + x*py - y*px),
            tw =    (w*pw - x*px - y*py - z*pz);

            x = tx;
            y = ty;
            z = tz;
            w = tw; 
    }//mulq
    
    //rotate pitch by angle (in radian)
    public function rotPitch(ang:Number):void
    {
        ang *= 0.5;        
        mulq(Math.sin(ang),0,0, Math.cos(ang));
        normalise();
     }//rotpitch
    
    public function rotYaw(ang:Number):void
    {
        ang *= 0.5;
        mulq(0,Math.sin(ang),0, Math.cos(ang));
        normalise();
     }//rotyaw
    
    public function rotRoll(ang:Number):void
    {
        ang *= 0.5;
        mulq(0,0,Math.sin(ang), Math.cos(ang));
        normalise();
     }//rotpitch


    public static var tempVec:Vector.<Number> = new Vector.<Number>(16,true);
    public function setMatrix(m:Matrix3D):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;
        
            tempVec[3]  = tempVec[7] = tempVec[11] = tempVec[12] = tempVec[13] = tempVec[14] = 0.0;
            tempVec[15] = 1.0;

            
            tempVec[0]  = 1.0 - 2.0 * ( yy + zz );
            tempVec[4]  =     2.0 * ( xy - zw );
            tempVec[8]  =     2.0 * ( xz + yw );

            tempVec[1]  =  2.0 * ( xy + zw ) ;
            tempVec[5]  = 1.0 - 2.0 * ( xx + zz ) ;
            tempVec[9]  =  2.0 * ( yz - xw ) ;

            tempVec[2]  =     2.0 * ( xz - yw );
            tempVec[6]  =     2.0 * ( yz + xw );
            tempVec[10] = 1.0 - 2.0 * ( xx + yy );
            
      m.rawData = tempVec;
        
    }//setmatrix
    
    

    
}//cquat



internal class cKeyMan
   {
       public function cKeyMan() {}//ctor (unused)
       
       public static var vecKey:Vector.<Boolean> = new Vector.<Boolean>(512,true);
       
       public static function setKey(k:int, b:Boolean):void
       {
           if (k < 0) return;
           if (k >= 512) return;
           vecKey[k] = b;
       }//setkey
       
       public static function isKeyDown(k:int):Boolean
       {
           if  (k < 0) return false;
           if (k >= 512) return false;
           return vecKey[k];
       }//iskey
       
   }//keyman