RavEngine
Loading...
Searching...
No Matches
NpRigidBodyTemplate.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef NP_RIGIDBODY_TEMPLATE_H
30#define NP_RIGIDBODY_TEMPLATE_H
31
32#include "NpRigidActorTemplate.h"
33#include "ScBodyCore.h"
34#include "NpPhysics.h"
35#include "NpShape.h"
36#include "NpScene.h"
37#include "CmVisualization.h"
38#include "NpDebugViz.h"
39
40#if PX_SUPPORT_PVD
41 // PT: updatePvdProperties() is overloaded and the compiler needs to know 'this' type to do the right thing.
42 // Thus we can't just move this as an inlined Base function.
43 #define UPDATE_PVD_PROPERTY_BODY \
44 { \
45 NpScene* sceneForPVD = RigidActorTemplateClass::getNpScene(); /* shared shapes also return zero here */ \
46 if(sceneForPVD) \
47 sceneForPVD->getScenePvdClientInternal().updateBodyPvdProperties(static_cast<NpActor*>(this)); \
48 }
49#else
50 #define UPDATE_PVD_PROPERTY_BODY
51#endif
52
53namespace physx
54{
55PX_INLINE PxVec3 invertDiagInertia(const PxVec3& m)
56{
57 return PxVec3( m.x == 0.0f ? 0.0f : 1.0f/m.x,
58 m.y == 0.0f ? 0.0f : 1.0f/m.y,
59 m.z == 0.0f ? 0.0f : 1.0f/m.z);
60}
61
62#if PX_ENABLE_DEBUG_VISUALIZATION
63/*
64given the diagonal of the body space inertia tensor, and the total mass
65this returns the body space AABB width, height and depth of an equivalent box
66*/
67PX_INLINE PxVec3 getDimsFromBodyInertia(const PxVec3& inertiaMoments, PxReal mass)
68{
69 const PxVec3 inertia = inertiaMoments * (6.0f/mass);
70 return PxVec3( PxSqrt(PxAbs(- inertia.x + inertia.y + inertia.z)),
71 PxSqrt(PxAbs(+ inertia.x - inertia.y + inertia.z)),
72 PxSqrt(PxAbs(+ inertia.x + inertia.y - inertia.z)));
73}
74#else
75 PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION
76#endif
77
78template<class APIClass>
80{
81protected:
83public:
84// PX_SERIALIZATION
85 NpRigidBodyTemplate(PxBaseFlags baseFlags) : RigidActorTemplateClass(baseFlags), mCore(PxEmpty) {}
86//~PX_SERIALIZATION
87 virtual ~NpRigidBodyTemplate();
88
89 // The rule is: If an API method is used somewhere in here, it has to be redeclared, else GCC whines
90
91 // PxRigidActor
92 virtual PxTransform getGlobalPose() const = 0;
93 virtual bool attachShape(PxShape& shape) PX_OVERRIDE;
94 //~PxRigidActor
95
96 // PxRigidBody
97 virtual PxTransform getCMassLocalPose() const PX_OVERRIDE;
98 virtual void setMass(PxReal mass) PX_OVERRIDE;
99 virtual PxReal getMass() const PX_OVERRIDE;
100 virtual PxReal getInvMass() const PX_OVERRIDE;
101 virtual void setMassSpaceInertiaTensor(const PxVec3& m) PX_OVERRIDE;
102 virtual PxVec3 getMassSpaceInertiaTensor() const PX_OVERRIDE;
103 virtual PxVec3 getMassSpaceInvInertiaTensor() const PX_OVERRIDE;
104 virtual void setLinearDamping(PxReal linDamp) PX_OVERRIDE;
105 virtual PxReal getLinearDamping() const PX_OVERRIDE;
106 virtual void setAngularDamping(PxReal angDamp) PX_OVERRIDE;
107 virtual PxReal getAngularDamping() const PX_OVERRIDE;
108 virtual PxVec3 getLinearVelocity() const PX_OVERRIDE;
109 virtual PxVec3 getAngularVelocity() const PX_OVERRIDE;
110 virtual void setMaxLinearVelocity(PxReal maxLinVel) PX_OVERRIDE;
111 virtual PxReal getMaxLinearVelocity() const PX_OVERRIDE;
112 virtual void setMaxAngularVelocity(PxReal maxAngVel) PX_OVERRIDE;
113 virtual PxReal getMaxAngularVelocity() const PX_OVERRIDE;
114 //~PxRigidBody
115
116 //---------------------------------------------------------------------------------
117 // Miscellaneous
118 //---------------------------------------------------------------------------------
119 NpRigidBodyTemplate(PxType concreteType, PxBaseFlags baseFlags, const PxActorType::Enum type, NpType::Enum npType, const PxTransform& bodyPose);
120
121 PX_FORCE_INLINE const Sc::BodyCore& getCore() const { return mCore; }
122 PX_FORCE_INLINE Sc::BodyCore& getCore() { return mCore; }
123
124 // Flags
125 virtual void setRigidBodyFlag(PxRigidBodyFlag::Enum, bool value) PX_OVERRIDE;
126 virtual void setRigidBodyFlags(PxRigidBodyFlags inFlags) PX_OVERRIDE;
127 PX_FORCE_INLINE PxRigidBodyFlags getRigidBodyFlagsFast() const { return mCore.getFlags(); }
128 virtual PxRigidBodyFlags getRigidBodyFlags() const PX_OVERRIDE
129 {
130 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
131 return getRigidBodyFlagsFast() & ~PxRigidBodyFlag::eRESERVED;
132 }
133
134 virtual void setMinCCDAdvanceCoefficient(PxReal advanceCoefficient) PX_OVERRIDE;
135 virtual PxReal getMinCCDAdvanceCoefficient() const PX_OVERRIDE;
136 virtual void setMaxDepenetrationVelocity(PxReal maxDepenVel) PX_OVERRIDE;
137 virtual PxReal getMaxDepenetrationVelocity() const PX_OVERRIDE;
138 virtual void setMaxContactImpulse(PxReal maxDepenVel) PX_OVERRIDE;
139 virtual PxReal getMaxContactImpulse() const PX_OVERRIDE;
140 virtual void setContactSlopCoefficient(PxReal slopCoefficient) PX_OVERRIDE;
141 virtual PxReal getContactSlopCoefficient() const PX_OVERRIDE;
142
143 virtual PxNodeIndex getInternalIslandNodeIndex() const PX_OVERRIDE;
144
145protected:
146 void setCMassLocalPoseInternal(const PxTransform&);
147
148 void addSpatialForce(const PxVec3* force, const PxVec3* torque, PxForceMode::Enum mode);
149 void clearSpatialForce(PxForceMode::Enum mode, bool force, bool torque);
150 void setSpatialForce(const PxVec3* force, const PxVec3* torque, PxForceMode::Enum mode);
151
152 PX_FORCE_INLINE void setRigidBodyFlagsInternal(const PxRigidBodyFlags& currentFlags, const PxRigidBodyFlags& newFlags);
153
154public:
155#if PX_ENABLE_DEBUG_VISUALIZATION
156 void visualize(PxRenderOutput& out, NpScene& scene, float scale) const;
157#else
158 PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION
159#endif
160
161 PX_FORCE_INLINE bool isKinematic() const
162 {
163 return (APIClass::getConcreteType() == PxConcreteType::eRIGID_DYNAMIC) && (mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC);
164 }
165
166 PX_INLINE void scSetSolverIterationCounts(PxU16 c)
167 {
168 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
169 mCore.setSolverIterationCounts(c);
170 UPDATE_PVD_PROPERTY_BODY
171 }
172
173 PX_INLINE void scSetLockFlags(PxRigidDynamicLockFlags f)
174 {
175 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
176 mCore.setRigidDynamicLockFlags(f);
177 UPDATE_PVD_PROPERTY_BODY
178 }
179
180 PX_INLINE void scSetBody2World(const PxTransform& p)
181 {
182 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
183 mCore.setBody2World(p);
184 UPDATE_PVD_PROPERTY_BODY
185 }
186
187 PX_INLINE void scSetLinearVelocity(const PxVec3& v)
188 {
189 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
190 mCore.setLinearVelocity(v);
191 UPDATE_PVD_PROPERTY_BODY
192 }
193
194 PX_INLINE void scSetAngularVelocity(const PxVec3& v)
195 {
196 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
197 mCore.setAngularVelocity(v);
198 UPDATE_PVD_PROPERTY_BODY
199 }
200
201 PX_INLINE void scWakeUpInternal(PxReal wakeCounter)
202 {
203 PX_ASSERT(RigidActorTemplateClass::getNpScene());
204
205 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
206 mCore.wakeUp(wakeCounter);
207 }
208
209 PX_FORCE_INLINE void scWakeUp()
210 {
211 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
212
213 NpScene* scene = RigidActorTemplateClass::getNpScene();
214 PX_ASSERT(scene); // only allowed for an object in a scene
215
216 scWakeUpInternal(scene->getWakeCounterResetValueInternal());
217 }
218
219 PX_INLINE void scPutToSleepInternal()
220 {
221 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
222 mCore.putToSleep();
223 }
224
225 PX_FORCE_INLINE void scPutToSleep()
226 {
227 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
228
229 scPutToSleepInternal();
230 }
231
232 PX_INLINE void scSetWakeCounter(PxReal w)
233 {
234 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
235
236 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
237 mCore.setWakeCounter(w);
238 UPDATE_PVD_PROPERTY_BODY
239 }
240
241 PX_INLINE void scSetFlags(PxRigidBodyFlags f)
242 {
243 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
244 mCore.setFlags(RigidActorTemplateClass::getNpScene() ? RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool() : NULL, f);
245 UPDATE_PVD_PROPERTY_BODY
246 }
247
248 PX_INLINE void scAddSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc)
249 {
250 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
251
252 mCore.addSpatialAcceleration(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linAcc, angAcc);
253 //Spatial acceleration isn't sent to PVD.
254 }
255
256 PX_INLINE void scSetSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc)
257 {
258 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
259
260 mCore.setSpatialAcceleration(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linAcc, angAcc);
261 //Spatial acceleration isn't sent to PVD.
262 }
263
264 PX_INLINE void scClearSpatialAcceleration(bool force, bool torque)
265 {
266 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
267
268 mCore.clearSpatialAcceleration(force, torque);
269 //Spatial acceleration isn't sent to PVD.
270 }
271
272 PX_INLINE void scAddSpatialVelocity(const PxVec3* linVelDelta, const PxVec3* angVelDelta)
273 {
274 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
275
276 mCore.addSpatialVelocity(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linVelDelta, angVelDelta);
277 UPDATE_PVD_PROPERTY_BODY
278 }
279
280 PX_INLINE void scClearSpatialVelocity(bool force, bool torque)
281 {
282 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
283
284 mCore.clearSpatialVelocity(force, torque);
285 UPDATE_PVD_PROPERTY_BODY
286 }
287
288 PX_INLINE void scSetKinematicTarget(const PxTransform& p)
289 {
290 NpScene* scene = RigidActorTemplateClass::getNpScene();
291 PX_ASSERT(scene); // only allowed for an object in a scene
292 const PxReal wakeCounterResetValue = scene->getWakeCounterResetValueInternal();
293
294 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim());
295
296 mCore.setKinematicTarget(p, wakeCounterResetValue);
297
298 UPDATE_PVD_PROPERTY_BODY
299
300 #if PX_SUPPORT_PVD
301 scene->getScenePvdClientInternal().updateKinematicTarget(this, p);
302 #endif
303 }
304
305 PX_INLINE PxMat33 scGetGlobalInertiaTensorInverse() const
306 {
307 PxMat33 inverseInertiaWorldSpace;
308 Cm::transformInertiaTensor(mCore.getInverseInertia(), PxMat33Padded(mCore.getBody2World().q), inverseInertiaWorldSpace);
309 return inverseInertiaWorldSpace;
310 }
311
312 PX_FORCE_INLINE bool scCheckSleepReadinessBesidesWakeCounter()
313 {
314 return (getLinearVelocity().isZero() && getAngularVelocity().isZero());
315 // no need to test for pending force updates yet since currently this is not supported on scene insertion
316 }
317
318protected:
319 Sc::BodyCore mCore;
320};
321
322template<class APIClass>
323NpRigidBodyTemplate<APIClass>::NpRigidBodyTemplate(PxType concreteType, PxBaseFlags baseFlags, PxActorType::Enum type, NpType::Enum npType, const PxTransform& bodyPose) :
324 RigidActorTemplateClass (concreteType, baseFlags, npType),
325 mCore (type, bodyPose)
326{
327}
328
329template<class APIClass>
330NpRigidBodyTemplate<APIClass>::~NpRigidBodyTemplate()
331{
332}
333
334namespace
335{
336 PX_FORCE_INLINE static bool hasNegativeMass(const PxShape& shape)
337 {
338 const PxGeometryType::Enum t = shape.getGeometryType();
339 if (t == PxGeometryType::eTRIANGLEMESH)
340 {
341 const PxTriangleMeshGeometry& triGeom = static_cast<const PxTriangleMeshGeometry&>(shape.getGeometry());
342 const Gu::TriangleMesh* mesh = static_cast<const Gu::TriangleMesh*>(triGeom.triangleMesh);
343 return mesh->getSdfDataFast().mSdf != NULL && mesh->getMass() < 0.f;
344 }
345 return false;
346 }
347
348 PX_FORCE_INLINE static bool isDynamicMesh(const PxGeometry& geom)
349 {
350 const PxTriangleMeshGeometry& triGeom = static_cast<const PxTriangleMeshGeometry&>(geom);
351 const Gu::TriangleMesh* mesh = static_cast<const Gu::TriangleMesh*>(triGeom.triangleMesh);
352 return mesh->getSdfDataFast().mSdf != NULL && mesh->getMass() > 0.f;
353 }
354
355 PX_FORCE_INLINE static bool isSimGeom(const PxShape& shape)
356 {
357 const PxGeometryType::Enum t = shape.getGeometryType();
358 return t != PxGeometryType::ePLANE && t != PxGeometryType::eHEIGHTFIELD && t != PxGeometryType::eTETRAHEDRONMESH &&
359 (t != PxGeometryType::eTRIANGLEMESH || isDynamicMesh(shape.getGeometry()));
360 }
361}
362
363template<class APIClass>
364bool NpRigidBodyTemplate<APIClass>::attachShape(PxShape& shape)
365{
366 NP_WRITE_CHECK(RigidActorTemplateClass::getNpScene());
367 PX_CHECK_AND_RETURN_VAL(!(shape.getFlags() & PxShapeFlag::eSIMULATION_SHAPE)
368 || !hasNegativeMass(shape)
369 || isKinematic(),
370 "attachShape: The faces of the mesh are oriented the wrong way round leading to a negative mass. Please invert the orientation of all faces and try again.", false);
371
372 PX_CHECK_AND_RETURN_VAL(!(shape.getFlags() & PxShapeFlag::eSIMULATION_SHAPE)
373 || isSimGeom(shape)
374 || isKinematic(),
375 "attachShape: non-SDF triangle mesh, tetrahedron mesh, heightfield or plane geometry shapes configured as eSIMULATION_SHAPE are not supported for non-kinematic PxRigidDynamic instances.", false);
376
377 return RigidActorTemplateClass::attachShape(shape);
378}
379
380template<class APIClass>
381void NpRigidBodyTemplate<APIClass>::setCMassLocalPoseInternal(const PxTransform& body2Actor)
382{
383 //the point here is to change the mass distribution w/o changing the actors' pose in the world
384
385 const PxTransform newBody2World = getGlobalPose() * body2Actor;
386
387 scSetBody2World(newBody2World);
388
389 // PT: TODO: assert & PVD update already done in scSetBody2World...
390 {
391 PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden());
392 mCore.setBody2Actor(body2Actor);
393 UPDATE_PVD_PROPERTY_BODY
394 }
395
396 RigidActorTemplateClass::updateShaderComs();
397
398#if PX_SUPPORT_OMNI_PVD
399 PxActor* actor = static_cast<PxActor*>(this);
400 OMNI_PVD_SET(actor, cMassLocalPose, *actor, body2Actor)
401#endif
402}
403
404template<class APIClass>
405PxTransform NpRigidBodyTemplate<APIClass>::getCMassLocalPose() const
406{
407 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
408
409 return mCore.getBody2Actor();
410}
411
412template<class APIClass>
413void NpRigidBodyTemplate<APIClass>::setMass(PxReal mass)
414{
415 NpScene* npScene = RigidActorTemplateClass::getNpScene();
416 NP_WRITE_CHECK(npScene);
417 PX_CHECK_AND_RETURN(PxIsFinite(mass), "PxRigidBody::setMass(): invalid float");
418 PX_CHECK_AND_RETURN(mass>=0, "PxRigidBody::setMass(): mass must be non-negative!");
419 PX_CHECK_AND_RETURN(this->getType() != PxActorType::eARTICULATION_LINK || mass > 0.0f, "PxRigidBody::setMass(): components must be > 0 for articulations");
420
421 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMass() not allowed while simulation is running. Call will be ignored.")
422
423 mCore.setInverseMass(mass > 0.0f ? 1.0f/mass : 0.0f);
424
425 UPDATE_PVD_PROPERTY_BODY
426
427#if PX_SUPPORT_OMNI_PVD
428 PxActor* actor = static_cast<PxActor*>(this);
429 OMNI_PVD_SET(actor, mass, *actor, mass)
430#endif
431}
432
433template<class APIClass>
434PxReal NpRigidBodyTemplate<APIClass>::getMass() const
435{
436 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
437 const PxReal invMass = mCore.getInverseMass();
438
439 return invMass > 0.0f ? 1.0f/invMass : 0.0f;
440}
441
442template<class APIClass>
443PxReal NpRigidBodyTemplate<APIClass>::getInvMass() const
444{
445 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
446
447 return mCore.getInverseMass();
448}
449
450template<class APIClass>
451void NpRigidBodyTemplate<APIClass>::setMassSpaceInertiaTensor(const PxVec3& m)
452{
453 NpScene* npScene = RigidActorTemplateClass::getNpScene();
454 NP_WRITE_CHECK(npScene);
455 PX_CHECK_AND_RETURN(m.isFinite(), "PxRigidBody::setMassSpaceInertiaTensor(): invalid inertia");
456 PX_CHECK_AND_RETURN(m.x>=0.0f && m.y>=0.0f && m.z>=0.0f, "PxRigidBody::setMassSpaceInertiaTensor(): components must be non-negative");
457 PX_CHECK_AND_RETURN(this->getType() != PxActorType::eARTICULATION_LINK || (m.x > 0.0f && m.y > 0.0f && m.z > 0.0f), "PxRigidBody::setMassSpaceInertiaTensor(): components must be > 0 for articulations");
458
459 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMassSpaceInertiaTensor() not allowed while simulation is running. Call will be ignored.")
460
461 mCore.setInverseInertia(invertDiagInertia(m));
462 UPDATE_PVD_PROPERTY_BODY
463
464#if PX_SUPPORT_OMNI_PVD
465 PxActor* actor = static_cast<PxActor*>(this);
466 OMNI_PVD_SET(actor, massSpaceInertiaTensor, *actor, m)
467#endif
468}
469
470template<class APIClass>
471PxVec3 NpRigidBodyTemplate<APIClass>::getMassSpaceInertiaTensor() const
472{
473 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
474
475 return invertDiagInertia(mCore.getInverseInertia());
476}
477
478template<class APIClass>
479PxVec3 NpRigidBodyTemplate<APIClass>::getMassSpaceInvInertiaTensor() const
480{
481 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
482
483 return mCore.getInverseInertia();
484}
485
486template<class APIClass>
487PxVec3 NpRigidBodyTemplate<APIClass>::getLinearVelocity() const
488{
489 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
490
491 PX_CHECK_SCENE_API_READ_FORBIDDEN_EXCEPT_COLLIDE_AND_RETURN_VAL(RigidActorTemplateClass::getNpScene(), "PxRigidBody::getLinearVelocity() not allowed while simulation is running (except during PxScene::collide()).", PxVec3(PxZero));
492
493 return mCore.getLinearVelocity();
494}
495
496template<class APIClass>
497PxVec3 NpRigidBodyTemplate<APIClass>::getAngularVelocity() const
498{
499 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
500
501 PX_CHECK_SCENE_API_READ_FORBIDDEN_EXCEPT_COLLIDE_AND_RETURN_VAL(RigidActorTemplateClass::getNpScene(), "PxRigidBody::getAngularVelocity() not allowed while simulation is running (except during PxScene::collide()).", PxVec3(PxZero));
502
503 return mCore.getAngularVelocity();
504}
505
506template<class APIClass>
507void NpRigidBodyTemplate<APIClass>::addSpatialForce(const PxVec3* force, const PxVec3* torque, PxForceMode::Enum mode)
508{
509 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
510
511 switch (mode)
512 {
514 {
515 PxVec3 linAcc, angAcc;
516 if (force)
517 {
518 linAcc = (*force) * mCore.getInverseMass();
519 force = &linAcc;
520 }
521 if (torque)
522 {
523 angAcc = scGetGlobalInertiaTensorInverse() * (*torque);
524 torque = &angAcc;
525 }
526 scAddSpatialAcceleration(force, torque);
527 }
528 break;
529
531 scAddSpatialAcceleration(force, torque);
532 break;
533
535 {
536 PxVec3 linVelDelta, angVelDelta;
537 if (force)
538 {
539 linVelDelta = ((*force) * mCore.getInverseMass());
540 force = &linVelDelta;
541 }
542 if (torque)
543 {
544 angVelDelta = (scGetGlobalInertiaTensorInverse() * (*torque));
545 torque = &angVelDelta;
546 }
547 scAddSpatialVelocity(force, torque);
548 }
549 break;
550
552 scAddSpatialVelocity(force, torque);
553 break;
554 }
555}
556
557template<class APIClass>
558void NpRigidBodyTemplate<APIClass>::setSpatialForce(const PxVec3* force, const PxVec3* torque, PxForceMode::Enum mode)
559{
560 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
561
562 switch (mode)
563 {
565 {
566 PxVec3 linAcc, angAcc;
567 if (force)
568 {
569 linAcc = (*force) * mCore.getInverseMass();
570 force = &linAcc;
571 }
572 if (torque)
573 {
574 angAcc = scGetGlobalInertiaTensorInverse() * (*torque);
575 torque = &angAcc;
576 }
577 scSetSpatialAcceleration(force, torque);
578 }
579 break;
580
582 scSetSpatialAcceleration(force, torque);
583 break;
584
586 {
587 PxVec3 linVelDelta, angVelDelta;
588 if (force)
589 {
590 linVelDelta = ((*force) * mCore.getInverseMass());
591 force = &linVelDelta;
592 }
593 if (torque)
594 {
595 angVelDelta = (scGetGlobalInertiaTensorInverse() * (*torque));
596 torque = &angVelDelta;
597 }
598 scAddSpatialVelocity(force, torque);
599 }
600 break;
601
603 scAddSpatialVelocity(force, torque);
604 break;
605 }
606}
607
608template<class APIClass>
609void NpRigidBodyTemplate<APIClass>::clearSpatialForce(PxForceMode::Enum mode, bool force, bool torque)
610{
611 PX_ASSERT(!(mCore.getFlags() & PxRigidBodyFlag::eKINEMATIC));
612
613 switch (mode)
614 {
617 scClearSpatialAcceleration(force, torque);
618 break;
621 scClearSpatialVelocity(force, torque);
622 break;
623 }
624}
625
626#if PX_ENABLE_DEBUG_VISUALIZATION
627template<class APIClass>
628void NpRigidBodyTemplate<APIClass>::visualize(PxRenderOutput& out, NpScene& scene, float scale) const
629{
630 RigidActorTemplateClass::visualize(out, scene, scale);
631
632 visualizeRigidBody(out, scene, *this, mCore, scale);
633}
634#else
635 PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION
636#endif
637
638template<class APIClass>
639PX_FORCE_INLINE void NpRigidBodyTemplate<APIClass>::setRigidBodyFlagsInternal(const PxRigidBodyFlags& currentFlags, const PxRigidBodyFlags& newFlags)
640{
641 PxRigidBodyFlags filteredNewFlags = newFlags;
642 //Test to ensure we are not enabling both CCD and kinematic state on a body. This is unsupported
643 if((filteredNewFlags & PxRigidBodyFlag::eENABLE_CCD) && (filteredNewFlags & PxRigidBodyFlag::eKINEMATIC))
644 {
645 PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
646 "PxRigidBody::setRigidBodyFlag(): kinematic bodies with CCD enabled are not supported! CCD will be ignored.");
648 }
649
650 NpScene* scene = RigidActorTemplateClass::getNpScene();
651 Sc::Scene* scScene = scene ? &scene->getScScene() : NULL;
652
653 const bool isKinematic = currentFlags & PxRigidBodyFlag::eKINEMATIC;
654 const bool willBeKinematic = filteredNewFlags & PxRigidBodyFlag::eKINEMATIC;
655 const bool kinematicSwitchingToDynamic = isKinematic && (!willBeKinematic);
656 const bool dynamicSwitchingToKinematic = (!isKinematic) && willBeKinematic;
657
658 bool mustUpdateSQ = false;
659
660 if(kinematicSwitchingToDynamic)
661 {
662 NpShapeManager& shapeManager = this->getShapeManager();
663 PxU32 nbShapes = shapeManager.getNbShapes();
664 NpShape*const* shapes = shapeManager.getShapes();
665 bool hasTriangleMesh = false;
666 for(PxU32 i=0;i<nbShapes;i++)
667 {
668 if((shapes[i]->getFlags() & PxShapeFlag::eSIMULATION_SHAPE) && (shapes[i]->getGeometryTypeFast()==PxGeometryType::eTRIANGLEMESH || shapes[i]->getGeometryTypeFast()==PxGeometryType::ePLANE || shapes[i]->getGeometryTypeFast()==PxGeometryType::eHEIGHTFIELD))
669 {
670 hasTriangleMesh = true;
671 break;
672 }
673 }
674 if(hasTriangleMesh)
675 {
676 PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRigidBody::setRigidBodyFlag(): dynamic meshes/planes/heightfields are not supported!");
677 return;
678 }
679
680 PxTransform bodyTarget;
681 if ((currentFlags & PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) && mCore.getKinematicTarget(bodyTarget) && scene)
682 mustUpdateSQ = true;
683
684 if(scScene)
685 {
686 scScene->decreaseNumKinematicsCounter();
687 scScene->increaseNumDynamicsCounter();
688 }
689 }
690 else if (dynamicSwitchingToKinematic)
691 {
692 if (this->getType() == PxActorType::eARTICULATION_LINK)
693 {
694 //We're an articulation, raise an issue
695 PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRigidBody::setRigidBodyFlag(): kinematic articulation links are not supported!");
696 return;
697 }
698
699 if(scScene)
700 {
701 scScene->decreaseNumDynamicsCounter();
702 scScene->increaseNumKinematicsCounter();
703 }
704 }
705
706 const bool kinematicSwitchingUseTargetForSceneQuery = isKinematic && willBeKinematic &&
708 if (kinematicSwitchingUseTargetForSceneQuery)
709 {
710 PxTransform bodyTarget;
711 if (mCore.getKinematicTarget(bodyTarget) && scene)
712 mustUpdateSQ = true;
713 }
714
715 scSetFlags(filteredNewFlags);
716#if PX_SUPPORT_OMNI_PVD
717 PxActor* actor = static_cast<PxActor*>(this);
718 OMNI_PVD_SET(actor, rigidBodyFlags, *actor, filteredNewFlags)
719#endif
720
721 // PT: the SQ update should be done after the scSetFlags() call
722 if(mustUpdateSQ)
723 this->getShapeManager().markActorForSQUpdate(scene->getSQAPI(), *this);
724}
725
726template<class APIClass>
727void NpRigidBodyTemplate<APIClass>::setRigidBodyFlag(PxRigidBodyFlag::Enum flag, bool value)
728{
729 NpScene* npScene = RigidActorTemplateClass::getNpScene();
730 NP_WRITE_CHECK(npScene);
731
732 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setRigidBodyFlag() not allowed while simulation is running. Call will be ignored.")
733
734 const PxRigidBodyFlags currentFlags = mCore.getFlags();
735 const PxRigidBodyFlags newFlags = value ? currentFlags | flag : currentFlags & (~PxRigidBodyFlags(flag));
736
737 setRigidBodyFlagsInternal(currentFlags, newFlags);
738}
739
740template<class APIClass>
741void NpRigidBodyTemplate<APIClass>::setRigidBodyFlags(PxRigidBodyFlags inFlags)
742{
743 NpScene* npScene = RigidActorTemplateClass::getNpScene();
744 NP_WRITE_CHECK(npScene);
745
746 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setRigidBodyFlags() not allowed while simulation is running. Call will be ignored.")
747
748 const PxRigidBodyFlags currentFlags = mCore.getFlags();
749
750 setRigidBodyFlagsInternal(currentFlags, inFlags);
751}
752
753template<class APIClass>
754void NpRigidBodyTemplate<APIClass>::setMinCCDAdvanceCoefficient(PxReal minCCDAdvanceCoefficient)
755{
756 NpScene* npScene = RigidActorTemplateClass::getNpScene();
757 NP_WRITE_CHECK(npScene);
758
759 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMinCCDAdvanceCoefficient() not allowed while simulation is running. Call will be ignored.")
760
761 mCore.setCCDAdvanceCoefficient(minCCDAdvanceCoefficient);
762 UPDATE_PVD_PROPERTY_BODY
763#if PX_SUPPORT_OMNI_PVD
764 PxActor* actor = static_cast<PxActor*>(this);
765 OMNI_PVD_SET(actor, minAdvancedCCDCoefficient, *actor, minCCDAdvanceCoefficient)
766#endif
767
768}
769
770template<class APIClass>
771PxReal NpRigidBodyTemplate<APIClass>::getMinCCDAdvanceCoefficient() const
772{
773 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
774 return mCore.getCCDAdvanceCoefficient();
775}
776
777template<class APIClass>
778void NpRigidBodyTemplate<APIClass>::setMaxDepenetrationVelocity(PxReal maxDepenVel)
779{
780 NpScene* npScene = RigidActorTemplateClass::getNpScene();
781 NP_WRITE_CHECK(npScene);
782 PX_CHECK_AND_RETURN(maxDepenVel > 0.0f, "PxRigidBody::setMaxDepenetrationVelocity(): maxDepenVel must be greater than zero.");
783
784 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxDepenetrationVelocity() not allowed while simulation is running. Call will be ignored.")
785
786 mCore.setMaxPenetrationBias(-maxDepenVel);
787 UPDATE_PVD_PROPERTY_BODY
788#if PX_SUPPORT_OMNI_PVD
789 PxActor* actor = static_cast<PxActor*>(this);
790 OMNI_PVD_SET(actor, maxDepenetrationVelocity, *actor, maxDepenVel)
791#endif
792}
793
794template<class APIClass>
795PxReal NpRigidBodyTemplate<APIClass>::getMaxDepenetrationVelocity() const
796{
797 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
798 return -mCore.getMaxPenetrationBias();
799}
800
801template<class APIClass>
802void NpRigidBodyTemplate<APIClass>::setMaxContactImpulse(const PxReal maxImpulse)
803{
804 NpScene* npScene = RigidActorTemplateClass::getNpScene();
805 NP_WRITE_CHECK(npScene);
806 PX_CHECK_AND_RETURN(maxImpulse >= 0.f, "PxRigidBody::setMaxContactImpulse(): impulse limit must be greater than or equal to zero.");
807
808 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxContactImpulse() not allowed while simulation is running. Call will be ignored.")
809
810 mCore.setMaxContactImpulse(maxImpulse);
811 UPDATE_PVD_PROPERTY_BODY
812#if PX_SUPPORT_OMNI_PVD
813 PxActor* actor = static_cast<PxActor*>(this);
814 OMNI_PVD_SET(actor, maxContactImpulse, *actor, maxImpulse)
815#endif
816}
817
818template<class APIClass>
819PxReal NpRigidBodyTemplate<APIClass>::getMaxContactImpulse() const
820{
821 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
822 return mCore.getMaxContactImpulse();
823}
824
825template<class APIClass>
826void NpRigidBodyTemplate<APIClass>::setContactSlopCoefficient(const PxReal contactSlopCoefficient)
827{
828 NpScene* npScene = RigidActorTemplateClass::getNpScene();
829 NP_WRITE_CHECK(npScene);
830 PX_CHECK_AND_RETURN(contactSlopCoefficient >= 0.f, "PxRigidBody::setContactSlopCoefficient(): contact slop coefficientmust be greater than or equal to zero.");
831
832 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setContactSlopCoefficient() not allowed while simulation is running. Call will be ignored.")
833
834 mCore.setOffsetSlop(contactSlopCoefficient);
835 UPDATE_PVD_PROPERTY_BODY
836#if PX_SUPPORT_OMNI_PVD
837 PxActor* actor = static_cast<PxActor*>(this);
838 OMNI_PVD_SET(actor, contactSlopCoefficient, *actor, contactSlopCoefficient)
839#endif
840}
841
842template<class APIClass>
843PxReal NpRigidBodyTemplate<APIClass>::getContactSlopCoefficient() const
844{
845 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
846 return mCore.getOffsetSlop();
847}
848
849template<class APIClass>
850PxNodeIndex NpRigidBodyTemplate<APIClass>::getInternalIslandNodeIndex() const
851{
852 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
853 return mCore.getInternalIslandNodeIndex();
854}
855
856template<class APIClass>
857void NpRigidBodyTemplate<APIClass>::setLinearDamping(PxReal linearDamping)
858{
859 NpScene* npScene = RigidActorTemplateClass::getNpScene();
860 NP_WRITE_CHECK(npScene);
861 PX_CHECK_AND_RETURN(PxIsFinite(linearDamping), "PxRigidBody::setLinearDamping(): invalid float");
862 PX_CHECK_AND_RETURN(linearDamping >= 0, "PxRigidBody::setLinearDamping(): The linear damping must be nonnegative!");
863
864 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setLinearDamping() not allowed while simulation is running. Call will be ignored.")
865
866 mCore.setLinearDamping(linearDamping);
867 UPDATE_PVD_PROPERTY_BODY
868#if PX_SUPPORT_OMNI_PVD
869 PxActor* actor = static_cast<PxActor*>(this);
870 OMNI_PVD_SET(actor, linearDamping, *actor, linearDamping)
871#endif
872}
873
874template<class APIClass>
875PxReal NpRigidBodyTemplate<APIClass>::getLinearDamping() const
876{
877 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
878
879 return mCore.getLinearDamping();
880}
881
882template<class APIClass>
883void NpRigidBodyTemplate<APIClass>::setAngularDamping(PxReal angularDamping)
884{
885 NpScene* npScene = RigidActorTemplateClass::getNpScene();
886 NP_WRITE_CHECK(npScene);
887 PX_CHECK_AND_RETURN(PxIsFinite(angularDamping), "PxRigidBody::setAngularDamping(): invalid float");
888 PX_CHECK_AND_RETURN(angularDamping>=0, "PxRigidBody::setAngularDamping(): The angular damping must be nonnegative!")
889
890 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setAngularDamping() not allowed while simulation is running. Call will be ignored.")
891
892 mCore.setAngularDamping(angularDamping);
893 UPDATE_PVD_PROPERTY_BODY
894#if PX_SUPPORT_OMNI_PVD
895 PxActor* actor = static_cast<PxActor*>(this);
896 OMNI_PVD_SET(actor, angularDamping, *actor, angularDamping)
897#endif
898}
899
900template<class APIClass>
901PxReal NpRigidBodyTemplate<APIClass>::getAngularDamping() const
902{
903 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
904
905 return mCore.getAngularDamping();
906}
907
908template<class APIClass>
909void NpRigidBodyTemplate<APIClass>::setMaxAngularVelocity(PxReal maxAngularVelocity)
910{
911 NpScene* npScene = RigidActorTemplateClass::getNpScene();
912 NP_WRITE_CHECK(npScene);
913 PX_CHECK_AND_RETURN(PxIsFinite(maxAngularVelocity), "PxRigidBody::setMaxAngularVelocity(): invalid float");
914 PX_CHECK_AND_RETURN(maxAngularVelocity>=0.0f, "PxRigidBody::setMaxAngularVelocity(): threshold must be non-negative!");
915
916 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxAngularVelocity() not allowed while simulation is running. Call will be ignored.")
917
918 mCore.setMaxAngVelSq(maxAngularVelocity * maxAngularVelocity);
919 UPDATE_PVD_PROPERTY_BODY
920#if PX_SUPPORT_OMNI_PVD
921 PxActor* actor = static_cast<PxActor*>(this);
922 OMNI_PVD_SET(actor, maxAngularVelocity, *actor, maxAngularVelocity)
923#endif
924}
925
926template<class APIClass>
927PxReal NpRigidBodyTemplate<APIClass>::getMaxAngularVelocity() const
928{
929 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
930
931 return PxSqrt(mCore.getMaxAngVelSq());
932}
933
934template<class APIClass>
935void NpRigidBodyTemplate<APIClass>::setMaxLinearVelocity(PxReal maxLinearVelocity)
936{
937 NpScene* npScene = RigidActorTemplateClass::getNpScene();
938 NP_WRITE_CHECK(npScene);
939 PX_CHECK_AND_RETURN(PxIsFinite(maxLinearVelocity), "PxRigidBody::setMaxLinearVelocity(): invalid float");
940 PX_CHECK_AND_RETURN(maxLinearVelocity >= 0.0f, "PxRigidBody::setMaxLinearVelocity(): threshold must be non-negative!");
941
942 PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxLinearVelocity() not allowed while simulation is running. Call will be ignored.")
943
944 mCore.setMaxLinVelSq(maxLinearVelocity * maxLinearVelocity);
945 UPDATE_PVD_PROPERTY_BODY
946#if PX_SUPPORT_OMNI_PVD
947 PxActor* actor = static_cast<PxActor*>(this);
948 OMNI_PVD_SET(actor, maxLinearVelocity, *actor, maxLinearVelocity)
949#endif
950}
951
952template<class APIClass>
953PxReal NpRigidBodyTemplate<APIClass>::getMaxLinearVelocity() const
954{
955 NP_READ_CHECK(RigidActorTemplateClass::getNpScene());
956
957 return PxSqrt(mCore.getMaxLinVelSq());
958}
959
960}
961
962#endif
Definition NpRigidActorTemplate.h:47
Definition NpRigidBodyTemplate.h:80
Definition NpScene.h:130
A padded version of PxMat33, to safely load its data using SIMD.
Definition PxSIMDHelpers.h:41
3x3 matrix class
Definition PxMat33.h:91
PxNodeIndex.
Definition PxNodeIndex.h:51
Definition PxRenderOutput.h:50
Abstract class for collision shapes.
Definition PxShape.h:146
virtual const PxGeometry & getGeometry() const =0
Retrieve a reference to the shape's geometry.
PX_DEPRECATED PX_FORCE_INLINE PxGeometryType::Enum getGeometryType() const
Get the geometry type of the shape.
Definition PxShape.h:192
virtual PxShapeFlags getFlags() const =0
Retrieves shape flags.
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
3 Element vector class.
Definition PxVec3.h:50
Definition ScBodyCore.h:49
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_OVERRIDE
Definition PxPreprocessor.h:375
PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation &PX_CALL_CONV PxGetFoundation()
Retrieves the Foundation SDK after it has been created.
Definition FdFoundation.cpp:279
#define PX_INLINE
Definition PxPreprocessor.h:320
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxIsFinite(float f)
returns true if the passed number is a finite floating point number as opposed to INF,...
Definition PxMath.h:326
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxSqrt(float a)
Square root.
Definition PxMath.h:146
PxFlags< PxRigidBodyFlag::Enum, PxU16 > PxRigidBodyFlags
collection of set bits defined in PxRigidBodyFlag.
Definition PxRigidBody.h:189
Enum
Definition PxActor.h:121
@ eARTICULATION_LINK
An articulation link.
Definition PxActor.h:138
@ eINVALID_PARAMETER
method called with invalid parameter(s)
Definition PxErrors.h:62
Enum
Definition PxForceMode.h:51
@ eFORCE
parameter has unit of mass * length / time^2, i.e., a force
Definition PxForceMode.h:52
@ eVELOCITY_CHANGE
parameter has unit of length / time, i.e., the effect is mass independent: a velocity change.
Definition PxForceMode.h:54
@ eIMPULSE
parameter has unit of mass * length / time, i.e., force * time
Definition PxForceMode.h:53
@ eACCELERATION
parameter has unit of length/ time^2, i.e., an acceleration. It gets treated just like a force except...
Definition PxForceMode.h:55
Enum
Definition PxGeometry.h:52
Collection of flags describing the behavior of a rigid body.
Definition PxRigidBody.h:50
Enum
Definition PxRigidBody.h:52
@ eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES
Use the kinematic target transform for scene queries.
Definition PxRigidBody.h:85
@ eKINEMATIC
Enables kinematic mode for the actor.
Definition PxRigidBody.h:74
@ eENABLE_CCD
Enables swept integration for the actor.
Definition PxRigidBody.h:96
@ eSIMULATION_SHAPE
The shape will partake in collision in the physical simulation.
Definition PxShape.h:83