// forked from yonatan2's away3d classifySphere() fix // forked from yonatan's flash on 2012-4-8 package { import flash.events.*; import flash.geom.*; import away3d.core.geom.*; import com.bit101.components.*; public class FlashTest extends VBox { private var txt:TextArea; private var sliX:HUISlider, sliY:HUISlider, sliZ:HUISlider, sliRad:HUISlider; private var f:FrustumPatch = new FrustumPatch; private var mtx:Matrix3D = new Matrix3D; public function FlashTest() { width=height=465; new Label(this, 0, 0, "Sphere center/radius"); sliX = new HUISlider(this, 0, 0, "X", classify); sliY = new HUISlider(this, 0, 0, "Y", classify); sliZ = new HUISlider(this, 0, 0, "Z", classify); sliRad = new HUISlider(this, 0, 0, "Radius", classify); var s:HUISlider; for each(s in [sliX, sliY, sliZ]) s.setSliderParams(-2, 2, 0); sliRad.setSliderParams(0, 2, 0); for each(s in [sliX, sliY, sliZ, sliRad]) s.labelPrecision = 2; txt = new TextArea(this); txt.height = 200; txt.width=465; f.extractFromMatrix(mtx); new PushButton(this, 0, 0, "Early return problem", function(e:Event):void { sliRad.value = 0.5; sliY.value = 2; sliX.value = 0.6; classify(); // should be OUT }) new PushButton(this, 0, 0, "Corner case", function(e:Event):void { sliRad.value = 0.51; sliX.value = 1.5; sliY.value = 1.5; sliZ.value = 1.5; classify(); // should be OUT }) } private function classify(e:Event = null):void { txt.text = "\nclassifySphere results:\n\n"; trace("original:", ["OUT", "IN", "INTERSECT"][f.classifySphere(new Vector3D(sliX.value, sliY.value, sliZ.value), sliRad.value)]); trace("patched:", ["OUT", "IN", "INTERSECT"][f.classifySpherePatch(new Vector3D(sliX.value, sliY.value, sliZ.value), sliRad.value)]); } private function trace(...a):void { txt.text += a.join(" ") + "\n"; } } } import flash.geom.*; import away3d.core.geom.*; class FrustumPatch extends Frustum { /** * Classify this sphere against this frustum * @return int Frustum.IN, Frustum.OUT or Frustum.INTERSECT */ public function classifySpherePatch(center:Vector3D, radius:Number):int { var _plane:Plane3D, _distance:Number; // private vars in Frustrum class var intersect:Boolean = false; for each(_plane in planes) { _distance = _plane.distance(center); if(_distance < -radius) return OUT; if(Math.abs(_distance) < radius) intersect = true; } return intersect ? INTERSECT : IN; } } away3d classifySphere() test