Hi there,
I need your help with a more or less general question.
I just started with jme and jmephysics, looked at the great physics-lessons and could
follow them. My first own task should be navigating an ice rectangle over a floor.
Well, sounds not so hard. :roll:
I didn’t want to use SurfaceMotion but wanted to use force and torque in order to move the rect
over the floor. So in order to steer left or right I used addTorque(…) around the y-axis. That worked
BUT now is the problem giving the force the right direction to follow the rectangle’s small part.
Now the question: Is there a possibility to get something like a direction(marked as red line in image).
Let’s say at the beginning it is [1,0,0] and changing with any degree that is changing after its construction .
If there isn’t I would do something like setting the direction at the beginning to vec=[1,0,0] and storing
the localeRotation startRot. If I want to accelerate and I need the direction I calculate the delta from
startRot and currentRot and would rotate the vector about that delta-degree.
I’m quite sure there is an easy way to achieve that problem. Maybe using joints is a better way? I tried
a lot since friday. Maybe you know a good tutorial about physics where it is described how everything is
playing togehter. (world/local-stuff joints forces torque etc.)
Thanx for taking time,
ToM
You can do the following to push a object along its current direction:
boxNode.addForce(boxNode.getLocalRotation().getRotationColumn(2).mult(5));
Push it, push it some more ....
import com.jme.bounding.BoundingBox;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jmex.physics.DynamicPhysicsNode;
import com.jmex.physics.StaticPhysicsNode;
import com.jmex.physics.material.Material;
import com.jmex.physics.util.SimplePhysicsGame;
public class TestPush extends SimplePhysicsGame {
public static void main(String[] args) {
TestPush main = new TestPush();
main.setConfigShowMode(ConfigShowMode.AlwaysShow);
main.start();
}
private DynamicPhysicsNode boxNode;
@Override
protected void simpleInitGame() {
KeyBindingManager.getKeyBindingManager().removeAll();
Box floor = new Box("", new Vector3f(), 1000, 0.5f, 1000);
floor.setModelBound(new BoundingBox());
floor.updateModelBound();
StaticPhysicsNode floorNode = getPhysicsSpace().createStaticNode();
floorNode.attachChild(floor);
floorNode.generatePhysicsGeometry();
floorNode.setMaterial(Material.CONCRETE);
rootNode.attachChild(floorNode);
Box b = new Box("", new Vector3f(), 1, 0.5f, 1);
b.setModelBound(new BoundingBox());
b.updateModelBound();
b.setLocalTranslation(0, 2, 0);
boxNode = getPhysicsSpace().createDynamicNode();
boxNode.attachChild(b);
boxNode.setMaterial(Material.ICE);
boxNode.generatePhysicsGeometry();
boxNode.computeMass();
rootNode.attachChild(boxNode);
cam.setLocation(new Vector3f(0, 50, 50));
cam.lookAt(boxNode.getLocalTranslation(), Vector3f.UNIT_Y);
KeyBindingManager.getKeyBindingManager().set("exit", KeyInput.KEY_ESCAPE);
KeyBindingManager.getKeyBindingManager().set("push", KeyInput.KEY_UP);
KeyBindingManager.getKeyBindingManager().set("rotate left", KeyInput.KEY_LEFT);
KeyBindingManager.getKeyBindingManager().set("rotate right", KeyInput.KEY_RIGHT);
}
@Override
protected void simpleUpdate() {
if (KeyBindingManager.getKeyBindingManager().isValidCommand("push", true)) {
boxNode.addForce(boxNode.getLocalRotation().getRotationColumn(2).mult(5));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("rotate left", true)) {
boxNode.addTorque(new Vector3f(0, 2, 0));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("rotate right", true)) {
boxNode.addTorque(new Vector3f(0, -2, 0));
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
System.exit(0);
}
}
}
You can take the LocalRotion of the Node and calculate the LookAt Vector,
for Example:
public static Vector3f getLookAtDirection(Quaternion quaternion) {
Vector3f[] neu =new Vector3f[3];
quaternion.toAxes(neu);
return new Vector3f(neu[1].crossLocal(neu[0]).normalizeLocal().negateLocal());
}
I'am not sure, if its always correct, but the most time :)
Thx a lot, you two.
You really helped me a lot. I realized that I have to become more familiar with that 3d-math.
Until you posted your solutions my second try was not to use force to turn but to use a force
that is orthogonal to the linearVelocity. That worked, but the object wasnt turning
public void turnRight()
{
brickNode.addForce(brickNode.getLinearVelocity(null).cross(new Vector3f(0,1,0)));
}
CU, ToM