away3d classifySphere() test

by yonatan forked from away3d classifySphere() fix (diff: 157)
♥0 | Line 65 | Modified 2012-04-13 12:24:08 | MIT License
play

ActionScript3 source code

/**
 * Copyright yonatan ( http://wonderfl.net/user/yonatan )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/eNu4
 */

// 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;
    }
}