コード例 #1
0
        private void updateCameraCommon()
        {
            speedCoeff = MathR.Max(veh.Speed, veh.Velocity.Magnitude() * 0.045454f);
            pointAt    = veh.Position + fullHeightOffset + (veh.ForwardVector * computeLookFrontOffset(speedCoeff, script.smoothIsInAir));

            fullLongitudeOffset = (distanceOffset + currentVehicleLongitudeOffset) /* + vehDummyOffset*/ + towedVehicleLongitude;

            finalDummyOffset = MathR.Lerp(vehDummyOffset, vehDummyOffsetHighSpeed, speedCoeff / (maxHighSpeed * 1.6f));

            // no offset if car is in the air
            finalDummyOffset = MathR.Lerp(finalDummyOffset, 0f, script.smoothIsInAir);

            currentDistanceIncrement = 0f;

            if (increaseDistanceAtHighSpeed)
            {
                var factor = veh.Speed / maxHighSpeed;
                currentDistanceIncrement = MathR.Lerp(0f, maxHighSpeedDistanceIncrement, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Cubic : EasingType.Linear));
            }

            if (accelerationAffectsCamDistance)
            {
                var factor = getVehicleAcceleration() / (maxHighSpeed * 10f);
                currentDistanceIncrement += MathR.Lerp(0f, accelerationCamDistanceMultiplier, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Quadratic : EasingType.Linear));
            }
        }
コード例 #2
0
        private float getFixedVsVelocityFactor(float speedCoeff)
        {
            // If the car isn't moving, default to looking forwards
            if (veh.Velocity.Magnitude() < nearlySttopedSpeed)
            {
                return(0f);
            }
            else
            {
                // for bikes, always look at velocity
                if (isCycleOrByke)
                {
                    return(1f);
                }

                // if veh is in air, look at is velocity
                if (veh.IsInAir || veh.CurrentGear == 0)
                {
                    return(1f);
                }
                else // if is on the ground. fit camera (mostly) behind vehicle (for better drift control)
                {
                    // Different factors for low/high speed
                    return(MathR.Lerp(velocityInfluenceLowSpeed, velocityInfluence, MathR.Clamp(speedCoeff / lowSpeedLimit, 0f, 1f)));
                }
            }
        }
コード例 #3
0
        public void PointAt(Vector3 target)
        {
            var res = MathR.LookAt(position, target);

            quaternion = res;
            rotation   = res.ToEulerAngles();
        }
コード例 #4
0
        public static Quaternion XLookRotation(Vector3 direction, Vector3 up)
        {
            Quaternion rightToForward  = Quaternion.Euler(0f, 90f, 0f);
            Quaternion forwardToTarget = MathR.LookRotationInternalY(direction, up);

            return(forwardToTarget * rightToForward);
        }
コード例 #5
0
 private void updateCameraCommon()
 {
     smoothIsInAir    = MathR.Lerp(smoothIsInAir, veh.IsInAir || veh.IsUpsideDown ? 1f : 0f, 2f * getDeltaTime());
     smoothIsRearGear = MathR.Lerp(smoothIsRearGear, veh.CurrentGear == 0 ? 1f : 0f, 1.3f * getDeltaTime());
     //speedCoeff = MathR.Max(veh.Speed, veh.Velocity.Magnitude() * 0.045454f);
     //pointAt = veh.Position + fullHeightOffset + (veh.ForwardVector * computeLookFrontOffset(veh, speedCoeff, smoothIsInAir));
 }
コード例 #6
0
        public static float LerpAngle(float a, float b, float t)
        {
            float num = MathR.Repeat(b - a, 360f);

            if ((double)num > 180.0)
            {
                num -= 360f;
            }
            return(a + num * MathR.Clamp01(t));
        }
コード例 #7
0
        private Quaternion getRotationFromAverageWheelPosBike()
        {
            // Front
            var fPos = veh.GetBoneCoord("wheel_lf");

            // Rear
            var rPos = veh.GetBoneCoord("wheel_lr");

            var dir = fPos - rPos;

            return MathR.XLookRotation(dir);
        }
コード例 #8
0
        private float computeLookFrontOffset(float speedCoeff, float smoothIsInAir)
        {
            var speed = speedCoeff;

            var factor = MathR.InverseLerp(lookLowSpeedStart, lookLowSpeedEnd, speedCoeff);

            var res = MathR.Lerp(lookFrontOffsetLowSpeed, lookFrontOffset, factor);

            // No offset while in air
            res = MathR.Lerp(res, 0f, script.smoothIsInAir);

            return(res);
        }
コード例 #9
0
        public static Quaternion QuaternionFromMatrix(Matrix m)
        {
            // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
            Quaternion q = new Quaternion();

            q.W  = MathR.Sqrt(MathR.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2;
            q.X  = MathR.Sqrt(MathR.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2;
            q.Y  = MathR.Sqrt(MathR.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2;
            q.Z  = MathR.Sqrt(MathR.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2;
            q.X *= MathR.Sign(q.X * (m[2, 1] - m[1, 2]));
            q.Y *= MathR.Sign(q.Y * (m[0, 2] - m[2, 0]));
            q.Z *= MathR.Sign(q.Z * (m[1, 0] - m[0, 1]));
            return(q);
        }
コード例 #10
0
        public void updateCameraCommon()
        {
            fullLongitudeOffset = distanceOffset + currentVehicleLongitudeOffset + towedVehicleLongitude;

            currentDistanceIncrement = 0f;

            if (increaseDistanceAtHighSpeed)
            {
                var factor = veh.Speed / maxHighSpeed;
                currentDistanceIncrement = MathR.Lerp(0f, maxHighSpeedDistanceIncrement, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Cubic : EasingType.Linear));
            }

            if (accelerationAffectsCamDistance)
            {
                var factor = getVehicleAcceleration() / (maxHighSpeed * 10f);
                currentDistanceIncrement += MathR.Lerp(0f, accelerationCamDistanceMultiplier, Easing.EaseOut(factor, useEasingForCamDistance ? EasingType.Quadratic : EasingType.Linear));
            }
        }
コード例 #11
0
        private Quaternion getSurfaceNormalRotation()
        {
            frameCounter++;
            bool proccess = frameCounter % 3 == 0; // Only proccess every 3 frames (Raycast seems to be slow on SHVDN)
            frameCounter = frameCounter % 9;

            if(proccess)
            {
                var raycast = World.Raycast(veh.Position, Vector3.WorldDown, 2f, IntersectOptions.Map, veh);

                if (raycast.DitHitAnything)
                {
                    cachedRaycastDir = MathR.OrthoNormalize(raycast.SurfaceNormal, veh.ForwardVector);
                    //cachedRaycastDir = Vector3.Cross(raycast.SurfaceNormal, veh.RightVector).Normalized;
                }
            }

            return MathR.XLookRotation(cachedRaycastDir);
        }
コード例 #12
0
        private Quaternion getRotationFromAverageWheelPosCar()
        {
            // Front Left
            var flPos = veh.GetBoneCoord("wheel_lf");

            // Front Right
            var frPos = veh.GetBoneCoord("wheel_rf");

            var frontAverage = (flPos + frPos) * 0.5f;

            // Rear Left
            var rlPos = veh.GetBoneCoord("wheel_lr");

            // Rear Right
            var rrPos = veh.GetBoneCoord("wheel_rr");

            var rearAverage = (rlPos + rrPos) * 0.5f;

            var dir = frontAverage - rearAverage;

            return MathR.XLookRotation(dir);
        }
コード例 #13
0
 public static float Repeat(float t, float length)
 {
     return(t - MathR.Floor(t / length) * length);
 }
コード例 #14
0
        private Transform UpdateCameraRear()
        {
            // smooth out current rotation and position
            currentRotation = MathR.EulerNlerp(currentRotation, rearCamCurrentTransform.quaternion, (responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime());
            currentPos      = Vector3.Lerp(currentPos, rearCamCurrentTransform.position, MathR.Clamp01((responsivenessMultiplier * generalMovementSpeed) * Time.getDeltaTime()));

            Quaternion look;

            var wantedPos = veh.Position + (veh.ForwardVector * finalDummyOffset);

            // If veh has towed vehicle, increase camera distance by towed vehicle longitude

            // should camera be attached to vehicle's back or back his velocity
            var fixedVsVelocity = getFixedVsVelocityFactor(speedCoeff);

            Quaternion vehQuat = veh.Quaternion;

            // Compute camera position rear the vechicle
            var wantedPosFixed = wantedPos - veh.Quaternion * Vector3.RelativeFront * fullLongitudeOffset;

            // smooth out velocity

            // Compute camera postition rear the direction of the vehcle
            if (speedCoeff >= stoppedSpeed)
            {
                wantedPosVelocity = wantedPos + MathR.QuaternionLookRotation(smoothVelocity) * Vector3.RelativeBottom * fullLongitudeOffset;
            }

            // Smooth factor between two above cam positions
            smoothFixedVsVelocity = MathR.Lerp(smoothFixedVsVelocity, fixedVsVelocity, (fixedVsVelocitySpeed) * Time.getDeltaTime());

            if (!isCycleOrByke)
            {
                tempSmoothVsVl        = MathR.Lerp(tempSmoothVsVl, MathR.Clamp(speedCoeff * 0.4347826f, 0.025f, 1f), (fixedVsVelocitySpeed * 0.05f));
                smoothFixedVsVelocity = MathR.Lerp(0f, smoothFixedVsVelocity, tempSmoothVsVl);
            }

            wantedPos = Vector3.Lerp(wantedPosFixed, wantedPosVelocity, MathR.Clamp01(smoothFixedVsVelocity));

            //currentPos = Vector3.Lerp(currentPos, wantedPos, Mathr.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime()));
            currentPos = Vector3.Lerp(currentPos, wantedPos, MathR.Clamp01((responsivenessMultiplier * cameraStickiness) * Time.getDeltaTime()));

            //rearCamCurrentTransform.position = currentPos;
            targetCamera.PointAt(pointAt);
            look = Quaternion.Euler(targetCamera.Rotation);

            // Rotate the camera towards the velocity vector.
            var finalCamRotationSpeed = MathR.Lerp(cameraRotationSpeedLowSpeed, cameraRotationSpeed, ((speedCoeff / lowSpeedLimit) * 1.32f) * Time.getDeltaTime() * 51f);

            look = MathR.EulerNlerp(currentRotation, look, (1.8f * finalCamRotationSpeed) * Time.getDeltaTime());


            // Fix stuttering (mantain camera distance fixed in local space)
            Transform fixedDistanceTr = new Transform(currentPos + fullHeightOffset + (Vector3.WorldUp * extraCamHeight), Quaternion.Identity);

            fixedDistanceTr.PointAt(pointAt);

            Quaternion finalQuat = fixedDistanceTr.quaternion;

            if (script.isMouseLooking)
            {
                finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking);
            }

            fixedDistanceTr.position = veh.Position + fullHeightOffset + (Vector3.WorldUp * extraCamHeight) + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + currentDistanceIncrement));

            //fixedDistanceTr.position = fixedDistanceTr.position + fullHeightOffset;

            var transform = new Transform();

            transform.position = fixedDistanceTr.position;
            //transform.position = currentPos + fullHeightOffset;
            transform.rotation   = look.ToEulerAngles();
            transform.quaternion = look;

            rearCamCurrentTransform = transform;

            return(transform);
        }
コード例 #15
0
 public static float Lerp(float value1, float value2, float ammount)
 {
     return(value1 + (value2 - value1) * MathR.Clamp01(ammount));
 }
コード例 #16
0
 // Cheaper than Slerp
 public static Quaternion EulerNlerp(Quaternion start, Quaternion end, float ammount)
 {
     return(QuaternionFromEuler(Vector3.Lerp(start.ToEulerAngles(), end.ToEulerAngles(), MathR.Clamp01(ammount)).Normalized));
 }
コード例 #17
0
        public override void updateCamera()
        {
            base.updateCamera();

            updateCameraCommon();

            var camExtraHeightV3 = Vector3.WorldUp * extraCamHeight;

            var posCenter = veh.Position + fullHeightOffset;

            float rotSpeed = rotationSpeed;
            if(useVariableRotSpeed)
            {
                var desiredRootSpeed = MathR.SmoothStep(minRotSpeed, maxRotSpeed, MathR.Clamp01(AngleInDeg(veh.ForwardVector, veh.Velocity) / 90));
                currentRootSpeed = MathR.Lerp(currentRootSpeed, desiredRootSpeed, 2f * Time.getDeltaTime());
            }

            if (veh.Speed > 1f)
            {
                //velQuat = MathR.LookRotation(veh.Velocity, Vector3.WorldUp);
                velocityQuat = MathR.XLookRotation(smoothVelocity);
            }

            Quaternion vehQuat;

            if(isCycleOrByke)
            {
                // Bykes / cycles (avoid unwanted cam rotations during wheelies/stoppies)
                if (veh.Speed < 3f)
                {
                    if(veh.IsOnAllWheels)
                        vehQuat = getRotationFromAverageWheelPosBike();
                    else
                        vehQuat = getSurfaceNormalRotation(); // Possibly unperformant (using it only for wheelie/stoppie al low speeds)
                }
                else
                    vehQuat = velocityQuat;
            }
            else // cars
            {
                if(avoidCameraBouncinessCar && veh.IsOnAllWheels)
                {
                    vehQuat = getRotationFromAverageWheelPosCar(); // Avoid camera movements caused by car suspension movement (wheels are on the floor)
                }
                else
                {
                    vehQuat = veh.Quaternion;
                }    
            }

            //smoothQuat = MathR.QuatNlerp(smoothQuat, veh.Quaternion, MathR.Clamp01(rotationSpeed * Time.getDeltaTime()));
            smoothQuat = Quaternion.SlerpUnclamped(smoothQuat, vehQuat, rotationSpeed * Time.getDeltaTime());

            smoothVelQuat = Quaternion.Lerp(smoothVelQuat, velocityQuat, 2f * Time.getDeltaTime());

            finalQuat = Quaternion.Lerp(smoothQuat, velocityQuat, script.smoothIsInAir);

            float finalDistMult = 1f;
            if (veh.Speed > 0.15f)
            {
                // TODO Optimize?
                finalDistMult = Vector3.Angle(finalQuat * Vector3.RelativeFront, veh.Velocity) / 180f;
                finalDistMult = MathR.Lerp(1f, -1f, finalDistMult);
            }

            if(script.isMouseLooking)
            {
                finalQuat = Quaternion.Lerp(finalQuat, getFreelookQuaternion(), script.smoothIsFreeLooking);
            }

            targetCamera.Position = posCenter + camExtraHeightV3 + (finalQuat * Vector3.RelativeBack * (fullLongitudeOffset + ( currentDistanceIncrement * finalDistMult )));

            var pointAt = posCenter - finalQuat * Vector3.RelativeBack * (currentDistanceIncrement + 2f);

            targetCamera.PointAt(pointAt);
        }
コード例 #18
0
 public float AngleInRad(Vector3 vec1, Vector3 vec2)
 {
     return MathR.Atan2(vec2.Y - vec1.Y, vec2.X - vec1.X);
 }
コード例 #19
0
 public Quaternion getFreelookQuaternion()
 {
     return(MathR.LookAt(Vector3.Zero, GameplayCamera.Direction));
 }