I have ran into something weird with SimpleWaterProcessor.
Sometimes when a spatial is attached to the scene at startup with a camera, at some coordinates the SimpleWaterProcessor will fail. Sometimes the spatial coordinates and monitors screen resolution affects it, other times it doesn’t.
Here’s an example of no problems, monitor screen resolution works on all resolutions.
Here’s what shows when there is a problem. Spatial is merely meters from last coordinate when loaded.
At this coordinate, no screen resolution works but just a few meters to the right and about half the screen resolutions will work. Yet as the first image shows, it may work perfectly no matter the resolution.
Its a pretty large area around the water that shows the problem, i.e its almost impossible to find a good coordinate the closer you are to the water.
I can show code for cam and water but its worked in test case so I would think the problems elsewhere somehow. I’m just tossing out observations in hope it triggers something for someone.
Like this is how I test it.
D-------A
| W |
| A |
+Z | T | -Z
| E |
| R |
C-------B
D- A coordinates are above C - B and everything is opposite each other and where character enter the game at startup.
C-D never displays the reflection.
A always displays the reflection.
B only displays the reflection when the water geometry is at Y +8
Code for water,
private void createShallowWaterA() {
//Add simple water
//create a water processor
SimpleWaterProcessor waterProcessor = new SimpleWaterProcessor(getApplication().getAssetManager());
waterProcessor.setReflectionScene(getOutdoorNode());
waterProcessor.setDebug(false);
// we set the water plane
// y should equal geometry y location
Vector3f waterLocation = new Vector3f(0, 5, 0);
waterProcessor.setPlane(new Plane(Vector3f.UNIT_Y, waterLocation.dot(Vector3f.UNIT_Y)));
this.getApplication().getViewPort().addProcessor(waterProcessor);
//set wave properties
waterProcessor.setWaterDepth(10); // transparency of water
waterProcessor.setDistortionScale(0.05f); // strength of waves
waterProcessor.setWaveSpeed(0.05f); // speed of waves
//water size, width-height
Quad quad = new Quad(140, 130);
//define the wave size by setting the size of the texture coordinates
quad.scaleTextureCoordinates(new Vector2f(6f, 6f));
//create the water geometry from the quad
Geometry water = new Geometry("water", quad);
water.setLocalRotation(new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X));
// terrainD location
water.setLocalTranslation(15, 5, 540);
water.setShadowMode(RenderQueue.ShadowMode.Receive);
water.setMaterial(waterProcessor.getMaterial());
//add water to waterNode-can not be in same node as setReflectionScene
getWaterNode().attachChild(water);
Code for the 3rd person cam,
//create 3rd person view.
private Node getHeadNode(BoundingBox bounds) {
Node head = new Node("headNode");
//offset head node using spatial bounds to positionType head level
head.setLocalTranslation(0, bounds.getYExtent() * 2, 0);
//use offset head node as target for cam to follow
ChaseCamera chaseCam = new ChaseCamera(app.getCamera(), head,
app.getInputManager());
//Set arrow keys to rotate view, sets CHASECAM_TOGGLEROTATE, you still
//have to map the triggers globaly, see KeyBoardRunState.
//Uses default mouse scrolling to zoom.
chaseCam.setToggleRotationTrigger(new MouseButtonTrigger(
MouseInput.AXIS_WHEEL),
new KeyTrigger(KeyInput.KEY_LEFT),
new KeyTrigger(KeyInput.KEY_RIGHT),
new KeyTrigger(KeyInput.KEY_UP),
new KeyTrigger(KeyInput.KEY_DOWN));
//duplicate blender rotation
chaseCam.setInvertVerticalAxis(true);
//disable so camera stays same distance from head when moving
chaseCam.setSmoothMotion(false);
//never hide cursor if used for picking
chaseCam.setHideCursorOnRotate(false);
//set camera to face spatial on start
chaseCam.setDefaultHorizontalRotation(FastMath.PI / 2);
chaseCam.setRotationSpeed(4f);
chaseCam.setMinDistance(bounds.getYExtent() * 2);
chaseCam.setDefaultDistance(bounds.getYExtent() * 15);
chaseCam.setMaxDistance(bounds.getYExtent() * 30);
//prevent camera rotation below head
chaseCam.setDownRotateOnCloseViewOnly(false);
return head;
}
Yes, the water is reflecting whatever is in the outdoorNode where its located. In this case I have added 2 water geometries at different coordinates and they work as expected. Depending on where the character loads that is.
If you see something I missed, please point it out.
Edit: outdoorNode has the sky and the terrains in it.
Edit2: I should clarify that A-B-C-D are where the character enters the scene at startup.