|
@@ -1,6 +1,6 @@
|
|
|
package h3d.col;
|
|
|
|
|
|
-class Sphere {
|
|
|
+class Sphere implements RayCollider {
|
|
|
|
|
|
public var x : Float;
|
|
|
public var y : Float;
|
|
@@ -18,31 +18,51 @@ class Sphere {
|
|
|
return new Point(x, y, z);
|
|
|
}
|
|
|
|
|
|
+ public function rayIntersection( r : Ray, ?p : Point ) : Null<Point> {
|
|
|
+ var r2 = this.r * this.r;
|
|
|
+ var px = r.px + r.lx;
|
|
|
+ var py = r.py + r.ly;
|
|
|
+ var pz = r.pz + r.lz;
|
|
|
+
|
|
|
+ var a = r.lx * r.lx + r.ly * r.ly + r.lz * r.lz;
|
|
|
+ var b = 2 * r.lx * (x - px) + 2 * r.ly * (y - py) + 2 * r.lz * (z - pz);
|
|
|
+ var c = (x * x + y * y + z * z) + (px * px + py * py + pz * pz) - 2 * (x * px + y * py + z * pz) - r2;
|
|
|
+
|
|
|
+ var d = b * b - 4 * a * c;
|
|
|
+ if( d < 0 ) return null;
|
|
|
+
|
|
|
+ d = Math.sqrt(d);
|
|
|
+ var t = ( -b + d) / (2 * a);
|
|
|
+ if( p == null ) p = new Point();
|
|
|
+ p.set(px - t * r.lx , py - t * r.ly, pz - t * r.lz);
|
|
|
+ return p;
|
|
|
+ }
|
|
|
+
|
|
|
public function inFrustum( mvp : Matrix ) {
|
|
|
var p = getCenter();
|
|
|
var pl = Plane.frustumLeft(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
var pl = Plane.frustumRight(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
var pl = Plane.frustumBottom(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
var pl = Plane.frustumTop(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
var pl = Plane.frustumNear(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
var pl = Plane.frustumNear(mvp);
|
|
|
pl.normalize();
|
|
|
- if( pl.distance(p) > r )
|
|
|
+ if( pl.distance(p) < -r )
|
|
|
return false;
|
|
|
return true;
|
|
|
}
|