using UnityEngine;
using UnityEngine.Serialization;

public class QuaternionPID : MonoBehaviour
{
	[Tooltip("Just a field for user naming. Doesn't do anything.")]
	[FormerlySerializedAs("name")]
	public string customName;

	[Tooltip("PID Constants.")]
	public Vector3 PID = new Vector3(1f, 0f, 0f);

	[Tooltip("The quaternion we are currently at.")]
	public Quaternion inputQuat = Quaternion.identity;

	[Tooltip("The quaternion we want to be at.")]
	public Quaternion targetQuat = Quaternion.identity;

	[Tooltip("Vector output from PID controller; what we read.")]
	[HideInInspector]
	public Vector3 outputVector = Vector3.zero;

	public float gain = 1f;

	private Vector3 errorSum = Vector3.zero;

	private Vector3 deltaError = Vector3.zero;

	private Vector3 lastError = Vector3.zero;

	private float lastUpdateTime;

	private void Start()
	{
		gain *= 60f * Time.fixedDeltaTime;
		lastUpdateTime = Time.time;
	}

	public Vector3 UpdatePID()
	{
		float time = Time.time;
		float num = time - lastUpdateTime;
		lastUpdateTime = time;
		if (num != 0f)
		{
			Quaternion quaternion = targetQuat * Quaternion.Inverse(inputQuat);
			if (quaternion.w < 0f)
			{
				quaternion.x *= -1f;
				quaternion.y *= -1f;
				quaternion.z *= -1f;
				quaternion.w *= -1f;
			}
			Vector3 vector = default(Vector3);
			vector.x = quaternion.x;
			vector.y = quaternion.y;
			vector.z = quaternion.z;
			errorSum += vector * num;
			deltaError = (vector - lastError) / num;
			lastError = vector;
			outputVector = vector * PID.x + errorSum * PID.y + deltaError * PID.z;
			return outputVector * gain;
		}
		return Vector3.zero;
	}
}
