Пример #1
0
        public void AverageToBranch(float keyTime, int fromKey, int toKey)
        {
            var position      = Vector3.zero;
            var rotationCum   = Vector4.zero;
            var firstRotation = source.GetKeyframeRotation(fromKey);
            var duration      = source.x.GetKeyframeByKey(toKey).time - source.x.GetKeyframeByKey(fromKey).time;

            for (var key = fromKey; key < toKey; key++)
            {
                var frameDuration = source.x.GetKeyframeByKey(key + 1).time - source.x.GetKeyframeByKey(key).time;
                var weight        = frameDuration / duration;
                position += source.GetKeyframePosition(key) * weight;
                QuaternionUtil.AverageQuaternion(ref rotationCum, source.GetKeyframeRotation(key), firstRotation, weight);
            }
            branch.SetKeyframe(keyTime, position, source.GetKeyframeRotation(fromKey), CurveTypeValues.SmoothLocal);
        }
Пример #2
0
        private void SampleController(FreeControllerV3 controller, List <FreeControllerAnimationTarget> targets, bool force)
        {
            if (ReferenceEquals(controller, null))
            {
                return;
            }
            var control = controller.control;

            if (targets.Count > _rotations.Length)
            {
                _rotations            = new Quaternion[targets.Count];
                _rotationBlendWeights = new float[targets.Count];
            }
            var rotationCount               = 0;
            var totalRotationBlendWeights   = 0f;
            var totalRotationControlWeights = 0f;

            var weightedPositionSum         = Vector3.zero;
            var totalPositionBlendWeights   = 0f;
            var totalPositionControlWeights = 0f;

            for (var i = 0; i < targets.Count; i++)
            {
                var target = targets[i];
                var clip   = target.clip;
                if (target.recording)
                {
                    target.SetKeyframeToCurrentTransform(clip.clipTime.Snap(), false);
                    return;
                }
                if (!clip.playbackEnabled && !clip.temporarilyEnabled)
                {
                    continue;
                }
                if (!target.playbackEnabled)
                {
                    continue;
                }
                var weight = clip.temporarilyEnabled ? 1f : clip.scaledWeight * target.scaledWeight;
                if (weight < float.Epsilon)
                {
                    continue;
                }

                if (!target.EnsureParentAvailable())
                {
                    return;
                }

                var smoothBlendWeight = Mathf.SmoothStep(0f, 1f, clip.temporarilyEnabled ? 1f : clip.playbackBlendWeight);

                if (target.controlRotation && controller.currentRotationState != FreeControllerV3.RotationState.Off)
                {
                    var rotLink    = target.GetPositionParentRB();
                    var hasRotLink = !ReferenceEquals(rotLink, null);

                    var targetRotation = target.EvaluateRotation(clip.clipTime);
                    if (hasRotLink)
                    {
                        targetRotation            = rotLink.rotation * targetRotation;
                        _rotations[rotationCount] = targetRotation;
                    }
                    else
                    {
                        _rotations[rotationCount] = control.transform.parent.rotation * targetRotation;
                    }

                    _rotationBlendWeights[rotationCount] = smoothBlendWeight;
                    totalRotationBlendWeights           += smoothBlendWeight;
                    totalRotationControlWeights         += weight * smoothBlendWeight;
                    rotationCount++;
                }

                if (target.controlPosition && controller.currentPositionState != FreeControllerV3.PositionState.Off)
                {
                    var posLink    = target.GetPositionParentRB();
                    var hasPosLink = !ReferenceEquals(posLink, null);

                    var targetPosition = target.EvaluatePosition(clip.clipTime);
                    if (hasPosLink)
                    {
                        targetPosition = posLink.transform.TransformPoint(targetPosition);
                    }
                    else
                    {
                        targetPosition = control.transform.parent.TransformPoint(targetPosition);
                    }

                    weightedPositionSum         += targetPosition * smoothBlendWeight;
                    totalPositionBlendWeights   += smoothBlendWeight;
                    totalPositionControlWeights += weight * smoothBlendWeight;
                }
            }

            if (totalRotationBlendWeights > float.Epsilon && controller.currentRotationState != FreeControllerV3.RotationState.Off)
            {
                Quaternion targetRotation;
                if (rotationCount > 1)
                {
                    var cumulative = Vector4.zero;
                    for (var i = 0; i < rotationCount; i++)
                    {
                        QuaternionUtil.AverageQuaternion(ref cumulative, _rotations[i], _rotations[0], _rotationBlendWeights[i] / totalRotationBlendWeights);
                    }
                    targetRotation = QuaternionUtil.FromVector(cumulative);
                }
                else
                {
                    targetRotation = _rotations[0];
                }
                var rotation = Quaternion.Slerp(control.rotation, targetRotation, totalRotationControlWeights / totalRotationBlendWeights);
                control.rotation = rotation;
            }

            if (totalPositionBlendWeights > float.Epsilon && controller.currentPositionState != FreeControllerV3.PositionState.Off)
            {
                var targetPosition = weightedPositionSum / totalPositionBlendWeights;
                var position       = Vector3.Lerp(control.position, targetPosition, totalPositionControlWeights / totalPositionBlendWeights);
                control.position = position;
            }

            if (force && controller.currentPositionState == FreeControllerV3.PositionState.Comply || controller.currentRotationState == FreeControllerV3.RotationState.Comply)
            {
                controller.PauseComply();
            }
        }