From fa46b16e870c321875386f9dd1b89d4aeab1b0f9 Mon Sep 17 00:00:00 2001 From: "bre..ns" Date: Wed, 24 Aug 2011 16:12:38 +0000 Subject: [PATCH] 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 --- .../com/jme3/terrain/geomipmap/LODGeomap.java | 108 +++++++++++++++--- .../jme3/terrain/geomipmap/TerrainPatch.java | 87 +++++--------- .../jme3/terrain/geomipmap/TerrainQuad.java | 21 ++-- 3 files changed, 133 insertions(+), 83 deletions(-) diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java b/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java index f8e2d3f46..1cd90500d 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/LODGeomap.java +++ b/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) { diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java index dccb99b06..fecebdd19 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainPatch.java +++ b/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) { diff --git a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java b/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java index b00e2976d..5d2a8eff5 100644 --- a/engine/src/terrain/com/jme3/terrain/geomipmap/TerrainQuad.java +++ b/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; }