浏览代码

Fixed some BodyInterface functions when body not added to world yet

* MoveKinematic, SetLinearVelocity, SetAngularVelocity, SetLinearAndAngularVelocity, AddLinearVelocity, AddLinearAndAngularVelocity, SetPositionRotationAndVelocity, SetMotionType
* Removed some redundant calls to InvalidateContactCacheForBody when body not added to world
Jorrit Rouwe 1 月之前
父节点
当前提交
273d8acdf2
共有 3 个文件被更改,包括 27 次插入22 次删除
  1. 3 0
      Docs/ReleaseNotes.md
  2. 17 16
      Jolt/Physics/Body/BodyInterface.cpp
  3. 7 6
      Jolt/Physics/Body/BodyInterface.h

+ 3 - 0
Docs/ReleaseNotes.md

@@ -10,9 +10,12 @@ For breaking API changes see [this document](https://github.com/jrouwe/JoltPhysi
 * Added ability to drive hinge constraints with `Ragdoll::DriveToPoseUsingMotors`. This also adds `HingeConstraint::SetTargetOrientationBS` which sets the target angle in body space.
 * Added `JPH_USE_EXTERNAL_PROFILE` cmake option that allows overriding the behavior of the profile macros.
 * Added `SoftBodyCreationSettings::mFacesDoubleSided` which treats the faces of the soft body as double sided. This can be used to make e.g. flags double sided.
+* Added functions to get the `CharacterSettings` from a `Character` and `CharacterVirtualSettings` from a `CharacterVirtual`.
 
 ### Bug Fixes
 
+* Fixed `BodyInterface::MoveKinematic`, `SetLinearVelocity`, `SetAngularVelocity`, `SetLinearAndAngularVelocity`, `AddLinearVelocity`, `AddLinearAndAngularVelocity`, `SetPositionRotationAndVelocity` and `SetMotionType` when body not added to the physics system yet.
+* Fixed UBSAN false positive error that detected a dirty trick in `SimShapeFilter``.
 * WheelSettingsTV and WheelSettingsWV were not serializing their base class members.
 * The remap tables in `SoftBodySharedSettings::OptimizationResults`` mapped from new to old index instead of from old to new as was documented. The maps now behave as documented.
 * Fixed an issue where soft body bend constraints could be created with identical vertices. This led to an assert triggering.

+ 17 - 16
Jolt/Physics/Body/BodyInterface.cpp

@@ -308,12 +308,12 @@ void BodyInterface::SetShape(const BodyID &inBodyID, const Shape *inShape, bool
 			// Update the shape
 			body.SetShapeInternal(inShape, inUpdateMassProperties);
 
-			// Flag collision cache invalid for this body
-			mBodyManager->InvalidateContactCacheForBody(body);
-
 			// Notify broadphase of change
 			if (body.IsInBroadPhase())
 			{
+				// Flag collision cache invalid for this body
+				mBodyManager->InvalidateContactCacheForBody(body);
+
 				BodyID id = body.GetID();
 				mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
 
@@ -338,12 +338,12 @@ void BodyInterface::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inPreviou
 		// Recalculate bounding box
 		body.CalculateWorldSpaceBoundsInternal();
 
-		// Flag collision cache invalid for this body
-		mBodyManager->InvalidateContactCacheForBody(body);
-
 		// Notify broadphase of change
 		if (body.IsInBroadPhase())
 		{
+			// Flag collision cache invalid for this body
+			mBodyManager->InvalidateContactCacheForBody(body);
+
 			BodyID id = body.GetID();
 			mBroadPhase->NotifyBodiesAABBChanged(&id, 1);
 
@@ -553,7 +553,7 @@ void BodyInterface::MoveKinematic(const BodyID &inBodyID, RVec3Arg inTargetPosit
 
 		body.MoveKinematic(inTargetPosition, inTargetRotation, inDeltaTime);
 
-		if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()))
+		if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()) && body.IsInBroadPhase())
 			mBodyManager->ActivateBodies(&inBodyID, 1);
 	}
 }
@@ -569,7 +569,7 @@ void BodyInterface::SetLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg
 			body.SetLinearVelocityClamped(inLinearVelocity);
 			body.SetAngularVelocityClamped(inAngularVelocity);
 
-			if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
+			if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()) && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -602,7 +602,7 @@ void BodyInterface::SetLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVe
 		{
 			body.SetLinearVelocityClamped(inLinearVelocity);
 
-			if (!body.IsActive() && !inLinearVelocity.IsNearZero())
+			if (!body.IsActive() && !inLinearVelocity.IsNearZero() && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -631,7 +631,7 @@ void BodyInterface::AddLinearVelocity(const BodyID &inBodyID, Vec3Arg inLinearVe
 		{
 			body.SetLinearVelocityClamped(body.GetLinearVelocity() + inLinearVelocity);
 
-			if (!body.IsActive() && !body.GetLinearVelocity().IsNearZero())
+			if (!body.IsActive() && !body.GetLinearVelocity().IsNearZero() && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -648,7 +648,7 @@ void BodyInterface::AddLinearAndAngularVelocity(const BodyID &inBodyID, Vec3Arg
 			body.SetLinearVelocityClamped(body.GetLinearVelocity() + inLinearVelocity);
 			body.SetAngularVelocityClamped(body.GetAngularVelocity() + inAngularVelocity);
 
-			if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()))
+			if (!body.IsActive() && (!body.GetLinearVelocity().IsNearZero() || !body.GetAngularVelocity().IsNearZero()) && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -664,7 +664,7 @@ void BodyInterface::SetAngularVelocity(const BodyID &inBodyID, Vec3Arg inAngular
 		{
 			body.SetAngularVelocityClamped(inAngularVelocity);
 
-			if (!body.IsActive() && !inAngularVelocity.IsNearZero())
+			if (!body.IsActive() && !inAngularVelocity.IsNearZero() && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -849,7 +849,7 @@ void BodyInterface::SetPositionRotationAndVelocity(const BodyID &inBodyID, RVec3
 			body.SetAngularVelocityClamped(inAngularVelocity);
 
 			// Optionally activate body
-			if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()))
+			if (!body.IsActive() && (!inLinearVelocity.IsNearZero() || !inAngularVelocity.IsNearZero()) && body.IsInBroadPhase())
 				mBodyManager->ActivateBodies(&inBodyID, 1);
 		}
 	}
@@ -869,7 +869,7 @@ void BodyInterface::SetMotionType(const BodyID &inBodyID, EMotionType inMotionTy
 		body.SetMotionType(inMotionType);
 
 		// Activate body if requested
-		if (inMotionType != EMotionType::Static && inActivationMode == EActivation::Activate)
+		if (inMotionType != EMotionType::Static && inActivationMode == EActivation::Activate && body.IsInBroadPhase())
 			ActivateBodyInternal(body);
 	}
 }
@@ -976,7 +976,8 @@ void BodyInterface::SetUseManifoldReduction(const BodyID &inBodyID, bool inUseRe
 			body.SetUseManifoldReduction(inUseReduction);
 
 			// Flag collision cache invalid for this body
-			mBodyManager->InvalidateContactCacheForBody(body);
+			if (body.IsInBroadPhase())
+				mBodyManager->InvalidateContactCacheForBody(body);
 		}
 	}
 }
@@ -1043,7 +1044,7 @@ const PhysicsMaterial *BodyInterface::GetMaterial(const BodyID &inBodyID, const
 void BodyInterface::InvalidateContactCache(const BodyID &inBodyID)
 {
 	BodyLockWrite lock(*mBodyLockInterface, inBodyID);
-	if (lock.Succeeded())
+	if (lock.SucceededAndIsInBroadPhase())
 		mBodyManager->InvalidateContactCacheForBody(lock.GetBody());
 }
 

+ 7 - 6
Jolt/Physics/Body/BodyInterface.h

@@ -98,7 +98,7 @@ public:
 	/// After adding, to get a body by ID use the BodyLockRead or BodyLockWrite interface!
 	void						AddBody(const BodyID &inBodyID, EActivation inActivationMode);
 
-	/// Remove body from the physics system.
+	/// Remove body from the physics system. Note that you need to add a body to the physics system before you can remove it.
 	void						RemoveBody(const BodyID &inBodyID);
 
 	/// Check if a body has been added to the physics system.
@@ -132,12 +132,12 @@ public:
 	/// Please ensure that the ioBodies array passed to AddBodiesPrepare is unmodified and passed again to this function.
 	void						AddBodiesAbort(BodyID *ioBodies, int inNumber, AddState inAddState);
 
-	/// Remove inNumber bodies in ioBodies from the PhysicsSystem.
+	/// Remove inNumber bodies in ioBodies from the PhysicsSystem. Note that bodies need to be added to the physics system before they can be removed.
 	/// ioBodies may be shuffled around by this function.
 	void						RemoveBodies(BodyID *ioBodies, int inNumber);
 	///@}
 
-	///@name Activate / deactivate a body
+	///@name Activate / deactivate a body. Note that you need to add a body to the physics system before you can activate it.
 	///@{
 	void						ActivateBody(const BodyID &inBodyID);
 	void						ActivateBodies(const BodyID *inBodyIDs, int inNumber);
@@ -151,7 +151,8 @@ public:
 	/// Create a two body constraint
 	TwoBodyConstraint *			CreateConstraint(const TwoBodyConstraintSettings *inSettings, const BodyID &inBodyID1, const BodyID &inBodyID2);
 
-	/// Activate non-static bodies attached to a constraint
+	/// Activate non-static bodies attached to a constraint.
+	/// Note that the bodies involved in the constraint should be added to the physics system before activating a constraint.
 	void						ActivateConstraint(const TwoBodyConstraint *inConstraint);
 
 	///@name Access to the shape of a body
@@ -214,7 +215,7 @@ public:
 	/// Note that the linear velocity is the velocity of the center of mass, which may not coincide with the position of your object, to correct for this: \f$VelocityCOM = Velocity - AngularVelocity \times ShapeCOM\f$
 	void						SetPositionRotationAndVelocity(const BodyID &inBodyID, RVec3Arg inPosition, QuatArg inRotation, Vec3Arg inLinearVelocity, Vec3Arg inAngularVelocity);
 
-	///@name Add forces to the body
+	///@name Add forces to the body. Note that you should add a body to the physics system before applying forces or torques.
 	///@{
 	void						AddForce(const BodyID &inBodyID, Vec3Arg inForce, EActivation inActivationMode = EActivation::Activate); ///< See Body::AddForce
 	void						AddForce(const BodyID &inBodyID, Vec3Arg inForce, RVec3Arg inPoint, EActivation inActivationMode = EActivation::Activate); ///< Applied at inPoint
@@ -222,7 +223,7 @@ public:
 	void						AddForceAndTorque(const BodyID &inBodyID, Vec3Arg inForce, Vec3Arg inTorque, EActivation inActivationMode = EActivation::Activate); ///< A combination of Body::AddForce and Body::AddTorque
 	///@}
 
-	///@name Add an impulse to the body
+	///@name Add an impulse to the body. Note that you should add a body to the physics system before applying impulses.
 	///@{
 	void						AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse); ///< Applied at center of mass
 	void						AddImpulse(const BodyID &inBodyID, Vec3Arg inImpulse, RVec3Arg inPoint); ///< Applied at inPoint