Camera location not updating

I seem to be having issues with setting the position of my camera. I copied the init code from SimpleGame but no matter what value I put in the loc vector my camera sits at 0,0,0. I also am confused to why my box is only visible when it’s z position is >0. I thought that the camera was looking down the -z axis and thus a position of -30 would be farther away than a position of -20. If I set the box’s position to negative anything it is behind the camera and the larger (positive) z position I give it the farther away it moves. I’m using FixedFramerateGame to drive my update/render loops. I have a GameStateManager and my main game state loaded through the manager. Here is my initialization code for my StandardGameState.



public class MainGameState extends StandardGameState {

   private DisplaySystem display;

   public MainGameState() {
      display = DisplaySystem.getDisplaySystem();

      Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
      Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);

      cam.setFrame(loc, left, up, dir);
      cam.update();

      Box b = new Box("Box", new Vector3f(0, 0, 10), 1f, 1f, 1f);
      stateNode.attachChild(b);
      b.setRandomColors();

      stateNode.updateGeometricState(0.0f, true);
      stateNode.updateRenderState();

      System.out.println("Cam at:" + cam.getLocation());
      System.out.println("Node at:" + b.getCenter());

   }



The output from those println's are:


     [java] Cam at:com.jme.math.Vector3f [X=0.0, Y=0.0, Z=25.0]
     [java] Node at:com.jme.math.Vector3f [X=0.0, Y=0.0, Z=10.0]



I also tried creating a CameraNode and putting the camera in that. If I set the local translation to (0,0,-25) then I see my box far away but I've moved in the -z direction when I thought I should have moved in the +z direction to back away. Reversing the dir vector up in the camera initialization didn't effect what I was seeing, I still got the same box in the same place.

Not sure if this helps, but your left vector is 1,0,0 if you’re at positive Z looking negative Z with an up of positive Y.

no matter what value I put in the loc vector my camera sits at 0,0,0


Your print out says:

[java] Cam at:com.jme.math.Vector3f [X=0.0, Y=0.0, Z=25.0]

which is exactly where you told it to be. So I'm confused about that problem, or did I misunderstand what you are saying?

OpenGL is a right handed coordinate system, so if your left is (-1,0,0) and up is (0,1,0) then your direction would need to be (0, 0, 1) not (0,0,-1). Setting it to (0,0,-1) a left handed coordinate system is created and going to result in very strange results.
"Cep21" wrote:
Not sure if this helps, but your left vector is 1,0,0 if you're at positive Z looking negative Z with an up of positive Y.

I copied my four vectors straight out of SimpleGame. I thought if you're looking at the origin from a positive Z position then positive Y would be "up" and negative X would be "left" while negative z is "ahead". Perhaps I'm getting my left/right hand coordinate systems all mixed up.


-z    +y
  <- |- - Can't see the box here at (0,0, -10);
      |
      |
       / <-- If I move the box here (0,0,0) the camera is inside the box
     /   
   /        <-- Box says it's here at (0,0,10)
 /           
-x            +z  <-- Camera says it's here at (0,0,25)



So if that drawing is correct then my box should get farther away when it's Z value goes more negative. Currently when I move the box more z-positive it gets further away as if I'm at -z looking towards +z but that can't be correct either because my box is between the camera and the origin (on the +z side). The thing that's most odd is that moving the box to 0,0,0 makes it appear around the camera which indicates to me that the camera is also at 0,0,0 even though it's reporting a position of 0,0,25.

I will definately go read up on left hand vs right hand coordinate systems but this still seems strange to me as it's straight out of the SimpleGame init().
I copied my four vectors straight out of SimpleGame.


You know, I totally screwed up in my answer.

(-1,0,0)(0,1,0)(0,0,-1) is a right handed coordinate system.

Give me a break, I just got off vacation :).

So, let me re-think your problem again...

I will definately go read up on left hand vs right hand coordinate systems but this still seems strange to me as it's straight out of the SimpleGame init().


No need... it was I who gave you the bad info.

Since you are playing with StandardGameState it has some of it’s own camera stuff so maybe something is conflicting with your camera settings? This is a guess.



Have you tried doing this state as a stand alone app to make sure it works in that mode (BaseGame rather than StandardGameState)?



That might give further insight.



and again, sorry for leading you down the wrong path with the LHC vs RHC junk.

Gah disregard my previous post. I was confused myself. This site explains the right/left handed thing.

http://www.evl.uic.edu/ralph/508S98/coordinates.html



Your code snip looks fine. What else are you doing in your code?

"Cep21" wrote:
Gah disregard my previous post. I was confused myself. This site explains the right/left handed thing.
http://www.evl.uic.edu/ralph/508S98/coordinates.html

Your code snip looks fine. What else are you doing in your code?

Thanks for the LH vs RH page, that lays it out nicely. One question about the left handed z rotation. It shows what looks to be a counter-clockwise rotation (same picture as righ hand with z axis flipped). I would think it would be moving from the y+ axis to the x+ axis in a clockwise fashion or do you view the rotation from the z+ side and therefore it's clockwise from that view?
"mojomonk" wrote:
Have you tried doing this state as a stand alone app to make sure it works in that mode (BaseGame rather than StandardGameState)?

I will definately cut out the whole game state manager and just instantiate a camera in the base game. Thanks for the help!

This method gets called from the StandardGameState constructor:


   /**
    * Initializes a standard camera.
    */
   private void initCamera() {
      DisplaySystem display = DisplaySystem.getDisplaySystem();
      
      cam = display.getRenderer().createCamera(
            display.getWidth(),
            display.getHeight());
      
      cam.setFrustumPerspective(45.0f,
            (float) display.getWidth() /
            (float) display.getHeight(), 1, 1000);
      
      cam.update();
   }


As you can see, this camera being created isn't set as the Renderers camera. That don't happen until the state is switched to.

I don't know what you do later in your app, but if that state of yours is never beeing switched upon, the camera you'r editing will never be activated (get set as the renderers camera).
"Per" wrote:
As you can see, this camera being created isn't set as the Renderers camera. That don't happen until the state is switched to.

I don't know what you do later in your app, but if that state of yours is never beeing switched upon, the camera you'r editing will never be activated (get set as the renderers camera).


public void switchTo(String name) {
      rootNode.detachAllChildren();

      current = (GameState)states.get(name);
      rootNode.attachChild(current.getStateNode());

      DisplaySystem.getDisplaySystem().getRenderer().
         setCamera(current.getCamera());
      
      try {
         if (SoundAPIController.getRenderer() != null)
            SoundAPIController.getRenderer().setCamera(current.getCamera());
      } catch (IllegalArgumentException e) {
         // Do nothing - it just means that the sound system hasn't been
         // initialised.
      }

      current.switchTo();

      rootNode.updateRenderState();
      rootNode.updateGeometricState(0, true);
   }



The GameStateManager switchTo() method after attaching the new stateNode sets the camera to state's camera and then calls the individual state's switchTo().
"EsotericMoniker" wrote:
The GameStateManager switchTo() method after attaching the new stateNode sets the camera to state's camera and then calls the individual state's switchTo().
Sorry, after I re-read your post I realized you already said this. ://

In my main game in the initGame() method I do:


protected void initGame()
   {      
      rootNode = new Node("Root node");
      manager = GameStateManager.create(rootNode);
      manager.addGameState("Main Game", new MainGameState());
      manager.addGameState("Main Menu", new MainMenuState());
      manager.switchTo("Main Game");
      
      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();
   }



So the state is definately getting switched on.

I put all my initialization code in the base game class and it works as expected. It’s a cut and paste from the MainGameState’s initGame plus the initCamera code from StandardGameState plus what was already in the main game initGame. With this code the box is viewable at positive (up to the camera’s position of course), negative and zero Z values.



Game.initGame()


protected void initGame()
   {      
      rootNode = new Node("Root node");
      Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
      Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);

      cam =   display.getRenderer().createCamera(
                  display.getWidth(),
                  display.getHeight());
      
      cam.setFrustumPerspective(45.0f,
            (float) display.getWidth() /
            (float) display.getHeight(), 1, 1000);
      cam.update();
      cam.setFrame(loc, left, up, dir);
      cam.update();
      
      display.getRenderer().setCamera(cam);
      
      Box b = new Box("Box", new Vector3f(0,0,0), 1, 1, 1);
      b.setRandomColors();
      rootNode.attachChild(b);
      
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.CF_LEQUAL);
      rootNode.setRenderState(buf);

      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();
   }



I put the exact same code back in the MainGameState's initGame and it goes back to the old behavior of the camera staying at 0,0,0 no matter what values I use for the loc vector. I even tried recreating the camera in the MainGameState's initGame with this code:

MainGameState.initGame()


Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);

cam = display.getRenderer().createCamera(
      display.getWidth(),
      display.getHeight());
      
cam.setFrustumPerspective(45.0f,
      (float) display.getWidth() /
      (float) display.getHeight(), 1, 1000);
            
cam.setFrame(loc, left, up, dir);
cam.update();



No change, still at 0,0,0 and the box at a positive z value moves away. }:-@

Just so I'm clear here is all the code I'm currently using:
(Game derives from FixedFramerateGame in case it matters)
Game.initSystem()


protected final void initSystem()
   {
       try
      {
           /** Get a DisplaySystem acording to the renderer selected in the startup box. */
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
          /** Create a window with the startup box's information. */
         display.createWindow(
               properties.getWidth(),
               properties.getHeight(),
               properties.getDepth(),
               properties.getFreq(),
               properties.getFullscreen());
       }
       catch (JmeException e)
      {
           /** If the displaysystem can't be initialized correctly, exit instantly. */
         e.printStackTrace();
         System.exit(1);
       }

       display.getRenderer().setBackgroundColor(new ColorRGBA(.98f, .98f, .65f, 0f));

       display.setTitle("Palabra");
     }




Game.initGame()


protected void initGame()
   {      
      rootNode = new Node("Root node");

       manager = GameStateManager.create(rootNode);
      manager.addGameState("Main Game", new MainGameState());
      manager.addGameState("Main Menu", new MainMenuState());
      manager.switchTo("Main Game");
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.CF_LEQUAL);
      rootNode.setRenderState(buf);

      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();
   }




Game.render()


protected void render(float tpf)
   {
      manager.render(tpf);
   }



MainGameState derives from StandardGameState
MainGameState.MainGameState()


public MainGameState()
{
   display = DisplaySystem.getDisplaySystem();
   input = new InputHandler();
   
   Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
   Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
   Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
   Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);

   cam.setFrame(loc, left, up, dir);
   cam.update();
      
   Box b = new Box("Box", new Vector3f(0, 0, 0), 1f, 1f, 1f);
   b.setRandomColors();
   stateNode.attachChild(b);
      
   stateNode.updateGeometricState(0.0f, true);
   stateNode.updateRenderState();
}



MainGameState.render()


public void render(float tpf)
{
   display.getRenderer().clearBuffers();
   display.getRenderer().draw(stateNode);
}

I can’t see you would do anything wrong with the handling of game states (except maybe you’r not updating them, but that shouldn’t matter in this case).



Maybe you should take a look at the TestGameStateSystem as I’m moving the camera some on line 71 in the IngameState class, which seems to work just fine.



Hope that helps.

"Per" wrote:
Maybe you should take a look at the TestGameStateSystem as I'm moving the camera some on line 71 in the IngameState class, which seems to work just fine.


public IngameState() {
      super();      
      initGame();
   }



The only difference I can see between the test implementation and my own is that the test calls super() before going about it's init tasks. Wouldn't super() have been implicitly called during object construction? As for updating, my main game does call manager.update(tpf) so that shouldn't be a problem.

Thanks everyone for all the help, I'm going to go off and figure this out or throw my computer out the windows, which ever comes first.

This brings back memories of Dirt’s game state system… I had to add additional reinit methods to my state interface and such to get my cameras working properly. I mentioned this in my comments on the whole game state code thread I believe… I’ll look back at the Dirt code and comment on the particulars if anyone is interested.

Renanse, is this something you put into the game state management itself or something you had to do while USING the game state manager? That is, is it something that should be added to this games state stuff to keep this problem from affecting someone else?

Ok, after a whole lot of experimentation I finally found out how to get everything working ok. It turns out I had to put cam.update() in my MainGameState’s switchTo(). This is very strange since I have a cam.update() in my MainGameState’s init() but that doesn’t seem to do the trick. Would it be possible to change the GameStateManager.switchTo() method to have this


current.getCamera.update();



at the end just before/after the rootNode.updateRenderState() and rootNode.updateGeometricState(0, true) ?

That way I wouldn't have to remember to put cam.update inside each new GameState's switchTo().

EDIT: I was going to point out that the TestGameState didn't have the cam.update in the switchTo() so maybe it's just some wacked out thing with my computer. I am running the 1.5 JVM and I've heard of issues with threading not working as it did in 1.4 so that might also becontributing to the problem.