精简版:
如何正确地将重力添加到我的物理更新中?
详细版本:
我遇到了一个问题,即用于移动球体到平面的通用碰撞算法(在下面发布以供参考)永远不会达到检测到未来碰撞的点。我相信这是由于我的物理更新方式。
我进行了设置,以便只有在确定将来会发生碰撞时,才会将重力应用于对象。因此,在将重力应用于对象之前,首先要进行碰撞检查。但是,由于始终假定未来不会发生任何碰撞,因此永远不会应用重力。想象一个场景,其值为
spherePosition = (0, 5, 0)
sphereVelocity = (2, 0, 0)
sphereRadius = 1
planeOrigin = (0, 0, 0)
planeNormal = (0, 1, 0)
这总是假设球体平行于平面移动。结果,将永远不会应用重力。
我的更新比较简单,比如
mAcceleration = mTotalForces / mMass;
Vector3 translation = (mVelocity * fElapsedTime) + 0.5 * mAcceleration * pow(fElapsedTime, 2);
mVelocity += mAcceleration * fElapsedTime;
所以操作的顺序大致是
int collisionResult = checkCollision(sphere, plane);
if(collisionResult == 2)
{
sphere.applyGravity(); // Just sets "mAcceleration" to (0, -9.81, 0). Which is then removed by my physics update.
}
sphere.update(timeSlice);
说了这么多,我应该什么时候在物理更新循环中对我的对象应用重力以及如何?如果我在碰撞检查之前应用它,那么在碰撞检查期间就没有关系,如果我在之后做,如果将来会有碰撞,我应该如何调整我的更新?
碰撞检查参考:
int IntersectMovingSpherePlane(float sphereRadius, const Vector3& sphereCenter, const Vector3& sphereVelocity, const Vector3& planeNormal,
const Vector3& planeOrigin, float planeD, float &t, Vector3 &q)
{
// Compute distance of sphere center to plane
float dist = Vec3Dot(&planeNormal, &sphereCenter) - planeD;
if (fabs(dist) <= sphereRadius) {
// The sphere is already overlapping the plane. Set time of
// intersection to zero and q to sphere center
t = 0.0f;
q = sphereCenter;
return 0;
} else {
float denom = Vec3Dot(&planeNormal, &sphereVelocity);
if (denom * dist >= 0.0f) {
// No intersection as sphere moving parallel to or away from plane
return 1;
} else {
// Sphere is moving towards the plane
// Use +r in computations if sphere in front of plane, else -r
float r = dist > 0.0f ? sphereRadius : -sphereRadius;
t = (r - dist) / denom;
q = sphereCenter + t * sphereVelocity - sphereRadius * planeNormal;
return 2;
}
}
}