Thank very much, the link to the Lemut example helped a lot.
I no longer have to manually update the geometry.
My SplitterVertical extends BaseAppState works fine except for one other problem (But I should certainly do some research and start a new post if necessary):
The camera’s lens is deformed with splitter.
I pause main camera, but don’t change it. I only manipulate my two copies of the cameras.
Code:
package jare.view.splitting;
import com.jme3.app.Application;
import com.jme3.app.state.BaseAppState;
import com.jme3.input.InputManager;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.VertexBuffer;
import static jare.basic.JaReConst.MOUSE_BUTTON_LEFT;
import static jare.basic.JaReConst.MOUSE_MOVE;
import jare.basic.JaReKeybinding;
/**
*
* @author Janusch Rentenatus
*/
public class SplitterVertical extends BaseAppState {
private final Node rootNode1;
private final Camera camera1;
private ViewPort view1;
private final Node rootNode2;
private final Camera camera2;
private ViewPort view2;
Geometry splitter;
private float splittPos;
private boolean moving;
public SplitterVertical(Application app, Node guiNode, Camera masterCam1, Camera masterCam2) {
super("SplitterV");
splittPos = 0.8f;
moving = false;
rootNode1 = new Node("SplitterRootNode1");
camera1 = masterCam1.clone();
camera1.setViewPort(0.0f, splittPos, 0.0f, 1.0f);
view1 = app.getRenderManager().createMainView("Splitter1", camera1);
view1.setClearFlags(true, true, true);
view1.attachScene(rootNode1);
view1.setBackgroundColor(new ColorRGBA(0.2f, 0.15f, 0.2f, 1.0f));
rootNode2 = new Node("SplitterRootNode2");
camera2 = masterCam2.clone();
camera2.setViewPort(splittPos, 1.0f, 0.0f, 1.0f);
view2 = app.getRenderManager().createMainView("Splitter2", camera2);
view2.setClearFlags(true, true, true);
view2.attachScene(rootNode2);
view2.setBackgroundColor(new ColorRGBA(0.15f, 0.2f, 0.2f, 1.0f));
int w = app.getCamera().getWidth();
int h = app.getCamera().getHeight();
Mesh mesh = createSplitterMesh(w, h);
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
splitter = new Geometry("SplitterBar", mesh);
splitter.setMaterial(mat);
guiNode.attachChild(splitter);
splitter.setLocalTranslation(w * splittPos, 0, 98f);
}
private Mesh createSplitterMesh(float h, float w) {
float[] vertexbuffer = new float[]{ //
-2f, 0, 0, //
2f, 0, 0,//
-2f, h, 0,//
2f, 0, 0,//
2f, h, 0,//
-2f, h, 0,//
};
final Mesh triMesh = new Mesh();
triMesh.setMode(Mesh.Mode.Triangles);
triMesh.setBuffer(VertexBuffer.Type.Position, 3, vertexbuffer);
triMesh.updateBound();
return triMesh;
}
private final AnalogListener mouseMoveListener = (name, keyPressed, tpf) -> {
if (moving) {
setPos(calcPos());
}
};
private final ActionListener startMoveListener = (name, keyPressed, tpf) -> {
if (MOUSE_BUTTON_LEFT.equals(name)) {
if (keyPressed) {
moving = isStartMove();
} else if (moving) {
resetViewports();
moving = false;
}
}
};
private boolean isStartMove() {
Application app = getApplication();
final Vector2f click2d = app.getInputManager().getCursorPosition();
float width = app.getCamera().getWidth();
float pos = width * splittPos;
return (click2d.x - 2 < pos && click2d.x + 2 > pos);
}
private float calcPos() {
Application app = getApplication();
final Vector2f click2d = app.getInputManager().getCursorPosition();
float width = app.getCamera().getWidth();
return click2d.x / width;
}
private void setPos(float newPos) {
Application app = getApplication();
float width = app.getCamera().getWidth();
splittPos = newPos;
splitter.setLocalTranslation(width * splittPos, 0, 98f);
}
private void resetViewports() {
//Application app = getApplication();
//int width = app.getCamera().getWidth();
//int height = app.getCamera().getHeight();
//int split = (int) (width * splittPos);
camera1.setViewPort(0.0f, splittPos, 0.0f, 1.0f);
camera2.setViewPort(splittPos, 1.0f, 0.0f, 1.0f);
}
@Override
protected void initialize(Application arg0) {
initMyKeys();
}
/**
* Custom Keybinding: Map named actions to inputs.
*/
private void initMyKeys() {
final InputManager inputManager = getApplication().getInputManager();
JaReKeybinding.initInputManager(inputManager);
// Add the names to the asction listener.
inputManager.addListener(mouseMoveListener, MOUSE_MOVE);
inputManager.addListener(startMoveListener, MOUSE_BUTTON_LEFT);
}
@Override
protected void cleanup(Application arg0) {
// noop
}
@Override
protected void onEnable() {
// noop
}
@Override
protected void onDisable() {
splitter.removeFromParent();
disposeViewPort();
}
@Override
public void update(final float tpf) {
super.update(tpf);
rootNode1.updateLogicalState(tpf);
rootNode2.updateLogicalState(tpf);
}
@Override
public void render(RenderManager rm) {
super.render(rm);
rootNode1.updateGeometricState();
rootNode2.updateGeometricState();
}
protected void disposeViewPort() {
if (view1 == null || view2 == null) {
return;
}
getApplication().getRenderManager().removePostView(view1);
getApplication().getRenderManager().removePostView(view2);
view1 = view2 = null;
}
public Node getRootNode1() {
return rootNode1;
}
public Camera getCamera1() {
return camera1;
}
public ViewPort getView1() {
return view1;
}
public Node getRootNode2() {
return rootNode2;
}
public Camera getCamera2() {
return camera2;
}
public ViewPort getView2() {
return view2;
}
}
Edit Oct 15 : Problem with camera update is solved.