Example #1
0
        public void Apply(LookAtEyeDirection eyeDirection, Dictionary <ExpressionKey, float> actualWeights)
        {
            var yaw   = eyeDirection.LeftYaw;
            var pitch = eyeDirection.LeftPitch;

            if (yaw < 0)
            {
                // Left
                actualWeights[_lookRightKey] = 0;
                actualWeights[_lookLeftKey]  = Mathf.Clamp(_horizontalOuter.Map(Mathf.Abs(yaw)), 0, 1.0f);
            }
            else
            {
                // Right
                actualWeights[_lookRightKey] = Mathf.Clamp(_horizontalOuter.Map(Mathf.Abs(yaw)), 0, 1.0f);
                actualWeights[_lookLeftKey]  = 0;
            }

            if (pitch < 0)
            {
                // Down
                actualWeights[_lookUpKey]   = 0;
                actualWeights[_lookDownKey] = Mathf.Clamp(_verticalDown.Map(Mathf.Abs(pitch)), 0, 1.0f);
            }
            else
            {
                // Up
                actualWeights[_lookUpKey]   = Mathf.Clamp(_verticalUp.Map(Mathf.Abs(pitch)), 0, 1.0f);
                actualWeights[_lookDownKey] = 0;
            }
        }
        /// <summary>
        /// LeftEyeボーンとRightEyeボーンに回転を適用する
        /// </summary>
        public void Apply(LookAtEyeDirection eyeDirection, Dictionary <ExpressionKey, float> actualWeights)
        {
            // FIXME
            var yaw   = eyeDirection.LeftYaw;
            var pitch = eyeDirection.LeftPitch;

            // horizontal
            float leftYaw, rightYaw;

            if (yaw < 0)
            {
                leftYaw  = -_horizontalOuter.Map(-yaw);
                rightYaw = -_horizontalInner.Map(-yaw);
            }
            else
            {
                rightYaw = _horizontalOuter.Map(yaw);
                leftYaw  = _horizontalInner.Map(yaw);
            }

            // vertical
            if (pitch < 0)
            {
                pitch = -_verticalDown.Map(-pitch);
            }
            else
            {
                pitch = _verticalUp.Map(pitch);
            }

            // Apply
            SetYawPitchToBones(new LookAtEyeDirection(leftYaw, pitch, rightYaw, pitch));
        }
 private void SetYawPitchToBones(LookAtEyeDirection actualEyeDirection)
 {
     if (_leftEye != null && _rightEye != null)
     {
         _leftEye.localRotation  = Matrix4x4.identity.YawPitchRotation(actualEyeDirection.LeftYaw, actualEyeDirection.LeftPitch);
         _rightEye.localRotation = Matrix4x4.identity.YawPitchRotation(actualEyeDirection.RightYaw, actualEyeDirection.RightPitch);
     }
 }
        /// <summary>
        /// 入力 Weight を基に、Validation を行い実際にモデルに適用される Weights を計算し、Merger を介して適用する。
        /// この際、LookAt の情報を pull してそれも適用する。
        /// </summary>
        private void Apply()
        {
            // 1. Get eye direction from provider.
            _inputEyeDirection = _eyeDirectionProvider?.EyeDirection ?? default;

            // 2. Validate user input, and Output as actual weights.
            _validator.Validate(_inputWeights, _actualWeights,
                                _inputEyeDirection, out _actualEyeDirection,
                                out var blink, out var lookAt, out var mouth);

            // 3. Set eye direction expression weights or any other side-effects (ex. eye bone).
            _eyeDirectionApplicable?.Apply(_actualEyeDirection, _actualWeights);

            // 4. Set actual weights to raw blendshapes.
            _merger.SetValues(_actualWeights);

            BlinkOverrideRate  = blink;
            LookAtOverrideRate = lookAt;
            MouthOverrideRate  = mouth;
        }
Example #5
0
        public void Validate(IReadOnlyDictionary <ExpressionKey, float> inputWeights, IDictionary <ExpressionKey, float> actualWeights,
                             LookAtEyeDirection inputEyeDirection, out LookAtEyeDirection actualEyeDirection,
                             out float blinkOverrideRate, out float lookAtOverrideRate, out float mouthOverrideRate)
        {
            // override rate
            blinkOverrideRate  = 0f;
            lookAtOverrideRate = 0f;
            mouthOverrideRate  = 0f;

            // 1. Set weights and Accumulate override rates.
            foreach (var key in _keys)
            {
                // Get expression.
                if (!_expressions.ContainsKey(key))
                {
                    continue;
                }
                var expression = _expressions[key];

                // Get weight with evaluation binary flag.
                var weight = expression.IsBinary ? Mathf.Round(inputWeights[key]) : inputWeights[key];

                // Set weight.
                actualWeights[key] = weight;

                // Override rate without targeting myself.
                if (!key.IsBlink)
                {
                    blinkOverrideRate += GetOverrideRate(expression.OverrideBlink, weight);
                }
                if (!key.IsLookAt)
                {
                    lookAtOverrideRate += GetOverrideRate(expression.OverrideLookAt, weight);
                }
                if (!key.IsMouth)
                {
                    mouthOverrideRate += GetOverrideRate(expression.OverrideMouth, weight);
                }
            }

            // 2. Saturate rate.
            blinkOverrideRate  = Mathf.Clamp01(blinkOverrideRate);
            lookAtOverrideRate = Mathf.Clamp01(lookAtOverrideRate);
            mouthOverrideRate  = Mathf.Clamp01(mouthOverrideRate);

            var blinkMultiplier  = 1f - blinkOverrideRate;
            var lookAtMultiplier = 1f - lookAtOverrideRate;
            var mouthMultiplier  = 1f - mouthOverrideRate;

            // 3. Set procedural key's weights.
            foreach (var key in _keys)
            {
                if (key.IsBlink)
                {
                    actualWeights[key] = inputWeights[key] * blinkMultiplier;
                }
                else if (key.IsLookAt)
                {
                    actualWeights[key] = inputWeights[key] * lookAtMultiplier;
                }
                else if (key.IsMouth)
                {
                    actualWeights[key] = inputWeights[key] * mouthMultiplier;
                }
            }

            // 4. eye direction
            actualEyeDirection = LookAtEyeDirection.Multiply(inputEyeDirection, 1f - lookAtOverrideRate);
        }