feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -106,7 +106,7 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont
|
|||
JPH_PROFILE_FUNCTION();
|
||||
|
||||
// Reset flag prior to collision detection
|
||||
mNeedContactCallback = false;
|
||||
mNeedContactCallback.store(false, memory_order_relaxed);
|
||||
|
||||
struct Collector : public CollideShapeBodyCollector
|
||||
{
|
||||
|
|
@ -170,7 +170,7 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont
|
|||
Array<LeafShape> mHits;
|
||||
};
|
||||
LeafShapeCollector collector;
|
||||
body.GetShape()->CollectTransformedShapes(mLocalBounds, com.GetTranslation(), com.GetQuaternion(), Vec3::sReplicate(1.0f), SubShapeIDCreator(), collector, mShapeFilter);
|
||||
body.GetShape()->CollectTransformedShapes(mLocalBounds, com.GetTranslation(), com.GetQuaternion(), Vec3::sOne(), SubShapeIDCreator(), collector, mShapeFilter);
|
||||
if (collector.mHits.empty())
|
||||
return;
|
||||
|
||||
|
|
@ -236,6 +236,7 @@ void SoftBodyMotionProperties::DetermineCollidingShapes(const SoftBodyUpdateCont
|
|||
DefaultBroadPhaseLayerFilter broadphase_layer_filter = inSystem.GetDefaultBroadPhaseLayerFilter(layer);
|
||||
DefaultObjectLayerFilter object_layer_filter = inSystem.GetDefaultLayerFilter(layer);
|
||||
inSystem.GetBroadPhaseQuery().CollideAABox(world_bounds, collector, broadphase_layer_filter, object_layer_filter);
|
||||
mNumSensors = uint(mCollidingSensors.size()); // Workaround for TSAN false positive: store mCollidingSensors.size() in a separate variable.
|
||||
}
|
||||
|
||||
void SoftBodyMotionProperties::DetermineCollisionPlanes(uint inVertexStart, uint inNumVertices)
|
||||
|
|
@ -269,7 +270,7 @@ void SoftBodyMotionProperties::DetermineSensorCollisions(CollidingSensor &ioSens
|
|||
|
||||
// We need a contact callback if one of the sensors collided
|
||||
if (ioSensor.mHasContact)
|
||||
mNeedContactCallback = true;
|
||||
mNeedContactCallback.store(true, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void SoftBodyMotionProperties::ApplyPressure(const SoftBodyUpdateContext &inContext)
|
||||
|
|
@ -315,7 +316,7 @@ void SoftBodyMotionProperties::IntegratePositions(const SoftBodyUpdateContext &i
|
|||
|
||||
// Integrate
|
||||
Vec3 sub_step_gravity = inContext.mGravity * dt;
|
||||
Vec3 sub_step_impulse = GetAccumulatedForce() * dt;
|
||||
Vec3 sub_step_impulse = GetAccumulatedForce() * dt / max(float(mVertices.size()), 1.0f);
|
||||
for (Vertex &v : mVertices)
|
||||
if (v.mInvMass > 0.0f)
|
||||
{
|
||||
|
|
@ -621,7 +622,7 @@ void SoftBodyMotionProperties::ApplyCollisionConstraintsAndUpdateVelocities(cons
|
|||
v.mHasContact = true;
|
||||
|
||||
// We need a contact callback if one of the vertices collided
|
||||
mNeedContactCallback = true;
|
||||
mNeedContactCallback.store(true, memory_order_relaxed);
|
||||
|
||||
// Note that we already calculated the velocity, so this does not affect the velocity (next iteration starts by setting previous position to current position)
|
||||
CollidingShape &cs = mCollidingShapes[v.mCollidingShapeIndex];
|
||||
|
|
@ -720,7 +721,7 @@ void SoftBodyMotionProperties::UpdateSoftBodyState(SoftBodyUpdateContext &ioCont
|
|||
JPH_PROFILE_FUNCTION();
|
||||
|
||||
// Contact callback
|
||||
if (mNeedContactCallback && ioContext.mContactListener != nullptr)
|
||||
if (mNeedContactCallback.load(memory_order_relaxed) && ioContext.mContactListener != nullptr)
|
||||
{
|
||||
// Remove non-colliding sensors from the list
|
||||
for (int i = int(mCollidingSensors.size()) - 1; i >= 0; --i)
|
||||
|
|
@ -765,7 +766,7 @@ void SoftBodyMotionProperties::UpdateSoftBodyState(SoftBodyUpdateContext &ioCont
|
|||
|
||||
// Calculate linear/angular velocity of the body by averaging all vertices and bringing the value to world space
|
||||
float num_vertices_divider = float(max(int(mVertices.size()), 1));
|
||||
SetLinearVelocity(ioContext.mCenterOfMassTransform.Multiply3x3(linear_velocity / num_vertices_divider));
|
||||
SetLinearVelocityClamped(ioContext.mCenterOfMassTransform.Multiply3x3(linear_velocity / num_vertices_divider));
|
||||
SetAngularVelocity(ioContext.mCenterOfMassTransform.Multiply3x3(angular_velocity / num_vertices_divider));
|
||||
|
||||
if (mUpdatePosition)
|
||||
|
|
@ -877,7 +878,7 @@ SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelDetermineCol
|
|||
// Process collision planes
|
||||
uint num_vertices_to_process = min(SoftBodyUpdateContext::cVertexCollisionBatch, num_vertices - next_vertex);
|
||||
DetermineCollisionPlanes(next_vertex, num_vertices_to_process);
|
||||
uint vertices_processed = ioContext.mNumCollisionVerticesProcessed.fetch_add(SoftBodyUpdateContext::cVertexCollisionBatch, memory_order_release) + num_vertices_to_process;
|
||||
uint vertices_processed = ioContext.mNumCollisionVerticesProcessed.fetch_add(SoftBodyUpdateContext::cVertexCollisionBatch, memory_order_acq_rel) + num_vertices_to_process;
|
||||
if (vertices_processed >= num_vertices)
|
||||
{
|
||||
// Determine next state
|
||||
|
|
@ -896,19 +897,18 @@ SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelDetermineCol
|
|||
SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelDetermineSensorCollisions(SoftBodyUpdateContext &ioContext)
|
||||
{
|
||||
// Do a relaxed read to see if there are more sensors to process
|
||||
uint num_sensors = (uint)mCollidingSensors.size();
|
||||
if (ioContext.mNextSensorIndex.load(memory_order_relaxed) < num_sensors)
|
||||
if (ioContext.mNextSensorIndex.load(memory_order_relaxed) < mNumSensors)
|
||||
{
|
||||
// Fetch next sensor to process
|
||||
uint sensor_index = ioContext.mNextSensorIndex.fetch_add(1, memory_order_acquire);
|
||||
if (sensor_index < num_sensors)
|
||||
if (sensor_index < mNumSensors)
|
||||
{
|
||||
// Process this sensor
|
||||
DetermineSensorCollisions(mCollidingSensors[sensor_index]);
|
||||
|
||||
// Determine next state
|
||||
uint sensors_processed = ioContext.mNumSensorsProcessed.fetch_add(1, memory_order_release) + 1;
|
||||
if (sensors_processed >= num_sensors)
|
||||
uint sensors_processed = ioContext.mNumSensorsProcessed.fetch_add(1, memory_order_acq_rel) + 1;
|
||||
if (sensors_processed >= mNumSensors)
|
||||
StartFirstIteration(ioContext);
|
||||
return EStatus::DidWork;
|
||||
}
|
||||
|
|
@ -961,7 +961,7 @@ SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelApplyConstra
|
|||
ProcessGroup(ioContext, next_group);
|
||||
|
||||
// Increment total number of groups processed
|
||||
num_groups_processed = ioContext.mNumConstraintGroupsProcessed.fetch_add(1, memory_order_relaxed) + 1;
|
||||
num_groups_processed = ioContext.mNumConstraintGroupsProcessed.fetch_add(1, memory_order_acq_rel) + 1;
|
||||
}
|
||||
|
||||
if (num_groups_processed >= num_groups)
|
||||
|
|
@ -981,7 +981,7 @@ SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelApplyConstra
|
|||
StartNextIteration(ioContext);
|
||||
|
||||
// Reset group logic
|
||||
ioContext.mNumConstraintGroupsProcessed.store(0, memory_order_relaxed);
|
||||
ioContext.mNumConstraintGroupsProcessed.store(0, memory_order_release);
|
||||
ioContext.mNextConstraintGroup.store(0, memory_order_release);
|
||||
}
|
||||
else
|
||||
|
|
@ -1002,7 +1002,7 @@ SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelApplyConstra
|
|||
|
||||
SoftBodyMotionProperties::EStatus SoftBodyMotionProperties::ParallelUpdate(SoftBodyUpdateContext &ioContext, const PhysicsSettings &inPhysicsSettings)
|
||||
{
|
||||
switch (ioContext.mState.load(memory_order_relaxed))
|
||||
switch (ioContext.mState.load(memory_order_acquire))
|
||||
{
|
||||
case SoftBodyUpdateContext::EState::DetermineCollisionPlanes:
|
||||
return ParallelDetermineCollisionPlanes(ioContext);
|
||||
|
|
|
|||
|
|
@ -286,10 +286,11 @@ private:
|
|||
AABox mLocalBounds; ///< Bounding box of all vertices
|
||||
AABox mLocalPredictedBounds; ///< Predicted bounding box for all vertices using extrapolation of velocity by last step delta time
|
||||
uint32 mNumIterations; ///< Number of solver iterations
|
||||
uint mNumSensors; ///< Workaround for TSAN false positive: store mCollidingSensors.size() in a separate variable.
|
||||
float mPressure; ///< n * R * T, amount of substance * ideal gas constant * absolute temperature, see https://en.wikipedia.org/wiki/Pressure
|
||||
float mSkinnedMaxDistanceMultiplier = 1.0f; ///< Multiplier applied to Skinned::mMaxDistance to allow tightening or loosening of the skin constraints
|
||||
bool mUpdatePosition; ///< Update the position of the body while simulating (set to false for something that is attached to the static world)
|
||||
bool mNeedContactCallback = false; ///< True if the soft body has collided with anything in the last update
|
||||
atomic<bool> mNeedContactCallback = false; ///< True if the soft body has collided with anything in the last update
|
||||
bool mEnableSkinConstraints = true; ///< If skin constraints are enabled
|
||||
bool mSkinStatePreviousPositionValid = false; ///< True if the skinning was updated in the last update so that the previous position of the skin state is valid
|
||||
};
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@ void SoftBodyShape::sRegister()
|
|||
{
|
||||
CollisionDispatch::sRegisterCollideShape(s, EShapeSubType::SoftBody, sCollideConvexVsSoftBody);
|
||||
CollisionDispatch::sRegisterCastShape(s, EShapeSubType::SoftBody, sCastConvexVsSoftBody);
|
||||
|
||||
CollisionDispatch::sRegisterCollideShape(EShapeSubType::SoftBody, s, CollisionDispatch::sReversedCollideShape);
|
||||
CollisionDispatch::sRegisterCastShape(EShapeSubType::SoftBody, s, CollisionDispatch::sReversedCastShape);
|
||||
}
|
||||
|
||||
// Specialized collision functions
|
||||
|
|
|
|||
|
|
@ -541,6 +541,10 @@ void SoftBodySharedSettings::Optimize(OptimizationResults &outResults)
|
|||
if (group_idx[i] == -1)
|
||||
bounds.Encapsulate(Vec3(mVertices[i].mPosition));
|
||||
|
||||
// If the bounds are invalid, it means that there were no ungrouped vertices
|
||||
if (!bounds.IsValid())
|
||||
break;
|
||||
|
||||
// Determine longest and shortest axis
|
||||
Vec3 bounds_size = bounds.GetSize();
|
||||
uint max_axis = bounds_size.GetHighestComponentIndex();
|
||||
|
|
@ -1029,4 +1033,147 @@ SoftBodySharedSettings::SettingsResult SoftBodySharedSettings::sRestoreWithMater
|
|||
return result;
|
||||
}
|
||||
|
||||
Ref<SoftBodySharedSettings> SoftBodySharedSettings::sCreateCube(uint inGridSize, float inGridSpacing)
|
||||
{
|
||||
const Vec3 cOffset = Vec3::sReplicate(-0.5f * inGridSpacing * (inGridSize - 1));
|
||||
|
||||
// Create settings
|
||||
SoftBodySharedSettings *settings = new SoftBodySharedSettings;
|
||||
for (uint z = 0; z < inGridSize; ++z)
|
||||
for (uint y = 0; y < inGridSize; ++y)
|
||||
for (uint x = 0; x < inGridSize; ++x)
|
||||
{
|
||||
SoftBodySharedSettings::Vertex v;
|
||||
(cOffset + Vec3::sReplicate(inGridSpacing) * Vec3(float(x), float(y), float(z))).StoreFloat3(&v.mPosition);
|
||||
settings->mVertices.push_back(v);
|
||||
}
|
||||
|
||||
// Function to get the vertex index of a point on the cube
|
||||
auto vertex_index = [inGridSize](uint inX, uint inY, uint inZ)
|
||||
{
|
||||
return inX + inY * inGridSize + inZ * inGridSize * inGridSize;
|
||||
};
|
||||
|
||||
// Create edges
|
||||
for (uint z = 0; z < inGridSize; ++z)
|
||||
for (uint y = 0; y < inGridSize; ++y)
|
||||
for (uint x = 0; x < inGridSize; ++x)
|
||||
{
|
||||
SoftBodySharedSettings::Edge e;
|
||||
e.mVertex[0] = vertex_index(x, y, z);
|
||||
if (x < inGridSize - 1)
|
||||
{
|
||||
e.mVertex[1] = vertex_index(x + 1, y, z);
|
||||
settings->mEdgeConstraints.push_back(e);
|
||||
}
|
||||
if (y < inGridSize - 1)
|
||||
{
|
||||
e.mVertex[1] = vertex_index(x, y + 1, z);
|
||||
settings->mEdgeConstraints.push_back(e);
|
||||
}
|
||||
if (z < inGridSize - 1)
|
||||
{
|
||||
e.mVertex[1] = vertex_index(x, y, z + 1);
|
||||
settings->mEdgeConstraints.push_back(e);
|
||||
}
|
||||
}
|
||||
settings->CalculateEdgeLengths();
|
||||
|
||||
// Tetrahedrons to fill a cube
|
||||
const int tetra_indices[6][4][3] = {
|
||||
{ {0, 0, 0}, {0, 1, 1}, {0, 0, 1}, {1, 1, 1} },
|
||||
{ {0, 0, 0}, {0, 1, 0}, {0, 1, 1}, {1, 1, 1} },
|
||||
{ {0, 0, 0}, {0, 0, 1}, {1, 0, 1}, {1, 1, 1} },
|
||||
{ {0, 0, 0}, {1, 0, 1}, {1, 0, 0}, {1, 1, 1} },
|
||||
{ {0, 0, 0}, {1, 1, 0}, {0, 1, 0}, {1, 1, 1} },
|
||||
{ {0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {1, 1, 1} }
|
||||
};
|
||||
|
||||
// Create volume constraints
|
||||
for (uint z = 0; z < inGridSize - 1; ++z)
|
||||
for (uint y = 0; y < inGridSize - 1; ++y)
|
||||
for (uint x = 0; x < inGridSize - 1; ++x)
|
||||
for (uint t = 0; t < 6; ++t)
|
||||
{
|
||||
SoftBodySharedSettings::Volume v;
|
||||
for (uint i = 0; i < 4; ++i)
|
||||
v.mVertex[i] = vertex_index(x + tetra_indices[t][i][0], y + tetra_indices[t][i][1], z + tetra_indices[t][i][2]);
|
||||
settings->mVolumeConstraints.push_back(v);
|
||||
}
|
||||
|
||||
settings->CalculateVolumeConstraintVolumes();
|
||||
|
||||
// Create faces
|
||||
for (uint y = 0; y < inGridSize - 1; ++y)
|
||||
for (uint x = 0; x < inGridSize - 1; ++x)
|
||||
{
|
||||
SoftBodySharedSettings::Face f;
|
||||
|
||||
// Face 1
|
||||
f.mVertex[0] = vertex_index(x, y, 0);
|
||||
f.mVertex[1] = vertex_index(x, y + 1, 0);
|
||||
f.mVertex[2] = vertex_index(x + 1, y + 1, 0);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(x + 1, y + 1, 0);
|
||||
f.mVertex[2] = vertex_index(x + 1, y, 0);
|
||||
settings->AddFace(f);
|
||||
|
||||
// Face 2
|
||||
f.mVertex[0] = vertex_index(x, y, inGridSize - 1);
|
||||
f.mVertex[1] = vertex_index(x + 1, y + 1, inGridSize - 1);
|
||||
f.mVertex[2] = vertex_index(x, y + 1, inGridSize - 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(x + 1, y, inGridSize - 1);
|
||||
f.mVertex[2] = vertex_index(x + 1, y + 1, inGridSize - 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
// Face 3
|
||||
f.mVertex[0] = vertex_index(x, 0, y);
|
||||
f.mVertex[1] = vertex_index(x + 1, 0, y + 1);
|
||||
f.mVertex[2] = vertex_index(x, 0, y + 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(x + 1, 0, y);
|
||||
f.mVertex[2] = vertex_index(x + 1, 0, y + 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
// Face 4
|
||||
f.mVertex[0] = vertex_index(x, inGridSize - 1, y);
|
||||
f.mVertex[1] = vertex_index(x, inGridSize - 1, y + 1);
|
||||
f.mVertex[2] = vertex_index(x + 1, inGridSize - 1, y + 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(x + 1, inGridSize - 1, y + 1);
|
||||
f.mVertex[2] = vertex_index(x + 1, inGridSize - 1, y);
|
||||
settings->AddFace(f);
|
||||
|
||||
// Face 5
|
||||
f.mVertex[0] = vertex_index(0, x, y);
|
||||
f.mVertex[1] = vertex_index(0, x, y + 1);
|
||||
f.mVertex[2] = vertex_index(0, x + 1, y + 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(0, x + 1, y + 1);
|
||||
f.mVertex[2] = vertex_index(0, x + 1, y);
|
||||
settings->AddFace(f);
|
||||
|
||||
// Face 6
|
||||
f.mVertex[0] = vertex_index(inGridSize - 1, x, y);
|
||||
f.mVertex[1] = vertex_index(inGridSize - 1, x + 1, y + 1);
|
||||
f.mVertex[2] = vertex_index(inGridSize - 1, x, y + 1);
|
||||
settings->AddFace(f);
|
||||
|
||||
f.mVertex[1] = vertex_index(inGridSize - 1, x + 1, y);
|
||||
f.mVertex[2] = vertex_index(inGridSize - 1, x + 1, y + 1);
|
||||
settings->AddFace(f);
|
||||
}
|
||||
|
||||
// Optimize the settings
|
||||
settings->Optimize();
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ public:
|
|||
/// Restore a shape and materials. Pass in an empty map in ioSettingsMap / ioMaterialMap or reuse the same map while reading multiple settings objects from the same stream in order to restore duplicates.
|
||||
static SettingsResult sRestoreWithMaterials(StreamIn &inStream, IDToSharedSettingsMap &ioSettingsMap, IDToMaterialMap &ioMaterialMap);
|
||||
|
||||
/// Create a cube. This can be used to create a simple soft body for testing purposes.
|
||||
/// It will contain edge constraints, volume constraints and faces.
|
||||
/// @param inGridSize Number of points along each axis
|
||||
/// @param inGridSpacing Distance between points
|
||||
static Ref<SoftBodySharedSettings> sCreateCube(uint inGridSize, float inGridSpacing);
|
||||
|
||||
/// A vertex is a particle, the data in this structure is only used during creation of the soft body and not during simulation
|
||||
struct JPH_EXPORT Vertex
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue