Repository: godotengine/godot
File: scene/3d/vehicle_body_3d.cpp (C++)

Code before:

	Vector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
	Vector3 source = wheel.m_raycastInfo.m_hardPointWS;
	wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
	const Vector3 &target = wheel.m_raycastInfo.m_contactPointWS;
	source -= wheel.m_wheelRadius * wheel.m_raycastInfo.m_wheelDirectionWS;

	real_t param = real_t(0.);

	PhysicsDirectSpaceState3D::RayResult rr;

	PhysicsDirectSpaceState3D *ss = s->get_space_state();

	PhysicsDirectSpaceState3D::RayParameters ray_params;
	ray_params.from = source;
	ray_params.to = target;
	ray_params.exclude = exclude;
	ray_params.collision_mask = get_collision_mask();

	bool col = ss->intersect_ray(ray_params, rr);

	wheel.m_raycastInfo.m_groundObject = nullptr;

	if (col) {
		param = source.distance_to(rr.position) / source.distance_to(target);
		depth = raylen * param;
		wheel.m_raycastInfo.m_contactNormalWS = rr.normal;

		wheel.m_raycastInfo.m_isInContact = true;
		if (rr.collider) {
			wheel.m_raycastInfo.m_groundObject = Object::cast_to<PhysicsBody3D>(rr.collider);
		}

		real_t hitDistance = param * raylen;
		wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelRadius;
		//clamp on max suspension travel

		real_t minSuspensionLength = wheel.m_suspensionRestLength - wheel.m_maxSuspensionTravelCm * real_t(0.01);
		real_t maxSuspensionLength = wheel.m_suspensionRestLength + wheel.m_maxSuspensionTravelCm * real_t(0.01);
		if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) {
			wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
		}
		if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) {
			wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength;
		}

		wheel.m_raycastInfo.m_contactPointWS = rr.position;

		real_t denominator = wheel.m_raycastInfo.m_contactNormalWS.dot(wheel.m_raycastInfo.m_wheelDirectionWS);

		Vector3 chassis_velocity_at_contactPoint;

Review comment (bug):
The logic here shouldn't be changed. It's safer to first set groundObject to nullptr. Otherwise there's a potential case somewhere below where the raycast returns an invalid collider and the ground object would stay set to the previous one instead of being null.

Code after:
	_update_wheel_transform(wheel, s);

	real_t depth = -1;

	real_t raylen = wheel.m_suspensionRestLength + wheel.m_wheelRadius;

	Vector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
	Vector3 source = wheel.m_raycastInfo.m_hardPointWS;
	wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
	const Vector3 &target = wheel.m_raycastInfo.m_contactPointWS;
	source -= wheel.m_wheelRadius * wheel.m_raycastInfo.m_wheelDirectionWS;

	real_t param = real_t(0.);

	PhysicsDirectSpaceState3D::RayResult rr;

	PhysicsDirectSpaceState3D *ss = s->get_space_state();

	PhysicsDirectSpaceState3D::RayParameters ray_params;
	ray_params.from = source;
	ray_params.to = target;
	ray_params.exclude = exclude;
	ray_params.collision_mask = get_collision_mask();

	wheel.m_raycastInfo.m_groundObject = nullptr;
	bool col = ss->intersect_ray(ray_params, rr);

	if (col) {
		param = source.distance_to(rr.position) / source.distance_to(target);
		depth = raylen * param;
		wheel.m_raycastInfo.m_contactNormalWS = rr.normal;

		wheel.m_raycastInfo.m_isInContact = true;
		if (rr.collider) {
			wheel.m_raycastInfo.m_groundObject = Object::cast_to<PhysicsBody3D>(rr.collider);
		}

		real_t hitDistance = param * raylen;
		wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelRadius;
		//clamp on max suspension travel

		real_t minSuspensionLength = wheel.m_suspensionRestLength - wheel.m_maxSuspensionTravelCm * real_t(0.01);
		real_t maxSuspensionLength = wheel.m_suspensionRestLength + wheel.m_maxSuspensionTravelCm * real_t(0.01);
		if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) {
			wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
		}
		if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength) {
			wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength;
		}

		wheel.m_raycastInfo.m_contactPointWS = rr.position;