public unsafe static object CastRay(this IVehicleRaycaster obj, ref OpenTK.Vector3 from, ref OpenTK.Vector3 to, VehicleRaycasterResult result)
 {
     fixed(OpenTK.Vector3 *fromPtr = &from)
     {
         fixed(OpenTK.Vector3 *toPtr = &to)
         {
             return(obj.CastRay(ref *(BulletSharp.Math.Vector3 *)fromPtr, ref *(BulletSharp.Math.Vector3 *)toPtr, result));
         }
     }
 }
Пример #2
0
        private float RayCast(WheelInfo wheel)
        {
            UpdateWheelTransformsWS(wheel, false);

            float depth  = -1;
            float raylen = wheel.SuspensionRestLength + wheel.WheelsRadius;

            Vector3 rayvector = wheel.RaycastInfo.WheelDirectionWS * raylen;
            Vector3 source    = wheel.RaycastInfo.HardPointWS;

            wheel.RaycastInfo.ContactPointWS = source + rayvector;
            Vector3 target = wheel.RaycastInfo.ContactPointWS;

            float param = 0;
            VehicleRaycasterResult rayResults = new VehicleRaycasterResult();

            Debug.Assert(vehicleRaycaster != null);
            object obj = vehicleRaycaster.CastRay(ref source, ref target, rayResults);

            wheel.RaycastInfo.GroundObject = null;

            if (obj != null)
            {
                param = rayResults.DistFraction;
                depth = raylen * rayResults.DistFraction;
                wheel.RaycastInfo.ContactNormalWS = rayResults.HitNormalInWorld;
                wheel.RaycastInfo.IsInContact     = true;

                wheel.RaycastInfo.GroundObject = fixedBody;///@todo for driving on dynamic/movable objects!;
                /////wheel.RaycastInfo.GroundObject = object;

                float hitDistance = param * raylen;
                wheel.RaycastInfo.SuspensionLength = hitDistance - wheel.WheelsRadius;
                //clamp on max suspension travel

                float minSuspensionLength = wheel.SuspensionRestLength - wheel.MaxSuspensionTravelCm * 0.01f;
                float maxSuspensionLength = wheel.SuspensionRestLength + wheel.MaxSuspensionTravelCm * 0.01f;
                if (wheel.RaycastInfo.SuspensionLength < minSuspensionLength)
                {
                    wheel.RaycastInfo.SuspensionLength = minSuspensionLength;
                }
                if (wheel.RaycastInfo.SuspensionLength > maxSuspensionLength)
                {
                    wheel.RaycastInfo.SuspensionLength = maxSuspensionLength;
                }

                wheel.RaycastInfo.ContactPointWS = rayResults.HitPointInWorld;

                float denominator = Vector3.Dot(wheel.RaycastInfo.ContactNormalWS, wheel.RaycastInfo.WheelDirectionWS);

                Vector3 chassis_velocity_at_contactPoint;
                Vector3 relpos = wheel.RaycastInfo.ContactPointWS - RigidBody.CenterOfMassPosition;

                chassis_velocity_at_contactPoint = RigidBody.GetVelocityInLocalPoint(relpos);

                float projVel = Vector3.Dot(wheel.RaycastInfo.ContactNormalWS, chassis_velocity_at_contactPoint);

                if (denominator >= -0.1f)
                {
                    wheel.SuspensionRelativeVelocity     = 0;
                    wheel.ClippedInvContactDotSuspension = 1.0f / 0.1f;
                }
                else
                {
                    float inv = -1.0f / denominator;
                    wheel.SuspensionRelativeVelocity     = projVel * inv;
                    wheel.ClippedInvContactDotSuspension = inv;
                }
            }
            else
            {
                //put wheel info as in rest position
                wheel.RaycastInfo.SuspensionLength   = wheel.SuspensionRestLength;
                wheel.SuspensionRelativeVelocity     = 0.0f;
                wheel.RaycastInfo.ContactNormalWS    = -wheel.RaycastInfo.WheelDirectionWS;
                wheel.ClippedInvContactDotSuspension = 1.0f;
            }

            return(depth);
        }