Well I didn’t write it for starters So I will have a hard time explaining all of it you can reveiw the Code. But its not well documented. Hopefully it will help. If not my partner (my Father) will be back Friday we could give you some more details then.
Also rememember some of this will be specific to what we are building.
Prinarly though I think you will be interested in the Rotation parts.
" public static void getQuat "
package behaviors;
/*
* Created on Jan 8, 2005
*
* MatrixRPSInterpolator class
*/
/**
* @author Jim Jones
*
* Sharp Productions
*/
import java.util.Enumeration;
import javax.media.j3d.Alpha;
import javax.media.j3d.Interpolator;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.WakeupCriterion;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
public class MatrixRPSInterpolator extends Interpolator {
Alpha alpha;
Transform3D[] keys;
Transform3D[] keyFrames;
int keyLength;
int currentFrame;
float[] knots;
int openClosed;
TransformGroup target = null;
WakeupCriterion wakeup;
protected float prevAlpha = Float.NaN;
protected float currentAlpha = Float.NaN;
protected float currentU;
protected float lowerKnot;
protected Transform3D lowerT = new Transform3D();
protected float upperKnot;
protected Transform3D upperT = new Transform3D();
private Transform3D currentTransform = new Transform3D();
private float totalAlpha = 0f;
private int indexAlpha = 0;
private Vector3f oneT = new Vector3f();
private Vector3f twoT = new Vector3f();
private Vector3f finalT = new Vector3f();
private Quat4f oneQ = new Quat4f();
private Quat4f twoQ = new Quat4f();
private Quat4f finalQ = new Quat4f();
private Vector3d oneS = new Vector3d();
private Vector3d twoS = new Vector3d();
private Vector3d finalS = new Vector3d();
// non-public, default constructor used by cloneNode
MatrixRPSInterpolator() {
}
/**
*
*/
public MatrixRPSInterpolator(int openClosed, Alpha alpha, Transform3D[] keys,
float[] knots, TransformGroup target) {
super(alpha);
this.openClosed = openClosed;
setKeys(keys);
setTarget(target);
this.currentFrame = 0;
this.wakeup = (WakeupCriterion) new WakeupOnElapsedFrames(0, true);
this.alpha = alpha;
setKnots(knots);
target.getTransform(currentTransform);
}
/**
*
*/
public void setKeys(Transform3D[] keys) {
if (keys.length < 2) {
throw new IllegalArgumentException("Key number of "+keys.length+" is too few");
}
this.keys = keys;
this.keyLength = keys.length;
keyFrames = new Transform3D[keyLength + 2];
keyFrames[0] = new Transform3D();
keyFrames[0] = keys[0];
for (int i = 1; i < keyLength+1; i++) {
keyFrames[i] = keys[i-1];
}
keyFrames[keyLength+1] = new Transform3D();
keyFrames[keyLength+1] = keys[keyLength-1];
}
/**
*
*/
public void setTarget(TransformGroup target) {
if (target == null) {
throw new IllegalArgumentException("Requires a non-null TransformGroup");
}
this.target = target;
}
/**
*
*/
public void setKnots(float[] knots) {
int len = knots.length;
if(keyLength != len) {
throw new IllegalArgumentException("# knots must equal # keys");
}
if((knots[0] != 0)|| (knots[knots.length-1] != 1)) {
throw new IllegalArgumentException("knots must start w/ 0 and end w/ 1");
}
for(int i=2; i<len; i++) {
float one = knots[i-1];
float two = knots[i];
if(one < two) {
continue;
} else {
throw new IllegalArgumentException("knots must be in sequence up or down");
}
}
this.knots = knots;
}
/**
*
*/
protected void computePathInterpolation() {
float value = (this.getAlpha()).value();
computePathInterpolation(value);
}
/**
*
*/
protected void computePathInterpolation(float aValue) {
// Bubble Gum
if(aValue < .0025f) {
aValue = .0025f;
}
int i = 0;
while((aValue > knots[i]) && (i < keyLength-2)) {
i++;
}
if(i == 1) {
currentU = 0f;
lowerT = keys[1];
upperT = keys[2];
} else {
//System.out.println("alpha "+aValue);
//System.out.println(" knot index "+i);
//System.out.println(" knot[i] "+knots[i]);
//System.out.println("currentU "+currentU);
//System.out.println(" knots[i-1} "+knots[i-1]);
currentU = (aValue - knots[i-1])/(knots[i] - knots[i-1]);
lowerT = keys[i-1];
upperT = keys[i];
}
}
public void computeTransform(float alphaValue, Transform3D currentTransform) {
computePathInterpolation(alphaValue);
// Get the rotation and translation components
getQuat(lowerT, oneQ);
getTrans(lowerT, oneT);
getScale(lowerT, oneS);
oneQ.normalize();
getQuat(upperT, twoQ);
getTrans(upperT, twoT);
getScale(upperT, twoS);
oneQ.normalize();
// Interpolate the translations
finalT.sub(twoT, oneT);
finalT.scaleAdd(1.0f, oneT);
// Interpolater the rotations
finalQ.sub(twoQ, oneQ);
finalQ.scaleAdd(1.0f, oneQ);
finalQ.normalize();
// Interpolate Scale
finalS.sub(twoS, oneS);
finalS.scaleAdd(1.0f, oneS);
// Set interpolations
currentTransform.setTranslation(finalT);
currentTransform.setRotation(finalQ);
currentTransform.setScale(finalS);
//currentTransform.normalize();
System.out.println("Type "+currentTransform.getBestType());
System.out.println("Sign "+currentTransform.getDeterminantSign());
}
/* (non-Javadoc)
* @see javax.media.j3d.Behavior#processStimulus(java.util.Enumeration)
*/
/**/
public void processStimulus(Enumeration criteria) {
if(alpha != null) {
currentAlpha = alpha.value();
if(currentAlpha != prevAlpha) {
//System.out.println("currentAlpha "+currentAlpha+" "+prevAlpha);
prevAlpha = currentAlpha;
target.getTransform(currentTransform);
computeTransform(currentAlpha, currentTransform);
target.setTransform(currentTransform);
}
if (!alpha.finished() && !alpha.isPaused()) {
wakeup = defaultWakeupCriterion;
}
}
wakeupOn(wakeup);
}
public static void getQuat(Transform3D t, Quat4f q) {
float[] mat = new float[16];
t.get(mat);
float trace = mat[0] + mat[5] + mat[10] + 1;
if(trace > 0) {
float s = 0.5f/(float)Math.sqrt(trace);
q.w = 0.25f/s;
q.x = (mat[9] - mat[6]) * s;
q.y = (mat[2] - mat[8]) * s;
q.w = (mat[4] - mat[1]) * s;
} else {
if((mat[0] > mat[5]) && (mat[0] > mat[10])) {
float s = (float)Math.sqrt(1.0f + mat[0] - mat[5] - mat[10]) * 2;
q.x = 0.5f/s;
q.y = (mat[1] + mat[4])/s;
q.z = (mat[2] + mat[8])/s;
q.w = (mat[6] + mat[9])/s;
} else if ((mat[5] > mat[0]) && (mat[5] > mat[10])) {
float s = (float)Math.sqrt(1.0f + mat[5] - mat[0] - mat[10]) * 2;
q.x = (mat[1] + mat[4])/s;
q.y = 0.5f/s;
q.z = (mat[6] + mat[9])/s;
q.w = (mat[2] + mat[8])/s;
} else if ((mat[10] > mat[0]) && (mat[10] > mat[5])) {
float s = (float)Math.sqrt(1.0f + mat[10] - mat[0] - mat[5]) * 2;
q.x = (mat[2] + mat[8])/s;
q.y = (mat[6] + mat[9])/s;
q.z = 0.5f/s;
q.w = (mat[1] + mat[4])/s;
}
}
}
public static void getTrans(Transform3D t, Vector3f v) {
float[] mat = new float[16];
t.get(mat);
v.x = mat[3];
v.y = mat[7];
v.z = mat[11];
}
public static void getScale(Transform3D t, Vector3d v) {
float[] mat = new float[16];
t.get(mat);
v.x = mat[0];
v.y = mat[5];
v.z = mat[10];
}
}