视频游戏中的物理学,对角加速度施加力矩

3
我正在开发一款关于2D顶视车辆游戏的项目。我希望自己管理所有的物理效果。我正在使用这本书:http://www.amazon.fr/Game-Physics-Engine-Development-Commercial-Grade/dp/0123819768 来实现这种物理效果。
目前,我的物理引擎可以处理不同轴上的力。但是在实现旋转的正确模拟方面,我遇到了一些问题。我正在尝试实现一些扭矩以找到角加速度。因此,我实现了一个惯性张量矩阵:
setMass(400.f);
Matrix3 it;
it.setBlockInertiaTensor(Vector3(2, 1, 1), 400);
setInertiaTensor(it);

void setBlockInertiaTensor(const Vector3 &halfSizes, float mass)
{
    Vector3 squares = halfSizes.componentProduct(halfSizes);
    setInertiaTensorCoeffs(0.3f*mass*(squares.y + squares.z),
        0.3f*mass*(squares.x + squares.z),
        0.3f*mass*(squares.x + squares.y));
}

为了施加扭矩,我在汽车的一个点上施加力,并通过叉积找到扭矩:

player->addForceAtBodyPoint(Vector3(-2000, 1000, 0), Vector3(0, 100, 0));

void AObject::addForceAtBodyPoint(const Vector3 &force, const Vector3 &point)
{
    Vector3 pt = getPointInWorldSpace(point);
    addForceAtPoint(force, pt);
}

void AObject::addForceAtPoint(const Vector3 &force,
    const Vector3 &point)
{
    // Convert to coordinates relative to center of mass.
    Vector3 pt = point;
    pt -= _position;

    _forceAccumulate += force;
    _torqueAccumulate += pt % force;
    //std::cout << "torque x " << pt.x << " y " << pt.y  <<  " z "<< pt.z <<  std::endl;
}

Vector3 Vector3::operator%(const Vector3 &vector) const
{
    return Vector3(y*vector.z - z*vector.y,
        z*vector.x - x*vector.z,
        x*vector.y - y*vector.x);
}

取模运算符%是一种交叉乘积运算。

最后,我对所有数据进行整合:

void    Player::integrate(float deltaTime)
{

    addForce(_velocity * -150.0f);

    // Calculate linear acceleration from force inputs.
    _lastFrameAcceleration = _acceleration;
    _lastFrameAcceleration.addScaledVector(_forceAccumulate, _inverseMass);
    // Calculate angular acceleration from torque inputs.
    Vector3 angularAcceleration = _inverseInertiaTensorWorld.transform(_torqueAccumulate);
    // Update linear velocity from acceleration .
    _velocity.addScaledVector(_lastFrameAcceleration, deltaTime);
    // Update angular velocity from  acceleration .
    _rotation.addScaledVector(angularAcceleration, deltaTime);
    // Impose drag.
    _velocity *= pow(_linearDamping, deltaTime);
    _rotation *= pow(_angularDamping, deltaTime);
    // Update linear position.
    _position.addScaledVector(_velocity, deltaTime);
    _position.z = 0;
    // Update angular position
    _orientation.addScaledVector(_rotation, deltaTime);
    // Normalise the orientation, and update the matrice
    calculateWorldLocalData();
    // Clear accumulators.
    clearAccumulator();
}

方向完全不起作用。我对物理学的东西并不是很擅长,所以我认为我误解了扭矩与惯性张量的物理实现...


阅读http://gafferongames.com/game-physics/physics-in-3d/和http://gafferongames.com/game-physics/integration-basics/或许会有所帮助。 - rashmatash
1个回答

1
如果您的游戏是2D俯视图,则只能在Z轴方向上进行旋转,即屏幕内外。因此,您可以简化问题并避免使用3D张量。在这种情况下,在您的汽车类中,我会有一个名为rotation的私有变量。例如:
private:
    double angle;
    double tourque;
public:
    void updateTorque(*some way of passing forces*)
    {
        double total_t = 0;
        for each force
        {
            double t = use cosine and length to point to generate a tourque
            total_t = t + total_t
        }
    }
    void update_angle // place your integration routine here and call once per loop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接