この質問には、1 つの大きな質問と 1 つの小さな質問があります。私は自分の研究からどちらの質問でも正しいと信じていますが、両方ではありません。
私の物理ループでは、最初にTotalForce
剛体オブジェクトに重力を適用します。TotalForce
次に、 myと myを使用して衝突をチェックしVelocity
ます。Myは物理ループごとに にTotalForce
リセットされますが、 .(0, 0, 0)
velocity
速度のみを使用する場合に、移動する球体と静的平面の間の衝突チェックを行うことに慣れています。velocity
しかし、重力など、以外の力がある場合はどうなるでしょうか。他の力を入れましたTotalForces
(今は重力しかありません)。それを補うために、球が現在平面に重なっていないと判断した場合は、
Vector3 forces = (sphereTotalForces + sphereVelocity);
Vector3 forcesDT = forces * fElapsedTime;
float denom = Vec3Dot(&plane->GetNormal(), &forces);
ただし、これは、連絡を取り合っていると私が思っていた方法にとって問題になる可能性があります。安静時の接触は次のように計算されたと思いました
denom * dist == 0.0f
どこdist
ですか
float dist = Vec3Dot(&plane->GetNormal(), &spherePosition) - plane->d;
(参考までにdenom * dist > 0.0f
、球が平面から離れているという明白な意味)
ただし、これは決して真実ではありません。「安静時の接触」があるように見える場合でも。これは、forces
上記の私の計算では常に少なくとも .y が -9.8 (私の重力) であるためです。法線が (0, 1, 0) の平面に向かって移動するとdenom
、-9.8 の y が生成されます。
私の質問は
1) 最初の 2 つのコード スニペットで述べた方法で、静止接触を正しく計算していますか?
もしそうなら、
2) 重力などの「その他の力」はどのように使用すればよいですか? 私の使い方はTotalForces
間違っていますか?
参考までに、私のタイムステップは
mAcceleration = mTotalForces / mMass;
mVelocity += mAcceleration * fElapsedTime;
Vector3 translation = (mVelocity * fElapsedTime);
編集
いくつかの提案された変更が衝突コードを変更するように見えるので、衝突状態を検出する方法は次のとおりです
if(fabs(dist) <= sphereRadius)
{ // There already is a collision }
else
{
Vector3 forces = (sphereTotalForces + sphereVelocity);
float denom = Vec3Dot(&plane->GetNormal(), &forces);
// Resting contact
if(dist == 0) { }
// Sphere is moving away from plane
else if(denom * dist > 0.0f) { }
// There will eventually be a collision
else
{
float fIntersectionTime = (sphereRadius - dist) / denom;
float r;
if(dist > 0.0f)
r = sphereRadius;
else
r = -sphereRadius;
Vector3 collisionPosition = spherePosition + fIntersectionTime * sphereVelocity - r * planeNormal;
}
}