Code / Development / My Own Stuff May 14, 2011 @ 22:52

Ardor3D: Squad Interpolation

Just ported a spherical cubic (quadrangle) interpolation method to be used with Ardor3D‘s quaternions. I shamelessly ripped it, so I might as well share it:

    public static Quaternion lerp(Quaternion q1, Quaternion q2, double t,
            Quaternion store) {
        Quaternion c = Quaternion.fetchTempInstance();
        Quaternion d = Quaternion.fetchTempInstance();

        q1.multiply(1 - t, c);
        q2.multiply(t, d);

        q1.add(q2, store);
        store.normalizeLocal();

        Quaternion.releaseTempInstance(c);
        Quaternion.releaseTempInstance(d);

        return store;
    }

    public static Quaternion slerpNoInvert(Quaternion q1, Quaternion q2,
            double t, Quaternion store) {

        Quaternion c = Quaternion.fetchTempInstance();
        Quaternion d = Quaternion.fetchTempInstance();

        double dot = q1.dot(q2);

        if (dot > -0.95f && dot < 0.95f) {
            double angle = MathUtils.acos(dot);
            q1.multiply(MathUtils.sin(angle * (1 - t)), c);
            q2.multiply(MathUtils.sin(angle * t), d);
            c.add(d, store);

            divide(store, MathUtils.sin(angle), store);
            store.normalizeLocal();
        } else {
            lerp(q1, q2, t, store);
        }

        Quaternion.releaseTempInstance(c);
        Quaternion.releaseTempInstance(d);

        return store;
    }

    public static Quaternion divide(Quaternion a, double n, Quaternion store) {
        if (0 == n)
            throw new ArithmeticException("Divide by zero!");
        return store.set(store.getX() / n, store.getY() / n, store.getZ() / n,
                store.getW() / n);

    }

    public static Quaternion squad(Quaternion q1, Quaternion q2, Quaternion a,
            Quaternion b, double t, Quaternion store) {
        Quaternion c = Quaternion.fetchTempInstance();
        Quaternion d = Quaternion.fetchTempInstance();

        slerpNoInvert(q1, q2, t, c);

        slerpNoInvert(a, b, t, d);

        slerpNoInvert(c, d, 2 * t * (1 - t), store);

        Quaternion.releaseTempInstance(c);
        Quaternion.releaseTempInstance(d);

        return store;
    }

Will Perone, thanks!

EDIT: The previous version had a divide-by-zero problem, which should be fixed in the code above.

2 Comments to Ardor3D: Squad Interpolation
  1. Josh Slack (May 16, 2011 @ 06:15)

    Cool, what do you plan to do with it?

  2. bmod (May 17, 2011 @ 23:36)

    Trying to smoothly rotate objects between several predetermined orientations without getting gimbal locks. Experiments mostly for now. Something like 3D Studio Max’ TCB Controller seem to be a good solution in terms of control, but now at least I have something to work with.
    BTW. Thanks for your work on Ardor3D, amazing library!


Add comment:


You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

By submitting a comment here you grant baseone:online a perpetual license to reproduce your words and name/web site in attribution. Inappropriate or irrelevant comments will be removed at an admin's discretion.