I’m working on auto leveling my spaceship while it’s in orbit. I found this old thread, but it uses BulletAppState and I’m not using BulletAppState. (It only works for 2.5D, right?) There is a link there for more info, but the link is bad.
I got this from the old topic and tried to implement it.
Vector3f spatialY = control.getPhysicsRotation().mult(Vector3f.UNIT_Y);
Vector3f cross = spatialY.crossLocal(Vector3f.UNIT_Y).normalizeLocal();
control.applyTorque(cross);
I’ve tried duplicating the above and still don’t get the right result – looking down on the planet my ship is orbiting (with my camera looking down on my ship).
I assume getPhysicsRotation() returns the local rotation (I’ve tried getting my Local as well as World rotation). I tried to look up getPhysicsRotation() but the page provides no details - only class header info. (http://javadoc.jmonkeyengine.org/com/jme3/bullet/objects/PhysicsRigidBody.html) Ah, I found it on GitHub…
I tried the second line above with no changes*.
The third line looks like it duplicates Quaternion move(v.x, v.y, v.z) which, I think, ‘add’s v to the current rotation.
Below is the autoLeveling stuff. How do those three lines work?
Vector3f startVector;
Vector3f currentVector;
Vector3f endVector;
Vector3f upVector;
Vector3f tempVector;
Vector3f spatialY;
Vector3f cross;
public void autoLevel(String action, boolean isPressed){
autoLevel = (autoLevel == false);
System.out.println("ControllableControl.autoLevel(): autoLevel=" + autoLevel);
if (autoLevel){
//start vector
float[] rads = new float[3];
spatial.getWorldRotation().toAngles(rads);//local
startVector = new Vector3f(rads[0], rads[1], rads[2]);
//current vector
currentVector = new Vector3f(rads[0], rads[1], rads[2]);
//end vector
endVector = new Vector3f(rads[0], rads[1], rads[2]);
//test
//Vector3f spatialY = control.getPhsicsRotation().mult(Vector3f.UNIT_Y);
//cross = spatialY.crossLocal(Vector3f.UNIT_Y).normalizeLocal();
upVector = Vector3f.UNIT_Y;
spatialY = new Vector3f(-rads[0], -rads[1], -rads[2]).multLocal(upVector);
//spatialY = new Vector3f(rads[0], rads[1], rads[2]).multLocal(upVector);
cross = spatialY.crossLocal(upVector).normalizeLocal();
}
else{
pitchDown("PitchDown", false);
pitchUp("PitchUp", false);
yawLeft("YawLeft", false);
yawRight("YawRight", false);
rollLeft("RollLeft", false);
rollRight("RollRight", false);
massControl.setSpin(new Vector3f(0f, 0f, 0f));
}
}
private void doAutoLevel(float tpf){
//current vector
float[] rads = new float[3];
spatial.getLocalRotation().toAngles(rads);
currentVector = new Vector3f(rads[0], rads[1], rads[2]);
//this should set the final rotation
spatial.rotate(cross.x, cross.y, cross.z);
//massControl.rotate(cross.x, cross.y, cross.z);
autoLevel = false;//shut off for testing
System.out.println("CC.autoLevel()" + ", startVector=" + startVector + ", currentVector=" + currentVector + ", endVector=" + endVector + ", cross=" + cross);
if (true) return;
//
Vector3f currentRotation = massControl.getRotation();
Vector3f diffVector = currentVector.subtract(endVector);
if (currentRotation.x < endVector.x - 0.01f)
pitchDown("PitchUp", true);
else if (currentRotation.x > endVector.x + 0.01f)
pitchUp("PitchDown", true);
else{
currentRotation.x = endVector.x;
pitchDown("PitchDown", false);
pitchUp("PitchUp", false);
massControl.setSpin(0, 0f);
}
if (currentRotation.y < endVector.y - 0.01f)
yawRight("YawRight", true);
else if (currentRotation.y > endVector.y + 0.01f)
yawLeft("YawLeft", true);
else{
massControl.setSpin(1, 0f);
yawLeft("YawLeft", false);
yawRight("YawRight", false);
currentRotation.y = endVector.y;
}
//
if (currentRotation.z < endVector.z - 0.01f)
rollLeft("RollLeft", true);
else if (currentRotation.z > endVector.z + 0.01f)
rollRight("RollRight", true);
else{
massControl.setSpin(2, 0f);
rollLeft("RollLeft", false);
rollRight("RollRight", false);
currentRotation.z = endVector.z;
}
}