|
@@ -88,6 +88,82 @@ class PolygonBuffer extends Collider {
|
|
|
return getBounds().dimension();
|
|
|
}
|
|
|
|
|
|
+ inline function isPointInTriangle( d : FPoint, d1 : FPoint, d2 : FPoint ) {
|
|
|
+ // Compute vectors
|
|
|
+ var dot02 = d1.dot(d);
|
|
|
+ var dot12 = d2.dot(d);
|
|
|
+
|
|
|
+ var dot00 = d1.dot(d1);
|
|
|
+ var dot01 = d1.dot(d2);
|
|
|
+ var dot11 = d2.dot(d2);
|
|
|
+ var invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
|
|
|
+
|
|
|
+ // Compute barycentric coordinates
|
|
|
+ var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
|
+ var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
|
+
|
|
|
+ // Check if point is in triangle
|
|
|
+ return (u >= 0) && (v >= 0) && (u + v < 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ inline function closestPointLine(p : FPoint, start : FPoint, d : FPoint) {
|
|
|
+ var t = p.sub(start).dot(d) / d.dot(d);
|
|
|
+ t = hxd.Math.clamp(t);
|
|
|
+ return start.add(d.scaled(t));
|
|
|
+ }
|
|
|
+
|
|
|
+ public function closestPoint( p : h3d.col.Point ) {
|
|
|
+ var p = new FPoint(p.x, p.y, p.z);
|
|
|
+ var minDistSq = hxd.Math.POSITIVE_INFINITY;
|
|
|
+ var closest = null;
|
|
|
+
|
|
|
+ var i = startIndex;
|
|
|
+ for ( t in 0...triCount ) {
|
|
|
+ var i0 = indexes[i++] * 3;
|
|
|
+ var p0 = new FPoint(buffer[i0++], buffer[i0++], buffer[i0]);
|
|
|
+ var i1 = indexes[i++] * 3;
|
|
|
+ var p1 = new FPoint(buffer[i1++], buffer[i1++], buffer[i1]);
|
|
|
+ var i2 = indexes[i++] * 3;
|
|
|
+ var p2 = new FPoint(buffer[i2++], buffer[i2++], buffer[i2]);
|
|
|
+
|
|
|
+ var c = null;
|
|
|
+ var d1 = p1.sub(p0);
|
|
|
+ var d2 = p2.sub(p0);
|
|
|
+ var d = p.sub(p0);
|
|
|
+ if ( isPointInTriangle(d, d1, d2) ) {
|
|
|
+ var n = d1.cross(d2).normalized();
|
|
|
+ var dProj = d.sub(n.scaled(d.dot(n)));
|
|
|
+ c = p0.add(dProj);
|
|
|
+ } else {
|
|
|
+ var c1 = closestPointLine(p, p0, d1);
|
|
|
+ var c2 = closestPointLine(p, p1, d2.sub(d1));
|
|
|
+ var c3 = closestPointLine(p, p0, d2);
|
|
|
+
|
|
|
+ var mag1 = p.sub(c1).lengthSq();
|
|
|
+ var mag2 = p.sub(c2).lengthSq();
|
|
|
+ var mag3 = p.sub(c3).lengthSq();
|
|
|
+
|
|
|
+ var min = mag1;
|
|
|
+ c = c1;
|
|
|
+ if ( mag2 < min ) {
|
|
|
+ min = mag2;
|
|
|
+ c = c2;
|
|
|
+ }
|
|
|
+ if ( mag3 < min ) {
|
|
|
+ min = mag3;
|
|
|
+ c = c3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var distSq = p.distanceSq(c);
|
|
|
+ if ( distSq < minDistSq ) {
|
|
|
+ closest = c;
|
|
|
+ minDistSq = distSq;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new h3d.col.Point(closest.x, closest.y, closest.z);
|
|
|
+ }
|
|
|
+
|
|
|
// Möller–Trumbore intersection
|
|
|
public function rayIntersection( r : Ray, bestMatch : Bool ) : Float {
|
|
|
var i = startIndex;
|