修改水

This commit is contained in:
2026-01-01 22:00:33 +08:00
parent 040a222bd6
commit 9ceffccd39
1800 changed files with 103929 additions and 139495 deletions

View File

@@ -1,5 +1,6 @@
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
using Unity.Mathematics;
using Unity.Collections;
namespace Obi
{
@@ -8,25 +9,34 @@ namespace Obi
public float4 pointA; // point A, expressed as simplex barycentric coords for simplices, as a solver-space position for colliders.
public float4 pointB; // point B, expressed as simplex barycentric coords for simplices, as a solver-space position for colliders.
public float4 normal; // contact normal on bodyB's surface.
public float4 tangent; // contact tangent on bodyB's surface.
public float4 normal;
public float4 tangent;
public float4 bitangent;
public float distance; // distance between bodyA's and bodyB's surface.
public float distance;
public float normalLambda;
public float tangentLambda;
public float bitangentLambda;
public float stickLambda;
public float rollingFrictionImpulse;
float normalLambda;
float tangentLambda;
float bitangentLambda;
float stickLambda;
float rollingFrictionImpulse;
public int bodyA;
public int bodyB;
public float normalInvMassA;
public float tangentInvMassA;
public float bitangentInvMassA;
public float normalInvMassB;
public float tangentInvMassB;
public float bitangentInvMassB;
public double pad0; // padding to ensure correct alignment to 128 bytes.
public int GetParticleCount() { return 2; }
public int GetParticle(int index) { return index == 0 ? bodyA : bodyB; }
public float4 bitangent => math.normalizesafe(new float4(math.cross(normal.xyz, tangent.xyz), 0));
public override string ToString()
{
return bodyA + "," + bodyB;
@@ -40,15 +50,85 @@ namespace Obi
return first;
}
public void CalculateTangent(float4 relativeVelocity)
public float TotalNormalInvMass
{
tangent = math.normalizesafe(relativeVelocity - math.dot(relativeVelocity, normal) * normal);
get { return normalInvMassA + normalInvMassB; }
}
public float SolveAdhesion(float normalMass, float4 posA, float4 posB, float stickDistance, float stickiness, float dt)
public float TotalTangentInvMass
{
get { return tangentInvMassA + tangentInvMassB; }
}
public float TotalBitangentInvMass
{
get { return bitangentInvMassA + bitangentInvMassB; }
}
public void CalculateBasis(float4 relativeVelocity)
{
tangent = math.normalizesafe(relativeVelocity - math.dot(relativeVelocity, normal) * normal);
bitangent = math.normalizesafe(new float4(math.cross(normal.xyz, tangent.xyz),0));
}
public void CalculateContactMassesA(float invMass,
float4 inverseInertiaTensor,
float4 position,
quaternion orientation,
float4 contactPoint,
bool rollingContacts)
{
// initialize inverse linear masses:
normalInvMassA = tangentInvMassA = bitangentInvMassA = invMass;
if (rollingContacts)
{
float4 rA = contactPoint - position;
float4x4 solverInertiaA = BurstMath.TransformInertiaTensor(inverseInertiaTensor, orientation);
normalInvMassA += BurstMath.RotationalInvMass(solverInertiaA, rA, normal);
tangentInvMassA += BurstMath.RotationalInvMass(solverInertiaA, rA, tangent);
bitangentInvMassA += BurstMath.RotationalInvMass(solverInertiaA, rA, bitangent);
}
}
public void CalculateContactMassesB(float invMass,
float4 inverseInertiaTensor,
float4 position,
quaternion orientation,
float4 contactPoint,
bool rollingContacts)
{
// initialize inverse linear masses:
normalInvMassB = tangentInvMassB = bitangentInvMassB = invMass;
if (rollingContacts)
{
float4 rB = contactPoint - position;
float4x4 solverInertiaB = BurstMath.TransformInertiaTensor(inverseInertiaTensor, orientation);
normalInvMassB += BurstMath.RotationalInvMass(solverInertiaB, rB, normal);
tangentInvMassB += BurstMath.RotationalInvMass(solverInertiaB, rB, tangent);
bitangentInvMassB += BurstMath.RotationalInvMass(solverInertiaB, rB, bitangent);
}
}
public void CalculateContactMassesB(in BurstRigidbody rigidbody, in BurstAffineTransform solver2World)
{
float4 rB = solver2World.TransformPoint(pointB) - rigidbody.com;
// initialize inverse linear masses:
normalInvMassB = tangentInvMassB = bitangentInvMassB = rigidbody.inverseMass;
normalInvMassB += BurstMath.RotationalInvMass(rigidbody.inverseInertiaTensor, rB, normal);
tangentInvMassB += BurstMath.RotationalInvMass(rigidbody.inverseInertiaTensor, rB, tangent);
bitangentInvMassB += BurstMath.RotationalInvMass(rigidbody.inverseInertiaTensor, rB, bitangent);
}
public float SolveAdhesion(float4 posA, float4 posB, float stickDistance, float stickiness, float dt)
{
if (normalMass <= 0 || stickDistance <= 0 || stickiness <= 0 || dt <= 0)
if (TotalNormalInvMass <= 0 || stickDistance <= 0 || stickiness <= 0 || dt <= 0)
return 0;
distance = math.dot(posA - posB, normal);
@@ -57,7 +137,7 @@ namespace Obi
float constraint = stickiness * (1 - math.max(distance / stickDistance, 0)) * dt;
// calculate lambda multiplier:
float dlambda = -constraint / normalMass;
float dlambda = -constraint / TotalNormalInvMass;
// accumulate lambda:
float newStickinessLambda = math.min(stickLambda + dlambda, 0);
@@ -69,9 +149,10 @@ namespace Obi
return lambdaChange;
}
public float SolvePenetration(float normalMass, float4 posA, float4 posB, float maxDepenetrationDelta)
public float SolvePenetration(float4 posA, float4 posB, float maxDepenetrationDelta)
{
if (normalMass <= 0)
if (TotalNormalInvMass <= 0)
return 0;
//project position delta to normal vector:
@@ -81,7 +162,7 @@ namespace Obi
float maxProjection = math.max(-distance - maxDepenetrationDelta, 0);
// calculate lambda multiplier:
float dlambda = -(distance + maxProjection) / normalMass;
float dlambda = -(distance + maxProjection) / TotalNormalInvMass;
// accumulate lambda:
float newLambda = math.max(normalLambda + dlambda, 0);
@@ -93,11 +174,11 @@ namespace Obi
return lambdaChange;
}
public float2 SolveFriction(float tangentMass, float bitangentMass, float4 relativeVelocity, float staticFriction, float dynamicFriction, float dt)
public float2 SolveFriction(float4 relativeVelocity, float staticFriction, float dynamicFriction, float dt)
{
float2 lambdaChange = float2.zero;
if (tangentMass <= 0 || bitangentMass <= 0 ||
if (TotalTangentInvMass <= 0 || TotalBitangentInvMass <= 0 ||
(dynamicFriction <= 0 && staticFriction <= 0) || (normalLambda <= 0 && stickLambda <= 0))
return lambdaChange;
@@ -110,7 +191,7 @@ namespace Obi
float staticFrictionCone = normalLambda / dt * staticFriction;
// tangent impulse:
float tangentLambdaDelta = -tangentPosDelta / tangentMass;
float tangentLambdaDelta = -tangentPosDelta / TotalTangentInvMass;
float newTangentLambda = tangentLambda + tangentLambdaDelta;
if (math.abs(newTangentLambda) > staticFrictionCone)
@@ -120,7 +201,7 @@ namespace Obi
tangentLambda = newTangentLambda;
// bitangent impulse:
float bitangentLambdaDelta = -bitangentPosDelta / bitangentMass;
float bitangentLambdaDelta = -bitangentPosDelta / TotalBitangentInvMass;
float newBitangentLambda = bitangentLambda + bitangentLambdaDelta;
if (math.abs(newBitangentLambda) > staticFrictionCone)
@@ -158,6 +239,6 @@ namespace Obi
return rolling_impulse_change;
}
}
}
}
#endif

View File

@@ -10,9 +10,9 @@ namespace Obi
public float4 queryPoint; // point B, expressed as simplex barycentric coords for simplices, as a solver-space position for colliders.
public float4 normal;
public float distance;
public float distanceAlongRay;
public int simplexIndex;
public int queryIndex;
public int pad0; // padding to ensure correct alignment.
}
}
#endif