22-02-2020, 02:12 AM
I've noticed that collision between ropes and other objects only occurs at the particles' centers. Between two connected particles, there is no collision.
I'm guessing the current collision force is something calculated like this:
However, the code you could use to push two connected particles away from one another is actually fairly similar.
For each pair of segments, you could perform the same math, treating the the two closest points between the two segments as imaginary particles. An imaginary particle would be linear interpolations of position and mass between the two original particles composing the segment. Then after the forces are calculated for the two imaginary particles, they'd similarly be applied to the four original particles:
There may be some considerations about how to distribute the added momentum between the two particles of a line segment if they have different mass, and the force direction isn't perpendicular to the direction of the line segment when the start and endpoints have different radiuses. However, this seems like it'd be a reasonable approximation to start with.
I'm guessing the current collision force is something calculated like this:
Code:
var diffAtoB = (bPos - aPos);
var currentDistance = diffAtoB.magnitude;
var minDistance = aRadius+bRadius;
// If the two particles are too far away, do not add forces.
if(currentDistance >= minDistance) return;
var desiredDiffAtoB = diffAtoB * (minDistance / currentDistance)
var relativeVelocityChange = desiredDiffAtoB - diffAtoB;
var massRatio = bMass / (bMass + aMass);
aVel -= relativeVelocityChange * massRatio;
bVel += relativeVelocityChange * (1-massRatio);
However, the code you could use to push two connected particles away from one another is actually fairly similar.
For each pair of segments, you could perform the same math, treating the the two closest points between the two segments as imaginary particles. An imaginary particle would be linear interpolations of position and mass between the two original particles composing the segment. Then after the forces are calculated for the two imaginary particles, they'd similarly be applied to the four original particles:
Code:
// Construct imaginary particles:
var aRatio = closest point on segmentA, expressed as a ratio between segA's start and end positions;
var bRatio = closest point on segmentB, expressed as a ratio between segB's start and end positions;
var aClosest = closest point on segmentA, segA.startPos * aRatio + segA.endPos * (1-aRatio);
var bClosest = closest point on segmentB, segB.startPos * aRatio + segB.endPos * (1-bRatio);
var aMass, bMass, aRadius, bRadius = linear interpolations of other properties.
// Apply the above code to the imaginary particles.
var aVelOffset, bVelOffset = GetParticleCollisionOffsets(imaginary particles' properties listed above);
// Distribute the velocitiy offsets to the original four particles.
segA.startVel += aVelOffset * aRatio;
segA.endVel += aVelOffset * (1-aRatio);
segB.startVel += bVelOffset * bRatio;
segB.endVel += bVelOffset * (1-bRatio);
There may be some considerations about how to distribute the added momentum between the two particles of a line segment if they have different mass, and the force direction isn't perpendicular to the direction of the line segment when the start and endpoints have different radiuses. However, this seems like it'd be a reasonable approximation to start with.