castRay method

double castRay(
  1. WheelInfo wheel
)

Implementation

double castRay(WheelInfo wheel){
  final rayvector = _castRayRayvector;
  final target = _castRayTarget;

  updateWheelTransformWorld(wheel);
  final chassisBody = this.chassisBody;

  double depth = -1;

  final raylen = wheel.suspensionRestLength + wheel.radius;

  wheel.directionWorld.scale(raylen, rayvector);
  final source = wheel.chassisConnectionPointWorld;
  source.vadd(rayvector, target);
  final raycastResult = wheel.raycastResult;

  //final param = 0;

  raycastResult.reset();
  // Turn off ray collision with the chassis temporarily
  final oldState = chassisBody.collisionResponse;
  chassisBody.collisionResponse = false;

  // Cast ray against world
  world!.rayTest(source, target, raycastResult);
  chassisBody.collisionResponse = oldState;

  final object = raycastResult.body;

  wheel.raycastResult.groundObject = 0;

  if (object != null) {
    depth = raycastResult.distance;
    wheel.raycastResult.hitNormalWorld = raycastResult.hitNormalWorld;
    wheel.isInContact = true;

    final hitDistance = raycastResult.distance;
    wheel.suspensionLength = hitDistance - wheel.radius;

    // clamp on max suspension travel
    final minSuspensionLength = wheel.suspensionRestLength - wheel.maxSuspensionTravel;
    final maxSuspensionLength = wheel.suspensionRestLength + wheel.maxSuspensionTravel;
    if (wheel.suspensionLength < minSuspensionLength) {
      wheel.suspensionLength = minSuspensionLength;
    }
    if (wheel.suspensionLength > maxSuspensionLength) {
      wheel.suspensionLength = maxSuspensionLength;
      wheel.raycastResult.reset();
    }

    final denominator = wheel.raycastResult.hitNormalWorld.dot(wheel.directionWorld);

    //final chassisVelocityAtContactPoint = Vec3();
    chassisBody.getVelocityAtWorldPoint(wheel.raycastResult.hitPointWorld, chassisVelocityAtContactPoint);

    final projVel = wheel.raycastResult.hitNormalWorld.dot(chassisVelocityAtContactPoint);

    if (denominator >= -0.1) {
      wheel.suspensionRelativeVelocity = 0;
      wheel.clippedInvContactDotSuspension = 1 / 0.1;
    } else {
      final inv = -1 / denominator;
      wheel.suspensionRelativeVelocity = projVel * inv;
      wheel.clippedInvContactDotSuspension = inv;
    }
  } else {
    //put wheel info as in rest position
    wheel.suspensionLength = wheel.suspensionRestLength + 0 * wheel.maxSuspensionTravel;
    wheel.suspensionRelativeVelocity = 0.0;
    wheel.directionWorld.scale(-1, wheel.raycastResult.hitNormalWorld);
    wheel.clippedInvContactDotSuspension = 1.0;
  }

  return depth;
}