Camera translation

Hi,

I just installed JME 2.0. I use this code


import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import javax.swing.ImageIcon;

import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;


import com.jme.bounding.BoundingBox;
import com.jme.input.AbsoluteMouse;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.CameraNode;
import com.jme.scene.shape.Box;
import com.jme.system.DisplaySystem;
import com.jmex.awt.JMECanvas;
import com.jmex.awt.SimpleCanvasImpl;
import com.jmex.awt.input.AWTMouseInput;

public class RotatingCube extends javax.swing.JFrame {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   private Canvas canvas1;
   int width = 640, height = 480;
   MyImplementor impl;

   /**
   * Auto-generated main method to display this JFrame
   */
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            RotatingCube inst = new RotatingCube();
            inst.setLocationRelativeTo(null);
            inst.setVisible(true);
         }
      });
   }
   
   public RotatingCube() {
      super();
      initOpenGl();
      initGUI();
      new Thread() {
         {
            setDaemon(true);
         }

         public void run() {
            while (true) {
               canvas1.repaint();
               try {
                  Thread.sleep(1);
               } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }// yield();
            }
         }
      }.start();
      Toolkit.getDefaultToolkit().getSystemEventQueue().push(
               new EventQueue(){
                   protected void dispatchEvent(AWTEvent event) {
                                if (event instanceof KeyEvent) {
                                      KeyEvent keyEvent = (KeyEvent) event;
                                      if (keyEvent.getID() == KeyEvent.KEY_TYPED){
                                             if(keyEvent.getKeyChar()=='+'){
                                                impl.scalePlus();
                        
                                             }else if(keyEvent.getKeyChar()=='-'){
                                                impl.scaleMinus();
                                             }
                                           
                                            }
                                    }
                                   super.dispatchEvent(event);
                 
                                      }
               });
   }
   
   private void initOpenGl(){
      canvas1 = DisplaySystem.getDisplaySystem("lwjgl").createCanvas(width,
            height);
      //
      // add a listener... if window is resized, we can do something about
      // it.
      canvas1.addComponentListener(new ComponentAdapter() {
         public void componentResized(ComponentEvent ce) {
            doResize();
         }
      });
      KeyInput.setProvider(KeyInput.INPUT_AWT);
      AWTMouseInput.setup(canvas1, false);
      // Important! Here is where we add the guts to the panel:
      impl = new MyImplementor(width, height);
      JMECanvas jmeCanvas = ((JMECanvas) canvas1);
      jmeCanvas.setImplementor(impl);
      jmeCanvas.setUpdateInput(true);
      
      
   }
   
   private void initGUI() {
      try {
         setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
         this.setIconImage(new ImageIcon(getClass().getClassLoader().getResource("stern_icon.png")).getImage());
         this.setTitle("Mouse Cube");
         {
            getContentPane().add(canvas1, BorderLayout.CENTER);
            canvas1.setBounds(0,0,width,height);
         }
         pack();      
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   
   protected void doResize() {
         impl.resizeCanvas(canvas1.getWidth(), canvas1.getHeight());
      

   }

   // Overridden so we can exit when window is closed
   protected void processWindowEvent(WindowEvent e) {
      super.processWindowEvent(e);
      if (e.getID() == WindowEvent.WINDOW_CLOSING) {
         System.exit(0);
      }
   }
   
   // IMPLEMENTING THE SCENE:
   
   public class MyImplementor extends SimpleCanvasImpl {

      private Quaternion rotQuat, rotQuat2;
      private Vector3f oCamTranslation;
      private CameraNode oCamNode;
      private Box box;
      private boolean pressed = false;
      AbsoluteMouse am;
      private float scale=0;
      
      
      private int oldX, oldY, newX, newY;
      public MyImplementor(int width, int height) {
         super(width, height);
      }
      public void scalePlus(){
         scale-=0.05f;
         if(scale<-0.25f)scale=-0.25f;
      }
      
      public void scaleMinus(){
         scale+=0.05f;
         if(scale>3)scale=3;
      }
      
      public void simpleSetup() {
         am = new AbsoluteMouse("The Mouse", width, height);
         DisplaySystem.getDisplaySystem().getRenderer().setBackgroundColor( ColorRGBA.white );
         // Normal Scene setup stuff...
         rotQuat = new Quaternion();
         rotQuat2 = new Quaternion();
         
         oCamNode = new CameraNode( "Camera Node", this.getCamera());
         Vector3f max = new Vector3f(5, 5, 5);
         Vector3f min = new Vector3f(-5, -5, -5);
         box = new Box("Box", min, max);
         rootNode.attachChild(box);
         rootNode.attachChild(oCamNode);
         box.setRandomColors();
         oCamTranslation=new Vector3f(0,0,-20f);
         oCamNode.setLocalTranslation(oCamTranslation);
         
         oCamNode.lookAt(box.getLocalTranslation(), new Vector3f(0,1,0));
         box.setModelBound(new BoundingBox());
         box.updateModelBound();
         rotQuat2=oCamNode.getLocalRotation();
         
         
      }

      private Vector3f trackBallMapping(int px, int py) {
         float x = ((float) px)-(float)width/2;
         float y = ((float) py)-(float)height/2;
         float z2 = width*height*1000 - x * x - y * y;
         float z = z2 > 0 ? FastMath.sqrt(z2) : 0;
         return new Vector3f(x, y, z);
      }
      
      
      
      public void simpleUpdate() {
         
         if (MouseInput.get().isButtonDown(0)) {
            if (!pressed) {
               pressed = true;
               oldX = MouseInput.get().getXAbsolute();
               oldY = MouseInput.get().getYAbsolute();
               
            }
            newX=MouseInput.get().getXAbsolute();
            newY=MouseInput.get().getYAbsolute();
            
            Vector3f oLastVector3f = this.trackBallMapping(oldX, oldY);         
         
            Vector3f oNewVector3f = this.trackBallMapping(newX, newY);
            Vector3f oAxisVector = oLastVector3f.cross(oNewVector3f);
            Vector2f oVector2f=new Vector2f(newX-oldX,newY-oldY);
            float tAngle = oVector2f.length();
            rotQuat.fromAngleAxis(-tAngle*FastMath.DEG_TO_RAD,oAxisVector);
            rotQuat2.multLocal(rotQuat);
            oCamNode.setLocalTranslation(rotQuat2.mult(oCamTranslation).mult(FastMath.exp(scale)));
            oCamNode.setLocalRotation(rotQuat2);
            oldX=newX;
            oldY=newY;
            
         } else {
            if (pressed) {
               pressed = false;
               
            }
            oCamNode.setLocalTranslation(rotQuat2.mult(oCamTranslation).mult(FastMath.exp(scale)));
         }

      }
   }
}

which you can execute here: http://www.lichtundliebe.info/projects/rotating_cube/RotatingCube.jnlp. In JME 1.0 the cube is displayed smaller than in JME 2.0. I think that has something to do with the camera. Why is that so? If I want the same size in jme 2.0 like in 1.0, I have to use this translation:


oCamTranslation=new Vector3f(0,0,-23f);
oCamNode.setLocalTranslation(oCamTranslation);



Best,
Andreas

It's because the fov in jme1.0 was calculated incorrectly.

Ok, thx.