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