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#include "geometry/PxTriangleMesh.h"
31#include "geomutils/GuContactBuffer.h"
32
33#include "GuVecBox.h"
34#include "GuVecConvexHull.h"
35#include "GuVecConvexHullNoScale.h"
36#include "GuVecTriangle.h"
37#include "GuGeometryUnion.h"
38#include "GuContactMethodImpl.h"
39#include "GuHeightField.h"
40#include "GuPCMContactConvexCommon.h"
41#include "GuPCMContactMeshCallback.h"
42
43using namespace physx;
44using namespace Gu;
45using namespace physx::shdfnd::aos;
46
47namespace physx
48{
49
50struct PCMSphereVsHeightfieldContactGenerationCallback : PCMHeightfieldContactGenerationCallback<PCMSphereVsHeightfieldContactGenerationCallback>
51{
52
53public:
54 PCMSphereVsMeshContactGeneration mGeneration;
55
56 PCMSphereVsHeightfieldContactGenerationCallback(
57 const Ps::aos::Vec3VArg sphereCenter,
58 const Ps::aos::FloatVArg sphereRadius,
59 const Ps::aos::FloatVArg contactDistance,
60 const Ps::aos::FloatVArg replaceBreakingThreshold,
61
62 const PsTransformV& sphereTransform,
63 const PsTransformV& heightfieldTransform,
64 const PxTransform& heightfieldTransform1,
65 Gu::MultiplePersistentContactManifold& multiManifold,
66 Gu::ContactBuffer& contactBuffer,
67 Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts,
68 Gu::HeightFieldUtil& hfUtil
69
70
71 ) :
72 PCMHeightfieldContactGenerationCallback<PCMSphereVsHeightfieldContactGenerationCallback>(hfUtil, heightfieldTransform1),
73 mGeneration(sphereCenter, sphereRadius, contactDistance, replaceBreakingThreshold, sphereTransform,
74 heightfieldTransform, multiManifold, contactBuffer, deferredContacts)
75 {
76 }
77
78 template<PxU32 CacheSize>
79 void processTriangleCache(Gu::TriangleCache<CacheSize>& cache)
80 {
81 mGeneration.processTriangleCache<CacheSize, PCMSphereVsMeshContactGeneration>(cache);
82 }
83
84};
85
86
87bool Gu::pcmContactSphereHeightField(GU_CONTACT_METHOD_ARGS)
88{
89 PX_UNUSED(renderOutput);
90
91 const PxSphereGeometry& shapeSphere = shape0.get<const PxSphereGeometry>();
92 const PxHeightFieldGeometryLL& shapeHeight = shape1.get<const PxHeightFieldGeometryLL>();
93
94 Gu::MultiplePersistentContactManifold& multiManifold = cache.getMultipleManifold();
95
96 const QuatV q0 = QuatVLoadA(v: &transform0.q.x);
97 const Vec3V p0 = V3LoadA(f: &transform0.p.x);
98
99 const QuatV q1 = QuatVLoadA(v: &transform1.q.x);
100 const Vec3V p1 = V3LoadA(f: &transform1.p.x);
101
102 const FloatV sphereRadius = FLoad(f: shapeSphere.radius);
103 const FloatV contactDist = FLoad(f: params.mContactDistance);
104
105 const PsTransformV sphereTransform(p0, q0);//sphere transform
106 const PsTransformV heightfieldTransform(p1, q1);//height feild
107 const PsTransformV curTransform = heightfieldTransform.transformInv(src: sphereTransform);
108
109
110 // We must be in local space to use the cache
111
112 if(multiManifold.invalidate(curRTrans: curTransform, minMargin: sphereRadius, ratio: FLoad(f: 0.02f)))
113 {
114 multiManifold.mNumManifolds = 0;
115 multiManifold.setRelativeTransform(curTransform);
116
117 const FloatV replaceBreakingThreshold = FMul(a: sphereRadius, b: FLoad(f: 0.001f));
118 Gu::HeightFieldUtil hfUtil(shapeHeight);
119 const PxVec3 sphereCenterShape1Space = transform1.transformInv(input: transform0.p);
120 const Vec3V sphereCenter = V3LoadU(f: sphereCenterShape1Space);
121 PxReal inflatedRadius = shapeSphere.radius + params.mContactDistance;
122 PxVec3 inflatedRadiusV(inflatedRadius);
123
124 PxBounds3 bounds(sphereCenterShape1Space - inflatedRadiusV, sphereCenterShape1Space + inflatedRadiusV);
125
126 Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE> delayedContacts;
127
128 PCMSphereVsHeightfieldContactGenerationCallback blockCallback(
129 sphereCenter,
130 sphereRadius,
131 contactDist,
132 replaceBreakingThreshold,
133 sphereTransform,
134 heightfieldTransform,
135 transform1,
136 multiManifold,
137 contactBuffer,
138 &delayedContacts,
139 hfUtil);
140
141 hfUtil.overlapAABBTriangles(transform1, bounds, flags: 0, callback: &blockCallback);
142
143 blockCallback.mGeneration.generateLastContacts();
144 blockCallback.mGeneration.processContacts(GU_SPHERE_MANIFOLD_CACHE_SIZE, isNotLastPatch: false);
145 }
146 else
147 {
148 const PsMatTransformV aToB(curTransform);
149 const FloatV projectBreakingThreshold = FMul(a: sphereRadius, b: FLoad(f: 0.05f));
150 const FloatV refereshDistance = FAdd(a: sphereRadius, b: contactDist);
151 multiManifold.refreshManifold(relTra: aToB, projectBreakingThreshold, contactDist: refereshDistance);
152
153 }
154
155 return multiManifold.addManifoldContactsToContactBuffer(contactBuffer, trA: sphereTransform, trB: heightfieldTransform, radius: sphereRadius);
156}
157
158
159}
160

source code of qtquick3dphysics/src/3rdparty/PhysX/source/geomutils/src/pcm/GuPCMContactSphereHeightField.cpp