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 | |
38 | using namespace physx; |
39 | using namespace Sc; |
40 | |
41 | // djs: temporary cruft |
42 | |
43 | static 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 | |
56 | static 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 | |
69 | static 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 | |
83 | ShapeCore::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 |
103 | ShapeCore::ShapeCore(const PxEMPTY) : |
104 | mQueryFilterData (PxEmpty), |
105 | mSimulationFilterData (PxEmpty), |
106 | mCore (PxEmpty) |
107 | { |
108 | mCore.mOwnsMaterialIdxMemory = false; |
109 | } |
110 | //~PX_SERIALIZATION |
111 | |
112 | ShapeCore::~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 | |
128 | PxU16 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 | |
149 | const 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 | |
170 | PX_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 | |
183 | void 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 | |
200 | void 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 | |
254 | PxShape* ShapeCore::getPxShape() |
255 | { |
256 | return Sc::gOffsetTable.convertScShape2Px(sc: this); |
257 | } |
258 | |
259 | const PxShape* ShapeCore::getPxShape() const |
260 | { |
261 | return Sc::gOffsetTable.convertScShape2Px(sc: this); |
262 | } |
263 | |
264 | // PX_SERIALIZATION |
265 | |
266 | PX_FORCE_INLINE void (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 | |
272 | void ShapeCore::(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 | |
288 | void ShapeCore::(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 | |
304 | void 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 | |
325 | void 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 | |