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; }
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); }