Selaa lähdekoodia

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 vuotta sitten
vanhempi
commit
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();
+    }
+}