2
0
Эх сурвалжийг харах

changed normal and tangent generation for terrain to handle scale, removing artifacts

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8070 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
bre..ns 14 жил өмнө
parent
commit
fa46b16e87

+ 95 - 13
engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java

@@ -45,6 +45,7 @@ import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Mesh;
 import com.jme3.scene.Mesh.Mode;
+import com.jme3.scene.VertexBuffer;
 import com.jme3.scene.VertexBuffer.Type;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.TangentBinormalGenerator;
@@ -78,16 +79,19 @@ public class LODGeomap extends GeoMap {
 
     public Mesh createMesh(Vector3f scale, Vector2f tcScale, Vector2f tcOffset, float offsetAmount, int totalSize, boolean center, int lod, boolean rightLod, boolean topLod, boolean leftLod, boolean bottomLod) {
         FloatBuffer pb = writeVertexArray(null, scale, center);
-        FloatBuffer tb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
+        FloatBuffer texb = writeTexCoordArray(null, tcOffset, tcScale, offsetAmount, totalSize);
         FloatBuffer nb = writeNormalArray(null, scale);
         IntBuffer ib = writeIndexArrayLodDiff(null, lod, rightLod, topLod, leftLod, bottomLod);
-        FloatBuffer tanb = writeTangentArray(null, scale);
+        FloatBuffer bb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
+        FloatBuffer tanb = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
+        writeTangentArray(tanb, bb, texb, scale);
         Mesh m = new Mesh();
         m.setMode(Mode.TriangleStrip);
         m.setBuffer(Type.Position, 3, pb);
         m.setBuffer(Type.Normal, 3, nb);
         m.setBuffer(Type.Tangent, 3, tanb);
-        m.setBuffer(Type.TexCoord, 2, tb);
+        m.setBuffer(Type.Binormal, 3, bb);
+        m.setBuffer(Type.TexCoord, 2, texb);
         m.setBuffer(Type.Index, 3, ib);
         m.setStatic();
         m.updateBound();
@@ -624,42 +628,120 @@ public class LODGeomap extends GeoMap {
         return num;
     }
     
-    public FloatBuffer writeTangentArray(FloatBuffer store, Vector3f scale) {
+    public FloatBuffer[] writeTangentArray(FloatBuffer tangentStore, FloatBuffer binormalStore, FloatBuffer textureBuffer, Vector3f scale) {
         if (!isLoaded()) {
             throw new NullPointerException();
         }
 
-        if (store != null) {
-            if (store.remaining() < getWidth() * getHeight() * 3) {
+        if (tangentStore != null) {
+            if (tangentStore.remaining() < getWidth() * getHeight() * 3) {
                 throw new BufferUnderflowException();
             }
         } else {
-            store = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
+            tangentStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
         }
-        store.rewind();
+        tangentStore.rewind();
+        
+        if (binormalStore != null) {
+            if (binormalStore.remaining() < getWidth() * getHeight() * 3) {
+                throw new BufferUnderflowException();
+            }
+        } else {
+            binormalStore = BufferUtils.createFloatBuffer(getWidth() * getHeight() * 3);
+        }
+        binormalStore.rewind();
         
         Vector3f tangent = new Vector3f();
+        Vector3f binormal = new Vector3f();
         Vector3f v1 = new Vector3f();
         Vector3f v2 = new Vector3f();
+        Vector3f v3 = new Vector3f();
+        Vector2f t1 = new Vector2f();
+        Vector2f t2 = new Vector2f();
+        Vector2f t3 = new Vector2f();
+        
+        scale = Vector3f.UNIT_XYZ;
         
         for (int r = 0; r < getHeight(); r++) {
             for (int c = 0; c < getWidth(); c++) {
                 
+                int texIdx = ((getHeight()-1-r)*getWidth()+c)*2; // pull from the end
+                int texIdxPrev = ((getHeight()-1-(r-1))*getWidth()+c)*2; // pull from the end
+                int texIdxNext = ((getHeight()-1-(r+1))*getWidth()+c)*2; // pull from the end
+                
                 v1.set(c, getValue(c, r), r);
+                t1.set(textureBuffer.get(texIdx), textureBuffer.get(texIdx+1));
+                
+                if (r == 0) { // first row
+                    v3.set(c, getValue(c, r), r); // ???
+                    t3.set(textureBuffer.get(texIdxNext), textureBuffer.get(texIdxNext+1)); // ???
+                } else {
+                    v3.set(c, getValue(c, r-1 ), r-1);
+                    t3.set(textureBuffer.get(texIdxPrev), textureBuffer.get(texIdxPrev+1));
+                }
                 
                 if (c == getWidth()-1) { // last column
                     v2.set(c+1, getValue(c, r ), r); // use same height
+                    t2.set(textureBuffer.get(texIdx), textureBuffer.get(texIdx+1));
                 } else {
-                    v2.set(c+1, getValue(c+1, r), r);
+                    v2.set(c+1, getValue(c+1, r), r); // one to the right
+                    t2.set(textureBuffer.get(texIdx+2), textureBuffer.get(texIdx+3));
                 }
-                tangent.set(v2.mult(scale).subtract(v1.mult(scale)));
-                BufferUtils.setInBuffer(tangent, store, (r * getWidth() + c)); // save the tangent
+                
+                calculateTangent(new Vector3f[]{v1.mult(scale),v2.mult(scale),v3.mult(scale)}, new Vector2f[]{t1,t2,t3}, tangent, binormal);
+                BufferUtils.setInBuffer(tangent, tangentStore, (r * getWidth() + c)); // save the tangent
+                BufferUtils.setInBuffer(binormal, binormalStore, (r * getWidth() + c)); // save the binormal
             }
         }
         
-        return store;
+        return new FloatBuffer[]{tangentStore,binormalStore};
+    }
+    
+    /**
+     * 
+     * @param v Takes 3 vertexes: root, right, top
+     * @param t Takes 3 tex coords: root, right, top
+     * @param tangent that will store the result
+     * @return the tangent store
+     */
+    public static Vector3f calculateTangent(Vector3f[] v, Vector2f[] t, Vector3f tangent, Vector3f binormal) {
+        Vector3f edge1 = new Vector3f(); // y=0
+        Vector3f edge2 = new Vector3f(); // x=0
+        Vector2f edge1uv = new Vector2f(); // y=0
+        Vector2f edge2uv = new Vector2f(); // x=0
+        
+        t[2].subtract(t[0], edge2uv);
+        t[1].subtract(t[0], edge1uv);
+        
+        float det = edge1uv.x*edge2uv.y;// - edge1uv.y*edge2uv.x;  = 0
+        
+        boolean normalize = true;
+        if (Math.abs(det) < 0.0000001f) {
+            det = 1;
+            normalize = true;
+        }
+        
+        v[1].subtract(v[0], edge1);
+        v[2].subtract(v[0], edge2);
+
+        tangent.set(edge1);
+        tangent.normalizeLocal();
+        binormal.set(edge2);
+        binormal.normalizeLocal();
+        
+        float factor = 1/det;
+        tangent.x = (edge2uv.y*edge1.x)*factor;
+        tangent.y = 0;
+        tangent.z = (edge2uv.y*edge1.z)*factor;
+        if (normalize) tangent.normalizeLocal();
+        
+        binormal.x = 0;
+        binormal.y = (edge1uv.x*edge2.y)*factor;
+        binormal.z = (edge1uv.x*edge2.z)*factor;
+        if (normalize) binormal.normalizeLocal();
+        
+        return tangent;
     }
-   
     
     @Override
     public FloatBuffer writeNormalArray(FloatBuffer store, Vector3f scale) {

+ 27 - 60
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java

@@ -62,7 +62,6 @@ import com.jme3.terrain.geomipmap.lodcalc.LodCalculatorFactory;
 import com.jme3.terrain.geomipmap.lodcalc.util.EntropyComputeUtil;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.TangentBinormalGenerator;
-import com.jme3.util.TangentBinormalGenerator.TriangleData;
 import java.io.IOException;
 import java.util.List;
 
@@ -333,8 +332,13 @@ public class TerrainPatch extends Geometry {
     protected void updateNormals() {
         FloatBuffer newNormalBuffer = geomap.writeNormalArray(null, getWorldScale());
         getMesh().getBuffer(Type.Normal).updateData(newNormalBuffer);
-        //FloatBuffer newTangentBuffer = geomap.writeTangentArray(null, getWorldScale());
-        //getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer);
+        FloatBuffer newTangentBuffer = null;
+        FloatBuffer newBinormalBuffer = null;
+        FloatBuffer[] tb = geomap.writeTangentArray(newTangentBuffer, newBinormalBuffer, (FloatBuffer)getMesh().getBuffer(Type.TexCoord).getData(), getWorldScale());
+        newTangentBuffer = tb[0];
+        newBinormalBuffer = tb[1];
+        getMesh().getBuffer(Type.Tangent).updateData(newTangentBuffer);
+        getMesh().getBuffer(Type.Binormal).updateData(newBinormalBuffer);
     }
 
     /**
@@ -359,7 +363,6 @@ public class TerrainPatch extends Geometry {
                                 TerrainPatch topRight,
                                 TerrainPatch topLeft)
     {
-
         Vector3f rootPoint = new Vector3f();
         Vector3f rightPoint = new Vector3f();
         Vector3f leftPoint = new Vector3f();
@@ -372,9 +375,6 @@ public class TerrainPatch extends Geometry {
         Vector2f bottomTex = new Vector2f();
         Vector3f normal = new Vector3f();
         Vector3f tangent = new Vector3f();
-        int[] indexes = new int[]{0,1,2};
-        Vector3f[] v = new Vector3f[3];
-        Vector2f[] t = new Vector2f[3];
 
         int s = this.getSize()-1;
         
@@ -390,7 +390,7 @@ public class TerrainPatch extends Geometry {
                     if (top == null) {
                         bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
                         this.getTex(s,i+1, bottomTex);
-                        averageNormalsTangents(v, t, indexes, null, rootPoint, leftPoint, bottomPoint, rightPoint, null, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, null, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
@@ -404,7 +404,7 @@ public class TerrainPatch extends Geometry {
                         bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
                         top.getTex(s,s-1, topTex);
                         this.getTex(s,i+1, bottomTex);
-                        averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
@@ -431,7 +431,7 @@ public class TerrainPatch extends Geometry {
                     if (bottom == null) {
                         topPoint.set(s, this.getHeightmapHeight(s,i-1), i-1);
                         this.getTex(s,i-1, topTex);
-                        averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, null, rightPoint, topTex, rootTex, leftTex, null, rightTex, normal, tangent);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, topTex, rootTex, leftTex, null, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
@@ -445,7 +445,7 @@ public class TerrainPatch extends Geometry {
                         bottomPoint.set(s, bottom.getHeightmapHeight(s,1), i+1);
                         this.getTex(s,i-1, topTex);
                         bottom.getTex(s,1, bottomTex);
-                        averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
@@ -474,7 +474,7 @@ public class TerrainPatch extends Geometry {
                     bottomPoint.set(s, this.getHeightmapHeight(s,i+1), i+1);
                     this.getTex(s,i-1, topTex);
                     this.getTex(s,i+1, bottomTex);
-                    averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                     VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                     VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                     VertexBuffer rightNB = right.getMesh().getBuffer(Type.Normal);
@@ -537,7 +537,7 @@ public class TerrainPatch extends Geometry {
                     rightPoint.set(i+1, this.getHeightmapHeight(i+1,s), s);
                     this.getTex(i-1,s, leftTex);
                     this.getTex(i+1,s, rightTex);
-                    averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                     VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                     VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                     VertexBuffer downNB = bottom.getMesh().getBuffer(Type.Normal);
@@ -564,7 +564,7 @@ public class TerrainPatch extends Geometry {
                     if (top == null) {
                         bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
                         this.getTex(0,i+1, bottomTex);
-                        averageNormalsTangents(v, t, indexes, null, rootPoint, leftPoint, bottomPoint, rightPoint, null, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, null, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
@@ -578,7 +578,7 @@ public class TerrainPatch extends Geometry {
                         bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
                         top.getTex(0,i-1, topTex);
                         this.getTex(0,i+1, bottomTex);
-                        averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                         VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                         VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                         VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
@@ -619,7 +619,7 @@ public class TerrainPatch extends Geometry {
                     bottomPoint.set(0, this.getHeightmapHeight(0,i+1), i+1);
                     this.getTex(0,i-1, topTex);
                     this.getTex(0,i+1, bottomTex);
-                    averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                     VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                     VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                     VertexBuffer leftNB = left.getMesh().getBuffer(Type.Normal);
@@ -655,7 +655,7 @@ public class TerrainPatch extends Geometry {
                     rightPoint.set(i+1, this.getHeightmapHeight(i+1,0), 0);
                     this.getTex(i-1,0, leftTex);
                     this.getTex(i+1,0, rightTex);
-                    averageNormalsTangents(v, t, indexes, topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
+                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, topTex, rootTex, leftTex, bottomTex, rightTex, normal, tangent);
                     VertexBuffer tpNB = this.getMesh().getBuffer(Type.Normal);
                     VertexBuffer tpTB = this.getMesh().getBuffer(Type.Tangent);
                     VertexBuffer topNB = top.getMesh().getBuffer(Type.Normal);
@@ -673,10 +673,12 @@ public class TerrainPatch extends Geometry {
         this.getMesh().getBuffer(Type.Tangent).setUpdateNeeded();
     }
 
-    protected void averageNormalsTangents(Vector3f[] v, Vector2f[] t, int[] indexes,
+    protected void averageNormalsTangents(
             Vector3f topPoint,
             Vector3f rootPoint,
-            Vector3f leftPoint, Vector3f bottomPoint, Vector3f rightPoint,
+            Vector3f leftPoint, 
+            Vector3f bottomPoint, 
+            Vector3f rightPoint,
             Vector2f topTex,
             Vector2f rootTex,
             Vector2f leftTex,
@@ -685,65 +687,30 @@ public class TerrainPatch extends Geometry {
             Vector3f normal,
             Vector3f tangent)
     {
-        Vector3f scale = Vector3f.UNIT_XYZ;//getWorldScale();
-        v[0] = topPoint;
-        v[1] = rootPoint;
-        v[2] = leftPoint;
-        t[0] = topTex;
-        t[1] = rootTex;
-        t[2] = leftTex;
+        Vector3f scale = getWorldScale();
+        
         Vector3f n1 = Vector3f.ZERO;
-        Vector3f t1 = Vector3f.ZERO;
         if (topPoint != null && leftPoint != null) {
-            TriangleData td1 = TangentBinormalGenerator.processTriangle(indexes, v, t);
             n1 = getNormal(topPoint.mult(scale), rootPoint.mult(scale), leftPoint.mult(scale));
-            t1 = td1.tangent;
         }
-        v[0] = leftPoint;
-        v[1] = rootPoint;
-        v[2] = bottomPoint;
-        t[0] = leftTex;
-        t[1] = rootTex;
-        t[2] = bottomTex;
         Vector3f n2 = Vector3f.ZERO;
-        Vector3f t2 = Vector3f.ZERO;
         if (leftPoint != null && bottomPoint != null) {
-            TriangleData td2 = TangentBinormalGenerator.processTriangle(indexes, v, t);
             n2 = getNormal(leftPoint.mult(scale), rootPoint.mult(scale), bottomPoint.mult(scale));
-            t2 = td2.tangent;
         }
-        v[0] = bottomPoint;
-        v[1] = rootPoint;
-        v[2] = rightPoint;
-        t[0] = bottomTex;
-        t[1] = rootTex;
-        t[2] = rightTex;
         Vector3f n3 = Vector3f.ZERO;
-        Vector3f t3 = Vector3f.ZERO;
         if (rightPoint != null && bottomPoint != null) {
-            TriangleData td3 = TangentBinormalGenerator.processTriangle(indexes, v, t);
             n3 = getNormal(bottomPoint.mult(scale), rootPoint.mult(scale), rightPoint.mult(scale));
-            t3 = td3.tangent;
         }
-        v[0] = rightPoint;
-        v[1] = rootPoint;
-        v[2] = topPoint;
-        t[0] = rightTex;
-        t[1] = rootTex;
-        t[2] = topTex;
         Vector3f n4 = Vector3f.ZERO;
-        Vector3f t4 = Vector3f.ZERO;
         if (rightPoint != null && topPoint != null) {
-            TriangleData td4 = TangentBinormalGenerator.processTriangle(indexes, v, t);
             n4 = getNormal(rightPoint.mult(scale), rootPoint.mult(scale), topPoint.mult(scale));
-            t4 = td4.tangent;
         }
+        
+        Vector3f binormal = new Vector3f();
+        if (topPoint != null && rightPoint != null)
+            LODGeomap.calculateTangent(new Vector3f[]{rootPoint.mult(scale),rightPoint.mult(scale),topPoint.mult(scale)}, new Vector2f[]{rootTex,rightTex,topTex}, tangent, binormal);
 
         normal.set(n1.add(n2).add(n3).add(n4).normalizeLocal());
-        tangent.set(t1.add(t2).add(t3).add(t4)).normalizeLocal();
-        /*if (rightPoint != null) {
-            tangent.set(rootPoint.mult(scale).subtract(rightPoint.mult(scale)));
-        }*/
     }
 
     private Vector3f getNormal(Vector3f firstPoint, Vector3f rootPoint, Vector3f secondPoint) {

+ 11 - 10
engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java

@@ -134,14 +134,14 @@ public class TerrainQuad extends Node implements Terrain {
     
     public TerrainQuad(String name, int patchSize, int size, int totalSize, float[] heightMap, LodCalculatorFactory lodCalculatorFactory) {
         this(name, patchSize, size, Vector3f.UNIT_XYZ, heightMap, totalSize, new Vector2f(), 0, lodCalculatorFactory);
-        affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
+        affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size*2, Float.MAX_VALUE, size*2);
         fixNormalEdges(affectedAreaBBox);
         addControl(new NormalRecalcControl(this));
     }
 
     public TerrainQuad(String name, int patchSize, int size, Vector3f scale, float[] heightMap, LodCalculatorFactory lodCalculatorFactory) {
         this(name, patchSize, size, scale, heightMap, size, new Vector2f(), 0, lodCalculatorFactory);
-        affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
+        affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size*2, Float.MAX_VALUE, size*2);
         fixNormalEdges(affectedAreaBBox);
         addControl(new NormalRecalcControl(this));
     }
@@ -214,7 +214,7 @@ public class TerrainQuad extends Node implements Terrain {
             //TODO background-thread this if it ends up being expensive
             fixNormals(affectedAreaBBox); // the affected patches
             fixNormalEdges(affectedAreaBBox); // the edges between the patches
-
+            
             setNormalRecalcNeeded(null); // set to false
         }
     }
@@ -691,7 +691,7 @@ public class TerrainQuad extends Node implements Terrain {
                 ((TerrainQuad)child).generateDebugTangents(mat);
             } else if (child instanceof TerrainPatch) {
                 Geometry debug = new Geometry( "Debug " + name,
-                    TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.1f));
+                    TangentBinormalGenerator.genTbnLines( ((TerrainPatch)child).getMesh(), 0.8f));
                 attachChild(debug);
                 debug.setLocalTranslation(child.getLocalTranslation());
                 debug.setCullHint(CullHint.Never);
@@ -734,7 +734,7 @@ public class TerrainQuad extends Node implements Terrain {
         patch1.setModelBound(new BoundingBox());
         patch1.updateModelBound();
         patch1.setLodCalculator(lodCalculatorFactory);
-        TangentBinormalGenerator.generate(patch1);
+        //TangentBinormalGenerator.generate(patch1);
 
         // 2 lower left
         float[] heightBlock2 = createHeightSubBlock(heightMap, 0, split - 1,
@@ -756,7 +756,7 @@ public class TerrainQuad extends Node implements Terrain {
         patch2.setModelBound(new BoundingBox());
         patch2.updateModelBound();
         patch2.setLodCalculator(lodCalculatorFactory);
-        TangentBinormalGenerator.generate(patch2);
+        //TangentBinormalGenerator.generate(patch2);
 
         // 3 upper right
         float[] heightBlock3 = createHeightSubBlock(heightMap, split - 1, 0,
@@ -778,7 +778,7 @@ public class TerrainQuad extends Node implements Terrain {
         patch3.setModelBound(new BoundingBox());
         patch3.updateModelBound();
         patch3.setLodCalculator(lodCalculatorFactory);
-        TangentBinormalGenerator.generate(patch3);
+        //TangentBinormalGenerator.generate(patch3);
 
         // 4 lower right
         float[] heightBlock4 = createHeightSubBlock(heightMap, split - 1,
@@ -800,7 +800,7 @@ public class TerrainQuad extends Node implements Terrain {
         patch4.setModelBound(new BoundingBox());
         patch4.updateModelBound();
         patch4.setLodCalculator(lodCalculatorFactory);
-        TangentBinormalGenerator.generate(patch4);
+        //TangentBinormalGenerator.generate(patch4);
     }
 
     public float[] createHeightSubBlock(float[] heightMap, int x,
@@ -878,10 +878,11 @@ public class TerrainQuad extends Node implements Terrain {
     protected boolean needToRecalculateNormals() {
         if (affectedAreaBBox != null)
             return true;
-        /*if (!lastScale.equals(getWorldScale())) {
+        if (!lastScale.equals(getWorldScale())) {
+            affectedAreaBBox = new BoundingBox(new Vector3f(0,0,0), size, Float.MAX_VALUE, size);
             lastScale = getWorldScale();
             return true;
-        }*/
+        }
         return false;
     }