浏览代码

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
rem..om 12 年之前
父节点
当前提交
306e88c678

+ 6 - 41
engine/src/core-effects/com/jme3/water/SimpleWaterProcessor.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);

+ 4 - 33
engine/src/core-effects/com/jme3/water/WaterFilter.java

@@ -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 - 0
engine/src/core-effects/com/jme3/water/WaterUtils.java

@@ -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();
+    }
+}