UP-Viagg-io/Viagg-io/Assets/Packages/DefaultPlayables/TransformTween/TransformTweenMixerBehaviou...

119 lines
4.0 KiB
C#
Raw Normal View History

2024-05-15 13:18:09 +02:00
using System;
using UnityEngine;
using UnityEngine.Playables;
public class TransformTweenMixerBehaviour : PlayableBehaviour
{
bool m_FirstFrameHappened;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Transform trackBinding = playerData as Transform;
if(trackBinding == null)
return;
Vector3 defaultPosition = trackBinding.position;
Quaternion defaultRotation = trackBinding.rotation;
int inputCount = playable.GetInputCount ();
float positionTotalWeight = 0f;
float rotationTotalWeight = 0f;
Vector3 blendedPosition = Vector3.zero;
Quaternion blendedRotation = new Quaternion(0f, 0f, 0f, 0f);
for (int i = 0; i < inputCount; i++)
{
ScriptPlayable<TransformTweenBehaviour> playableInput = (ScriptPlayable<TransformTweenBehaviour>)playable.GetInput (i);
TransformTweenBehaviour input = playableInput.GetBehaviour ();
if(input.endLocation == null)
continue;
float inputWeight = playable.GetInputWeight(i);
if (!m_FirstFrameHappened && !input.startLocation)
{
input.startingPosition = defaultPosition;
input.startingRotation = defaultRotation;
}
float normalisedTime = (float)(playableInput.GetTime() / playableInput.GetDuration ());
float tweenProgress = input.EvaluateCurrentCurve(normalisedTime);
if (input.tweenPosition)
{
positionTotalWeight += inputWeight;
blendedPosition += Vector3.Lerp(input.startingPosition, input.endLocation.position, tweenProgress) * inputWeight;
}
if (input.tweenRotation)
{
rotationTotalWeight += inputWeight;
Quaternion desiredRotation = Quaternion.Lerp(input.startingRotation, input.endLocation.rotation, tweenProgress);
desiredRotation = NormalizeQuaternion(desiredRotation);
if (Quaternion.Dot (blendedRotation, desiredRotation) < 0f)
{
desiredRotation = ScaleQuaternion (desiredRotation, -1f);
}
desiredRotation = ScaleQuaternion(desiredRotation, inputWeight);
blendedRotation = AddQuaternions (blendedRotation, desiredRotation);
}
}
blendedPosition += defaultPosition * (1f - positionTotalWeight);
Quaternion weightedDefaultRotation = ScaleQuaternion (defaultRotation, 1f - rotationTotalWeight);
blendedRotation = AddQuaternions (blendedRotation, weightedDefaultRotation);
trackBinding.position = blendedPosition;
trackBinding.rotation = blendedRotation;
m_FirstFrameHappened = true;
}
public override void OnPlayableDestroy (Playable playable)
{
m_FirstFrameHappened = false;
}
static Quaternion AddQuaternions (Quaternion first, Quaternion second)
{
first.w += second.w;
first.x += second.x;
first.y += second.y;
first.z += second.z;
return first;
}
static Quaternion ScaleQuaternion (Quaternion rotation, float multiplier)
{
rotation.w *= multiplier;
rotation.x *= multiplier;
rotation.y *= multiplier;
rotation.z *= multiplier;
return rotation;
}
static float QuaternionMagnitude (Quaternion rotation)
{
return Mathf.Sqrt ((Quaternion.Dot (rotation, rotation)));
}
static Quaternion NormalizeQuaternion (Quaternion rotation)
{
float magnitude = QuaternionMagnitude (rotation);
if (magnitude > 0f)
return ScaleQuaternion (rotation, 1f / magnitude);
Debug.LogWarning ("Cannot normalize a quaternion with zero magnitude.");
return Quaternion.identity;
}
}