Esempio n. 1
0
        protected Quaternion GetCounterRotationDelta(Quaternion deltaRot)
        {
            Vector3 ea = new Angle3(deltaRot.eulerAngles).eulerAcute;

            ea.x *= counterRotationPerAxis.x;
            ea.y *= counterRotationPerAxis.y;
            ea.z *= counterRotationPerAxis.z;
            ea   *= counterRotationStrength;
            return(Quaternion.Euler(ea));
        }
Esempio n. 2
0
        protected float CalculateMotion(float dT)
        {
            dT = Mathf.Max(dT, 0.000001f);
            float fx = 0;                // Total effect strength from all motion types

                        #if UNITY_EDITOR // Debug motion calculations
            // Cache current settings
            bool  wasUsingAv = useAngularVelocity;
            bool  wasUsingLa = useAcceleration;
            bool  wasUsingLv = useVelocity;
            float prevAvStr  = angularVelocityStrength;
            float prevLaStr  = accelerationStrength;
            float prevLvStr  = velocityStrength;

            // Turn on all motion calculations
            if (_debugMotionCalculations)
            {
                // Disable contributions of unused motion types
                if (!useAngularVelocity)
                {
                    angularVelocityStrength = 0;
                }
                if (!useAcceleration)
                {
                    accelerationStrength = 0;
                }
                if (!useVelocity)
                {
                    velocityStrength = 0;
                }

                useAngularVelocity = useAcceleration = useVelocity = true;
            }
                        #endif

            // Rotation
            Vector3 fwd = motionTarget.forward;
            if (useAngularVelocity)
            {
                float av = Vector3.Angle(_lastFwd, fwd) / dT;

                                #if UNITY_EDITOR
                _debugAv = av;
                                #endif

                av          = Mathf.InverseLerp(angularVelocityMin, angularVelocityMax, av);
                _avSmoothed = Mathf.SmoothDamp(_avSmoothed, av, ref _avSlew, angularVelocitySmoothing);
                fx         += _avSmoothed * angularVelocityStrength;
            }

            // Velocity
            float   speed = 0;
            Vector3 dPos  = motionTarget.position - _lastPos;
            Vector3 vel   = dPos / dT;
            if (useVelocity || useAcceleration)
            {
                speed = vel.magnitude;

                                #if UNITY_EDITOR
                _debugLv = speed;
                                #endif
            }
            if (useVelocity)
            {
                _speedSmoothed = Mathf.SmoothDamp(_speedSmoothed, speed, ref _speedSlew, velocitySmoothing);
                float lm = 0;

                // Check for divide-by-zero
                if (!Mathf.Approximately(velocityMax, velocityMin))
                {
                    lm = Mathf.Clamp01((_speedSmoothed - velocityMin) / (velocityMax - velocityMin));
                }
                fx += lm * velocityStrength;
            }

            // Acceleration
            if (useAcceleration)
            {
                // Use unsmoothed vel to keep smoothing independent
                float accel = Mathf.Abs(speed - _lastSpeed) / dT;

                                #if UNITY_EDITOR
                _debugLa = accel;
                                #endif

                // Check for divide-by-zero
                if (!Mathf.Approximately(accelerationMax, accelerationMin))
                {
                    accel = Mathf.Clamp01((accel - accelerationMin) / (accelerationMax - accelerationMin));
                }
                _accelSmoothed = Mathf.SmoothDamp(_accelSmoothed, accel, ref _accelSlew, accelerationSmoothing);
                fx            += _accelSmoothed * accelerationStrength;
            }
            ;

            // Clamp and scale final effect strength
            fx = RemapRadius(fx) * RemapRadius(effectCoverage);

            #region Motion Effects
            #region Artificial Tilt
            // Check if target has changed or bool has been toggled
            if ((useArtificialTilt != _prevUseTilt) || (motionEffectTarget != _prevMotionEffectTarget))
            {
                // Reset smoothing params
                _prevUseTilt   = useArtificialTilt;
                _tiltAccelSlew = _tiltAccelSmoothed = Vector3.zero;
                // Ensure previous tilt target gets its rotation reset
                if (_prevMotionEffectTarget != null)
                {
                    _prevMotionEffectTarget.localEulerAngles = _tiltInit.eulerAcute;
                }
                // Reset tilt offset
                if (motionEffectTarget != null)
                {
                    _tiltInit           = new Angle3(motionEffectTarget.localEulerAngles);
                    _mfxTgtLocalPosInit = motionEffectTarget.localPosition;
                    _mfxTgtLocalRotInit = motionEffectTarget.localRotation;
                }
                else
                {
                    _tiltInit = Vector3.zero;
                }
                // Cache new target
                _prevMotionEffectTarget = motionEffectTarget;
            }
            // Apply tilt
            if (useArtificialTilt && motionEffectTarget != null)
            {
                Vector3 accTgt = motionTarget.InverseTransformDirection(vel - _lastVel) / dT;
                // Convert to log_e
                for (int i = 0; i < 3; ++i)
                {
                    float acc  = accTgt[i];
                    float sign = Mathf.Sign(acc);
                    acc       = Mathf.Abs(acc);
                    acc       = Mathf.Log(acc + 1);
                    accTgt[i] = acc * sign;
                }
                _tiltAccelSmoothed = Vector3.SmoothDamp(_tiltAccelSmoothed, accTgt, ref _tiltAccelSlew, tiltSmoothTime, 1000, dT);

                Vector3 tilt = new Angle3(_tiltAccelSmoothed.z * tiltStrength, 0, _tiltAccelSmoothed.x * tiltStrength).eulerAcute;
                if (tiltMaxAngles.sqrMagnitude > 0)
                {
                    tilt = new Vector3(
                        Mathf.Clamp(tilt.x, -tiltMaxAngles.x, tiltMaxAngles.x), 0,
                        Mathf.Clamp(tilt.z, -tiltMaxAngles.y, tiltMaxAngles.y)
                        );
                }
                motionEffectTarget.localEulerAngles = (_tiltInit + tilt).eulerAcute;
            }
            #endregion

            #region Framerate Division
            bool updateFps = false;
            if (framerateDivision > 1 && (divideTranslation || divideRotation))
            {
                if (Time.frameCount % framerateDivision == 0)
                {
                    updateFps = true;
                }
                else
                {
                    motionEffectTarget.position = _fpsPosition;
                    motionEffectTarget.rotation = _fpsRotation;
                }
            }
            // Check for settings change
            if (_lastFpsDivision != framerateDivision)
            {
                updateFps        = true;
                _lastFpsDivision = framerateDivision;
            }
            if (updateFps)
            {
                if (divideTranslation)
                {
                    motionEffectTarget.localPosition = _mfxTgtLocalPosInit;
                    _fpsPosition = motionEffectTarget.position;
                }
                if (divideRotation)
                {
                    motionEffectTarget.localRotation = _mfxTgtLocalRotInit;
                    _fpsRotation = motionEffectTarget.rotation;
                }
            }
            #endregion

            if (useCounterMotion)
            {
                UpdateCounterMotion(dPos, Quaternion.Inverse(motionTarget.rotation) * _lastRot);
            }
            #endregion

            // Cache current motion params for next frame
            _lastFwd   = fwd;
            _lastPos   = motionTarget.position;
            _lastSpeed = speed;
            _lastVel   = vel;
            _lastRot   = motionTarget.rotation;

                        #if UNITY_EDITOR
            // Restore motion settings
            if (_debugMotionCalculations)
            {
                useAngularVelocity = wasUsingAv;
                useAcceleration    = wasUsingLa;
                useVelocity        = wasUsingLv;

                angularVelocityStrength = prevAvStr;
                accelerationStrength    = prevLaStr;
                velocityStrength        = prevLvStr;
            }

            // Use forced value
            if (_debugForceOn)
            {
                return(Mathf.Clamp01(RemapRadius(_debugForceValue) * RemapRadius(effectCoverage)));
            }
                        #endif

            return(Mathf.Clamp01(fx));
        }