Code / Development / My Own Stuff / Unity September 25, 2013 @ 12:01

Clamped Bezier Spline for Unity

There are probably a many more of these BSpline implementstions to be found on the interwebs, so here’s another one:

using UnityEngine;

public class BSpline {
   
    private BSpline() { }
   
    public static Vector3 GetPoint(Vector3[] cvs, float t) {
        int segCount = cvs.Length - 1;
       
        float u = t * segCount;
        float v = u % 1;
        int seg = Mathf.FloorToInt(u);
       
        if (seg >= segCount) {
            v = 1;
            seg = segCount - 1;
        } else if (seg < 0) {
            v = 0;
            seg = 0;
        }
       
        Vector3 a, b, c ,d;
       
        if (seg == 0) {
            a = cvs[seg];
            b = cvs[seg];
            c = cvs[seg+1];
            d = cvs[seg+2];
        } else if (seg == segCount - 1) {
            a = cvs[seg-1];
            b = cvs[seg];
            c = cvs[seg+1];
            d = cvs[seg+1];
        } else {
            a = cvs[seg-1];
            b = cvs[seg];
            c = cvs[seg+1];
            d = cvs[seg+2];
        }
       
        return curveFunction(a, b, c, d, v);
    }
   
    private static Vector3 curveFunction(Vector3 a, Vector3 b,
            Vector3 c, Vector3 d, float t) {
        float it = 1 - t;
        float t2 = t * t;
        float t3 = t2 * t;
        float b0 = it * it * it / 6;
        float b1 = (3 * t3 - 6 * t2 + 4) / 6;
        float b2 = (-3 * t3 + 3 * t2 + 3 * t + 1) / 6;
        float b3 = t3 / 6;
        return b0 * a + b1 * b + b2 * c + b3 * d;
    }
}
Code / Development / My Own Stuff April 11, 2012 @ 13:13

Python in French

# Pour Rudy, qui ne comprends pas un mot de Python quand c'est en Anglais.
import sys
dites = sys.stdout.write
ouvrez = open
lire = 'r'
ecrire = 'w'
fichier = 'd:/temp.txt'
texte_a_ecrire = u'Bonjour beau monde!'

dites('Je vais ouvrir un fichier qui s\'appelle %s\n' % fichier)
objet_fichier = ouvrez(fichier, ecrire)

# Traduire quelques fonctions
ecrivez = objet_fichier.write
fermez = objet_fichier.close

dites('Et maintenant, je vais ecrire cette texte dans le ficher: "%s"\n' % texte_a_ecrire)
ecrivez(texte_a_ecrire)
fermez()

dites('J\'ai ecrit et ferme le fichier, maintenant je vais ouvrir le meme ficher et dire ce qui se trouve de dedans.\n')

objet_fichier = ouvrez(fichier, lire)

# Encore plus des traductions
lisez = objet_fichier.read
fermez = objet_fichier.close

la_texte_dans_le_fichier = lisez()
dites('La texte dans le fichier: %s' % la_texte_dans_le_fichier)
fermez()

dites('Et voila, je disais tout que je vourdrais dire, merci!\n')
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.