Revision control

- //
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
- // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
+ // Copyright (c) 2008-2026 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
-
- #ifndef PX_COLLISION_SHAPE_INTERACTION
- #define PX_COLLISION_SHAPE_INTERACTION
+ #ifndef SC_SHAPE_INTERACTION_H
+ #define SC_SHAPE_INTERACTION_H
#include "ScElementSimInteraction.h"
#include "ScShapeSim.h"
#include "ScActorPair.h"
#include "ScScene.h"
#include "ScBodySim.h"
#include "PxsContactManager.h"
#include "PxsContext.h"
#include "PxsSimpleIslandManager.h"
#define INVALID_REPORT_PAIR_ID 0xffffffff
namespace physx
{
+
class PxsContactManagerOutputIterator;
namespace Sc
{
class ContactReportAllocationManager;
+
+ PX_FORCE_INLINE IG::Edge::EdgeType getInteractionEdgeType(PxActorType::Enum actorTypeLargest)
+ {
+ IG::Edge::EdgeType type = IG::Edge::eCONTACT_MANAGER;
+ #if PX_SUPPORT_GPU_PHYSX
+ if(actorTypeLargest == PxActorType::eDEFORMABLE_VOLUME)
+ type = IG::Edge::eSOFT_BODY_CONTACT;
+ else if(actorTypeLargest == PxActorType::eDEFORMABLE_SURFACE)
+ type = IG::Edge::eFEM_CLOTH_CONTACT;
+ else if(actorTypeLargest == PxActorType::ePBD_PARTICLESYSTEM)
+ type = IG::Edge::ePARTICLE_SYSTEM_CONTACT;
+ #else
+ PX_UNUSED(actorTypeLargest);
+ #endif
+ return type;
+ }
+
/*
Description: A ShapeInteraction represents a pair of objects which _may_ have contacts. Created by the broadphase
and processed by the NPhaseCore.
*/
class ShapeInteraction : public ElementSimInteraction
{
friend class NPhaseCore;
ShapeInteraction& operator=(const ShapeInteraction&);
public:
enum SiFlag
{
PAIR_FLAGS_MASK = (PxPairFlag::eNEXT_FREE - 1), // Bits where the PxPairFlags get stored
NEXT_FREE = ((PAIR_FLAGS_MASK << 1) & ~PAIR_FLAGS_MASK),
HAS_TOUCH = (NEXT_FREE << 0), // Tracks the last know touch state
HAS_NO_TOUCH = (NEXT_FREE << 1), // Tracks the last know touch state
TOUCH_KNOWN = (HAS_TOUCH | HAS_NO_TOUCH), // If none of these flags is set, the touch state is not known (for example, this is true for pairs that never ran narrowphase
CONTACTS_COLLECT_POINTS = (NEXT_FREE << 2), // The user wants to get the contact points (includes debug rendering)
CONTACTS_RESPONSE_DISABLED = (NEXT_FREE << 3), // Collision response disabled (either by the user through PxPairFlag::eSOLVE_CONTACT or because the pair has two kinematics)
CONTACT_FORCE_THRESHOLD_PAIRS = PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND) | PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS) | PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST),
CONTACT_REPORT_EVENTS = PxU32(PxPairFlag::eNOTIFY_TOUCH_FOUND) | PxU32(PxPairFlag::eNOTIFY_TOUCH_PERSISTS) | PxU32(PxPairFlag::eNOTIFY_TOUCH_LOST) |
PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND) | PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS) | PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST),
CONTACT_REPORT_EXTRA_DATA = PxU32(PxPairFlag::ePRE_SOLVER_VELOCITY) | PxU32(PxPairFlag::ePOST_SOLVER_VELOCITY) | PxU32(PxPairFlag::eCONTACT_EVENT_POSE),
FORCE_THRESHOLD_EXCEEDED_NOW = (NEXT_FREE << 4),
FORCE_THRESHOLD_EXCEEDED_BEFORE = (NEXT_FREE << 5),
FORCE_THRESHOLD_EXCEEDED_FLAGS = FORCE_THRESHOLD_EXCEEDED_NOW | FORCE_THRESHOLD_EXCEEDED_BEFORE,
IS_IN_PERSISTENT_EVENT_LIST = (NEXT_FREE << 6), // The pair is in the list of persistent contact events
WAS_IN_PERSISTENT_EVENT_LIST = (NEXT_FREE << 7), // The pair is inactive but used to be in the list of persistent contact events
IN_PERSISTENT_EVENT_LIST = IS_IN_PERSISTENT_EVENT_LIST | WAS_IN_PERSISTENT_EVENT_LIST,
IS_IN_FORCE_THRESHOLD_EVENT_LIST= (NEXT_FREE << 8), // The pair is in the list of force threshold contact events
IS_IN_CONTACT_EVENT_LIST = IS_IN_PERSISTENT_EVENT_LIST | IS_IN_FORCE_THRESHOLD_EVENT_LIST,
LL_MANAGER_RECREATE_EVENT = CONTACT_REPORT_EVENTS | CONTACTS_COLLECT_POINTS |
CONTACTS_RESPONSE_DISABLED | PxU32(PxPairFlag::eMODIFY_CONTACTS)
};
- ShapeInteraction(ShapeSim& s1, ShapeSim& s2, PxPairFlags pairFlags, PxsContactManager* contactManager);
+ ShapeInteraction(ShapeSimBase& s1, ShapeSimBase& s2, PxPairFlags pairFlags, PxsContactManager* contactManager);
~ShapeInteraction();
// Submits to contact stream
- void processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, const PxU32 ccdPass, const bool useCurrentTransform,
+ void processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, PxU32 ccdPass, bool useCurrentTransform,
PxsContactManagerOutputIterator& outputs); // ccdPass is 0 for discrete collision and then 1,2,... for the CCD passes
-
void processUserNotificationSync();
+ void processUserNotificationAsync(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, PxU32 ccdPass, bool useCurrentTransform,
+ PxsContactManagerOutputIterator& outputs, ContactReportAllocationManager* alloc = NULL); // ccdPass is 0 for discrete collision and then 1,2,... for the CCD passes
- void processUserNotificationAsync(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, const PxU32 ccdPass, const bool useCurrentTransform,
- PxsContactManagerOutputIterator& outputs, ContactReportAllocationManager* alloc = NULL); // ccdPass is 0 for discrete collision and then 1,2,... for the CCD passes
-
- void visualize(Cm::RenderOutput&, PxsContactManagerOutputIterator&);
+ void visualize( PxRenderOutput&, PxsContactManagerOutputIterator&,
+ float scale, float contactImpulse, float contactNormal, float contactError, float contactPoint,
+ float frictionImpulse, float frictionNormal, float frictionPoint);
PxU32 getContactPointData(const void*& contactPatches, const void*& contactPoints, PxU32& contactDataSize, PxU32& contactPointCount, PxU32& patchCount, const PxReal*& impulses, PxU32 startOffset, PxsContactManagerOutputIterator& outputs);
+ PxU32 getContactPointData(const void*& contactPatches, const void*& contactPoints, PxU32& contactDataSize, PxU32& contactPointCount, PxU32& patchCount, const PxReal*& impulses, PxU32 startOffset, PxsContactManagerOutputIterator& outputs, const void*& frictionPatches);
- bool managerLostTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs, bool useAdaptiveForce);
- void managerNewTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs, bool useAdaptiveForce);
+ bool managerLostTouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs);
+ void managerNewTouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs);
- PX_FORCE_INLINE void adjustCountersOnLostTouch(BodySim*, BodySim*, bool useAdaptiveForce);
- PX_FORCE_INLINE void adjustCountersOnNewTouch(bool useAdaptiveForce);
+ PX_FORCE_INLINE void adjustCountersOnLostTouch();
+ PX_FORCE_INLINE void adjustCountersOnNewTouch();
- PX_FORCE_INLINE void sendCCDRetouch(const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs);
+ PX_FORCE_INLINE void sendCCDRetouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs);
void setContactReportPostSolverVelocity(ContactStreamManager& cs);
- PX_FORCE_INLINE void sendLostTouchReport(bool shapeVolumeRemoved, const PxU32 ccdPass, PxsContactManagerOutputIterator& ouptuts);
+ void sendLostTouchReport(bool shapeVolumeRemoved, PxU32 ccdPass, PxsContactManagerOutputIterator& ouptuts);
void resetManagerCachedState() const;
- PX_FORCE_INLINE ActorPair* getActorPair() const { return mActorPair; }
- PX_FORCE_INLINE void setActorPair(ActorPair& aPair) { mActorPair = &aPair; }
+ PX_FORCE_INLINE ActorPair* getActorPair() const { return mActorPair; }
+ PX_FORCE_INLINE void setActorPair(ActorPair& aPair) { mActorPair = &aPair; }
PX_FORCE_INLINE void clearActorPair() { mActorPair = NULL; }
- PX_FORCE_INLINE ActorPairReport& getActorPairReport() const { return ActorPairReport::cast(*mActorPair); }
- PX_INLINE Ps::IntBool isReportPair() const { /*PX_ASSERT(!(Ps::IntBool(getPairFlags() & CONTACT_REPORT_EVENTS)) || mActorPair->isReportPair());*/ return Ps::IntBool(getPairFlags() & CONTACT_REPORT_EVENTS); }
- PX_INLINE Ps::IntBool hasTouch() const { return readFlag(HAS_TOUCH); }
- PX_INLINE Ps::IntBool hasCCDTouch() const { PX_ASSERT(mManager); return mManager->getHadCCDContact(); }
+ PX_FORCE_INLINE ActorPairReport& getActorPairReport() const { return ActorPairReport::cast(*mActorPair); }
+ PX_INLINE PxIntBool isReportPair() const { /*PX_ASSERT(!(PxIntBool(getPairFlags() & CONTACT_REPORT_EVENTS)) || mActorPair->isReportPair());*/ return PxIntBool(getPairFlags() & CONTACT_REPORT_EVENTS); }
+ PX_INLINE PxIntBool hasTouch() const { return readFlag(HAS_TOUCH); }
+ PX_INLINE PxIntBool hasCCDTouch() const { PX_ASSERT(mManager); return mManager->getHadCCDContact(); }
PX_INLINE void swapAndClearForceThresholdExceeded();
- PX_FORCE_INLINE void raiseFlag(SiFlag flag) { mFlags |= flag; }
- PX_FORCE_INLINE Ps::IntBool readFlag(SiFlag flag) const { return Ps::IntBool(mFlags & flag); }
- PX_FORCE_INLINE PxU32 getPairFlags() const;
+ PX_FORCE_INLINE void raiseFlag(SiFlag flag) { mFlags |= flag; }
+ PX_FORCE_INLINE PxIntBool readFlag(SiFlag flag) const { return PxIntBool(mFlags & flag); }
+ PX_FORCE_INLINE PxU32 getPairFlags() const;
PX_FORCE_INLINE void removeFromReportPairList();
void onShapeChangeWhileSleeping(bool shapeOfDynamicChanged);
- PX_FORCE_INLINE Ps::IntBool hasKnownTouchState() const;
+ PX_FORCE_INLINE PxIntBool hasKnownTouchState() const;
- bool onActivate_(void* data);
- bool onDeactivate_();
+ bool onActivate(PxsContactManager* contactManager);
+ bool onDeactivate();
void updateState(const PxU8 externalDirtyFlags);
- const PxsContactManager* getContactManager() const { return mManager; }
+ const PxsContactManager* getContactManager() const { return mManager; }
- void clearIslandGenData();
+ void clearIslandGenData(IG::SimpleIslandManager& islandManager);
- PX_FORCE_INLINE PxU32 getEdgeIndex() const { return mEdgeIndex; }
+ PX_FORCE_INLINE IG::EdgeIndex getEdgeIndex() const { return mEdgeIndex; }
- PX_FORCE_INLINE Sc::ShapeSim& getShape0() const { return static_cast<ShapeSim&>(getElement0()); }
- PX_FORCE_INLINE Sc::ShapeSim& getShape1() const { return static_cast<ShapeSim&>(getElement1()); }
+ PX_FORCE_INLINE Sc::ShapeSimBase& getShape0() const { return static_cast<ShapeSimBase&>(getElement0()); }
+ PX_FORCE_INLINE Sc::ShapeSimBase& getShape1() const { return static_cast<ShapeSimBase&>(getElement1()); }
+
+ PX_FORCE_INLINE Sc::ActorSim& getActor0() { return getActorSim0(); }
+ PX_FORCE_INLINE Sc::ActorSim& getActor1() { return getActorSim1(); }
private:
- PxU32 mContactReportStamp;
- PxU32 mFlags;
ActorPair* mActorPair;
- PxU32 mReportPairIndex; // Owned by NPhaseCore for its report pair list
-
PxsContactManager* mManager;
+ PxU32 mContactReportStamp;
+ PxU32 mReportPairIndex; // Owned by NPhaseCore for its report pair list
+ PxU32 mReportStreamIndex; // position of this pair in the contact report stream
- PxU32 mEdgeIndex;
-
- PxU16 mReportStreamIndex; // position of this pair in the contact report stream
-
- // Internal functions:
-
- void createManager(void* contactManager);
- PX_INLINE void resetManager();
- PX_INLINE bool updateManager(void* contactManager);
+ void createManager(PxsContactManager* contactManager);
+ PX_INLINE bool updateManager(PxsContactManager* contactManager);
PX_INLINE void destroyManager();
PX_FORCE_INLINE bool activeManagerAllowed() const;
PX_FORCE_INLINE PxU32 getManagerContactState() const { return mFlags & LL_MANAGER_RECREATE_EVENT; }
PX_FORCE_INLINE void clearFlag(SiFlag flag) { mFlags &= ~flag; }
PX_INLINE void setFlag(SiFlag flag, bool value)
{
if (value)
raiseFlag(flag);
else
clearFlag(flag);
}
PX_FORCE_INLINE void setHasTouch() { clearFlag(HAS_NO_TOUCH); raiseFlag(HAS_TOUCH); }
PX_FORCE_INLINE void setHasNoTouch() { clearFlag(HAS_TOUCH); raiseFlag(HAS_NO_TOUCH); }
PX_FORCE_INLINE void setPairFlags(PxPairFlags flags);
PX_FORCE_INLINE void processReportPairOnActivate();
PX_FORCE_INLINE void processReportPairOnDeactivate();
// Certain SiFlag cache properties of the pair. If these properties change then the flags have to be updated.
// For example: is collision enabled for this pair? are contact points requested for this pair?
- PX_FORCE_INLINE void updateFlags(const Sc::Scene&, const Sc::BodySim*, const Sc::BodySim*, const PxU32 pairFlags);
+ PX_FORCE_INLINE void updateFlags(const Sc::Scene&, const Sc::ActorSim&, const Sc::ActorSim&, const PxU32 pairFlags);
friend class Sc::Scene;
};
} // namespace Sc
-
- PX_FORCE_INLINE void Sc::ShapeInteraction::sendLostTouchReport(bool shapeVolumeRemoved, const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs)
- {
- PX_ASSERT(hasTouch());
- PX_ASSERT(isReportPair());
-
- PxU32 thresholdForceLost = readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_NOW) ? PxU32(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST) : 0; // make sure to only send report if force is still above threshold
- PxU32 triggeredFlags = getPairFlags() & (PxU32(PxPairFlag::eNOTIFY_TOUCH_LOST) | thresholdForceLost);
- if (triggeredFlags)
- {
- PxU16 infoFlag = 0;
- if (mActorPair->getTouchCount() == 1) // this code assumes that the actor pair touch count does get decremented afterwards
- {
- infoFlag |= PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH;
- }
-
- //Lost touch is processed after solver, so we should use the previous transform to update the pose for objects if user request eCONTACT_EVENT_POSE
- processUserNotification(triggeredFlags, infoFlag, true, ccdPass, false, outputs);
- }
-
- ActorPairReport& apr = getActorPairReport();
- if (apr.hasReportData() && !apr.streamResetNeeded(getScene().getTimeStamp()))
- {
- // If there has been no event recorded yet, there is no need to worry about events with shape pointers which might later reference
- // removed shapes due to buffered removal, i.e., removal while the simulation was running.
- // This is also correct for CCD scenarios where a touch could get lost and then found again etc. If in such a case there ever is a contact event
- // recorded, there will always be another sendLostTouchReport() call at some later point (caused by the simulation or when the shape gets
- // removed at fetchResults).
- PxU16 flagsToRaise = ContactStreamManagerFlag::eHAS_PAIRS_THAT_LOST_TOUCH;
-
- ContactStreamManager& cs = apr.getContactStreamManager();
-
- if (shapeVolumeRemoved)
- {
- flagsToRaise |= ContactStreamManagerFlag::eTEST_FOR_REMOVED_SHAPES;
-
- // if an actor gets deleted while the simulation is running and the actor has a pending contact report with post solver
- // velocity extra data, then the post solver velocity needs to get written now because it is too late when the reports
- // get fired (the object will have been deleted already)
-
- if (cs.getFlags() & ContactStreamManagerFlag::eNEEDS_POST_SOLVER_VELOCITY)
- setContactReportPostSolverVelocity(cs);
- }
-
- cs.raiseFlags(flagsToRaise);
- }
- }
-
-
PX_FORCE_INLINE void Sc::ShapeInteraction::setPairFlags(PxPairFlags flags)
{
PX_ASSERT(PxU32(flags) < PxPairFlag::eNEXT_FREE); // to find out if a new PxPairFlag has been added after eLAST instead of in front
PxU32 newFlags = mFlags;
PxU32 fl = PxU32(flags) & PAIR_FLAGS_MASK;
newFlags &= (~PAIR_FLAGS_MASK); // clear old flags
newFlags |= fl;
mFlags = newFlags;
}
-
// PT: returning PxU32 instead of PxPairFlags to remove LHS. Please do not undo this.
PX_FORCE_INLINE PxU32 Sc::ShapeInteraction::getPairFlags() const
{
return (mFlags & PAIR_FLAGS_MASK);
}
-
PX_INLINE void Sc::ShapeInteraction::swapAndClearForceThresholdExceeded()
{
PxU32 flags = mFlags;
PX_COMPILE_TIME_ASSERT(FORCE_THRESHOLD_EXCEEDED_NOW == (FORCE_THRESHOLD_EXCEEDED_BEFORE >> 1));
PxU32 nowToBefore = (flags & FORCE_THRESHOLD_EXCEEDED_NOW) << 1;
flags &= ~(FORCE_THRESHOLD_EXCEEDED_NOW | FORCE_THRESHOLD_EXCEEDED_BEFORE);
flags |= nowToBefore;
mFlags = flags;
}
PX_FORCE_INLINE void Sc::ShapeInteraction::removeFromReportPairList()
{
// this method should only get called if the pair is in the list for
// persistent or force based contact reports
PX_ASSERT(mReportPairIndex != INVALID_REPORT_PAIR_ID);
PX_ASSERT(readFlag(IS_IN_CONTACT_EVENT_LIST));
Scene& scene = getScene();
if (readFlag(IS_IN_FORCE_THRESHOLD_EVENT_LIST))
scene.getNPhaseCore()->removeFromForceThresholdContactEventPairs(this);
else
{
PX_ASSERT(readFlag(IS_IN_PERSISTENT_EVENT_LIST));
scene.getNPhaseCore()->removeFromPersistentContactEventPairs(this);
}
}
- PX_INLINE bool Sc::ShapeInteraction::updateManager(void* contactManager)
+ PX_INLINE bool Sc::ShapeInteraction::updateManager(PxsContactManager* contactManager)
{
if (activeManagerAllowed())
{
if (mManager == 0)
createManager(contactManager);
return (mManager != NULL); // creation might fail (pool reached limit, mem allocation failed etc.)
}
else
return false;
}
PX_INLINE void Sc::ShapeInteraction::destroyManager()
{
PX_ASSERT(mManager);
Scene& scene = getScene();
PxvNphaseImplementationContext* nphaseImplementationContext = scene.getLowLevelContext()->getNphaseImplementationContext();
PX_ASSERT(nphaseImplementationContext);
nphaseImplementationContext->unregisterContactManager(mManager);
/*if (mEdgeIndex != IG_INVALID_EDGE)
scene.getSimpleIslandManager()->clearEdgeRigidCM(mEdgeIndex);*/
scene.getLowLevelContext()->destroyContactManager(mManager);
mManager = 0;
}
-
PX_FORCE_INLINE bool Sc::ShapeInteraction::activeManagerAllowed() const
{
- PX_ASSERT(getShape0().getActor().isDynamicRigid() || getShape1().getActor().isDynamicRigid());
-
- const BodySim* bodySim0 = getShape0().getBodySim();
- const BodySim* bodySim1 = getShape1().getBodySim();
- PX_ASSERT(bodySim0); // the first shape always belongs to a dynamic body
+ ActorSim& bodySim0 = getActorSim0();
+ ActorSim& bodySim1 = getActorSim1();
+
+ // the first shape always belongs to a dynamic body or deformable volume
+ #if PX_SUPPORT_GPU_PHYSX
+ PX_ASSERT(bodySim0.isDynamicRigid() || bodySim0.isDeformableSurface() || bodySim0.isDeformableVolume() || bodySim0.isParticleSystem());
+ #else
+ PX_ASSERT(bodySim0.isDynamicRigid());
+ #endif
+
+ // PT: try to prevent OM-103695 / PX-4509
+ // ### DEFENSIVE
+ if(!bodySim0.getNodeIndex().isValid())
+ return PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "ShapeInteraction::activeManagerAllowed: found invalid node!");
const IG::IslandSim& islandSim = getScene().getSimpleIslandManager()->getSpeculativeIslandSim();
- //if((bodySim0->isActive()) || (bodySim1 && bodySim1->isActive()))
//check whether active in the speculative sim!
- if (islandSim.getNode(bodySim0->getNodeIndex()).isActive() ||
- (bodySim1 && islandSim.getNode(bodySim1->getNodeIndex()).isActive()))
- {
- return true;
- }
- else
- {
- //Sleeping kinematic 0 vs sleeping kinematic 1
- return false;
- }
+ return (islandSim.getNode(bodySim0.getNodeIndex()).isActive() ||
+ (!bodySim1.isStaticRigid() && islandSim.getNode(bodySim1.getNodeIndex()).isActive()));
}
-
- PX_FORCE_INLINE void Sc::ShapeInteraction::sendCCDRetouch(const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs)
+ PX_FORCE_INLINE void Sc::ShapeInteraction::sendCCDRetouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs)
{
- PxU32 pairFlags = getPairFlags();
+ const PxU32 pairFlags = getPairFlags();
if (pairFlags & PxPairFlag::eNOTIFY_TOUCH_CCD)
- {
processUserNotification(PxPairFlag::eNOTIFY_TOUCH_CCD, 0, false, ccdPass, false, outputs);
- }
}
-
- PX_FORCE_INLINE void Sc::ShapeInteraction::adjustCountersOnLostTouch(BodySim* body0, BodySim* body1, bool useAdaptiveForce)
+ PX_FORCE_INLINE void Sc::ShapeInteraction::adjustCountersOnLostTouch()
{
- PX_ASSERT(body0); // the first shape always belongs to a dynamic body
-
PX_ASSERT(mActorPair->getTouchCount());
mActorPair->decTouchCount();
-
- if (useAdaptiveForce || mActorPair->getTouchCount() == 0)
- {
- body0->decrementBodyConstraintCounter();
- if (body1)
- body1->decrementBodyConstraintCounter();
- }
}
-
- PX_FORCE_INLINE void Sc::ShapeInteraction::adjustCountersOnNewTouch(bool useAdaptiveForce)
+ PX_FORCE_INLINE void Sc::ShapeInteraction::adjustCountersOnNewTouch()
{
- BodySim* body0 = getShape0().getBodySim();
- BodySim* body1 = getShape1().getBodySim();
- PX_ASSERT(body0); // the first shape always belongs to a dynamic body
-
mActorPair->incTouchCount();
- //If using adaptive force, always record a body constraint, otherwise only record if this is the first constraint
- //with this pair of bodies (doubling up usage of this counter for both adaptive force and stabilization)
- if (useAdaptiveForce || mActorPair->getTouchCount() == 1)
- {
- body0->incrementBodyConstraintCounter();
- if (body1)
- body1->incrementBodyConstraintCounter();
- }
}
-
- PX_FORCE_INLINE Ps::IntBool Sc::ShapeInteraction::hasKnownTouchState() const
+ PX_FORCE_INLINE PxIntBool Sc::ShapeInteraction::hasKnownTouchState() const
{
// For a pair where the bodies were added asleep, the touch state is not known until narrowphase runs on the pair for the first time.
// If such a pair looses AABB overlap before, the conservative approach is to wake the bodies up. This method provides an indicator that
// this is such a pair. Note: this might also wake up objects that do not touch but that's the price to pay (unless we want to run
// overlap tests on such pairs).
-
if (mManager)
return mManager->touchStatusKnown();
else
return readFlag(TOUCH_KNOWN);
}
-
}
#endif