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#include "NpRigidDynamic.h"
32#include "NpRigidActorTemplateInternal.h"
33
34using namespace physx;
35
36NpRigidDynamic::NpRigidDynamic(const PxTransform& bodyPose)
37: NpRigidDynamicT(PxConcreteType::eRIGID_DYNAMIC, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE, PxActorType::eRIGID_DYNAMIC, bodyPose)
38{}
39
40NpRigidDynamic::~NpRigidDynamic()
41{
42}
43
44// PX_SERIALIZATION
45void NpRigidDynamic::requiresObjects(PxProcessPxBaseCallback& c)
46{
47 NpRigidDynamicT::requiresObjects(c);
48}
49
50void NpRigidDynamic::preExportDataReset()
51{
52 NpRigidDynamicT::preExportDataReset();
53 if (isKinematic() && NpActor::getAPIScene(actor: *this))
54 {
55 //Restore dynamic data in case the actor is configured as a kinematic.
56 //otherwise we would loose the data for switching the kinematic actor back to dynamic
57 //after deserialization.
58 getScbBodyFast().getScBody().restoreDynamicData();
59 }
60}
61
62NpRigidDynamic* NpRigidDynamic::createObject(PxU8*& address, PxDeserializationContext& context)
63{
64 NpRigidDynamic* obj = new (address) NpRigidDynamic(PxBaseFlag::eIS_RELEASABLE);
65 address += sizeof(NpRigidDynamic);
66 obj->importExtraData(context);
67 obj->resolveReferences(context);
68 return obj;
69}
70//~PX_SERIALIZATION
71
72void NpRigidDynamic::release()
73{
74 releaseActorT(actor: this, scbActor&: mBody);
75}
76
77
78void NpRigidDynamic::setGlobalPose(const PxTransform& pose, bool autowake)
79{
80 NpScene* scene = NpActor::getAPIScene(actor: *this);
81
82#if PX_CHECKED
83 if(scene)
84 scene->checkPositionSanity(*this, pose, "PxRigidDynamic::setGlobalPose");
85#endif
86
87 PX_CHECK_AND_RETURN(pose.isSane(), "PxRigidDynamic::setGlobalPose: pose is not valid.");
88 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
89
90 const PxTransform newPose = pose.getNormalized(); //AM: added to fix 1461 where users read and write orientations for no reason.
91
92 Scb::Body& b = getScbBodyFast();
93 const PxTransform body2World = newPose * b.getBody2Actor();
94 b.setBody2World(p: body2World, asPartOfBody2ActorChange: false);
95
96 if(scene)
97 updateDynamicSceneQueryShapes(shapeManager&: mShapeManager, sqManager&: scene->getSceneQueryManagerFast(), actor: *this);
98
99 // invalidate the pruning structure if the actor bounds changed
100 if(mShapeManager.getPruningStructure())
101 {
102 Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, messageFmt: "PxRigidDynamic::setGlobalPose: Actor is part of a pruning structure, pruning structure is now invalid!");
103 mShapeManager.getPruningStructure()->invalidate(actor: this);
104 }
105
106 if(scene && autowake && !(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION))
107 wakeUpInternal();
108}
109
110
111PX_FORCE_INLINE void NpRigidDynamic::setKinematicTargetInternal(const PxTransform& targetPose)
112{
113 Scb::Body& b = getScbBodyFast();
114
115 // The target is actor related. Transform to body related target
116 const PxTransform bodyTarget = targetPose * b.getBody2Actor();
117
118 b.setKinematicTarget(bodyTarget);
119
120 NpScene* scene = NpActor::getAPIScene(actor: *this);
121 if ((b.getFlags() & PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) && scene)
122 {
123 updateDynamicSceneQueryShapes(shapeManager&: mShapeManager, sqManager&: scene->getSceneQueryManagerFast(), actor: *this);
124 }
125}
126
127
128void NpRigidDynamic::setKinematicTarget(const PxTransform& destination)
129{
130 PX_CHECK_AND_RETURN(destination.isSane(), "PxRigidDynamic::setKinematicTarget: destination is not valid.");
131 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
132
133#if PX_CHECKED
134 NpScene* scene = NpActor::getAPIScene(*this);
135 if(scene)
136 scene->checkPositionSanity(*this, destination, "PxRigidDynamic::setKinematicTarget");
137
138 Scb::Body& b = getScbBodyFast();
139 PX_CHECK_AND_RETURN((b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setKinematicTarget: Body must be kinematic!");
140 PX_CHECK_AND_RETURN(scene, "PxRigidDynamic::setKinematicTarget: Body must be in a scene!");
141 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setKinematicTarget: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
142#endif
143
144 setKinematicTargetInternal(destination.getNormalized());
145}
146
147
148bool NpRigidDynamic::getKinematicTarget(PxTransform& target) const
149{
150 NP_READ_CHECK(NpActor::getOwnerScene(*this));
151
152 const Scb::Body& b = getScbBodyFast();
153 if(b.getFlags() & PxRigidBodyFlag::eKINEMATIC)
154 {
155 PxTransform bodyTarget;
156 if(b.getKinematicTarget(p&: bodyTarget))
157 {
158 // The internal target is body related. Transform to actor related target
159 target = bodyTarget * b.getBody2Actor().getInverse();
160 return true;
161 }
162 }
163 return false;
164}
165
166void NpRigidDynamic::setCMassLocalPose(const PxTransform& pose)
167{
168 PX_CHECK_AND_RETURN(pose.isSane(), "PxRigidDynamic::setCMassLocalPose pose is not valid.");
169 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
170
171 const PxTransform p = pose.getNormalized();
172
173 const PxTransform oldBody2Actor = getScbBodyFast().getBody2Actor();
174
175 NpRigidDynamicT::setCMassLocalPoseInternal(p);
176
177 Scb::Body& b = getScbBodyFast();
178 if(b.getFlags() & PxRigidBodyFlag::eKINEMATIC)
179 {
180 PxTransform bodyTarget;
181 if(b.getKinematicTarget(p&: bodyTarget))
182 {
183 PxTransform actorTarget = bodyTarget * oldBody2Actor.getInverse(); // get old target pose for the actor from the body target
184 setKinematicTargetInternal(actorTarget);
185 }
186 }
187}
188
189
190void NpRigidDynamic::setLinearDamping(PxReal linearDamping)
191{
192 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
193 PX_CHECK_AND_RETURN(PxIsFinite(linearDamping), "PxRigidDynamic::setLinearDamping: invalid float");
194 PX_CHECK_AND_RETURN(linearDamping >=0, "PxRigidDynamic::setLinearDamping: The linear damping must be nonnegative!");
195
196 getScbBodyFast().setLinearDamping(linearDamping);
197}
198
199
200PxReal NpRigidDynamic::getLinearDamping() const
201{
202 NP_READ_CHECK(NpActor::getOwnerScene(*this));
203
204 return getScbBodyFast().getLinearDamping();
205}
206
207
208void NpRigidDynamic::setAngularDamping(PxReal angularDamping)
209{
210 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
211 PX_CHECK_AND_RETURN(PxIsFinite(angularDamping), "PxRigidDynamic::setAngularDamping: invalid float");
212 PX_CHECK_AND_RETURN(angularDamping>=0, "PxRigidDynamic::setAngularDamping: The angular damping must be nonnegative!")
213
214 getScbBodyFast().setAngularDamping(angularDamping);
215}
216
217
218PxReal NpRigidDynamic::getAngularDamping() const
219{
220 NP_READ_CHECK(NpActor::getOwnerScene(*this));
221
222 return getScbBodyFast().getAngularDamping();
223}
224
225
226void NpRigidDynamic::setLinearVelocity(const PxVec3& velocity, bool autowake)
227{
228 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
229 PX_CHECK_AND_RETURN(velocity.isFinite(), "PxRigidDynamic::setLinearVelocity: velocity is not valid.");
230 PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setLinearVelocity: Body must be non-kinematic!");
231 PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setLinearVelocity: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
232
233 Scb::Body& b = getScbBodyFast();
234 b.setLinearVelocity(velocity);
235
236 NpScene* scene = NpActor::getAPIScene(actor: *this);
237 if(scene)
238 wakeUpInternalNoKinematicTest(body&: b, forceWakeUp: (!velocity.isZero()), autowake);
239}
240
241
242void NpRigidDynamic::setAngularVelocity(const PxVec3& velocity, bool autowake)
243{
244 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
245 PX_CHECK_AND_RETURN(velocity.isFinite(), "PxRigidDynamic::setAngularVelocity: velocity is not valid.");
246 PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setAngularVelocity: Body must be non-kinematic!");
247 PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setAngularVelocity: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
248
249 Scb::Body& b = getScbBodyFast();
250 b.setAngularVelocity(velocity);
251
252 NpScene* scene = NpActor::getAPIScene(actor: *this);
253 if(scene)
254 wakeUpInternalNoKinematicTest(body&: b, forceWakeUp: (!velocity.isZero()), autowake);
255}
256
257
258void NpRigidDynamic::setMaxAngularVelocity(PxReal maxAngularVelocity)
259{
260 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
261 PX_CHECK_AND_RETURN(PxIsFinite(maxAngularVelocity), "PxRigidDynamic::setMaxAngularVelocity: invalid float");
262 PX_CHECK_AND_RETURN(maxAngularVelocity>=0.0f, "PxRigidDynamic::setMaxAngularVelocity: threshold must be non-negative!");
263
264 getScbBodyFast().setMaxAngVelSq(maxAngularVelocity * maxAngularVelocity);
265}
266
267
268PxReal NpRigidDynamic::getMaxAngularVelocity() const
269{
270 NP_READ_CHECK(NpActor::getOwnerScene(*this));
271
272 return PxSqrt(a: getScbBodyFast().getMaxAngVelSq());
273}
274
275void NpRigidDynamic::setMaxLinearVelocity(PxReal maxLinearVelocity)
276{
277 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
278 PX_CHECK_AND_RETURN(PxIsFinite(maxLinearVelocity), "PxRigidDynamic::setMaxAngularVelocity: invalid float");
279 PX_CHECK_AND_RETURN(maxLinearVelocity >= 0.0f, "PxRigidDynamic::setMaxAngularVelocity: threshold must be non-negative!");
280
281 getScbBodyFast().setMaxLinVelSq(maxLinearVelocity * maxLinearVelocity);
282}
283
284PxReal NpRigidDynamic::getMaxLinearVelocity() const
285{
286 NP_READ_CHECK(NpActor::getOwnerScene(*this));
287
288 return PxSqrt(a: getScbBodyFast().getMaxLinVelSq());
289}
290
291
292void NpRigidDynamic::addForce(const PxVec3& force, PxForceMode::Enum mode, bool autowake)
293{
294 Scb::Body& b = getScbBodyFast();
295
296 PX_CHECK_AND_RETURN(force.isFinite(), "PxRigidDynamic::addForce: force is not valid.");
297 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
298 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addForce: Body must be in a scene!");
299 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addForce: Body must be non-kinematic!");
300 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
301
302 addSpatialForce(force: &force, NULL, mode);
303
304 wakeUpInternalNoKinematicTest(body&: b, forceWakeUp: (!force.isZero()), autowake);
305}
306
307void NpRigidDynamic::setForceAndTorque(const PxVec3& force, const PxVec3& torque, PxForceMode::Enum mode)
308{
309 Scb::Body& b = getScbBodyFast();
310
311 PX_CHECK_AND_RETURN(force.isFinite(), "PxRigidDynamic::setForce: force is not valid.");
312 PX_CHECK_AND_RETURN(torque.isFinite(), "PxRigidDynamic::setForce: force is not valid.");
313 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
314 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addForce: Body must be in a scene!");
315 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addForce: Body must be non-kinematic!");
316 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
317
318 setSpatialForce(force: &force, torque: &torque, mode);
319
320 wakeUpInternalNoKinematicTest(body&: b, forceWakeUp: (!force.isZero()), autowake: true);
321}
322
323
324void NpRigidDynamic::addTorque(const PxVec3& torque, PxForceMode::Enum mode, bool autowake)
325{
326 Scb::Body& b = getScbBodyFast();
327
328 PX_CHECK_AND_RETURN(torque.isFinite(), "PxRigidDynamic::addTorque: torque is not valid.");
329 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
330 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::addTorque: Body must be in a scene!");
331 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::addTorque: Body must be non-kinematic!");
332 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::addTorque: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
333
334 addSpatialForce(NULL, torque: &torque, mode);
335
336 wakeUpInternalNoKinematicTest(body&: b, forceWakeUp: (!torque.isZero()), autowake);
337}
338
339void NpRigidDynamic::clearForce(PxForceMode::Enum mode)
340{
341 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
342 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::clearForce: Body must be in a scene!");
343 PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::clearForce: Body must be non-kinematic!");
344 PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::clearForce: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
345
346 clearSpatialForce(mode, force: true, torque: false);
347}
348
349
350void NpRigidDynamic::clearTorque(PxForceMode::Enum mode)
351{
352 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
353 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::clearTorque: Body must be in a scene!");
354 PX_CHECK_AND_RETURN(!(getScbBodyFast().getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::clearTorque: Body must be non-kinematic!");
355 PX_CHECK_AND_RETURN(!(getScbBodyFast().getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::clearTorque: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
356
357 clearSpatialForce(mode, force: false, torque: true);
358}
359
360
361bool NpRigidDynamic::isSleeping() const
362{
363 NP_READ_CHECK(NpActor::getOwnerScene(*this));
364 PX_CHECK_AND_RETURN_VAL(NpActor::getAPIScene(*this), "PxRigidDynamic::isSleeping: Body must be in a scene.", true);
365
366 return getScbBodyFast().isSleeping();
367}
368
369
370void NpRigidDynamic::setSleepThreshold(PxReal threshold)
371{
372 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
373 PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setSleepThreshold: invalid float.");
374 PX_CHECK_AND_RETURN(threshold>=0.0f, "PxRigidDynamic::setSleepThreshold: threshold must be non-negative!");
375
376 getScbBodyFast().setSleepThreshold(threshold);
377}
378
379
380PxReal NpRigidDynamic::getSleepThreshold() const
381{
382 NP_READ_CHECK(NpActor::getOwnerScene(*this));
383
384 return getScbBodyFast().getSleepThreshold();
385}
386
387void NpRigidDynamic::setStabilizationThreshold(PxReal threshold)
388{
389 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
390 PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setSleepThreshold: invalid float.");
391 PX_CHECK_AND_RETURN(threshold>=0.0f, "PxRigidDynamic::setSleepThreshold: threshold must be non-negative!");
392
393 getScbBodyFast().setFreezeThreshold(threshold);
394}
395
396
397PxReal NpRigidDynamic::getStabilizationThreshold() const
398{
399 NP_READ_CHECK(NpActor::getOwnerScene(*this));
400
401 return getScbBodyFast().getFreezeThreshold();
402}
403
404
405void NpRigidDynamic::setWakeCounter(PxReal wakeCounterValue)
406{
407 Scb::Body& b = getScbBodyFast();
408
409 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
410 PX_CHECK_AND_RETURN(PxIsFinite(wakeCounterValue), "PxRigidDynamic::setWakeCounter: invalid float.");
411 PX_CHECK_AND_RETURN(wakeCounterValue>=0.0f, "PxRigidDynamic::setWakeCounter: wakeCounterValue must be non-negative!");
412 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::setWakeCounter: Body must be non-kinematic!");
413 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::setWakeCounter: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
414
415 b.setWakeCounter(wakeCounterValue);
416}
417
418
419PxReal NpRigidDynamic::getWakeCounter() const
420{
421 NP_READ_CHECK(NpActor::getOwnerScene(*this));
422
423 return getScbBodyFast().getWakeCounter();
424}
425
426
427void NpRigidDynamic::wakeUp()
428{
429 Scb::Body& b = getScbBodyFast();
430
431 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
432 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::wakeUp: Body must be in a scene.");
433 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::wakeUp: Body must be non-kinematic!");
434 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::wakeUp: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
435
436 b.wakeUp();
437}
438
439
440void NpRigidDynamic::putToSleep()
441{
442 Scb::Body& b = getScbBodyFast();
443
444 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
445 PX_CHECK_AND_RETURN(NpActor::getAPIScene(*this), "PxRigidDynamic::putToSleep: Body must be in a scene.");
446 PX_CHECK_AND_RETURN(!(b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "PxRigidDynamic::putToSleep: Body must be non-kinematic!");
447 PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "PxRigidDynamic::putToSleep: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");
448
449 b.putToSleep();
450}
451
452
453void NpRigidDynamic::setSolverIterationCounts(PxU32 positionIters, PxU32 velocityIters)
454{
455 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
456 PX_CHECK_AND_RETURN(positionIters > 0, "PxRigidDynamic::setSolverIterationCount: positionIters must be more than zero!");
457 PX_CHECK_AND_RETURN(positionIters <= 255, "PxRigidDynamic::setSolverIterationCount: positionIters must be no greater than 255!");
458 PX_CHECK_AND_RETURN(velocityIters <= 255, "PxRigidDynamic::setSolverIterationCount: velocityIters must be no greater than 255!");
459
460 getScbBodyFast().setSolverIterationCounts((velocityIters & 0xff) << 8 | (positionIters & 0xff));
461}
462
463
464void NpRigidDynamic::getSolverIterationCounts(PxU32 & positionIters, PxU32 & velocityIters) const
465{
466 NP_READ_CHECK(NpActor::getOwnerScene(*this));
467
468 PxU16 x = getScbBodyFast().getSolverIterationCounts();
469 velocityIters = PxU32(x >> 8);
470 positionIters = PxU32(x & 0xff);
471}
472
473
474void NpRigidDynamic::setContactReportThreshold(PxReal threshold)
475{
476 NP_WRITE_CHECK(NpActor::getOwnerScene(*this));
477 PX_CHECK_AND_RETURN(PxIsFinite(threshold), "PxRigidDynamic::setContactReportThreshold: invalid float.");
478 PX_CHECK_AND_RETURN(threshold >= 0.0f, "PxRigidDynamic::setContactReportThreshold: Force threshold must be greater than zero!");
479
480 getScbBodyFast().setContactReportThreshold(threshold<0 ? 0 : threshold);
481}
482
483
484PxReal NpRigidDynamic::getContactReportThreshold() const
485{
486 NP_READ_CHECK(NpActor::getOwnerScene(*this));
487
488 return getScbBodyFast().getContactReportThreshold();
489}
490
491
492PxU32 physx::NpRigidDynamicGetShapes(Scb::Body& body, void* const*& shapes, bool* isCompound)
493{
494 NpRigidDynamic* a = static_cast<NpRigidDynamic*>(body.getScBody().getPxActor());
495 NpShapeManager& sm = a->getShapeManager();
496 shapes = reinterpret_cast<void *const *>(sm.getShapes());
497 if(isCompound)
498 *isCompound = sm.isSqCompound();
499 return sm.getNbShapes();
500}
501
502
503void NpRigidDynamic::switchToNoSim()
504{
505 getScbBodyFast().switchBodyToNoSim();
506}
507
508
509void NpRigidDynamic::switchFromNoSim()
510{
511 getScbBodyFast().switchFromNoSim(isDynamic: true);
512}
513
514
515void NpRigidDynamic::wakeUpInternalNoKinematicTest(Scb::Body& body, bool forceWakeUp, bool autowake)
516{
517 NpScene* scene = NpActor::getOwnerScene(actor: *this);
518 PX_ASSERT(scene);
519 PxReal wakeCounterResetValue = scene->getWakeCounterResetValueInteral();
520
521 PxReal wakeCounter = body.getWakeCounter();
522
523 bool needsWakingUp = body.isSleeping() && (autowake || forceWakeUp);
524 if (autowake && (wakeCounter < wakeCounterResetValue))
525 {
526 wakeCounter = wakeCounterResetValue;
527 needsWakingUp = true;
528 }
529
530 if (needsWakingUp)
531 body.wakeUpInternal(wakeCounter);
532}
533
534PxRigidDynamicLockFlags NpRigidDynamic::getRigidDynamicLockFlags() const
535{
536 return mBody.getLockFlags();
537}
538void NpRigidDynamic::setRigidDynamicLockFlags(PxRigidDynamicLockFlags flags)
539{
540 mBody.setLockFlags(flags);
541}
542void NpRigidDynamic::setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, bool value)
543{
544 PxRigidDynamicLockFlags flags = mBody.getLockFlags();
545 if (value)
546 flags = flags | flag;
547 else
548 flags = flags & (~flag);
549
550 mBody.setLockFlags(flags);
551}
552
553
554#if PX_ENABLE_DEBUG_VISUALIZATION
555void NpRigidDynamic::visualize(Cm::RenderOutput& out, NpScene* npScene)
556{
557 NpRigidDynamicT::visualize(out, scene: npScene);
558
559 if (getScbBodyFast().getActorFlags() & PxActorFlag::eVISUALIZATION)
560 {
561 PX_ASSERT(npScene);
562 const PxReal scale = npScene->getVisualizationParameter(param: PxVisualizationParameter::eSCALE);
563
564 const PxReal massAxes = scale * npScene->getVisualizationParameter(param: PxVisualizationParameter::eBODY_MASS_AXES);
565 if (massAxes != 0.0f)
566 {
567 PxReal sleepTime = getScbBodyFast().getWakeCounter() / npScene->getWakeCounterResetValueInteral();
568 PxU32 color = PxU32(0xff * (sleepTime>1.0f ? 1.0f : sleepTime));
569 color = getScbBodyFast().isSleeping() ? 0xff0000 : (color<<16 | color<<8 | color);
570 PxVec3 dims = invertDiagInertia(m: getScbBodyFast().getInverseInertia());
571 dims = getDimsFromBodyInertia(inertiaMoments: dims, mass: 1.0f / getScbBodyFast().getInverseMass());
572
573 out << color << getScbBodyFast().getBody2World() << Cm::DebugBox(dims * 0.5f);
574 }
575 }
576}
577#endif
578

source code of qtquick3dphysics/src/3rdparty/PhysX/source/physx/src/NpRigidDynamic.cpp