I read manuals about collision and physics but don’t understand how to reach my goal. Here is code of simple scene:
[java]
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.cursors.plugins.JmeCursor;
import com.jme3.input.KeyInput;
import com.jme3.input.RawInputListener;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;
import com.jme3.light.AmbientLight;
import com.jme3.light.Light;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.material.MaterialDef;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
/**
-
test
-
@author normenhansen
*/
public class Main extends SimpleApplication implements ActionListener {
private static final String ACTION_FORWARD = “Forward”;
private static final String ACTION_BACK = “Back”;
private static final String ACTION_LEFT = “Left”;
private static final String ACTION_RIGHT = “Right”;
private static final float PLAYER_MOVE_SPEED = 4f;
private static final float PLAYER_ROTATION_SPEED = FastMath.HALF_PI;private BulletAppState bulletAppState;
private Node scene;
private Entity player;
private RigidBodyControl playerControl;
private boolean left = false;
private boolean right = false;
private boolean forward = false;
private boolean back = false;public static void main(String[] args) {
Main app = new Main();
app.start();
}public Main() {
super(new StatsAppState());
}@Override
public void simpleInitApp() {bulletAppState = new BulletAppState(); stateManager.attach(bulletAppState); //scene = (Node)assetManager.loadModel("Scenes/scene.mesh.j3o"); scene = initScene(); rootNode.attachChild(scene); CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(scene); RigidBodyControl sceneControl = new RigidBodyControl(sceneShape, 0); sceneControl.setKinematic(true); scene.addControl(sceneControl); bulletAppState.getPhysicsSpace().add(sceneControl); //Spatial playerMesh = assetManager.loadModel("Textures/units/player/player.obj"); Spatial playerMesh = new Geometry("player", new Box(0.5f, 0.5f, 1f)); Material playerMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); playerMaterial.setColor("Color", ColorRGBA.Blue); playerMesh.setMaterial(playerMaterial); player = new Entity("Player", playerMesh); player.setSpeed(PLAYER_MOVE_SPEED); player.setRotationSpeed(PLAYER_ROTATION_SPEED); player.setLocalTranslation(0, 0.1f, 0); scene.attachChild(player); CollisionShape playerShape = CollisionShapeFactory.createBoxShape(player); playerControl = new RigidBodyControl(playerShape, 1f); player.addControl(playerControl); bulletAppState.getPhysicsSpace().add(playerControl); Light light = new AmbientLight(); rootNode.addLight(light); PointLight pointLight = new PointLight(); pointLight.setPosition(new Vector3f(15, 10, 15)); rootNode.addLight(pointLight); cam.setLocation(new Vector3f(0, 15, 15)); cam.lookAt(player.getLocalTranslation(), Vector3f.UNIT_Y); setupKeys();
}
private Node initScene() {
Geometry floor = new Geometry(“floor”, new Box(10, 0.1f, 10f));
Material floorMaterial = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
floorMaterial.setColor(“Color”, ColorRGBA.Gray);
floor.setMaterial(floorMaterial);Geometry box1 = new Geometry("box1", new Box(1, 1, 1)); box1.setLocalTranslation(2, 0.5f, 1); Geometry box2 = new Geometry("box2", new Box(1, 1, 1)); box2.setLocalTranslation(-2, 0.5f, 1); Material boxMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); boxMaterial.setColor("Color", ColorRGBA.Brown); box1.setMaterial(boxMaterial); box2.setMaterial(boxMaterial); Node scene = new Node("scene"); scene.attachChild(floor); scene.attachChild(box1); scene.attachChild(box2); return scene;
}
private void setupKeys() {
inputManager.addMapping(ACTION_FORWARD, new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping(ACTION_BACK, new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping(ACTION_LEFT, new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping(ACTION_RIGHT, new KeyTrigger(KeyInput.KEY_D));inputManager.addListener(this, ACTION_FORWARD); inputManager.addListener(this, ACTION_BACK); inputManager.addListener(this, ACTION_LEFT); inputManager.addListener(this, ACTION_RIGHT); mouseInput.setCursorVisible(true);
}
@Override
public void simpleUpdate(float tpf) {
if (left) {
Quaternion rotation = new Quaternion().fromAngleAxis(
player.getRotationSpeed() * tpf, Vector3f.UNIT_Y);
player.setDirection(rotation.mult(player.getDirection()));
player.rotate(rotation);
} else if (right) {
Quaternion rotation = new Quaternion().fromAngleAxis(
-player.getRotationSpeed() * tpf, Vector3f.UNIT_Y);
player.setDirection(rotation.mult(player.getDirection()));
player.rotate(rotation);
}player.setMoveDirection(Vector3f.ZERO); if (forward) { player.setMoveDirection(player.getDirection().mult(player.getSpeed())); } else if (back) { player.setMoveDirection(player.getDirection().negate().multLocal(player.getSpeed())); } playerControl.setLinearVelocity(player.getMoveDirection()); //player.move(player.getMoveDirection().mult(tpf)); cam.lookAt(player.getLocalTranslation(), Vector3f.UNIT_Y);
}
@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}@Override
public void onAction(String name, boolean isPressed, float tpf) {
if (ACTION_FORWARD.equals(name)) {
if (isPressed) {
forward = true;
} else {
forward = false;
}
} else if (ACTION_BACK.equals(name)) {
if (isPressed) {
back = true;
} else {
back = false;
}
} else if (ACTION_LEFT.equals(name)) {
if (isPressed) {
left = true;
} else {
left = false;
}
} else if (ACTION_RIGHT.equals(name)) {
if (isPressed) {
right = true;
} else {
right = false;
}
}
}
}
[/java]
Say we have something like a tank (can rotate and move). Move by W&S and rotate by A&D.
- Why my character is not rotated? If I remove RigidBodyControl from it I can rotate model by A&D.
- Why it sometimes rotates when I move it forward or backward?
- How make next behaviour - when characters hit with obstacle it just stops and not begins rotation?
I tried implement collision detection via Spatial.collideWith but I found that in JME3 collisions between spaitals are not supported.