Example #1
0
void PhysicsVehicleWheel::transform(Node* node) const
{
    GP_ASSERT(_host);
    GP_ASSERT(_host->_node);

    node->setRotation(_orientation);

    // Use only the component parallel to the defined strut line
    Vector3 strutLine;
    getWheelDirection(&strutLine);
    _host->_node->getMatrix().transformVector(&strutLine);
    Vector3 wheelPos;
    getWheelPos(&wheelPos);
    node->setTranslation(wheelPos + strutLine*(strutLine.dot(_positionDelta) / strutLine.lengthSquared()));
}
Example #2
0
void PhysicsVehicleWheel::getConnectionDefault(Vector3* result) const
{
    // projected strut length
    getWheelDirection(result);
    result->normalize();
    float length = 0.58f * getStrutRestLength();
    *result *= -length;

    // nudge wheel contact point to outer edge of tire for stability
    Vector3 nudge;
    getWheelAxle(&nudge);
    nudge *= nudge.dot(_initialOffset);
    nudge.normalize();
    *result += nudge * 0.068f * getWheelRadius(); // rough-in for tire width

    // offset at bind time
    *result += _initialOffset;
}
Example #3
0
void Wheel::calculateForces(double dt)
{
    f = Vector2D(0, 0);
    force_moment = 0;
    double mu_par, mu_perp;
    switch (state)
    {
    case WheelState::Broken:
        mu_par = mu_broken_friction;
        mu_perp = mu_broken_friction;
        break;
    case WheelState::Braking:
        mu_par = mu_parallel_friction;
        mu_perp = mu_perpendicular_friction;
        break;
    case WheelState::Free:        
    case WheelState::Forward:
    case WheelState::Backward:
    default:
        mu_par = mu_parallel_roll / radius;
        mu_perp = mu_perpendicular_friction;
        break;
    }
    double vl = v.getLength();
    Vector2D w = getWheelDirection();
    double v_par = std::abs(v.scalar(w));
    double v_perp = sqrt(std::abs(vl * vl - v_par * v_par));
    if (v_par > eps) {
        Vector2D f_par = w;
        if (f_par.scalar(v) > 0)
        {
            f_par.mul(-1);
        }
        f_par.mul(distributed_weight * getChangedMu(mu_par));
        if (f_par.getLength() > shaking_koef * v_par * (distributed_weight / G) / dt)
        {
            f_par.setLength(shaking_koef * v_par * (distributed_weight / G) / dt);
        }/**/
        f.add(f_par);
    }
    if (v_perp > eps) {
        Vector2D f_perp = w;
        f_perp.rotate(M_PI / 2);
        if (f_perp.scalar(v) > 0)
        {
            f_perp.mul(-1);
        }
        f_perp.mul(distributed_weight * getChangedMu(mu_perp));
        if (f_perp.getLength() > shaking_koef * v_perp * (distributed_weight / G) / dt)
        {
            f_perp.setLength(shaking_koef * v_perp * (distributed_weight / G) / dt);
        }/**/
        force_moment += 10 * r.cross(f_perp);
        Vector2D p_f_p(f_perp.getLength(), 0);
        if (p_f_p.scalar(v) > 0)
        {
            p_f_p.mul(-1);
        }
        double p_v_perp = std::abs(v.scalar(Vector2D(1, 0)));
        if (p_f_p.getLength() > shaking_koef * p_v_perp * (distributed_weight / G) / dt)
        {
            p_f_p.setLength(shaking_koef * p_v_perp * (distributed_weight / G) / dt);
        }
        f.add(p_f_p);
    }
    if ((state == WheelState::Forward) || (state == WheelState::Backward))
    {
        int force_koef = (state == WheelState::Forward ? 1 : -1);
        Vector2D acc_force = w;
        acc_force.mul((force_koef * distributed_torque / radius));
        f.add(acc_force);
    }
    force_moment += r.cross(f);
}