I am using euler conversion code that I have seen around. No matter what I play around with I can't get it to work. Currently i'm testing with 5 boxes stacking on top of each other. They fall and pop they bounce up. Looks nice. It becomes noticable that when the boxes settle they are not flat. often they are at an angle with the tips graphicly sinking into the ground. Seems to indicate that my rotation is off.
JPCt doesn't support rotation absolute values. I rotate the object by an amount. So I compare new and old rotation. Below is my MotionState that I wrote up. I have been working on this for days.
Code: Select all
import javax.vecmath.Vector3f;
import javax.vecmath.Quat4f;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Object3D;
import javabullet.linearmath.MotionState;
import javabullet.linearmath.Transform;
public class JPCTBulletMotionState implements MotionState{
public final Transform graphicsWorldTrans = new Transform();
public final Transform centerOfMassOffset = new Transform();
public final Transform startWorldTrans = new Transform();
private Object3D obj3d;
private float tran_x, tran_y, tran_z; // empty place spots
private SimpleVector rotate = new SimpleVector();
private SimpleVector last_rotate = new SimpleVector();
public JPCTBulletMotionState()
{
graphicsWorldTrans.setIdentity();
centerOfMassOffset.setIdentity();
startWorldTrans.setIdentity();
}
public JPCTBulletMotionState(Transform startTrans)
{
this.graphicsWorldTrans.set(startTrans);
centerOfMassOffset.setIdentity();
this.startWorldTrans.set(startTrans);
}
public JPCTBulletMotionState(Transform startTrans, Transform centerOfMassOffset)
{
this.graphicsWorldTrans.set(startTrans);
this.centerOfMassOffset.set(centerOfMassOffset);
this.startWorldTrans.set(startTrans);
}
public void setObject(Object3D obj)
{
obj3d = obj;
}
public void getWorldTransform(Transform worldTrans){
worldTrans.set(graphicsWorldTrans);
//worldTrans.inverse(centerOfMassOffset);
//worldTrans.set(centerOfMassOffset);
//worldTrans.mul(graphicsWorldTrans);
return;
}
public void setWorldTransform(Transform worldTrans)
{
SimpleVector pos = obj3d.getTransformedCenter();
tran_x = worldTrans.origin.x - pos.x;
tran_y = worldTrans.origin.y - pos.y;
tran_z = worldTrans.origin.z - pos.z;
obj3d.translate(tran_x, tran_y, tran_z);
Quat4f quat = worldTrans.getRotation();
quat.inverse();
quat.normalize();
QuatToEuler(quat);
graphicsWorldTrans.origin.set(tran_x, tran_y, tran_z);
float rx = last_rotate.x - rotate.x;
float rz = last_rotate.y - rotate.y;
float ry = last_rotate.z - rotate.z;
quat.set(rx,rz,ry, quat.w);
graphicsWorldTrans.setRotation(quat);
if(obj3d != null)
{
obj3d.rotateX(rx);
obj3d.rotateY(ry);
obj3d.rotateZ(rz);
}
}
public void print(String txt)
{
System.out.println(txt);
}
public void QuatToEuler(Quat4f quat)
{
double sqw;
double sqx;
double sqy;
double sqz;
double rotxrad;
double rotyrad;
double rotzrad;
sqw = quat.w * quat.w;
sqx = quat.x * quat.x;
sqy = quat.y * quat.y;
sqz = quat.z * quat.z;
rotxrad = (double)Math.atan2(2.0 * ( quat.y * quat.z + quat.x * quat.w ) , ( -sqx - sqy + sqz + sqw ));
rotyrad = (double)Math.asin(-2.0 * ( quat.x * quat.z - quat.y * quat.w ));
rotzrad = (double)Math.atan2(2.0 * ( quat.x * quat.y + quat.z * quat.w ) , ( sqx - sqy - sqz + sqw ));
last_rotate.set((float)rotate.x, (float)rotate.y, (float)rotate.z);
rotate.set((float)rotxrad, (float)rotyrad, (float)rotzrad);
return;
}
}