title: Java Monkey Engine (jME) - Physics Control
body: <p>I am new in jME (java Monkey Engine). I am doing my master project about a smart home simulator. I decided to do this project with jME.</p>
  
  <p>Right now, I have a 3D model into my simulator, the next step I want to do It's control the main door of my virtual house, so, I followed this tutorial and I could implement exactly I wanted.</p>
  
  <pre><code>http://www.youtube.com/watch?v=MNDiZ9YHIpM
  </code></pre>
  
  <p>I tried opening and closing the door, and I got. But the problem is the physics, when the door is opening you can see how the door is opening, but when I try to cross the door I can't , I know I can do a physics layer into the object but when I try to do this the control disapear. </p>
  
  <p>I have a class which control my main door and I would like insert into that class a rigid body for my door but i can't, so i would like to know if someone know how do this.</p>
  
  <p>Thank You!!!</p>
  
  <p>PD: sorry for my english!!!</p>
  
  <p>This is the code I am using:</p>
  
  <p>Main Class</p>
  
  <pre><code>public class Main extends SimpleApplication
          implements ActionListener{
  
  private GhostControl ghostControl;
    private Node staticScene,dynamicScene;
    private BulletAppState bulletAppState;
    private RigidBodyControl landscape;
    private OpenDoor rigidDoor;
    private CharacterControl player;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;
  
    Spatial mainDoor;
    OpenDoor control;
  
    HUD hud = new HUD();
    BitmapText hudText;
  
    public static void main(String[] args) {
      Main app = new Main();
       //some presets
      AppSettings settings = new AppSettings(true);
      settings.setResolution(1280,720);
      settings.setFrameRate(60);
      //settings.setFullscreen(true);
      app.setSettings(settings);
      //app.setShowSettings(false);
      app.setPauseOnLostFocus(true);
      app.start();
    }
  
    public void simpleInitApp() {   
      //don't show stats
      setDisplayFps(false);
      setDisplayStatView(false);
  
      //PIC
      Picture pic = new Picture("HUD Picture");
      pic.setImage(assetManager, "Textures/hudFrame.png", true);
      pic.setWidth(settings.getWidth());
      pic.setHeight(settings.getHeight()/8);
      pic.setPosition(0,settings.getHeight()-settings.getHeight()/8);
      guiNode.attachChild(pic);
      //Show HUD
  
  
      hudText = new BitmapText(guiFont, false);   
      hudText.setSize(guiFont.getCharSet().getRenderedSize());      // font size
      hudText.setSize(settings.getHeight()/45);
      hudText.setColor(ColorRGBA.Green);                             // font color
      hudText.setLocalTranslation(settings.getWidth()/45,settings.getHeight()-settings.getHeight()/45, 0); // 
      guiNode.attachChild(hudText);
  
      hud = new HUD();
  
      /** Set up Physics */
      bulletAppState = new BulletAppState();
      bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);//for bullets
      stateManager.attach(bulletAppState);
      //bulletAppState.getPhysicsSpace().enableDebug(assetManager);
      // 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();
  
      //Preload Levels
  
      staticScene = (Node) assetManager.loadModel("Scenes/newScene.j3o");
      staticScene.setLocalScale(5f);
  
      //Intentamos hacer lo mismo pero a partir de un nodo del modelo
      mainDoor = (Spatial)staticScene.getChild("MainDoor-ogremesh");    
  
  
  
  
      //Set up physics and add level/player to scenegraph
  
      setDoor(mainDoor);
      setLevel(staticScene);    
  
    }
  
    private void setLevel(Spatial level) {
       // We set up collision detection for the scene by creating a
      // compound collision shape and a static RigidBodyControl with mass zero.
      CollisionShape sceneShape =
              CollisionShapeFactory.createMeshShape((Node) level);
  
      landscape = new RigidBodyControl(sceneShape, 0);  
      level.addControl(landscape);
  
      // We set up collision detection for the player by creating
      // a capsule collision shape and a CharacterControl.
      // The CharacterControl 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, 6f, 1);
      player = new CharacterControl(capsuleShape, 0.05f);
      player.setJumpSpeed(20);
      player.setFallSpeed(30);
      player.setGravity(30);
      player.setPhysicsLocation(new Vector3f(20,10,-10));
      // We attach the scene and the player to the rootnode and the physics space,
      // to make them appear in the game world.
      rootNode.attachChild(level);
      bulletAppState.getPhysicsSpace().add(landscape);
      bulletAppState.getPhysicsSpace().add(player); 
  
  
    }
  
    public void setDoor(Spatial door){
  
      CollisionShape sceneDoor =
              CollisionShapeFactory.createMeshShape((Node)door);
  
      rigidDoor = new OpenDoor(sceneDoor, 0);
      rigidDoor.setKinematic(true);
  
      door.addControl(rigidDoor);
      bulletAppState.getPhysicsSpace().add(door); 
  
    }
  
    private PhysicsSpace getPhysicsSpace() {
          return bulletAppState.getPhysicsSpace();
    }
  
    private void setUpLight() {
      // We add light so we see the scene
      AmbientLight al = new AmbientLight();
      al.setColor(ColorRGBA.White.mult(0.1f));
      rootNode.addLight(al);
  
      DirectionalLight dl = new DirectionalLight();
      dl.setColor(ColorRGBA.White);
      dl.setDirection(new Vector3f(1.5f, -2, 2).normalizeLocal());
      rootNode.addLight(dl);
    }
  
    /** We over-write some navigational key mappings here, so we can
     * add physics-controlled walking and jumping: */
    private void setUpKeys() {
      inputManager.deleteMapping(INPUT_MAPPING_EXIT);
      inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
      inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
      inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
      inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
      inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
      inputManager.addMapping("Action", new KeyTrigger(KeyInput.KEY_E));
      inputManager.addMapping("Quit", new KeyTrigger(KeyInput.KEY_ESCAPE));
      inputManager.addListener(this, "Left");
      inputManager.addListener(this, "Right");
      inputManager.addListener(this, "Up");
      inputManager.addListener(this, "Down");
      inputManager.addListener(this, "Jump");
      inputManager.addListener(actionListener,"Action");
      inputManager.addListener(this, "Quit"); // listen for ESC key to close game
    }
  
    public void onAction(String binding, boolean value, float tpf) {
  
      hud.setToken(binding);
  
      if (binding.equals("Left")) {
        if (value) { left = true; } else { left = false; }
      } else if (binding.equals("Right")) {
        if (value) { right = true; } else { right = false; }
      } else if (binding.equals("Up")) {
        if (value) { up = true; } else { up = false; }
      } else if (binding.equals("Down")) {
        if (value) { down = true; } else { down = false; }
      } else if (binding.equals("Jump")) {
        player.jump();
      } else if (binding.equals("Quit")) {
        stop(); // simple way to close game
      } 
    }
  
    private ActionListener actionListener = new ActionListener() {
      public void onAction(String name, boolean keyPressed, float tpf) {
        if (name.equals("Action") &amp;&amp; !keyPressed) {
           rigidDoor.actionDoor();
  
        }
      }
    };
  
  
    @Override
    public void simpleUpdate(float tpf) {
  
          Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
          Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
          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()); }
          player.setWalkDirection(walkDirection);
          cam.setLocation(player.getPhysicsLocation());  
    }
  
  
  }
  </code></pre>
  
  <p>DoorControl Class</p>
  
  <pre><code>    public class OpenDoor extends RigidBodyControl{
  
      static final float PI = 3.14159265359f;    
      private float speed = 5;
      private float inipos = 0f;
      private boolean action = false; //true=opening, false=closing
      RigidBodyControl myRigidBody;
  
      public OpenDoor() {
  
      }
  
      public OpenDoor(CollisionShape sceneDoor, int i) {
          super(sceneDoor,i);
  
      }
  
      @Override
      public void update(float tpf) {
          super.update(tpf);
          Quaternion q = new Quaternion();
          q.fromAngles(0, -tpf, 0);
  
          spatial.rotate(q); 
  
  
  
          /*float angle;
          float angleRads;
          angle = speed;
          angleRads = (angle * PI)/180;
          if(action==true){
              //counter = counter + angleRads;
              if(Math.abs(spatial.getLocalRotation().getY()*2.2-inipos)&lt;PI/2){
                  spatial.rotate(0, -angleRads,0); 
  
              }
  
          }else{
  
              if(spatial.getLocalRotation().getY()*2.2-inipos&lt;0){
              spatial.rotate(0, angleRads,0);
              }            
  
          }          
  
  */
      }
  
      /**
       * @return the speed
       */
      public float getSpeed() {
          return speed;
      }
  
      /**
       * @param speed the speed to set
       */
      public void setSpeed(float speed) {
          this.speed = speed;
      }
  
      /**
       * @return the action
       */
      public boolean isAction() {
          return action;
      }
  
      /**
       * @param action the action to set
       */
      public void setAction(boolean action) {
          this.action = action;
      }
  
      public boolean getAction() {
          return action;
      }
  
      public void actionDoor(){
  
         setAction(!action);
  
      }
  
      public Object getRigidDoor() {
          return myRigidBody;
      }
  
  
  
  }
  </code></pre>