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 "foundation/PxErrorCallback.h"
31#include "ScShapeSim.h"
32#include "ScPhysics.h"
33#include "GuConvexMesh.h"
34#include "GuTriangleMesh.h"
35#include "GuHeightField.h"
36#include "ScMaterialCore.h"
37
38using namespace physx;
39using namespace Sc;
40
41// djs: temporary cruft
42
43static PxConvexMeshGeometryLL extendForLL(const PxConvexMeshGeometry& hlGeom)
44{
45 PxConvexMeshGeometryLL llGeom;
46 static_cast<PxConvexMeshGeometry&>(llGeom) = hlGeom;
47
48 Gu::ConvexMesh* cm = static_cast<Gu::ConvexMesh*>(hlGeom.convexMesh);
49
50 llGeom.hullData = &(cm->getHull());
51 llGeom.gpuCompatible = hlGeom.convexMesh->isGpuCompatible();
52
53 return llGeom;
54}
55
56static PxTriangleMeshGeometryLL extendForLL(const PxTriangleMeshGeometry& hlGeom)
57{
58 PxTriangleMeshGeometryLL llGeom;
59 static_cast<PxTriangleMeshGeometry&>(llGeom) = hlGeom;
60
61 Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(hlGeom.triangleMesh);
62 llGeom.meshData = tm;
63 llGeom.materialIndices = tm->getMaterials();
64 llGeom.materials = static_cast<const PxTriangleMeshGeometryLL&>(hlGeom).materials;
65
66 return llGeom;
67}
68
69static PxHeightFieldGeometryLL extendForLL(const PxHeightFieldGeometry& hlGeom)
70{
71 PxHeightFieldGeometryLL llGeom;
72 static_cast<PxHeightFieldGeometry&>(llGeom) = hlGeom;
73
74 Gu::HeightField* hf = static_cast<Gu::HeightField*>(hlGeom.heightField);
75
76 llGeom.heightFieldData = &hf->getData();
77
78 llGeom.materials = static_cast<const PxHeightFieldGeometryLL&>(hlGeom).materials;
79
80 return llGeom;
81}
82
83ShapeCore::ShapeCore(const PxGeometry& geometry, PxShapeFlags shapeFlags, const PxU16* materialIndices, PxU16 materialCount) :
84 mRestOffset (0.0f),
85 mTorsionalRadius (0.0f),
86 mMinTorsionalPatchRadius(0.0f)
87{
88 mCore.mOwnsMaterialIdxMemory = true;
89
90 PX_ASSERT(materialCount > 0);
91
92 const PxTolerancesScale& scale = Physics::getInstance().getTolerancesScale();
93 mCore.geometry.set(geometry);
94 mCore.transform = PxTransform(PxIdentity);
95 mCore.contactOffset = 0.02f * scale.length;
96
97 mCore.mShapeFlags = shapeFlags;
98
99 setMaterialIndices(materialIndices, materialIndexCount: materialCount);
100}
101
102// PX_SERIALIZATION
103ShapeCore::ShapeCore(const PxEMPTY) :
104 mQueryFilterData (PxEmpty),
105 mSimulationFilterData (PxEmpty),
106 mCore (PxEmpty)
107{
108 mCore.mOwnsMaterialIdxMemory = false;
109}
110//~PX_SERIALIZATION
111
112ShapeCore::~ShapeCore()
113{
114 if(mCore.geometry.getType() == PxGeometryType::eTRIANGLEMESH)
115 {
116 PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
117 if(mCore.mOwnsMaterialIdxMemory)
118 meshGeom.materials.deallocate();
119 }
120 else if(mCore.geometry.getType() == PxGeometryType::eHEIGHTFIELD)
121 {
122 PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
123 if(mCore.mOwnsMaterialIdxMemory)
124 hfGeom.materials.deallocate();
125 }
126}
127
128PxU16 Sc::ShapeCore::getNbMaterialIndices() const
129{
130 const PxGeometryType::Enum geomType = mCore.geometry.getType();
131
132 if((geomType != PxGeometryType::eTRIANGLEMESH) && (geomType != PxGeometryType::eHEIGHTFIELD))
133 {
134 return 1;
135 }
136 else if(geomType == PxGeometryType::eTRIANGLEMESH)
137 {
138 const PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
139 return meshGeom.materials.numIndices;
140 }
141 else
142 {
143 PX_ASSERT(geomType == PxGeometryType::eHEIGHTFIELD);
144 const PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
145 return hfGeom.materials.numIndices;
146 }
147}
148
149const PxU16* Sc::ShapeCore::getMaterialIndices() const
150{
151 const PxGeometryType::Enum geomType = mCore.geometry.getType();
152
153 if((geomType != PxGeometryType::eTRIANGLEMESH) && (geomType != PxGeometryType::eHEIGHTFIELD))
154 {
155 return &mCore.materialIndex;
156 }
157 else if(geomType == PxGeometryType::eTRIANGLEMESH)
158 {
159 const PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
160 return meshGeom.materials.indices;
161 }
162 else
163 {
164 PX_ASSERT(geomType == PxGeometryType::eHEIGHTFIELD);
165 const PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
166 return hfGeom.materials.indices;
167 }
168}
169
170PX_FORCE_INLINE void setMaterialsHelper(MaterialIndicesStruct& materials, const PxU16* materialIndices, PxU16 materialIndexCount, PxU8& ownsMemory)
171{
172 if(materials.numIndices < materialIndexCount)
173 {
174 if(materials.indices && ownsMemory)
175 materials.deallocate();
176 materials.allocate(size: materialIndexCount);
177 ownsMemory = true;
178 }
179 PxMemCopy(dest: materials.indices, src: materialIndices, count: sizeof(PxU16)*materialIndexCount);
180 materials.numIndices = materialIndexCount;
181}
182
183void ShapeCore::setMaterialIndices(const PxU16* materialIndices, PxU16 materialIndexCount)
184{
185 const PxGeometryType::Enum geomType = mCore.geometry.getType();
186 mCore.materialIndex = materialIndices[0];
187
188 if(geomType == PxGeometryType::eTRIANGLEMESH)
189 {
190 PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
191 setMaterialsHelper(materials&: meshGeom.materials, materialIndices, materialIndexCount, ownsMemory&: mCore.mOwnsMaterialIdxMemory);
192 }
193 else if(geomType == PxGeometryType::eHEIGHTFIELD)
194 {
195 PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
196 setMaterialsHelper(materials&: hfGeom.materials, materialIndices, materialIndexCount, ownsMemory&: mCore.mOwnsMaterialIdxMemory);
197 }
198}
199
200void ShapeCore::setGeometry(const PxGeometry& geom)
201{
202 const PxGeometryType::Enum oldGeomType = mCore.geometry.getType();
203 const PxGeometryType::Enum newGeomType = geom.getType();
204
205 // copy material related data to restore it after the new geometry has been set
206 MaterialIndicesStruct materials;
207 PX_ASSERT(materials.numIndices == 0);
208
209 if(oldGeomType == PxGeometryType::eTRIANGLEMESH)
210 {
211 PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
212 materials = meshGeom.materials;
213 }
214 else if(oldGeomType == PxGeometryType::eHEIGHTFIELD)
215 {
216 PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
217 materials = hfGeom.materials;
218 }
219
220 mCore.geometry.set(geom);
221
222 if((newGeomType == PxGeometryType::eTRIANGLEMESH) || (newGeomType == PxGeometryType::eHEIGHTFIELD))
223 {
224 MaterialIndicesStruct* newMaterials;
225
226 if(newGeomType == PxGeometryType::eTRIANGLEMESH)
227 {
228 PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
229 newMaterials = &meshGeom.materials;
230 }
231 else
232 {
233 PX_ASSERT(newGeomType == PxGeometryType::eHEIGHTFIELD);
234 PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
235 newMaterials = &hfGeom.materials;
236 }
237
238 if(materials.numIndices != 0) // old type was mesh type
239 *newMaterials = materials;
240 else
241 { // old type was non-mesh type
242 newMaterials->allocate(size: 1);
243 *newMaterials->indices = mCore.materialIndex;
244 mCore.mOwnsMaterialIdxMemory = true;
245 }
246 }
247 else if((materials.numIndices != 0) && mCore.mOwnsMaterialIdxMemory)
248 {
249 // geometry changed to non-mesh type
250 materials.deallocate();
251 }
252}
253
254PxShape* ShapeCore::getPxShape()
255{
256 return Sc::gOffsetTable.convertScShape2Px(sc: this);
257}
258
259const PxShape* ShapeCore::getPxShape() const
260{
261 return Sc::gOffsetTable.convertScShape2Px(sc: this);
262}
263
264// PX_SERIALIZATION
265
266PX_FORCE_INLINE void exportExtraDataMaterials(PxSerializationContext& stream, const MaterialIndicesStruct& materials)
267{
268 stream.alignData(PX_SERIAL_ALIGN);
269 stream.writeData(data: materials.indices, size: sizeof(PxU16)*materials.numIndices);
270}
271
272void ShapeCore::exportExtraData(PxSerializationContext& stream)
273{
274 const PxGeometryType::Enum geomType = mCore.geometry.getType();
275
276 if(geomType == PxGeometryType::eTRIANGLEMESH)
277 {
278 PxTriangleMeshGeometryLL& meshGeom = mCore.geometry.get<PxTriangleMeshGeometryLL>();
279 exportExtraDataMaterials(stream, materials: meshGeom.materials);
280 }
281 else if(geomType == PxGeometryType::eHEIGHTFIELD)
282 {
283 PxHeightFieldGeometryLL& hfGeom = mCore.geometry.get<PxHeightFieldGeometryLL>();
284 exportExtraDataMaterials(stream, materials: hfGeom.materials);
285 }
286}
287
288void ShapeCore::importExtraData(PxDeserializationContext& context)
289{
290 const PxGeometryType::Enum geomType = mCore.geometry.getType();
291
292 if(geomType == PxGeometryType::eTRIANGLEMESH)
293 {
294 MaterialIndicesStruct& materials = mCore.geometry.get<PxTriangleMeshGeometryLL>().materials;
295 materials.indices = context.readExtraData<PxU16, PX_SERIAL_ALIGN>(count: materials.numIndices);
296 }
297 else if(geomType == PxGeometryType::eHEIGHTFIELD)
298 {
299 MaterialIndicesStruct& materials = mCore.geometry.get<PxHeightFieldGeometryLL>().materials;
300 materials.indices = context.readExtraData<PxU16, PX_SERIAL_ALIGN>(count: materials.numIndices);
301 }
302}
303
304void ShapeCore::resolveMaterialReference(PxU32 materialTableIndex, PxU16 materialIndex)
305{
306 if(materialTableIndex == 0)
307 {
308 mCore.materialIndex = materialIndex;
309 }
310
311 PxGeometry& geom = const_cast<PxGeometry&>(mCore.geometry.getGeometry());
312
313 if(geom.getType() == PxGeometryType::eHEIGHTFIELD)
314 {
315 PxHeightFieldGeometryLL& hfGeom = static_cast<PxHeightFieldGeometryLL&>(geom);
316 hfGeom.materials.indices[materialTableIndex] = materialIndex;
317 }
318 else if(geom.getType() == PxGeometryType::eTRIANGLEMESH)
319 {
320 PxTriangleMeshGeometryLL& meshGeom = static_cast<PxTriangleMeshGeometryLL&>(geom);
321 meshGeom.materials.indices[materialTableIndex] = materialIndex;
322 }
323}
324
325void ShapeCore::resolveReferences(PxDeserializationContext& context)
326{
327 // Resolve geometry pointers if needed
328 PxGeometry& geom = const_cast<PxGeometry&>(mCore.geometry.getGeometry());
329
330 switch(geom.getType())
331 {
332 case PxGeometryType::eCONVEXMESH:
333 {
334 PxConvexMeshGeometryLL& convexGeom = static_cast<PxConvexMeshGeometryLL&>(geom);
335 context.translatePxBase(base&: convexGeom.convexMesh);
336
337 // update the hullData pointer
338 static_cast<PxConvexMeshGeometryLL&>(geom) = extendForLL(hlGeom: convexGeom);
339 }
340 break;
341
342 case PxGeometryType::eHEIGHTFIELD:
343 {
344 PxHeightFieldGeometryLL& hfGeom = static_cast<PxHeightFieldGeometryLL&>(geom);
345 context.translatePxBase(base&: hfGeom.heightField);
346
347 // update hf pointers
348 static_cast<PxHeightFieldGeometryLL&>(geom) = extendForLL(hlGeom: hfGeom);
349 }
350 break;
351
352 case PxGeometryType::eTRIANGLEMESH:
353 {
354 PxTriangleMeshGeometryLL& meshGeom = static_cast<PxTriangleMeshGeometryLL&>(geom);
355 context.translatePxBase(base&: meshGeom.triangleMesh);
356
357 // update mesh pointers
358 static_cast<PxTriangleMeshGeometryLL&>(geom) = extendForLL(hlGeom: meshGeom);
359 }
360 break;
361 case PxGeometryType::eSPHERE:
362 case PxGeometryType::ePLANE:
363 case PxGeometryType::eCAPSULE:
364 case PxGeometryType::eBOX:
365 case PxGeometryType::eGEOMETRY_COUNT:
366 case PxGeometryType::eINVALID:
367 break;
368
369 }
370}
371
372//~PX_SERIALIZATION
373

source code of qtquick3dphysics/src/3rdparty/PhysX/source/simulationcontroller/src/ScShapeCore.cpp