Comparing two quaternions issue

I’m having some strange issues with my quaternion comparison script. Here’s the code I’m using:

if (QuaternionEpsilonComparison(this.transform.localRotation, internalRotation, epsilonValue) == false) {
                Debug.Log ("LOG ROTATION");
                AddRotationKeyframe ();
                timeSinceLastKeyframe = 0;
                internalRotation = this.transform.localRotation;
            }

And here’s the comparison boolean I’m using (with an epsilon value of 0.002f):

    bool QuaternionEpsilonComparison (Quaternion a, Quaternion b, float epsilon) {
        return Mathf.Abs (Quaternion.Angle (a, b)) < epsilon;
    }

The problem is that in some cases it just constantly spews out “LOG ROTATION” even when the object is completely still. Is there something I’m missing here? Here’s the full script in case that helps provide further context:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

public class GrandCentralStation : MonoBehaviour {

    public string animationName = "animation";
    public int syncDelay = 60;
    private int timeSinceLastKeyframe = 0;
    public int endkeyFrame = 5184000;
    private int totalKeyframes = 0;
    public float epsilonValue = 0.002f;
    private Quaternion internalRotation;
    private Vector3 internalVelocity;
    private AnimationClip positionAnim;
    private AnimationClip rotationAnim;
    public AnimationCurve positionCurve;
    public AnimationCurve rotationCurve;
    private Keyframe[] positionKeyframes;
    private Keyframe[] rotationKeyframes;
    private NavMeshAgent agent;

    // Use this for initialization
    void Start () {
        agent = GetComponent<NavMeshAgent>();
        InitialiseKeyframes ();
        AddPositionKeyframe ();
        AddRotationKeyframe ();
        internalRotation = this.transform.localRotation;
        internalVelocity = agent.velocity;
    }

    bool FloatEpsilonComparison (float a, float b, float epsilon) {
        return Mathf.Abs(a - b) < epsilon;
    }

    bool Vector3EpsilonComparison (Vector3 a, Vector3 b, float epsilon) {
        return Mathf.Abs (Vector3.Distance (a, b)) < epsilon;
    }

    bool QuaternionEpsilonComparison (Quaternion a, Quaternion b, float epsilon) {
        return Mathf.Abs (Quaternion.Angle (a, b)) < epsilon;
    }

    public void SaveAnimation () {
        AssetDatabase.CreateAsset(positionAnim, "Assets/Internal/Animations/position" + animationName + ".anim");
        AssetDatabase.CreateAsset(rotationAnim, "Assets/Internal/Animations/rotation" + animationName + ".anim");
        AssetDatabase.SaveAssets();
    }

    void InitialiseKeyframes() {
        positionAnim = new AnimationClip();
        rotationAnim = new AnimationClip();
        positionKeyframes = new Keyframe[endkeyFrame];
        rotationKeyframes = new Keyframe[endkeyFrame];
    }

    void AddPositionKeyframe () {
       
    }

    void AddRotationKeyframe () {

    }

    // Update is called once per frame
    void Update () {

        if (timeSinceLastKeyframe >= syncDelay) {

            if (QuaternionEpsilonComparison(this.transform.localRotation, internalRotation, epsilonValue) == false) {
                Debug.Log ("LOG ROTATION");
                AddRotationKeyframe ();
                timeSinceLastKeyframe = 0;
                internalRotation = this.transform.localRotation;
            }

            if (Vector3EpsilonComparison(agent.velocity, internalVelocity, epsilonValue) == false) {
                Debug.Log ("LOG POSITION");
                AddPositionKeyframe ();
                timeSinceLastKeyframe = 0;
                internalVelocity = agent.velocity;
            }

        }

        timeSinceLastKeyframe++;
        totalKeyframes++;

    }
}

8

Insert a Debug.Log in the evaluation function: What is Quaternion.Angle returning? Also, output the two quaternions while you’re at it

I only glanced at this quickly but I suspect this line:

internalRotation =this.transform.localRotation;

means that your angle comparison will always return zero on subsequent frames, which is presumably lower than your epsilon value…