-
Notifications
You must be signed in to change notification settings - Fork 452
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SoftBodyManifold now returns sensor contacts separately (#1276)
Before this change, there was a limit of a single colliding body per soft body vertex. If the closest body happened to be a sensor this effectively disabled the collision with the world and caused artifacts. We can now also detect multiple sensor contacts per soft body and they are returned through a new interface SoftBodyManifold::GetSensorContactBodyID. * Shape::CollideSoftBodyVertices is no longer using SoftBodyVertex but CollideSoftBodyVertexIterator which can write to other things than a SoftBodyVertex * Removed delta time and displacement due to gravity from Shape::CollideSoftBodyVertices * Added soft body vs sensor test that doesn't have a limit of 1 sensor per soft body Fixes #1016
- Loading branch information
Showing
48 changed files
with
665 additions
and
313 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics) | ||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe | ||
// SPDX-License-Identifier: MIT | ||
|
||
#pragma once | ||
|
||
JPH_NAMESPACE_BEGIN | ||
|
||
/// A strided pointer behaves exactly like a normal pointer except that the | ||
/// elements that the pointer points to can be part of a larger structure. | ||
/// The stride gives the number of bytes from one element to the next. | ||
template <class T> | ||
class JPH_EXPORT StridedPtr | ||
{ | ||
public: | ||
using value_type = T; | ||
|
||
/// Constructors | ||
StridedPtr() = default; | ||
StridedPtr(const StridedPtr &inRHS) = default; | ||
StridedPtr(T *inPtr, int inStride = sizeof(T)) : mPtr(const_cast<uint8 *>(reinterpret_cast<const uint8 *>(inPtr))), mStride(inStride) { } | ||
|
||
/// Assignment | ||
inline StridedPtr & operator = (const StridedPtr &inRHS) = default; | ||
|
||
/// Incrementing / decrementing | ||
inline StridedPtr & operator ++ () { mPtr += mStride; return *this; } | ||
inline StridedPtr & operator -- () { mPtr -= mStride; return *this; } | ||
inline StridedPtr operator ++ (int) { StridedPtr old_ptr(*this); mPtr += mStride; return old_ptr; } | ||
inline StridedPtr operator -- (int) { StridedPtr old_ptr(*this); mPtr -= mStride; return old_ptr; } | ||
inline StridedPtr operator + (int inOffset) const { StridedPtr new_ptr(*this); new_ptr.mPtr += inOffset * mStride; return new_ptr; } | ||
inline StridedPtr operator - (int inOffset) const { StridedPtr new_ptr(*this); new_ptr.mPtr -= inOffset * mStride; return new_ptr; } | ||
inline void operator += (int inOffset) { mPtr += inOffset * mStride; } | ||
inline void operator -= (int inOffset) { mPtr -= inOffset * mStride; } | ||
|
||
/// Distance between two pointers in elements | ||
inline int operator - (const StridedPtr &inRHS) const { JPH_ASSERT(inRHS.mStride == mStride); return (mPtr - inRHS.mPtr) / mStride; } | ||
|
||
/// Comparison operators | ||
inline bool operator == (const StridedPtr &inRHS) const { return mPtr == inRHS.mPtr; } | ||
inline bool operator != (const StridedPtr &inRHS) const { return mPtr != inRHS.mPtr; } | ||
inline bool operator <= (const StridedPtr &inRHS) const { return mPtr <= inRHS.mPtr; } | ||
inline bool operator >= (const StridedPtr &inRHS) const { return mPtr >= inRHS.mPtr; } | ||
inline bool operator < (const StridedPtr &inRHS) const { return mPtr < inRHS.mPtr; } | ||
inline bool operator > (const StridedPtr &inRHS) const { return mPtr > inRHS.mPtr; } | ||
|
||
/// Access value | ||
inline T & operator * () const { return *reinterpret_cast<T *>(mPtr); } | ||
inline T * operator -> () const { return reinterpret_cast<T *>(mPtr); } | ||
inline T & operator [] (int inOffset) const { uint8 *ptr = mPtr + inOffset * mStride; return *reinterpret_cast<T *>(ptr); } | ||
|
||
/// Explicit conversion | ||
inline T * GetPtr() const { return reinterpret_cast<T *>(mPtr); } | ||
|
||
/// Get stride in bytes | ||
inline int GetStride() const { return mStride; } | ||
|
||
private: | ||
uint8 * mPtr = nullptr; /// Pointer to element | ||
int mStride = 0; /// Stride (number of bytes) between elements | ||
}; | ||
|
||
JPH_NAMESPACE_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics) | ||
// SPDX-FileCopyrightText: 2024 Jorrit Rouwe | ||
// SPDX-License-Identifier: MIT | ||
|
||
#pragma once | ||
|
||
#include <Jolt/Physics/SoftBody/SoftBodyVertex.h> | ||
#include <Jolt/Core/StridedPtr.h> | ||
|
||
JPH_NAMESPACE_BEGIN | ||
|
||
/// Class that allows iterating over the vertices of a soft body. | ||
/// It tracks the largest penetration and allows storing the resulting collision in a different structure than the soft body vertex itself. | ||
class CollideSoftBodyVertexIterator | ||
{ | ||
public: | ||
/// Default constructor | ||
CollideSoftBodyVertexIterator() = default; | ||
CollideSoftBodyVertexIterator(const CollideSoftBodyVertexIterator &) = default; | ||
|
||
/// Construct using (strided) pointers | ||
CollideSoftBodyVertexIterator(const StridedPtr<const Vec3> &inPosition, const StridedPtr<const float> &inInvMass, const StridedPtr<Plane> &inCollisionPlane, const StridedPtr<float> &inLargestPenetration, const StridedPtr<int> &inCollidingShapeIndex) : | ||
mPosition(inPosition), | ||
mInvMass(inInvMass), | ||
mCollisionPlane(inCollisionPlane), | ||
mLargestPenetration(inLargestPenetration), | ||
mCollidingShapeIndex(inCollidingShapeIndex) | ||
{ | ||
} | ||
|
||
/// Construct using a soft body vertex | ||
explicit CollideSoftBodyVertexIterator(SoftBodyVertex *inVertices) : | ||
mPosition(&inVertices->mPosition, sizeof(SoftBodyVertex)), | ||
mInvMass(&inVertices->mInvMass, sizeof(SoftBodyVertex)), | ||
mCollisionPlane(&inVertices->mCollisionPlane, sizeof(SoftBodyVertex)), | ||
mLargestPenetration(&inVertices->mLargestPenetration, sizeof(SoftBodyVertex)), | ||
mCollidingShapeIndex(&inVertices->mCollidingShapeIndex, sizeof(SoftBodyVertex)) | ||
{ | ||
} | ||
|
||
/// Default assignment | ||
CollideSoftBodyVertexIterator & operator = (const CollideSoftBodyVertexIterator &) = default; | ||
|
||
/// Equality operator. | ||
/// Note: Only used to determine end iterator, so we only compare position. | ||
bool operator != (const CollideSoftBodyVertexIterator &inRHS) const | ||
{ | ||
return mPosition != inRHS.mPosition; | ||
} | ||
|
||
/// Next vertex | ||
CollideSoftBodyVertexIterator & operator ++ () | ||
{ | ||
++mPosition; | ||
++mInvMass; | ||
++mCollisionPlane; | ||
++mLargestPenetration; | ||
++mCollidingShapeIndex; | ||
return *this; | ||
} | ||
|
||
/// Add an offset | ||
/// Note: Only used to determine end iterator, so we only set position. | ||
CollideSoftBodyVertexIterator operator + (int inOffset) const | ||
{ | ||
return CollideSoftBodyVertexIterator(mPosition + inOffset, StridedPtr<const float>(), StridedPtr<Plane>(), StridedPtr<float>(), StridedPtr<int>()); | ||
} | ||
|
||
/// Get the position of the current vertex | ||
Vec3 GetPosition() const | ||
{ | ||
return *mPosition; | ||
} | ||
|
||
/// Get the inverse mass of the current vertex | ||
float GetInvMass() const | ||
{ | ||
return *mInvMass; | ||
} | ||
|
||
/// Update penetration of the current vertex | ||
/// @return Returns true if the vertex has the largest penetration so far, this means you need to follow up by calling SetCollision | ||
bool UpdatePenetration(float inLargestPenetration) const | ||
{ | ||
float &penetration = *mLargestPenetration; | ||
if (penetration >= inLargestPenetration) | ||
return false; | ||
penetration = inLargestPenetration; | ||
return true; | ||
} | ||
|
||
/// Update the collision of the current vertex | ||
void SetCollision(const Plane &inCollisionPlane, int inCollidingShapeIndex) const | ||
{ | ||
*mCollisionPlane = inCollisionPlane; | ||
*mCollidingShapeIndex = inCollidingShapeIndex; | ||
} | ||
|
||
private: | ||
/// Input data | ||
StridedPtr<const Vec3> mPosition; | ||
StridedPtr<const float> mInvMass; | ||
|
||
/// Output data | ||
StridedPtr<Plane> mCollisionPlane; | ||
StridedPtr<float> mLargestPenetration; | ||
StridedPtr<int> mCollidingShapeIndex; | ||
}; | ||
|
||
JPH_NAMESPACE_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.