75 lines
3.0 KiB
C#
75 lines
3.0 KiB
C#
using UnityEngine;
|
|
|
|
namespace Passer.Humanoid {
|
|
|
|
[System.Serializable]
|
|
public class HeadPredictor : HeadSensor {
|
|
private Vector3 positionalVelocity;
|
|
private Quaternion rotationalVelocity;
|
|
|
|
public override void Start(HumanoidControl _humanoid, Transform targetTransform) {
|
|
base.Start(_humanoid, targetTransform);
|
|
}
|
|
|
|
public override void Update() {
|
|
base.Update();
|
|
if (headTarget.head.bone.transform == null)
|
|
return;
|
|
|
|
CalculatePositionalVelocity();
|
|
CalculateRotationalVelocity();
|
|
|
|
if (headTarget.neck.target.confidence.rotation > 0.1F) {
|
|
headTarget.neck.target.transform.rotation *= Quaternion.Slerp(Quaternion.identity, rotationalVelocity, Time.deltaTime);
|
|
headTarget.neck.target.confidence.rotation -= Time.deltaTime; // 0.1F;
|
|
}
|
|
|
|
if (headTarget.neck.target.confidence.rotation > 0.1F) {
|
|
headTarget.neck.target.transform.position += positionalVelocity * Time.deltaTime;
|
|
headTarget.neck.target.confidence.position -= Time.deltaTime; // 0.1F;
|
|
}
|
|
}
|
|
|
|
private Quaternion lastOrientation;
|
|
private float velocityChange;
|
|
private void CalculateRotationalVelocity() {
|
|
if (headTarget.neck.bone.transform == null)
|
|
return;
|
|
|
|
if (lastOrientation.w != 0) {
|
|
Quaternion lastRotationalVelocity = rotationalVelocity;
|
|
|
|
Quaternion rotation = Quaternion.Inverse(lastOrientation) * headTarget.neck.bone.targetRotation;
|
|
rotationalVelocity = Quaternion.SlerpUnclamped(Quaternion.identity, rotation, 1 / Time.deltaTime);
|
|
|
|
velocityChange = (velocityChange + Quaternion.Angle(lastRotationalVelocity, rotationalVelocity)) / 2;
|
|
|
|
// stabelize head
|
|
if (velocityChange < 1)
|
|
rotationalVelocity = Quaternion.Slerp(Quaternion.identity, rotationalVelocity, velocityChange);
|
|
}
|
|
lastOrientation = headTarget.neck.bone.targetRotation;
|
|
}
|
|
|
|
private Vector3 lastPosition;
|
|
private float positionalVelocityChange;
|
|
private void CalculatePositionalVelocity() {
|
|
if (headTarget.neck.bone.transform == null)
|
|
return;
|
|
|
|
if (lastPosition.sqrMagnitude != 0) {
|
|
Vector3 lastPositionalVelocity = positionalVelocity;
|
|
|
|
Vector3 translation = headTarget.neck.bone.transform.position - lastPosition;
|
|
positionalVelocity = translation / Time.deltaTime;
|
|
|
|
positionalVelocityChange = (positionalVelocityChange + (positionalVelocity - lastPositionalVelocity).magnitude) / 2;
|
|
|
|
// stabelize head
|
|
if (positionalVelocityChange < 10)
|
|
positionalVelocity = positionalVelocity * (positionalVelocityChange / 10);
|
|
}
|
|
lastPosition = headTarget.neck.bone.transform.position;
|
|
}
|
|
}
|
|
} |