Closest point between sphere and rotating box Move sphere with arrow keys and WASD mutantleg forked:1favorite:2lines:293license : MIT License modified : 2012-02-03 17:41:11 Embed Tweet 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 alternativa.engine3d.containers.ConflictContainer; import alternativa.engine3d.containers.BSPContainer; import alternativa.engine3d.core.Camera3D; import alternativa.engine3d.primitives.Plane; import alternativa.engine3d.primitives.Box; import alternativa.engine3d.primitives.Sphere; import alternativa.engine3d.core.View; import alternativa.engine3d.materials.Material; import alternativa.engine3d.materials.FillMaterial; import alternativa.engine3d.materials.TextureMaterial; import alternativa.engine3d.core.Object3D; import alternativa.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 alternativa.engine3d.containers.ConflictContainer; import alternativa.engine3d.containers.BSPContainer; import alternativa.engine3d.core.Camera3D; import alternativa.engine3d.primitives.Plane; import alternativa.engine3d.primitives.Box; import alternativa.engine3d.primitives.Sphere; import alternativa.engine3d.core.View; import alternativa.engine3d.materials.Material; import alternativa.engine3d.materials.FillMaterial; import alternativa.engine3d.materials.TextureMaterial; import alternativa.engine3d.core.Object3D; import alternativa.types.Texture; import alternativa.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 Code Fullscreen Preview Fullscreen bradsedito Mingchoi 3D collision math quaternion tutorial Matrix3D invert appendTranslation addEventListener rawData Math.sqrt rotationX Math.cos Math.sin Boolean Event.ENTER_FRAME Vector addChild Event Sprite int Number sort new page view favorite forked pv31 forked from: Closest point bet.. augnam08 forked:0 favorite:0lines:287 (diff:9)