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
This commit is contained in:
parent
9e8abfb6ec
commit
306e88c678
@ -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) {
|
||||
|
53
engine/src/core-effects/com/jme3/water/WaterUtils.java
Normal file
53
engine/src/core-effects/com/jme3/water/WaterUtils.java
Normal file
@ -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…
x
Reference in New Issue
Block a user