How to move Camera in X and Y position?

Hello guys.

I’m just started to get into jME3.
I’m trying to build a 3D object viewer in jme.

I’ve set up a scene with a 3D Object and also set up a ChaseCam with parallel projection. So right now I can rotate around the object 360°.

The only thing which I just can’t get to work is how I can implent to move the camera on the x and y axes.
I just wanted to have that you can press WASD to move the camera by 10 pixel every time. Just in all 4 direction.

Can anyone help me?

Here is my code right now.

    public void simpleInitApp() {
    setDisplayFps(false);
    setDisplayStatView(false); 
    
    // Model laden
    Geometry model = (Geometry) assetManager.loadModel("Models/test/test.j3o");

    // Model 45° drehen
    Quaternion roll45 = new Quaternion(); 
    roll45.fromAngleAxis( FastMath.PI/4 , new Vector3f(0,-1,0));

    // Kamera
    
    flyCam.setEnabled(false);
    ChaseCamera chaseCam = new ChaseCamera(cam, model, inputManager);
    chaseCam.setSmoothMotion(true);
    chaseCam.setRotationSensitivity(50f);
    chaseCam.setTrailingSensitivity(50f);
    chaseCam.setChasingSensitivity(50f);
    chaseCam.setTrailingRotationInertia(0.1f);
    chaseCam.setMinVerticalRotation(-FastMath.PI / 2);
    chaseCam.setInvertVerticalAxis(true);
    viewPort.setBackgroundColor(new ColorRGBA(0.69f, 0.72f, 0.79f, 1f));
            
    // Parallelperspektive
    cam.setParallelProjection(true);
    float aspect = (float) cam.getWidth() / cam.getHeight();
    cam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize);
            

    Node pivot = new Node("pivot");
    pivot.attachChild(model);      
    rootNode.attachChild(pivot);
    pivot.setLocalScale(0.035f);
    
    pivot.setLocalRotation(roll45);  
    }   

Thanks in advance!

http://wiki.jmonkeyengine.org/doku.php/jme3:beginner:hello_input_system

Thank you :slight_smile:

I’ve seen that site already. I’ve set up some key triggers which works great. But I just can’t get the camera moved to left/right/up/down. :confused:

Maybe something along these lines:

protected void moveCamera(float value, boolean sideways) {

    // Moving is strafing over the map plane
    Vector3f vel = new Vector3f();
    Vector3f pos = cam.getLocation().clone();
    if (sideways) {
        cam.getLeft(vel);
    } else {
        cam.getUp(vel);
    }
    vel.multLocal(value * MOVE_SPEED, 0, value * MOVE_SPEED);
    pos.addLocal(vel);

    cam.setLocation(pos);
}

Thx @tonihele for the quick answer. The problem is I’m completely new to this and I don’t know how to use the moveCamera function. I just thought it should be not that hard… I proved myself wrong :smiley:

Me too :slight_smile: Ok, here is the context:

The snippet is part of my code. In my view package there is an AppState for listening the user input that has to do with the camera. And I have a small camera class that translates the user input to actual camera movement. Mostly copied from JME’s FlyCam itself, shamelessly. This works for me, for now, and is not probably 100% right or nice. But may give you a hint.

Sorry sorry for bumping and sorry for the long post but i am stuck on this.
I cant get the camera to move on the 2D node view.

I extended FlyByCam to create an Ortho cam (although you could set it as a FlyBy as well) so i could set parallel projection and dragtorotate
I have a 3D node using FlyCam and a “2D” node using my OrthoCam, i enable/disable between switching nodes
the 2d view is for clicking on the map to add new objects in the world

I added WASD and QZ triggers and they fire.
The OrthoCam gets instantiated with a new Camera (but with the build in cam’s width and height)
I made sure i wasnt secretly changing the wrong camera.
I made sure my moveOrthoCamera which initially was a wrapper for moveCamera was working by copying the code from the FlyByCamera.java, peppering it with println, and i can see pos is changing. I also added Q and Z for zooming in and out and at least they fire.

Nothing is moving in the 2D node view (but i can see the objects).
If i use WASDQZ keys in the 3D node view i directly see movement and if i then switch back to 2D node view i see the objects have moved.

I do remember a topic on 2D games and parallel projection where an extra line was addded after setting the camera to parallel projection but i cant find it anywhere and it is not in my code.

As the first reply would be show us your code here it goes, some code still contains debugging println’s and so on.

OrthoCam class
(most of the use of the this pointer is unnecessary here although it does not hurt)

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.input.FlyByCamera;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;

/**
 *
 * @author Martien
 */
public class OrthoCam extends FlyByCamera {
    

    public OrthoCam( Camera cam ) {
        super( cam );
        //the super does:
        //this.cam = cam;
        //initialUpVec = cam.getUp().clone();
        // 
        this.cam.setParallelProjection( true );
        this.setDragToRotate( true );
        if ( this.cam.getName() == null ) {
            System.out.println( "Creating new Ortho Cam " );
        }
        else {
            System.out.println( "Creating new Ortho Cam " + this.cam.getName() );
        }
        if ( this.cam.getName() != "cam" ) {
            this.cam.setName( "Ortho" );
        }
        setCanRotate( true );
        this.moveSpeed = 100 * this.moveSpeed;
    };
    
    public void setLocation( Vector3f location ) {
        this.cam.setLocation( location );
    };
    
    public Vector3f getLocation() {
        return this.cam.getLocation();
    };
    
    public void setFrustum ( int i, int j, float a, float b, float c, float d) {
        this.cam.setFrustum( i, j, a, b, c, d);
    };
    
    public void setParallelProjection( boolean setParallel ) {
        this.cam.setParallelProjection( setParallel );
    };
    
    
    public void setDragToRotate( boolean dragToRotate ) {
        this.dragToRotate = dragToRotate;
    };
    
    public void setCanRotate( boolean setCanRotate ) {
        this.canRotate = setCanRotate;
    };
    
    public float getFrustumTop() {
        return cam.getFrustumTop();
    }
    
    public Vector3f getWorldCoordinates( Vector2f screenPos, float projectionZPos ) {
        return this.cam.getWorldCoordinates( screenPos, projectionZPos);
    };
    
    protected void moveOrthoCamera(float value, boolean sideways){
        //moveCamera(value, sideways);
        System.out.println( "Moving " + cam.getName() );
        Vector3f vel = new Vector3f();
        Vector3f pos = this.cam.getLocation().clone();
        System.out.println( "from " + pos );

        if (sideways){
            this.cam.getLeft(vel);
        }
        else{
            this.cam.getDirection(vel);
        }
        vel.multLocal(value * this.moveSpeed);

        if (this.motionAllowed != null)
            this.motionAllowed.checkMotionAllowed(pos, vel);
        else
            pos.addLocal(vel);
        System.out.println( "to " + pos );
        this.cam.setLocation(pos);
    }
    
}

instantiating my OrthoCam in simpleInitApp, the handle myOrthoCam is in my App


        cam.setName( "cam" );
        flyCam.setDragToRotate(true);
        Camera myCam = null;
        try {
            myCam = new Camera( cam.getWidth(), cam.getHeight() );
        }
        catch ( NullPointerException e ) {
            System.err.println( "Severe ERROR: Failed to create base Camera for OrthoCam");
        };
        
        try {
            myOrthoCam = new OrthoCam( myCam ) ;
            //we start off in 3D view with FlyCam enabled
            
        }
        catch ( NullPointerException e ) {
            System.err.println( "Severe ERROR: Failed to create OrthoCam, no base Camera");
        };

        myOrthoCam.setEnabled( false );
        myOrthoCam.setLocation( new Vector3f( 9, 3, 3 ) );
                                
        //  _> cam.setDragToRotate(false);  no such method tho
        float aspect = (float) cam.getWidth() / cam.getHeight();
        float size   = 1f;
        myOrthoCam.setFrustum(-1000, 1000, -aspect * size, aspect * size, size, -size);
        
        //myOrthoCam = new OrthoCam( myCam ) ;
            
        View3D = new Node ( "View3D" );
        View2D = new Node ( "View2D" );

in ActionListener we switch the views and camera’s

if (name.equals("Edit") && !keyPressed) {
            
            isEditMode = !isEditMode;
            
            if ( isEditMode ) {
                
                rootNode.detachChild( View3D );
                rootNode.attachChild( View2D );
                flyCam.setEnabled( false );
                myOrthoCam.setEnabled( true ) ;
            
            };
            if ( !isEditMode ) {
                myOrthoCam.setEnabled( false );
                flyCam.setEnabled( true );
                rootNode.detachChild( View2D );
                rootNode.attachChild( View3D );
            };
            
        }

in AnalogListener we handle WASD for map movement (along XY was the intention) and QZ for zoom in and out, here a snippet of the handlers

          if (name.equals("D")){
              if ( isEditMode ) {
                  //value = 0;
                  System.out.println("D key was pressed.");
                  myOrthoCam.moveOrthoCamera( -value, true );
                  //Vector3f location = myOrthoCam.getLocation( );
                  //myOrthoCam.setLocation( new Vector3f( location.x - value*speed, location.y, location.z));
                  dirtyTrackNodes = true;
              }
          }

          if (name.equals("Q")) {
              if ( isEditMode ) {
                System.out.println("Q key was pressed.");  
                frustumSize = myOrthoCam.getFrustumTop() + 0.3f * tpf;

                float aspect = (float) cam.getWidth() / cam.getHeight();
                myOrthoCam.setFrustum(-1000, 1000, -aspect * frustumSize, aspect * frustumSize, frustumSize, -frustumSize);          
                dirtyTrackNodes = true;

              }
          }

Output shows messages like below after setting moveSpeed to moveSpeed * 1000:
AD change pos along X-axis, WS along Z-axis i noted. Vusually nothing moves

Constructing aligned Section succeeded with 2 segments.
Constructing extended aligned Section succeeded with 3 segments.
OGL: Throttling update loop.
OGL: Enter showing state.
OGL: Visible. Create strategy.
OGL: Enter showing state.
OGL: Visible. Create strategy.
OGL: Ceased throttling update loop.
A key was pressed.
Moving Ortho
from (9.0, 3.0, 3.0)
to (131.99875, 3.0, 3.0)
A key was pressed.
Moving Ortho
from (131.99875, 3.0, 3.0)
to (279.45422, 3.0, 3.0)
A key was pressed.
Moving Ortho
from (279.45422, 3.0, 3.0)
to (420.2791, 3.0, 3.0)
A key was pressed.
Moving Ortho
from (420.2791, 3.0, 3.0)
to (561.1069, 3.0, 3.0)

Thanks,
Martien

update:

instantiated orthocam with the build-in cam as base cam and the view jumped out of sight on first keystroke due to the 1000* Movespeed (i guess) so probably i have to register my camera with a / the inputmanager???

Thanks,
Martien

Just move the gui node, not the camera. I dont believe moving the camera affects the gui node. So you just move the nodes instead.

1 Like

@jayfella is correct that moving the main camera doesn’t affect the view of the GUI node. The guiNode is rendered using a different camera – not LegacyApplication.cam but a different Camera instance with its own location, direction, and frustum.

If you don’t want to move your GUI spatials around, you can move the guiNode camera by invoking LegacyApplication.getGuiViewPort().getCamera().setLocation(Vector3f).

And that still won’t affect where the GUI elements are drawn, I think… because the GUI bucket (which the gui node is in) ignores camera settings, flattens z, etc…

1 Like

If it is possible to have a certain behaviour with a certain class then inheritance should guarantee you can get the same behaviour with a derived class. The fact my derived camera class from FlyByCam does not show the same behaviour as FlyBYCam can only mean i somehow configured my class differently.

I dont want to sound ungrateful for people coming up with ideas but moving the GUI sounds more like a trick and doesnt show what is really going on here. A better grasp of what is going on will help me better later on.
I will read LegacyApp again and then SimpleApp to see if i missed out on something. I have the feel i am almost there and i want to know what is going on. When i used the build in cam as base for my OrthoCam the whole 3d node went blank, when i disabled the FlyCam altogether and just switvched the OrthoCam from parallel projection to normal when i go ftom 2D to 3D it wasnt working either.

In LegacyApp there is a initCamera() for the build in cam

some of the statements are in my application too like setting frustum and location but others are missing for my OrthoCam

i dont have a lookAt call (for camera direction i guess) so i made a wrapper
a renderManager is created in there but it is also used for viewPort as well as guiViewPort so i dont need a second one i guess

the original creates a viewPort for the built in cam

viewPort = renderManager.createMainView(“Default”, cam);

where i dont have a viewPort for my cam or i dont set a new one. However i do have the initial view of my objects.

after adding a viewPort for the OrthoCam and some other lines of code to switch (disabling/ enabling the cams and viewPorts) between 3D and 2D i also attached the new ortho viewport to the panel where also my 3d view is projecting

At normal start it should show the 3D scene with a moving object but the screen stays black
The edit view is black and does not show the static objects i had before
When i switch back from edit to 3d it shows the 3d objects again as should have happened straight away…

I even added a big cross to the 2d scene on the XY (z = 0 ) but it does not show. Added the object that was moving to the 2d scene as well and now it disappears from 3d and does not show up in 2d either. They are different nodes!!!