Explorar o código

added TransformCollider

Nicolas Cannasse %!s(int64=4) %!d(string=hai) anos
pai
achega
5f9aced97d
Modificáronse 2 ficheiros con 95 adicións e 0 borrados
  1. 14 0
      h3d/Matrix.hx
  2. 81 0
      h3d/col/TransformCollider.hx

+ 14 - 0
h3d/Matrix.hx

@@ -80,6 +80,20 @@ class Matrix {
 		return _44 == 1;
 	}
 
+	public function isIdentityEpsilon( e : Float ) {
+		if( Math.abs(_41) > e || Math.abs(_42) > e || Math.abs(_43) > e )
+			return false;
+		if( Math.abs(_11-1) > e || Math.abs(_22-1) > e || Math.abs(_33-1) > e )
+			return false;
+		if( Math.abs(_12) > e || Math.abs(_13) > e || Math.abs(_14) > e )
+			return false;
+		if( Math.abs(_21) > e || Math.abs(_23) > e || Math.abs(_24) > e )
+			return false;
+		if( Math.abs(_31) > e || Math.abs(_32) > e || Math.abs(_34) > e )
+			return false;
+		return Math.abs(_44 - 1) <= e;
+	}
+
 	public function initRotationX( a : Float ) {
 		var cos = Math.cos(a);
 		var sin = Math.sin(a);

+ 81 - 0
h3d/col/TransformCollider.hx

@@ -0,0 +1,81 @@
+package h3d.col;
+
+class TransformCollider implements Collider {
+
+	public var collider : Collider;
+	public var mat(default, set) : h3d.Matrix;
+	var invMat : h3d.Matrix;
+
+	static var TMP_RAY = new Ray();
+	static var TMP_MAT = new Matrix();
+
+	public function new(mat, collider) {
+		this.invMat = new h3d.Matrix();
+		this.mat = mat;
+		this.collider = collider;
+	}
+
+	function set_mat(m) {
+		this.mat = m;
+		invMat.initInverse(m);
+		return m;
+	}
+
+	public function rayIntersection( r : Ray, bestMatch : Bool ) : Float {
+		var tmpRay = TMP_RAY;
+		TMP_RAY = null;
+		tmpRay.load(r);
+		r.transform(invMat);
+		var hit = collider.rayIntersection(r, bestMatch);
+		if( hit < 0 ) {
+			r.load(tmpRay);
+			TMP_RAY = tmpRay;
+			return hit;
+		}
+		var pt = r.getPoint(hit);
+		pt.transform(mat);
+		r.load(tmpRay);
+		TMP_RAY = tmpRay;
+		return hxd.Math.distance(pt.x - r.px, pt.y - r.py, pt.z - r.pz);
+	}
+
+	public function contains( p : Point ) {
+		var ptmp = p.clone();
+		p.transform(invMat);
+		var b = collider.contains(p);
+		p.load(ptmp);
+		return b;
+	}
+
+	public function inFrustum( f : Frustum, ?m : h3d.Matrix ) {
+		if( m == null )
+			return collider.inFrustum(f, mat);
+		var mat = TMP_MAT;
+		mat.multiply3x4inline(m, this.mat);
+		return collider.inFrustum(f, mat);
+	}
+
+	public function inSphere( s : Sphere ) {
+		var oldX = s.x, oldY = s.y, oldZ = s.z, oldR = s.r;
+		var center = s.getCenter();
+		center.transform(invMat);
+		var scale = invMat.getScale();
+		s.x = center.x;
+		s.y = center.y;
+		s.z = center.z;
+		s.r *= Math.max(Math.max(scale.x, scale.y), scale.z);
+		var res = collider.inSphere(s);
+		s.x = oldX;
+		s.y = oldY;
+		s.z = oldZ;
+		s.r = oldR;
+		return res;
+	}
+
+	public static function make( mat : h3d.Matrix, col ) {
+		if( mat.isIdentityEpsilon(1e-10) )
+			return col;
+		return new TransformCollider(mat, col);
+	}
+
+}