Multiple Camera Views
You can split the screen and look into the 3D scene from different camera angles at the same time. E.g. you can have two rootnodes with different scene graphs, and two viewPorts, each of which can only see its own subset of the scene with its own subset of post-processing filters, so you get two very different views of the scene.
The packages used in this example are
com.jme3.renderer.ViewPort. You can get the full sample code here: TestMultiViews.java
The default viewPort is as big as the window. If you have several, they must be of different sizes, either overlapping or adjacent to one another. How do you tell jME which of the ViewPorts should appear where on the screen, and how big they should be?
Imagine the window as a 1.0f x 1.0f rectangle. The default cam’s viewPort is set to
cam.setViewPort(0f, 1f, 0f, 1f);
This setting makes the ViewPort take up the whole rectangle.
The four values are read in the following order:
cam.setViewPort(x1,x2 , y1,y2);
X-axis from left to right
Y-axis upwards from bottom to top
Here are a few examples:
cam1.setViewPort( 0.0f , 1.0f , 0.0f , 1.0f ); cam2.setViewPort( 0.5f , 1.0f , 0.0f , 0.5f );
These viewport parameters are, (in this order) the left-right extend, and the bottom-top extend of a views’s rectangle on the screen.
0.0 , 1.0 1.0 , 1.0 +-----+-----+ |cam1 | | | | +-----+ | | | | |cam2 | +-----+-----+ 0.0 , 0.0 1.0 , 0.0
Example: Cam2’s rectangle is in the bottom right: It extends from mid (x1=0.5f) bottom (y1=0.0f), to right (x2=1.0f) mid (y2=0.5f)
If you scale the views in a way so that the aspect ratio of a ViewPort is different than the window’s aspect ratio, then the ViewPort appears distorted. In these cases, you must recreate (not clone) the ViewPort’s cam object with the right aspect ratio. For example:
In this example, you create four views (2x2) with the same aspect ratio as the window, but each is only half the width and height.
You use the preconfigured Camera
SimpleApplication for the first view. It’s in the bottom right.
cam.setViewPort(.5f, 1f, 0f, 0.5f); // Resize the viewPort to half its size, bottom right.
Optionally, place the main camera in the scene and rotate it in its start position.
cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f)); cam.setRotation(new Quaternion (-0.07f, 0.92f, -0.25f, -0.27f));
Here is the outline for how you create the three other cams and viewPorts (Full code sample is here.) In the code snippet,
cam_n stand for
cam_4, respectively, same for
Clone the first cam to reuse its settings
Resize and position the cam’s viewPort with setViewPort().
(Optionally) Move the cameras in the scene and rotate them so they face what you want to see.
Create a ViewPort for each camera
Reset the camera’s enabled statuses
Attach the Node to be displayed to this ViewPort.
The camera doesn’t have to look at the rootNode, but that is the most common use case.
Here is the abstract code sample for camera
Camera cam_n = cam.clone(); cam_n.setViewPort(...); // resize the viewPort cam_n.setLocation(new Vector3f(...)); cam_n.setRotation(new Quaternion(...)); ViewPort view_n = renderManager.createMainView("View of camera #n", cam_n); view_n.setClearEnabled(true); view_n.attachScene(rootNode); view_n.setBackgroundColor(ColorRGBA.Black);
To visualize what you do, use the following drawing of the viewport positions:
0.0 , 1.0 1.0 , 1.0 +-----+-----+ | | | |cam3 |cam4 | +-----------+ | | | |cam2 |cam1 | +-----+-----+ 0.0 , 0.0 1.0 , 0.0
This are the lines of code that set the four cameras to create a four-times split screen.
cam1.setViewPort( 0.5f , 1.0f , 0.0f , 0.5f); ... cam2.setViewPort( 0.0f , 0.5f , 0.0f , 0.5f); ... cam3.setViewPort( 0.0f , 0.5f , 0.5f , 1.0f); ... cam4.setViewPort( 0.5f , 1.0f , 0.5f , 1.0f);
The following code snippet sets up two views, one covers the whole screen, and the second is a small view in the top center.
+-----+-----+ | |cam| | | | 2 | | + +---+ + | | | cam | +-----+-----+
// Setup first full-window view cam.setViewPort(0f, 1f, 0f, 1f); cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f)); cam.setRotation(new Quaternion(-0.07f, 0.92f, -0.25f, -0.27f)); // Setup second, smaller PiP view Camera cam2 = cam.clone(); cam2.setViewPort(.4f, .6f, 0.8f, 1f); cam2.setLocation(new Vector3f(-0.10f, 1.57f, 4.81f)); cam2.setRotation(new Quaternion(0.00f, 0.99f, -0.04f, 0.02f)); ViewPort viewPort2 = renderManager.createMainView("PiP", cam2); viewPort2.setClearFlags(true, true, true); viewPort2.attachScene(rootNode);
You can customize the camera and the viewPort of each view individually. For example, each view can have a different background color:
You have full control to determine which Nodes the camera can see! It can see the full rootNode…
… or you can give each camera a special node whose content it can see: