代码之家  ›  专栏  ›  技术社区  ›  RCIX

Verlet Integration正在炸毁我的物理引擎

  •  5
  • RCIX  · 技术社区  · 16 年前

    我的主要物理体类的更新,应用力,应用脉冲系统:

    public void Update(float timestepLength)
    {
        if (!this._isStatic)
        {
            Vector2 velocity =  Vector2.Subtract(_position, _lastPosition);
            Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength);
            _lastPosition = _position;
            _position = nextPos;
            _acceleration = Vector2.Zero;
        }
    }
    
    public void ApplyForce(Vector2 accelerationValue)
    {
        if (!this._isStatic)
            _acceleration += (accelerationValue) * _mass;
    }
    public void ApplyImpulse(Vector2 impulse)
    {
        if (!this._isStatic)
            _acceleration +=-1 * impulse;
    }
    

    • 脉冲应用代码是否正确,如果不正确,应该是什么?
    • 如何更改position属性,使其设置保持物体的当前速度?

    以下是代码:

    public Vector2 Position
    {
        get { return _position; }
        set { _position = value;}
    }
    public void Update(float timestepLength)
    {
        if (!this._isStatic)
        {
            Vector2 velocity =  Vector2.Subtract(_position, _lastPosition);
            Vector2 velocityChange = Vector2.Subtract(velocity, Vector2.Subtract(_lastPosition, _twoStepsAgoPosition));
            Vector2 nextPos = _position + (_position - _lastPosition) + _acceleration * (timestepLength * timestepLength);
            _twoStepsAgoPosition = _lastPosition;
            _lastPosition = _position;
            _position = nextPos;
            _acceleration = Vector2.Multiply(velocityChange, timestepLength);
        }
    }
    
    public void ApplyForce(Vector2 force)
    {
        if (!this._isStatic)
            _lastPosition -= force;
    }
    public void ApplyImpulse(Vector2 impulse)
    {
        if (!this._isStatic)
            _acceleration +=-1 * impulse;
    }
    
    1 回复  |  直到 16 年前
        1
  •  4
  •   Theraot    9 年前

    作为对他人的参考。..你可能提到的verlet论文是这样的: advanced character physics 由创造杀手的团队制作,是首批基于布娃娃物理学的团队之一

    不管怎样。..他们使用的原始代码是:

     void ParticleSystem::Verlet() {
           for(int i=0; i<NUM_PARTICLES; i++) {
                 Vector3& x = m_x[i];
                 Vector3 temp = x;
                 Vector3& oldx = m_oldx[i];
                 Vector3& a = m_a[i];
                 x += x-oldx+a*fTimeStep*fTimeStep;
                 oldx = temp;
           }
     }
    

    此外,通过这种verlet集成,确保您在整个游戏中使用的时间步长是恒定的。(例如30帧/秒(因此时间步长为1/30)),并且不会波动。如果是这样,你应该使用 time corrected verlet integration 这是什么原因造成的

    编辑:

    问题2的答案:要移动你的位置(不改变速度/加速度),只需将位置更新到新位置,然后作为额外的步骤,将此移动的增量(因此newPosition oldPosition)添加到旧位置,这样它就会相应地更新。

    问题1的答案:冲量是在一段时间内施加在物体上的力。所以你的解决方案是不正确的。脉冲是在X个时间步(或帧)内,用固定的力调用applyForce函数。