Best Practice for multiple cameras

I’ve seen examples of using multiple cameras per viewport, but I haven’t found any examples on how to switch between different cameras.



Suppose I want a flyover camera and some other camera for a 2D overview. And I want to switch between them. What is the best practice outside the SimpleApplication class?



My first idea was: Create a CameraManager as an AppState and let it say: SimpleApplication.setCamera.

But the function doesn’t exist!



Setting the settings of the camera to new settings will not fix it, because there are couplings. I would really like to use something simple as multiple Camera classes.



Should I just create a SET function myself in my inherited version of SimpleApplication?

Don’t change the Camera object, you just need controls over the same camera.

Look at how the Cinematic class does to activate cameras, this is basically what you need.

I got stuck in the following design:



A FlyByCamera is enabled on a Camera.

The Camera is also attached to a CameraNode. The direction is Cam → Node.



Problem: When I want to disable the camera, I disable the CameraNode, but this will not kill functionaitly in the FlyByCamera.



So this is going to my other question… I need a bit of abstraction for the FlyByCamera to be a control as well. Else I should keep track of all FlyByCameras separately. That would be a shame in my design :frowning:



Other question:
http://hub.jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/flyovercamera-needs-some-abstraction/?_wpnonce=ec48a05d22#post-128097

The thing is Controls are controlling Spatials. CameraNode, and ChaseCamera are attached to a Spatial, but the flyByCamera, is just some camera holder, but doesn’t affect any Spatial…



But you’ve got a point, if we don’t make it a Control (which make little sense actually), we should have some kind of interface for camera holders of some sort, that would have an activate or setEnabled method…



@Normen, @Momoko_Fan, what do you think?

Couln’t you just make it a fake CameraControl/Node that is not in the tree? In this way, i could always use the methods that are in the default CameraControl. And then I could also create new Controls that ARE in the tree. I don’t see any problem for why it shouldn’t be a default CameraControl.

I came up with a short solution for now.



For switching cameras, we can create a new kind of CameraControl, which I call: SharedCameraControl. It doesn’t do much, but when set to enabled, it snaps the camera to the point of the spatial.



[java]

/**

  • This Control snaps the camera to the node at the moment of switching on or off.

    */

    public class SharedCameraControl extends CameraControl

    {

    public SharedCameraControl(Camera cam)

    {

    super(cam);

    }



    public SharedCameraControl(Camera cam, ControlDirection dir)

    {

    super(cam, dir);

    }



    @Override

    public void setEnabled(boolean enabled)

    {

    super.setEnabled(enabled);



    // enable the camera

    // snap the main camera to this spatial

    if(enabled)

    {

    ControlDirection old = this.getControlDir();

    this.setControlDir(ControlDirection.SpatialToCamera);

    this.controlUpdate(0);

    this.setControlDir(old);

    }

    }

    }

    [/java]



    Now I have also inherited from this class to create a FlyByCameraControl. This class enables/disables the flybycamera when it enables/disabled the control.



    [java]

    /**
  • This is a shared camera model.
  • And as an extra, it contains a flycam.

    *
  • @see FlyByCamera

    */

    public class FlyByCameraControl extends SharedCameraControl

    {

    private FlyByCamera flyCam;



    public FlyByCameraControl(FlyByCamera flyCam, Camera cam)

    {

    super(cam);

    this.flyCam = flyCam;

    }



    public FlyByCameraControl(FlyByCamera flyCam, Camera cam, ControlDirection dir)

    {

    super(cam, dir);

    this.flyCam = flyCam;

    }



    /**
  • Enable/disable the {@code FlyByCamera}.
  • @param enabled

    */

    @Override

    public void setEnabled(boolean enabled)

    {

    super.setEnabled(enabled);

    this.flyCam.setEnabled(enabled);

    }

    }

    [/java]



    This doesn’t meet my standards completely, but it is quite ok, I think. Only one problem is annoying: When the flyCam is turned off, the mouse gets visible, so I have to call InputManager.setCursorVisible(false) again in my cameraManager. And it still is just a workaround for the FlyByCamera, right?



    As a question: Is this a solid solution? How could we make this work in the nicest way? Camera management is quite important, but the documentation is a bit contradictory:



    On one side we have: Only use one camera, you have to place it at the places you want it.

    On the other hand: Let’s use multiple cameras, so we can set different settings (an orthogonal and a projection view). The Camera class is used on a lot of places, but we only have one camera… Even the documentation (https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:intermediate:api_feature_mapping?s=want&s=do) says that we should use the Camera class.