RavEngine
Loading...
Searching...
No Matches
ScBodySim.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 SC_BODYSIM_H
30#define SC_BODYSIM_H
31
32#include "foundation/PxUtilities.h"
33#include "foundation/PxIntrinsics.h"
34#include "ScRigidSim.h"
35#include "PxvDynamics.h"
36#include "ScBodyCore.h"
37#include "ScSimStateData.h"
38#include "ScConstraintGroupNode.h"
39#include "PxRigidDynamic.h"
40#include "PxsRigidBody.h"
41
42namespace physx
43{
44namespace Bp
45{
46 class BoundsArray;
47}
48 class PxsTransformCache;
49namespace Sc
50{
51 class Scene;
52 class ArticulationSim;
53
54#if PX_VC
55 #pragma warning(push)
56 #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value.
57#endif
58
59 class BodySim : public RigidSim
60 {
61 public:
62 //enum InternalFlags
63 //{
64 // //BF_DISABLE_GRAVITY = 1 << 0, // Don't apply the scene's gravity
65
66 // BF_HAS_STATIC_TOUCH = 1 << 1, // Set when a body is part of an island with static contacts. Needed to be able to recalculate adaptive force if this changes
67 // BF_KINEMATIC_MOVED = 1 << 2, // Set when the kinematic was moved
68
69 // BF_ON_DEATHROW = 1 << 3, // Set when the body is destroyed
70
71 // BF_IS_IN_SLEEP_LIST = 1 << 4, // Set when the body is added to the list of bodies which were put to sleep
72 // BF_IS_IN_WAKEUP_LIST = 1 << 5, // Set when the body is added to the list of bodies which were woken up
73 // BF_SLEEP_NOTIFY = 1 << 6, // A sleep notification should be sent for this body (and not a wakeup event, even if the body is part of the woken list as well)
74 // BF_WAKEUP_NOTIFY = 1 << 7, // A wake up notification should be sent for this body (and not a sleep event, even if the body is part of the sleep list as well)
75
76 // BF_HAS_CONSTRAINTS = 1 << 8, // Set if the body has one or more constraints
77 // BF_KINEMATIC_SETTLING = 1 << 9, // Set when the body was moved kinematically last frame
78 // BF_KINEMATIC_SETTLING_2 = 1 << 10,
79 // BF_KINEMATIC_MOVE_FLAGS = BF_KINEMATIC_MOVED | BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2, //Used to clear kinematic masks in 1 call
80 // BF_KINEMATIC_SURFACE_VELOCITY = 1 << 11, //Set when the application calls setKinematicVelocity. Actor remains awake until application calls clearKinematicVelocity.
81 // BF_IS_COMPOUND_RIGID = 1 << 12 // Set when the body is a compound actor, we dont want to set the sq bounds
82
83 // // PT: WARNING: flags stored on 16-bits now.
84 //};
85
86 public:
87 BodySim(Scene&, BodyCore&, bool);
88 virtual ~BodySim();
89
90 private:
91 bool setupSimStateData(PxPool<SimStateData>* simStateDataPool, const bool isKinematic);
92 void tearDownSimStateData(PxPool<SimStateData>* simStateDataPool, const bool isKinematic);
93 public:
94 void switchToKinematic(PxPool<SimStateData>* simStateDataPool);
95 void switchToDynamic(PxPool<SimStateData>* simStateDataPool);
96
97 private:
98 void postSwitchToKinematic();
99 void postSwitchToDynamic();
100 public:
101 PX_FORCE_INLINE const SimStateData* getSimStateData(bool isKinematic) const { return (mSimStateData && (checkSimStateKinematicStatus(isKinematic)) ? mSimStateData : NULL); }
102 PX_FORCE_INLINE SimStateData* getSimStateData(bool isKinematic) { return (mSimStateData && (checkSimStateKinematicStatus(isKinematic)) ? mSimStateData : NULL); }
103 PX_FORCE_INLINE SimStateData* getSimStateData_Unchecked() const { return mSimStateData; }
104 PX_FORCE_INLINE bool checkSimStateKinematicStatus(const bool isKinematic) const
105 {
106 PX_ASSERT(mSimStateData);
107 return mSimStateData->isKine() == isKinematic;
108 }
109
110 void setKinematicTarget(const PxTransform& p);
111
112 void addSpatialAcceleration(PxPool<SimStateData>* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc);
113 void setSpatialAcceleration(PxPool<SimStateData>* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc);
114 void clearSpatialAcceleration(bool force, bool torque);
115 void addSpatialVelocity(PxPool<SimStateData>* simStateDataPool, const PxVec3* linVelDelta, const PxVec3* angVelDelta);
116 void clearSpatialVelocity(bool force, bool torque);
117 private:
118 void raiseVelocityModFlagAndNotify(VelocityModFlags flag);
119 PX_FORCE_INLINE void notifyAddSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); }
120 PX_FORCE_INLINE void notifyClearSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); }
121 PX_FORCE_INLINE void notifyAddSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); }
122 PX_FORCE_INLINE void notifyClearSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); }
123 public:
124 void updateCached(PxBitMapPinned* shapeChangedMap);
125 void updateCached(PxsTransformCache& transformCache, Bp::BoundsArray& boundsArray);
126 void updateContactDistance(PxReal* contactDistance, const PxReal dt, const Bp::BoundsArray& boundsArray);
127
128 // hooks for actions in body core when it's attached to a sim object. Generally
129 // we get called after the attribute changed.
130
131 virtual void postActorFlagChange(PxU32 oldFlags, PxU32 newFlags);
132 void postBody2WorldChange();
133 void postSetWakeCounter(PxReal t, bool forceWakeUp);
134 void postPosePreviewChange(const PxU32 posePreviewFlag); // called when PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW changes
135
136 PX_FORCE_INLINE const PxTransform& getBody2World() const { return getBodyCore().getCore().body2World; }
137 PX_FORCE_INLINE const PxTransform& getBody2Actor() const { return getBodyCore().getCore().getBody2Actor(); }
138 PX_FORCE_INLINE const PxsRigidBody& getLowLevelBody() const { return mLLBody; }
139 PX_FORCE_INLINE PxsRigidBody& getLowLevelBody() { return mLLBody; }
140 void wakeUp(); // note: for user API call purposes only, i.e., use from BodyCore. For simulation internal purposes there is internalWakeUp().
141 void putToSleep();
142
143 void disableCompound();
144
145 static PxU32 getRigidBodyOffset() { return PxU32(PX_OFFSET_OF_RT(BodySim, mLLBody));}
146
147 virtual void activate();
148 virtual void deactivate();
149
150 //---------------------------------------------------------------------------------
151 // Constraint projection
152 //---------------------------------------------------------------------------------
153 PX_FORCE_INLINE ConstraintGroupNode* getConstraintGroup() { return mConstraintGroup; }
154 PX_FORCE_INLINE void setConstraintGroup(ConstraintGroupNode* node) { mConstraintGroup = node; }
155
157 //PX_FORCE_INLINE void projectPose() { PX_ASSERT(mConstraintGroup); ConstraintGroupNode::projectPose(*mConstraintGroup); }
158
159 //---------------------------------------------------------------------------------
160 // Kinematics
161 //---------------------------------------------------------------------------------
162 PX_FORCE_INLINE bool isKinematic() const { return getBodyCore().getFlags() & PxRigidBodyFlag::eKINEMATIC; }
163 PX_FORCE_INLINE bool isArticulationLink() const { return getActorType() == PxActorType::eARTICULATION_LINK; }
164 PX_FORCE_INLINE bool hasForcedKinematicNotif() const
165 {
167 }
168 void calculateKinematicVelocity(PxReal oneOverDt);
169 void updateKinematicPose();
170 bool deactivateKinematic();
171 private:
172 PX_FORCE_INLINE void initKinematicStateBase(BodyCore&, bool asPartOfCreation);
173
174 //---------------------------------------------------------------------------------
175 // Sleeping
176 //---------------------------------------------------------------------------------
177 public:
178 virtual void internalWakeUp(PxReal wakeCounterValue);
179 void internalWakeUpArticulationLink(PxReal wakeCounterValue); // called by ArticulationSim to wake up this link
180
181 PxReal updateWakeCounter(PxReal dt, PxReal energyThreshold, const Cm::SpatialVector& motionVelocity);
182
183 void resetSleepFilter();
184 void notifyReadyForSleeping(); // inform the sleep island generation system that the body is ready for sleeping
185 void notifyNotReadyForSleeping(); // inform the sleep island generation system that the body is not ready for sleeping
186 PX_FORCE_INLINE bool checkSleepReadinessBesidesWakeCounter(); // for API triggered changes to test sleep readiness
187
188 virtual void registerCountedInteraction() { mLLBody.getCore().numCountedInteractions++; PX_ASSERT(mLLBody.getCore().numCountedInteractions); }
189 virtual void unregisterCountedInteraction() { PX_ASSERT(mLLBody.getCore().numCountedInteractions); mLLBody.getCore().numCountedInteractions--; }
190 virtual PxU32 getNumCountedInteractions() const { return mLLBody.getCore().numCountedInteractions; }
191
192 PX_FORCE_INLINE PxIntBool isFrozen() const { return PxIntBool(mLLBody.mInternalFlags & PxsRigidBody::eFROZEN); }
193 private:
194 PX_FORCE_INLINE void notifyWakeUp(); // inform the sleep island generation system that the object got woken up
195 PX_FORCE_INLINE void notifyPutToSleep(); // inform the sleep island generation system that the object was put to sleep
196 PX_FORCE_INLINE void internalWakeUpBase(PxReal wakeCounterValue);
197
198 //---------------------------------------------------------------------------------
199 // External velocity changes
200 //---------------------------------------------------------------------------------
201 public:
202 void updateForces(PxReal dt, PxsRigidBody** updatedBodySims, PxU32* updatedBodyNodeIndices,
203 PxU32& index, Cm::SpatialVector* acceleration);
204
205 PX_FORCE_INLINE bool readVelocityModFlag(VelocityModFlags f) { return (mVelModState & f) != 0; }
206 private:
207 PX_FORCE_INLINE void raiseVelocityModFlag(VelocityModFlags f) { mVelModState |= f; }
208 PX_FORCE_INLINE void clearVelocityModFlag(VelocityModFlags f) { mVelModState &= ~f; }
209
210 PX_FORCE_INLINE void setForcesToDefaults(bool enableGravity);
211
212 //---------------------------------------------------------------------------------
213 // Miscellaneous
214 //---------------------------------------------------------------------------------
215 public:
216 /* PX_FORCE_INLINE PxU16 getInternalFlag() const { return mInternalFlags; }
217 PX_FORCE_INLINE PxU16 readInternalFlag(InternalFlags flag) const { return PxU16(mInternalFlags & flag); }
218 PX_FORCE_INLINE void raiseInternalFlag(InternalFlags flag) { mInternalFlags |= flag; }
219 PX_FORCE_INLINE void clearInternalFlag(InternalFlags flag) { mInternalFlags &= ~flag; }*/
220 PX_FORCE_INLINE PxU32 getFlagsFast() const { return getBodyCore().getFlags(); }
221
222 PX_FORCE_INLINE BodyCore& getBodyCore() const { return static_cast<BodyCore&>(getRigidCore()); }
223
224 PX_INLINE ArticulationSim* getArticulation() const { return mArticulation; }
225 void setArticulation(ArticulationSim* a, PxReal wakeCounter, bool asleep, PxU32 bodyIndex);
226
227 //PX_FORCE_INLINE IG::NodeIndex getNodeIndex() const { return mNodeIndex; }
228
229 PX_FORCE_INLINE void onConstraintAttach() { raiseInternalFlag(BF_HAS_CONSTRAINTS); registerCountedInteraction(); }
230 void onConstraintDetach();
231
232 PX_FORCE_INLINE void onOriginShift(const PxVec3& shift, const bool isKinematic)
233 {
234 PX_ASSERT(!mSimStateData || checkSimStateKinematicStatus(isKinematic));
235 mLLBody.mLastTransform.p -= shift;
236 if (mSimStateData && isKinematic && mSimStateData->getKinematicData()->targetValid)
237 mSimStateData->getKinematicData()->targetPose.p -= shift;
238 }
239
240 PX_FORCE_INLINE bool notInScene() const { return mActiveListIndex == SC_NOT_IN_SCENE_INDEX; }
241
242 PX_FORCE_INLINE bool usingSqKinematicTarget() const
243 {
245 return (getFlagsFast()&ktFlags) == ktFlags;
246 }
247
248 PX_FORCE_INLINE PxU32 getNbShapes() const { return mShapes.getCount(); }
249
250 void createSqBounds();
251 void destroySqBounds();
252 void freezeTransforms(PxBitMapPinned* shapeChangedMap);
253 void invalidateSqBounds();
254 private:
255 //---------------------------------------------------------------------------------
256 // Base body
257 //---------------------------------------------------------------------------------
258 PxsRigidBody mLLBody;
259
260 //---------------------------------------------------------------------------------
261 // Island manager
262 //---------------------------------------------------------------------------------
263 // IG::NodeIndex mNodeIndex;
264
265 //---------------------------------------------------------------------------------
266 // External velocity changes
267 //---------------------------------------------------------------------------------
268 // VelocityMod data allocated on the fly when the user applies velocity changes
269 // which need to be accumulated.
270 // VelMod dirty flags stored in BodySim so we can save ourselves the expense of looking at
271 // the separate velmod data if no forces have been set.
272 //PxU16 mInternalFlags;
273 SimStateData* mSimStateData;
274 PxU8 mVelModState;
275
276 //---------------------------------------------------------------------------------
277 // Articulation
278 //---------------------------------------------------------------------------------
279 ArticulationSim* mArticulation; // NULL if not in an articulation
280
281 //---------------------------------------------------------------------------------
282 // Joints & joint groups
283 //---------------------------------------------------------------------------------
284
285 // This is a tree data structure that gives us the projection order of joints in which this body is the tree root.
286 // note: the link of the root body is not necces. the root link due to the re-rooting of the articulation!
287 ConstraintGroupNode* mConstraintGroup;
288 };
289
290#if PX_VC
291 #pragma warning(pop)
292#endif
293
294} // namespace Sc
295
296PX_FORCE_INLINE void Sc::BodySim::setForcesToDefaults(bool enableGravity)
297{
298 if (!(mLLBody.mCore->mFlags & PxRigidBodyFlag::eRETAIN_ACCELERATIONS))
299 {
300 SimStateData* simStateData = getSimStateData(false);
301 if(simStateData)
302 {
303 VelocityMod* velmod = simStateData->getVelocityModData();
304 velmod->clear();
305 }
306
307 if (enableGravity)
308 mVelModState = VMF_GRAVITY_DIRTY; // We want to keep the gravity flag to make sure the acceleration gets changed to gravity-only
309 // in the next step (unless the application adds new forces of course)
310 else
311 mVelModState = 0;
312 }
313 else
314 {
315 SimStateData* simStateData = getSimStateData(false);
316 if (simStateData)
317 {
318 VelocityMod* velmod = simStateData->getVelocityModData();
319 velmod->clearPerStep();
320 }
321
322 mVelModState &= (~(VMF_VEL_DIRTY));
323 }
324}
325
326PX_FORCE_INLINE bool Sc::BodySim::checkSleepReadinessBesidesWakeCounter()
327{
328 const BodyCore& bodyCore = getBodyCore();
329 const SimStateData* simStateData = getSimStateData(false);
330 const VelocityMod* velmod = simStateData ? simStateData->getVelocityModData() : NULL;
331
332 bool readyForSleep = bodyCore.getLinearVelocity().isZero() && bodyCore.getAngularVelocity().isZero();
333 if (readVelocityModFlag(VMF_ACC_DIRTY))
334 {
335 readyForSleep = readyForSleep && (!velmod || velmod->getLinearVelModPerSec().isZero());
336 readyForSleep = readyForSleep && (!velmod || velmod->getAngularVelModPerSec().isZero());
337 }
338 if (readVelocityModFlag(VMF_VEL_DIRTY))
339 {
340 readyForSleep = readyForSleep && (!velmod || velmod->getLinearVelModPerStep().isZero());
341 readyForSleep = readyForSleep && (!velmod || velmod->getAngularVelModPerStep().isZero());
342 }
343
344 return readyForSleep;
345}
346
347
348}
349
350#endif
Definition BpAABBManagerBase.h:101
Definition CmSpatialVector.h:46
Definition PxPool.h:248
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 PxsRigidBody.h:43
Definition PxsTransformCache.h:60
Definition ScArticulationSim.h:68
Definition ScBodyCore.h:49
Definition ScBodySim.h:60
Definition ScRigidSim.h:42
Definition ScScene.h:240
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#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
@ eARTICULATION_LINK
An articulation link.
Definition PxActor.h:138
@ eFORCE_KINE_KINE_NOTIFICATIONS
Forces kinematic-kinematic pairs notifications for this actor.
Definition PxRigidBody.h:157
@ eFORCE_STATIC_KINE_NOTIFICATIONS
Forces static-kinematic pairs notifications for this actor.
Definition PxRigidBody.h:170
@ eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES
Use the kinematic target transform for scene queries.
Definition PxRigidBody.h:85
@ eRETAIN_ACCELERATIONS
Carries over forces/accelerations between frames, rather than clearing them.
Definition PxRigidBody.h:137
@ eKINEMATIC
Enables kinematic mode for the actor.
Definition PxRigidBody.h:74
Definition ScConstraintGroupNode.h:45
Definition ScSimStateData.h:108