Changed the way the reflection cam position and orientation were computed in the SimpleWaterProcessor to avoid some issues when the cam was parallel to the water plane. thanks to @sgold in this thread http://hub.jmonkeyengine.org/forum/topic/simplewater-with-horizontal-camera/

Also extracted the code in an utility class so that the WaterFilter can use the same routine without code duplication

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10899 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
rem..om 11 years ago
parent 9e8abfb6ec
commit 306e88c678
  1. 47
      engine/src/core-effects/com/jme3/water/SimpleWaterProcessor.java
  2. 37
      engine/src/core-effects/com/jme3/water/WaterFilter.java
  3. 53
      engine/src/core-effects/com/jme3/water/WaterUtils.java

@ -48,6 +48,7 @@ import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.texture.Texture2D;
import com.jme3.ui.Picture;
import com.jme3.util.TempVars;
/**
*
@ -119,15 +120,12 @@ public class SimpleWaterProcessor implements SceneProcessor {
private Plane reflectionClipPlane;
private Plane refractionClipPlane;
private float refractionClippingOffset = 0.3f;
private float reflectionClippingOffset = -5f;
private Vector3f vect1 = new Vector3f();
private Vector3f vect2 = new Vector3f();
private Vector3f vect3 = new Vector3f();
private float reflectionClippingOffset = -5f;
private float distortionScale = 0.2f;
private float distortionMix = 0.5f;
private float texScale = 1f;
/**
* Creates a SimpleWaterProcessor
* @param manager the asset manager
@ -190,10 +188,6 @@ public class SimpleWaterProcessor implements SceneProcessor {
public void postQueue(RenderQueue rq) {
Camera sceneCam = rm.getCurrentCamera();
//update ray
ray.setOrigin(sceneCam.getLocation());
ray.setDirection(sceneCam.getDirection());
//update refraction cam
refractionCam.setLocation(sceneCam.getLocation());
refractionCam.setRotation(sceneCam.getRotation());
@ -203,40 +197,11 @@ public class SimpleWaterProcessor implements SceneProcessor {
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
refractionCam.setParallelProjection(false);
refractionCam.setParallelProjection(sceneCam.isParallelProjection());
//update reflection cam
boolean inv = false;
if (!ray.intersectsWherePlane(plane, targetLocation)) {
ray.setDirection(ray.getDirection().negateLocal());
ray.intersectsWherePlane(plane, targetLocation);
inv = true;
}
Vector3f loc = plane.reflect(sceneCam.getLocation(), new Vector3f());
reflectionCam.setLocation(loc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(false);
// tempVec and calcVect are just temporary vector3f objects
vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
float planeDistance = plane.pseudoDistance(vect1);
vect2.set(plane.getNormal()).multLocal(planeDistance * 2.0f);
vect3.set(vect1.subtractLocal(vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
// now set the up vector
reflectionCam.lookAt(targetLocation, vect3);
if (inv) {
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
}
//we are rendering a sub part of the scene so the camera planeState may never be reseted to 0.
// reflectionCam.setPlaneState(0);
// refractionCam.setPlaneState(0);
WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam);
//Rendering reflection and refraction
rm.renderViewPort(reflectionView, savedTpf);
rm.renderViewPort(refractionView, savedTpf);

@ -153,40 +153,11 @@ public class WaterFilter extends Filter {
material.setVector3("CameraPosition", sceneCam.getLocation());
material.setFloat("WaterHeight", waterHeight);
//update reflection cam
ray.setOrigin(sceneCam.getLocation());
ray.setDirection(sceneCam.getDirection());
//update reflection cam
plane = new Plane(Vector3f.UNIT_Y, new Vector3f(0, waterHeight, 0).dot(Vector3f.UNIT_Y));
reflectionProcessor.setReflectionClipPlane(plane);
boolean inv = false;
if (!ray.intersectsWherePlane(plane, targetLocation)) {
ray.setDirection(ray.getDirection().negateLocal());
ray.intersectsWherePlane(plane, targetLocation);
inv = true;
}
Vector3f loc = plane.reflect(sceneCam.getLocation(), new Vector3f());
reflectionCam.setLocation(loc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(false);
TempVars vars = TempVars.get();
vars.vect1.set(sceneCam.getLocation()).addLocal(sceneCam.getUp());
float planeDistance = plane.pseudoDistance(vars.vect1);
vars.vect2.set(plane.getNormal()).multLocal(planeDistance * 2.0f);
vars.vect3.set(vars.vect1.subtractLocal(vars.vect2)).subtractLocal(loc).normalizeLocal().negateLocal();
reflectionCam.lookAt(targetLocation, vars.vect3);
vars.release();
if (inv) {
reflectionCam.setAxes(reflectionCam.getLeft().negateLocal(), reflectionCam.getUp(), reflectionCam.getDirection().negateLocal());
}
reflectionProcessor.setReflectionClipPlane(plane);
WaterUtils.updateReflectionCam(reflectionCam, plane, sceneCam);
//if we're under water no need to compute reflection
if (sceneCam.getLocation().y >= waterHeight) {

@ -0,0 +1,53 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.water;
import com.jme3.math.Plane;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.util.TempVars;
/**
*
* @author Nehon
*/
public class WaterUtils {
public static void updateReflectionCam(Camera reflectionCam, Plane plane, Camera sceneCam){
TempVars vars = TempVars.get();
//Temp vects for reflection cam orientation calculation
Vector3f sceneTarget = vars.vect1;
Vector3f reflectDirection = vars.vect2;
Vector3f reflectUp = vars.vect3;
Vector3f reflectLeft = vars.vect4;
Vector3f camLoc = vars.vect5;
camLoc = plane.reflect(sceneCam.getLocation(), camLoc);
reflectionCam.setLocation(camLoc);
reflectionCam.setFrustum(sceneCam.getFrustumNear(),
sceneCam.getFrustumFar(),
sceneCam.getFrustumLeft(),
sceneCam.getFrustumRight(),
sceneCam.getFrustumTop(),
sceneCam.getFrustumBottom());
reflectionCam.setParallelProjection(sceneCam.isParallelProjection());
sceneTarget.set(sceneCam.getLocation()).addLocal(sceneCam.getDirection());
reflectDirection = plane.reflect(sceneTarget, reflectDirection);
reflectDirection.subtractLocal(camLoc);
sceneTarget.set(sceneCam.getLocation()).subtractLocal(sceneCam.getUp());
reflectUp = plane.reflect(sceneTarget, reflectUp);
reflectUp.subtractLocal(camLoc);
sceneTarget.set(sceneCam.getLocation()).addLocal(sceneCam.getLeft());
reflectLeft = plane.reflect(sceneTarget, reflectLeft);
reflectLeft.subtractLocal(camLoc);
reflectionCam.setAxes(reflectLeft, reflectUp, reflectDirection);
vars.release();
}
}
Loading…
Cancel
Save