1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | |
31 | #ifndef GU_CCD_SWEEP_H |
32 | #define GU_CCD_SWEEP_H |
33 | |
34 | #include "common/PxPhysXCommonConfig.h" |
35 | #include "CmPhysXCommon.h" |
36 | #include "PsVecTransform.h" |
37 | #include "GuGeometryUnion.h" |
38 | #include "CmScaling.h" |
39 | |
40 | #define GU_TRIANGLE_SWEEP_METHOD_ARGS \ |
41 | const Gu::GeometryUnion& shape0, \ |
42 | const Gu::GeometryUnion& shape1, \ |
43 | const PxTransform& transform0, \ |
44 | const PxTransform& transform1, \ |
45 | const PxTransform& lastTm0, \ |
46 | const PxTransform& lastTm1, \ |
47 | PxReal restDistance, \ |
48 | PxVec3& worldNormal, \ |
49 | PxVec3& worldPoint, \ |
50 | const Cm::FastVertex2ShapeScaling& meshScaling, \ |
51 | Gu::TriangleV& triangle, \ |
52 | const PxF32 toiEstimate |
53 | |
54 | |
55 | #define GU_SWEEP_METHOD_ARGS \ |
56 | const Gu::CCDShape& shape0, \ |
57 | const Gu::CCDShape& shape1, \ |
58 | const PxTransform& transform0, \ |
59 | const PxTransform& transform1, \ |
60 | const PxTransform& lastTm0, \ |
61 | const PxTransform& lastTm1, \ |
62 | PxReal restDistance, \ |
63 | PxVec3& worldNormal, \ |
64 | PxVec3& worldPoint, \ |
65 | const PxF32 toiEstimate, \ |
66 | PxU32& outCCDFaceIndex, \ |
67 | const PxReal fastMovingThreshold |
68 | |
69 | |
70 | #define GU_SWEEP_ESTIMATE_ARGS \ |
71 | const CCDShape& shape0, \ |
72 | const CCDShape& shape1, \ |
73 | const PxTransform& transform0, \ |
74 | const PxTransform& transform1, \ |
75 | const PxTransform& lastTr0, \ |
76 | const PxTransform& lastTr1, \ |
77 | const PxReal restDistance, \ |
78 | const PxReal fastMovingThreshold |
79 | |
80 | |
81 | #define GU_SWEEP_METHOD_ARGS_UNUSED \ |
82 | const Gu::CCDShape& /*shape0*/, \ |
83 | const Gu::CCDShape& /*shape1*/, \ |
84 | const PxTransform& /*transform0*/, \ |
85 | const PxTransform& /*transform1*/, \ |
86 | const PxTransform& /*lastTm0*/, \ |
87 | const PxTransform& /*lastTm1*/, \ |
88 | PxReal /*restDistance*/, \ |
89 | PxVec3& /*worldNormal*/, \ |
90 | PxVec3& /*worldPoint*/, \ |
91 | const PxF32 /*toiEstimate*/, \ |
92 | PxU32& /*outCCDFaceIndex*/, \ |
93 | const PxReal /*fastMovingThreshold*/ |
94 | |
95 | namespace physx |
96 | { |
97 | namespace Gu |
98 | { |
99 | struct CCDShape |
100 | { |
101 | const Gu::GeometryUnion* mGeometry; |
102 | PxReal mFastMovingThreshold; //The CCD threshold for this shape |
103 | PxTransform mPrevTransform; //This shape's previous transform |
104 | PxTransform mCurrentTransform; //This shape's current transform |
105 | PxVec3 mExtents; //The extents of this shape's AABB |
106 | PxVec3 mCenter; //The center of this shape's AABB |
107 | PxU32 mUpdateCount; //How many times this shape has been updated in the CCD. This is correlated with the CCD body's update count. |
108 | }; |
109 | |
110 | PX_FORCE_INLINE PxF32 sweepAABBAABB(const PxVec3& centerA, const PxVec3& extentsA, const PxVec3& centerB, const PxVec3& extentsB, const PxVec3& trA, const PxVec3& trB) |
111 | { |
112 | //Sweep 2 AABBs against each other, return the TOI when they hit else PX_MAX_REAL if they don't hit |
113 | const PxVec3 cAcB = centerA - centerB; |
114 | const PxVec3 sumExtents = extentsA + extentsB; |
115 | |
116 | //Initial hit |
117 | if(PxAbs(a: cAcB.x) <= sumExtents.x && |
118 | PxAbs(a: cAcB.y) <= sumExtents.y && |
119 | PxAbs(a: cAcB.z) <= sumExtents.z) |
120 | return 0.f; |
121 | |
122 | //No initial hit - perform the sweep |
123 | const PxVec3 relTr = trB - trA; |
124 | PxF32 tfirst = 0.f; |
125 | PxF32 tlast = 1.f; |
126 | |
127 | const PxVec3 aMax = centerA + extentsA; |
128 | const PxVec3 aMin = centerA - extentsA; |
129 | const PxVec3 bMax = centerB + extentsB; |
130 | const PxVec3 bMin = centerB - extentsB; |
131 | |
132 | const PxF32 eps = 1e-6f; |
133 | |
134 | for(PxU32 a = 0; a < 3; ++a) |
135 | { |
136 | if(relTr[a] < -eps) |
137 | { |
138 | if(bMax[a] < aMin[a]) |
139 | return PX_MAX_REAL; |
140 | if(aMax[a] < bMin[a]) |
141 | tfirst = PxMax(a: (aMax[a] - bMin[a])/relTr[a], b: tfirst); |
142 | if(bMax[a] > aMin[a]) |
143 | tlast = PxMin(a: (aMin[a] - bMax[a])/relTr[a], b: tlast); |
144 | } |
145 | else if(relTr[a] > eps) |
146 | { |
147 | if(bMin[a] > aMax[a]) |
148 | return PX_MAX_REAL; |
149 | if(bMax[a] < aMin[a]) |
150 | tfirst = PxMax(a: (aMin[a] - bMax[a])/relTr[a], b: tfirst); |
151 | if(aMax[a] > bMin[a]) |
152 | tlast = PxMin(a: (aMax[a] - bMin[a])/relTr[a], b: tlast); |
153 | } |
154 | else |
155 | { |
156 | if(bMax[a] < aMin[a] || bMin[a] > aMax[a]) |
157 | return PX_MAX_REAL; |
158 | } |
159 | |
160 | //No hit |
161 | if(tfirst > tlast) |
162 | return PX_MAX_REAL; |
163 | } |
164 | //There was a hit so return the TOI |
165 | return tfirst; |
166 | } |
167 | |
168 | PX_PHYSX_COMMON_API PxReal SweepShapeShape(GU_SWEEP_METHOD_ARGS); |
169 | |
170 | PX_PHYSX_COMMON_API PxReal SweepEstimateAnyShapeHeightfield(GU_SWEEP_ESTIMATE_ARGS); |
171 | |
172 | PX_PHYSX_COMMON_API PxReal SweepEstimateAnyShapeMesh(GU_SWEEP_ESTIMATE_ARGS); |
173 | |
174 | |
175 | } |
176 | } |
177 | #endif |
178 | |
179 | |