aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp')
-rw-r--r--PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp353
1 files changed, 353 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp b/PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp
new file mode 100644
index 00000000..906f4400
--- /dev/null
+++ b/PhysX_3.4/Source/GeomUtils/src/distance/GuDistancePointTriangle.cpp
@@ -0,0 +1,353 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "foundation/PxVec3.h"
+#include "GuDistancePointTriangle.h"
+#include "GuDistancePointTriangleSIMD.h"
+
+using namespace physx;
+
+// Based on Christer Ericson's book
+PxVec3 Gu::closestPtPointTriangle(const PxVec3& p, const PxVec3& a, const PxVec3& b, const PxVec3& c, float& s, float& t)
+{
+ // Check if P in vertex region outside A
+ const PxVec3 ab = b - a;
+ const PxVec3 ac = c - a;
+ const PxVec3 ap = p - a;
+ const float d1 = ab.dot(ap);
+ const float d2 = ac.dot(ap);
+ if(d1<=0.0f && d2<=0.0f)
+ {
+ s = 0.0f;
+ t = 0.0f;
+ return a; // Barycentric coords 1,0,0
+ }
+
+ // Check if P in vertex region outside B
+ const PxVec3 bp = p - b;
+ const float d3 = ab.dot(bp);
+ const float d4 = ac.dot(bp);
+ if(d3>=0.0f && d4<=d3)
+ {
+ s = 1.0f;
+ t = 0.0f;
+ return b; // Barycentric coords 0,1,0
+ }
+
+ // Check if P in edge region of AB, if so return projection of P onto AB
+ const float vc = d1*d4 - d3*d2;
+ if(vc<=0.0f && d1>=0.0f && d3<=0.0f)
+ {
+ const float v = d1 / (d1 - d3);
+ s = v;
+ t = 0.0f;
+ return a + v * ab; // barycentric coords (1-v, v, 0)
+ }
+
+ // Check if P in vertex region outside C
+ const PxVec3 cp = p - c;
+ const float d5 = ab.dot(cp);
+ const float d6 = ac.dot(cp);
+ if(d6>=0.0f && d5<=d6)
+ {
+ s = 0.0f;
+ t = 1.0f;
+ return c; // Barycentric coords 0,0,1
+ }
+
+ // Check if P in edge region of AC, if so return projection of P onto AC
+ const float vb = d5*d2 - d1*d6;
+ if(vb<=0.0f && d2>=0.0f && d6<=0.0f)
+ {
+ const float w = d2 / (d2 - d6);
+ s = 0.0f;
+ t = w;
+ return a + w * ac; // barycentric coords (1-w, 0, w)
+ }
+
+ // Check if P in edge region of BC, if so return projection of P onto BC
+ const float va = d3*d6 - d5*d4;
+ if(va<=0.0f && (d4-d3)>=0.0f && (d5-d6)>=0.0f)
+ {
+ const float w = (d4-d3) / ((d4 - d3) + (d5-d6));
+ s = 1.0f-w;
+ t = w;
+ return b + w * (c-b); // barycentric coords (0, 1-w, w)
+ }
+
+ // P inside face region. Compute Q through its barycentric coords (u,v,w)
+ const float denom = 1.0f / (va + vb + vc);
+ const float v = vb * denom;
+ const float w = vc * denom;
+ s = v;
+ t = w;
+ return a + ab*v + ac*w;
+}
+
+//Ps::aos::FloatV Gu::distancePointTriangleSquared( const Ps::aos::Vec3VArg p,
+// const Ps::aos::Vec3VArg a,
+// const Ps::aos::Vec3VArg b,
+// const Ps::aos::Vec3VArg c,
+// Ps::aos::FloatV& u,
+// Ps::aos::FloatV& v,
+// Ps::aos::Vec3V& closestP)
+//{
+// using namespace Ps::aos;
+//
+// const FloatV zero = FZero();
+// const FloatV one = FOne();
+// //const Vec3V zero = V3Zero();
+// const Vec3V ab = V3Sub(b, a);
+// const Vec3V ac = V3Sub(c, a);
+// const Vec3V bc = V3Sub(c, b);
+// const Vec3V ap = V3Sub(p, a);
+// const Vec3V bp = V3Sub(p, b);
+// const Vec3V cp = V3Sub(p, c);
+//
+// const FloatV d1 = V3Dot(ab, ap); // snom
+// const FloatV d2 = V3Dot(ac, ap); // tnom
+// const FloatV d3 = V3Dot(ab, bp); // -sdenom
+// const FloatV d4 = V3Dot(ac, bp); // unom = d4 - d3
+// const FloatV d5 = V3Dot(ab, cp); // udenom = d5 - d6
+// const FloatV d6 = V3Dot(ac, cp); // -tdenom
+// const FloatV unom = FSub(d4, d3);
+// const FloatV udenom = FSub(d5, d6);
+//
+// //check if p in vertex region outside a
+// const BoolV con00 = FIsGrtr(zero, d1); // snom <= 0
+// const BoolV con01 = FIsGrtr(zero, d2); // tnom <= 0
+// const BoolV con0 = BAnd(con00, con01); // vertex region a
+// const FloatV u0 = zero;
+// const FloatV v0 = zero;
+//
+// //check if p in vertex region outside b
+// const BoolV con10 = FIsGrtrOrEq(d3, zero);
+// const BoolV con11 = FIsGrtrOrEq(d3, d4);
+// const BoolV con1 = BAnd(con10, con11); // vertex region b
+// const FloatV u1 = one;
+// const FloatV v1 = zero;
+//
+// //check if p in vertex region outside c
+// const BoolV con20 = FIsGrtrOrEq(d6, zero);
+// const BoolV con21 = FIsGrtrOrEq(d6, d5);
+// const BoolV con2 = BAnd(con20, con21); // vertex region c
+// const FloatV u2 = zero;
+// const FloatV v2 = one;
+//
+// //check if p in edge region of AB
+// const FloatV vc = FSub(FMul(d1, d4), FMul(d3, d2));
+//
+// const BoolV con30 = FIsGrtr(zero, vc);
+// const BoolV con31 = FIsGrtrOrEq(d1, zero);
+// const BoolV con32 = FIsGrtr(zero, d3);
+// const BoolV con3 = BAnd(con30, BAnd(con31, con32));
+// const FloatV sScale = FDiv(d1, FSub(d1, d3));
+// const Vec3V closest3 = V3Add(a, V3Scale(ab, sScale));
+// const FloatV u3 = sScale;
+// const FloatV v3 = zero;
+//
+// //check if p in edge region of BC
+// const FloatV va = FSub(FMul(d3, d6),FMul(d5, d4));
+// const BoolV con40 = FIsGrtr(zero, va);
+// const BoolV con41 = FIsGrtrOrEq(d4, d3);
+// const BoolV con42 = FIsGrtrOrEq(d5, d6);
+// const BoolV con4 = BAnd(con40, BAnd(con41, con42));
+// const FloatV uScale = FDiv(unom, FAdd(unom, udenom));
+// const Vec3V closest4 = V3Add(b, V3Scale(bc, uScale));
+// const FloatV u4 = FSub(one, uScale);
+// const FloatV v4 = uScale;
+//
+// //check if p in edge region of AC
+// const FloatV vb = FSub(FMul(d5, d2), FMul(d1, d6));
+// const BoolV con50 = FIsGrtr(zero, vb);
+// const BoolV con51 = FIsGrtrOrEq(d2, zero);
+// const BoolV con52 = FIsGrtr(zero, d6);
+// const BoolV con5 = BAnd(con50, BAnd(con51, con52));
+// const FloatV tScale = FDiv(d2, FSub(d2, d6));
+// const Vec3V closest5 = V3Add(a, V3Scale(ac, tScale));
+// const FloatV u5 = zero;
+// const FloatV v5 = tScale;
+//
+// //P must project inside face region. Compute Q using Barycentric coordinates
+// const FloatV denom = FRecip(FAdd(va, FAdd(vb, vc)));
+// const FloatV t = FMul(vb, denom);
+// const FloatV w = FMul(vc, denom);
+// const Vec3V bCom = V3Scale(ab, t);
+// const Vec3V cCom = V3Scale(ac, w);
+// const Vec3V closest6 = V3Add(a, V3Add(bCom, cCom));
+// const FloatV u6 = t;
+// const FloatV v6 = w;
+//
+// const Vec3V closest= V3Sel(con0, a, V3Sel(con1, b, V3Sel(con2, c, V3Sel(con3, closest3, V3Sel(con4, closest4, V3Sel(con5, closest5, closest6))))));
+// u = FSel(con0, u0, FSel(con1, u1, FSel(con2, u2, FSel(con3, u3, FSel(con4, u4, FSel(con5, u5, u6))))));
+// v = FSel(con0, v0, FSel(con1, v1, FSel(con2, v2, FSel(con3, v3, FSel(con4, v4, FSel(con5, v5, v6))))));
+// closestP = closest;
+//
+// const Vec3V vv = V3Sub(p, closest);
+//
+// return V3Dot(vv, vv);
+//}
+
+
+Ps::aos::FloatV Gu::distancePointTriangleSquared( const Ps::aos::Vec3VArg p,
+ const Ps::aos::Vec3VArg a,
+ const Ps::aos::Vec3VArg b,
+ const Ps::aos::Vec3VArg c,
+ Ps::aos::FloatV& u,
+ Ps::aos::FloatV& v,
+ Ps::aos::Vec3V& closestP)
+{
+ using namespace Ps::aos;
+
+ const FloatV zero = FZero();
+ const FloatV one = FOne();
+ //const Vec3V zero = V3Zero();
+ const Vec3V ab = V3Sub(b, a);
+ const Vec3V ac = V3Sub(c, a);
+ const Vec3V bc = V3Sub(c, b);
+ const Vec3V ap = V3Sub(p, a);
+ const Vec3V bp = V3Sub(p, b);
+ const Vec3V cp = V3Sub(p, c);
+
+ const FloatV d1 = V3Dot(ab, ap); // snom
+ const FloatV d2 = V3Dot(ac, ap); // tnom
+ const FloatV d3 = V3Dot(ab, bp); // -sdenom
+ const FloatV d4 = V3Dot(ac, bp); // unom = d4 - d3
+ const FloatV d5 = V3Dot(ab, cp); // udenom = d5 - d6
+ const FloatV d6 = V3Dot(ac, cp); // -tdenom
+ const FloatV unom = FSub(d4, d3);
+ const FloatV udenom = FSub(d5, d6);
+
+ //check if p in vertex region outside a
+ const BoolV con00 = FIsGrtr(zero, d1); // snom <= 0
+ const BoolV con01 = FIsGrtr(zero, d2); // tnom <= 0
+ const BoolV con0 = BAnd(con00, con01); // vertex region a
+
+ if(BAllEqTTTT(con0))
+ {
+ u = zero;
+ v = zero;
+ const Vec3V vv = V3Sub(p, a);
+ closestP = a;
+ return V3Dot(vv, vv);
+ }
+
+ //check if p in vertex region outside b
+ const BoolV con10 = FIsGrtrOrEq(d3, zero);
+ const BoolV con11 = FIsGrtrOrEq(d3, d4);
+ const BoolV con1 = BAnd(con10, con11); // vertex region b
+ if(BAllEqTTTT(con1))
+ {
+ u = one;
+ v = zero;
+ const Vec3V vv = V3Sub(p, b);
+ closestP = b;
+ return V3Dot(vv, vv);
+ }
+
+ //check if p in vertex region outside c
+ const BoolV con20 = FIsGrtrOrEq(d6, zero);
+ const BoolV con21 = FIsGrtrOrEq(d6, d5);
+ const BoolV con2 = BAnd(con20, con21); // vertex region c
+ if(BAllEqTTTT(con2))
+ {
+ u = zero;
+ v = one;
+ const Vec3V vv = V3Sub(p, c);
+ closestP = c;
+ return V3Dot(vv, vv);
+ }
+
+ //check if p in edge region of AB
+ const FloatV vc = FSub(FMul(d1, d4), FMul(d3, d2));
+
+ const BoolV con30 = FIsGrtr(zero, vc);
+ const BoolV con31 = FIsGrtrOrEq(d1, zero);
+ const BoolV con32 = FIsGrtr(zero, d3);
+ const BoolV con3 = BAnd(con30, BAnd(con31, con32));
+ if(BAllEqTTTT(con3))
+ {
+ const FloatV sScale = FDiv(d1, FSub(d1, d3));
+ const Vec3V closest3 = V3Add(a, V3Scale(ab, sScale));
+ u = sScale;
+ v = zero;
+ const Vec3V vv = V3Sub(p, closest3);
+ closestP = closest3;
+ return V3Dot(vv, vv);
+ }
+
+ //check if p in edge region of BC
+ const FloatV va = FSub(FMul(d3, d6),FMul(d5, d4));
+ const BoolV con40 = FIsGrtr(zero, va);
+ const BoolV con41 = FIsGrtrOrEq(d4, d3);
+ const BoolV con42 = FIsGrtrOrEq(d5, d6);
+ const BoolV con4 = BAnd(con40, BAnd(con41, con42));
+ if(BAllEqTTTT(con4))
+ {
+ const FloatV uScale = FDiv(unom, FAdd(unom, udenom));
+ const Vec3V closest4 = V3Add(b, V3Scale(bc, uScale));
+ u = FSub(one, uScale);
+ v = uScale;
+ const Vec3V vv = V3Sub(p, closest4);
+ closestP = closest4;
+ return V3Dot(vv, vv);
+ }
+
+ //check if p in edge region of AC
+ const FloatV vb = FSub(FMul(d5, d2), FMul(d1, d6));
+ const BoolV con50 = FIsGrtr(zero, vb);
+ const BoolV con51 = FIsGrtrOrEq(d2, zero);
+ const BoolV con52 = FIsGrtr(zero, d6);
+ const BoolV con5 = BAnd(con50, BAnd(con51, con52));
+ if(BAllEqTTTT(con5))
+ {
+ const FloatV tScale = FDiv(d2, FSub(d2, d6));
+ const Vec3V closest5 = V3Add(a, V3Scale(ac, tScale));
+ u = zero;
+ v = tScale;
+ const Vec3V vv = V3Sub(p, closest5);
+ closestP = closest5;
+ return V3Dot(vv, vv);
+ }
+
+ //P must project inside face region. Compute Q using Barycentric coordinates
+ const FloatV denom = FRecip(FAdd(va, FAdd(vb, vc)));
+ const FloatV t = FMul(vb, denom);
+ const FloatV w = FMul(vc, denom);
+ const Vec3V bCom = V3Scale(ab, t);
+ const Vec3V cCom = V3Scale(ac, w);
+ const Vec3V closest6 = V3Add(a, V3Add(bCom, cCom));
+ u = t;
+ v = w;
+ closestP = closest6;
+
+ const Vec3V vv = V3Sub(p, closest6);
+
+ return V3Dot(vv, vv);
+}