Here's my problem. I have a gamestate in which I have some PhysicsNodes. I would want the player to be able to rotate an object, that implements physics. In example if a ball falls on the object, the player must be able to rotate the underlying object to balance the ball, so that it won't fall. In simple terms, this means that the player rotates the level and tries to balance it so that he/she can move the ball to the finish line. (Like kororinpa on the wii).
I've tried to accomplish this with the following code in the gamestate (I guess some variable/method names are a bit off-putting, but try to bear with me):
pSpace = PhysicsSpace
.getPhysicsSpace(PhysicsSpace.BroadphaseTypes.AXIS_SWEEP_3);
KeyBindingManager.getKeyBindingManager().add("rotateLevelNorth",
KeyInput.KEY_U);
KeyBindingManager.getKeyBindingManager().add("rotateLevelSouth",
KeyInput.KEY_J);
KeyBindingManager.getKeyBindingManager().add("rotateLevelWest",
KeyInput.KEY_H);
KeyBindingManager.getKeyBindingManager().add("rotateLevelEast",
KeyInput.KEY_K);
createSkyBox();
Sphere sphere = new Sphere("sphere", 20, 20, 0.5f);
sphere.setModelBound(new BoundingSphere());
sphere.updateModelBound();
PhysicsNode pSphere = new PhysicsNode(sphere,
CollisionShape.ShapeTypes.SPHERE);
pSphere.setLocalTranslation(new Vector3f(-15.0f, 0.0f, -12.5f));
pSphere.setRestitution(0.3f);
pSpace.add(pSphere);
rootNode.attachChild(pSphere);
pSphere.updateRenderState();
ObjToJme converter = new ObjToJme();
try {
URL objFile = SandBoxGameState.class.getClassLoader().getResource(
"models/level1.obj");
converter.setProperty("mtllib", objFile);
converter.setProperty("texdir", objFile);
ByteArrayOutputStream BO = new ByteArrayOutputStream();
converter.convert(objFile.openStream(), BO);
TriMesh level = (TriMesh) BinaryImporter.getInstance().load(
new ByteArrayInputStream(BO.toByteArray()));
level.setModelBound(new BoundingBox());
level.updateModelBound();
level.setLocalScale(7.0f);
pLevel = new PhysicsNode(level, CollisionShape.ShapeTypes.MESH, 0);
pLevel.setLocalTranslation(new Vector3f(0.0f, -5.0f, 0.0f));
pLevel.setRestitution(0.3f);
pSpace.add(pLevel);
rootNode.attachChild(pLevel);
pLevel.updateRenderState();
} catch (Exception e) {
// just don't create the object :)
}
In the state's update method I try to rotate the "level" object:
if (KeyBindingManager.getKeyBindingManager().isValidCommand(
"rotateLevelNorth", true)) {
if (xAngle == 360.0f || xAngle == 0.0f) {
xAngle = 0.1f;
} else {
xAngle = xAngle + 0.1f;
}
pLevel.setLocalRotation(rotateY().mult(rotateX()));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand(
"rotateLevelSouth", true)) {
if (xAngle == -360.0f || xAngle == 0.0f) {
xAngle = -0.1f;
} else {
xAngle = xAngle - 0.1f;
}
pLevel.setLocalRotation(rotateY().mult(rotateX()));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand(
"rotateLevelWest", true)) {
if (yAngle == -360.0f || yAngle == 0.0f) {
yAngle = -0.1f;
} else {
yAngle = yAngle - 0.1f;
}
pLevel.setLocalRotation(rotateY().mult(rotateX()));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand(
"rotateLevelEast", true)) {
if (yAngle == 360.0f || yAngle == 0.0f) {
yAngle = 0.1f;
} else {
yAngle = yAngle + 0.1f;
}
pLevel.setLocalRotation(rotateY().mult(rotateX()));
}
super.update(tpf);
pSpace.update(tpf);
Here's the rotateY() and rotateX() methods:
private Quaternion rotateY() {
Quaternion pitch = new Quaternion();
pitch.fromAngleAxis(FastMath.PI * xAngle / 180.0f, new Vector3f(0.0f,
0.0f, -1.0f));
return pitch;
}
private Quaternion rotateX() {
Quaternion pitch = new Quaternion();
pitch.fromAngleAxis(FastMath.PI * yAngle / 180.0f, new Vector3f(1.0f,
0.0f, 0.0f));
return pitch;
}
The problem I have is that when I rotate the level object too much (i.e. 60 degrees), the ball (and other physics objects) start falling "through" the object in some places on the surface of the "level". When I turn it back to the original position, it starts working again. Also when the objects fall through, sometimes they freeze in the air. Sometimes they even freeze when they just touch the level object. Even if I haven't moved the level, the ball just spawns on top of it and randomly freezes. I'm pretty frustrated because it seems so random, I may have taken a wrong approach completely?
I'm using jmonkeyengine 2.0 from trunk and jbullet-jme 0.9.5.