setPhysicsLocation() - What am I doing wrong?

Hello all,



I’m having an issue getting setPhysicsLocation() to work. My model always starts in the centre of the scene and half below the floor surface, unable to move! And I can’t seem to change it at all no matter what location vector3f I put in to model.setPhysicsLocation().



I started with the collision tutorial with the first person camera int he “town” scene and went about altering the code to be third-person using walkingCharacter example which uses a chase camera. Initially it seemed to be working fine with an orge model loaded in as my character model which used setPhysicsLocation() for its starting location.



Unfortunately I messed up in modelling/animation and my character was rotated 90 degrees. In trying to fix this using model.setLocalRotation() it seems to have had an effect on the setPhysicsLocation. I believe its the only thing I changed in between builds. But its always possible I did something else. Either way I can’t seem to fix the problem.



Heres my code:



package mygame;





import com.jme3.animation.AnimChannel;

import com.jme3.animation.AnimControl;

import com.jme3.animation.AnimEventListener;

import com.jme3.app.SimpleApplication;

import com.jme3.asset.plugins.ZipLocator;

import com.jme3.bullet.BulletAppState;

import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;

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.input.ChaseCamera;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.scene.Node;

import com.jme3.scene.Spatial;



/**

  • Example 9 - How to make walls and floors solid.
  • This version uses Physics and a custom Action Listener.
  • @author normen, with edits by Zathras

    /

    public class Main extends SimpleApplication

    implements ActionListener, AnimEventListener {



    private Spatial sceneModel;

    private BulletAppState bulletAppState;

    private RigidBodyControl landscape;

    private CharacterControl player;

    private Node model;

    private Vector3f walkDirection = new Vector3f();

    private boolean left = false, right = false, up = false, down = false;

    private ChaseCamera chaseCam;



    private AnimChannel animationChannel;

    private AnimControl animationControl;



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    public void simpleInitApp() {

    /
    * Set up Physics /

    bulletAppState = new BulletAppState();

    stateManager.attach(bulletAppState);



    // We re-use the flyby camera for rotation, while positioning is handled by physics

    viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));

    flyCam.setMoveSpeed(100);

    setUpKeys();

    setUpLight();



    // We load the scene from the zip file and adjust its size.

    assetManager.registerLocator(“town.zip”, ZipLocator.class.getName());

    sceneModel = assetManager.loadModel(“main.scene”);

    sceneModel.setLocalScale(2f);



    // We set up collision detection for the scene by creating a

    // compound collision shape and a static physics node with mass zero.

    CollisionShape sceneShape = CollisionShapeFactory.createMeshShape((Node) sceneModel);

    landscape = new RigidBodyControl(sceneShape, 0);

    sceneModel.addControl(landscape);



    // We set up collision detection for the player by creating

    // a capsule collision shape and a physics character node.

    // The physics character node offers extra settings for

    // size, stepheight, jumping, falling, and gravity.

    // We also put the player in its starting position.

    CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f, 1.0f, 1);

    player = new CharacterControl(capsuleShape, 0.05f);

    player.setJumpSpeed(18);

    player.setFallSpeed(30);

    player.setGravity(40);

    model = (Node) assetManager.loadModel(“Models/Cow/Cube.mesh.j3o”);

    model.setLocalScale(2.0f);

    player.setPhysicsLocation(new Vector3f(0f,10f,0f));

    rootNode.attachChild(model);



    // We attach the scene and the player to the rootnode and the physics space,

    // to make them appear in the game world.

    rootNode.attachChild(sceneModel);

    bulletAppState.getPhysicsSpace().add(landscape);

    bulletAppState.getPhysicsSpace().add(player);



    SetupChaseCamera();

    SetupAnimationController();

    }



    private void SetupChaseCamera() {

    flyCam.setEnabled(false);

    chaseCam = new ChaseCamera(cam, model, inputManager);

    }



    private void setUpLight() {

    // We add light so we see the scene

    AmbientLight al = new AmbientLight();

    al.setColor(ColorRGBA.White.mult(1.3f));

    rootNode.addLight(al);



    DirectionalLight dl = new DirectionalLight();

    dl.setColor(ColorRGBA.White);

    dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());

    rootNode.addLight(dl);

    }



    private void SetupAnimationController() {

    animationControl = model.getControl(AnimControl.class);

    animationControl.addListener(this);

    animationChannel = animationControl.createChannel();

    }



    /
    * We over-write some navigational key mappings here, so we can
  • add physics-controlled walking and jumping: /

    private void setUpKeys() {

    inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_A));

    inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_D));

    inputManager.addMapping(“Ups”, new KeyTrigger(KeyInput.KEY_W));

    inputManager.addMapping(“Downs”, new KeyTrigger(KeyInput.KEY_S));

    inputManager.addMapping(“Jumps”, new KeyTrigger(KeyInput.KEY_SPACE));

    inputManager.addListener(this, “Lefts”);

    inputManager.addListener(this, “Rights”);

    inputManager.addListener(this, “Ups”);

    inputManager.addListener(this, “Downs”);

    inputManager.addListener(this, “Jumps”);

    }



    /
    * These are our custom actions triggered by key presses.
  • We do not walk yet, we just keep track of the direction the user pressed. */

    public void onAction(String binding, boolean value, float tpf) {

    if (binding.equals(“Lefts”)) {

    left = value;

    } else if (binding.equals(“Rights”)) {

    right = value;

    } else if (binding.equals(“Ups”)) {

    up = value;

    } else if (binding.equals(“Downs”)) {

    down = value;

    } else if (binding.equals(“Jumps”)) {

    player.jump();

    }



    }



    /**
  • This is the main event loop–walking happens here.
  • We check in which direction the player is walking by interpreting
  • the camera direction forward (camDir) and to the side (camLeft).
  • The setWalkDirection() command is what lets a physics-controlled player walk.
  • We also make sure here that the camera moves with player.

    */

    @Override

    public void simpleUpdate(float tpf) {

    Vector3f camDir = cam.getDirection().clone().multLocal(0.2f);

    Vector3f camLeft = cam.getLeft().clone().multLocal(0.2f);

    camDir.y = 0;

    camLeft.y = 0;

    walkDirection.set(0, 0, 0);

    if (left) { walkDirection.addLocal(camLeft); }

    if (right) { walkDirection.addLocal(camLeft.negate()); }

    if (up) { walkDirection.addLocal(camDir); }

    if (down) { walkDirection.addLocal(camDir.negate()); }



    if (walkDirection.length() == 0) {

    if (!“Stand”.equals(animationChannel.getAnimationName())) {

    animationChannel.setAnim(“Stand”, 1f);

    }

    } else {

    player.setViewDirection(walkDirection);

    if (!“Walk”.equals(animationChannel.getAnimationName())) {

    animationChannel.setAnim(“Walk”, 0.7f);

    }

    }



    player.setWalkDirection(walkDirection);

    cam.setLocation(player.getPhysicsLocation());

    }



    public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {



    }



    public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {

    }

    }

You never add the character control to the model…

Oh man what an idiot! I must have deleted it by accidident… How embarassing!



Thanks so much!