Browse Source

Merge pull request #2144 from riccardobl/deprecatetbn

Deprecate TangentBinormalGenerator
Ryan McDonough 8 months ago
parent
commit
8dd829dc42
28 changed files with 270 additions and 227 deletions
  1. 13 132
      jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java
  2. 148 0
      jme3-core/src/main/java/com/jme3/util/TangentUtils.java
  3. 48 38
      jme3-core/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java
  4. 3 3
      jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java
  5. 2 2
      jme3-examples/src/main/java/jme3test/effect/TestEverything.java
  6. 2 2
      jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java
  7. 3 3
      jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java
  8. 2 2
      jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java
  9. 2 2
      jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java
  10. 3 3
      jme3-examples/src/main/java/jme3test/light/TestSpotLight.java
  11. 3 3
      jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java
  12. 2 2
      jme3-examples/src/main/java/jme3test/light/TestTangentCube.java
  13. 5 3
      jme3-examples/src/main/java/jme3test/light/TestTangentGen.java
  14. 4 3
      jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java
  15. 2 1
      jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java
  16. 2 2
      jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java
  17. 2 2
      jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java
  18. 2 2
      jme3-examples/src/main/java/jme3test/material/TestBumpModel.java
  19. 2 2
      jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java
  20. 3 3
      jme3-examples/src/main/java/jme3test/material/TestParallax.java
  21. 3 3
      jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java
  22. 2 2
      jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java
  23. 2 2
      jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java
  24. 2 2
      jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java
  25. 2 2
      jme3-examples/src/main/java/jme3test/post/TestLightScattering.java
  26. 2 2
      jme3-examples/src/main/java/jme3test/post/TestPostFilters.java
  27. 2 2
      jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java
  28. 2 2
      jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java

+ 13 - 132
jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java

@@ -59,9 +59,11 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- *
+ * @deprecated This is an outdated and non-standard method. Please use @{link MikktspaceTangentGenerator}
+ *             instead.
  * @author Lex (Aleksey Nikiforov)
  */
+@Deprecated
 public class TangentBinormalGenerator {
 
     private static final Logger log = Logger.getLogger(TangentBinormalGenerator.class.getName());
@@ -860,142 +862,21 @@ public class TangentBinormalGenerator {
         }
     }
 
+    /**
+     * @deprecated Use {@link TangentUtils#genTbnLines(com.jme3.scene.Mesh, float) } instead.
+     */
+    @Deprecated
     public static Mesh genTbnLines(Mesh mesh, float scale) {
-        if (mesh.getBuffer(Type.Tangent) == null) {
-            return genNormalLines(mesh, scale);
-        } else {
-            return genTangentLines(mesh, scale);
-        }
+        return TangentUtils.genTbnLines(mesh, scale);
     }
 
+    /**
+     * @deprecated Use {@link TangentUtils#genNormalLines(com.jme3.scene.Mesh, float) } instead.
+     */
+    @Deprecated
     public static Mesh genNormalLines(Mesh mesh, float scale) {
-        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
-        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
-
-        ColorRGBA originColor = ColorRGBA.White;
-        ColorRGBA normalColor = ColorRGBA.Blue;
-
-        Mesh lineMesh = new Mesh();
-        lineMesh.setMode(Mesh.Mode.Lines);
-
-        Vector3f origin = new Vector3f();
-        Vector3f point = new Vector3f();
-
-        FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 2);
-        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 2);
-
-        for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
-            populateFromBuffer(origin, vertexBuffer, i);
-            populateFromBuffer(point, normalBuffer, i);
-
-            int index = i * 2;
-
-            setInBuffer(origin, lineVertex, index);
-            setInBuffer(originColor, lineColor, index);
-
-            point.multLocal(scale);
-            point.addLocal(origin);
-            setInBuffer(point, lineVertex, index + 1);
-            setInBuffer(normalColor, lineColor, index + 1);
-        }
-
-        lineMesh.setBuffer(Type.Position, 3, lineVertex);
-        lineMesh.setBuffer(Type.Color, 4, lineColor);
-
-        lineMesh.setStatic();
-        //lineMesh.setInterleaved();
-        return lineMesh;
+        return TangentUtils.genNormalLines(mesh, scale);
     }
 
-    private static Mesh genTangentLines(Mesh mesh, float scale) {
-        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
-        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
-        FloatBuffer tangentBuffer = (FloatBuffer) mesh.getBuffer(Type.Tangent).getData();
-
-        FloatBuffer binormalBuffer = null;
-        if (mesh.getBuffer(Type.Binormal) != null) {
-            binormalBuffer = (FloatBuffer) mesh.getBuffer(Type.Binormal).getData();
-        }
-
-        ColorRGBA originColor = ColorRGBA.White;
-        ColorRGBA tangentColor = ColorRGBA.Red;
-        ColorRGBA binormalColor = ColorRGBA.Green;
-        ColorRGBA normalColor = ColorRGBA.Blue;
-
-        Mesh lineMesh = new Mesh();
-        lineMesh.setMode(Mesh.Mode.Lines);
-
-        Vector3f origin = new Vector3f();
-        Vector3f point = new Vector3f();
-        Vector3f tangent = new Vector3f();
-        Vector3f normal = new Vector3f();
 
-        IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6);
-        FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4);
-        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4);
-
-        boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
-        float tangentW = 1;
-
-        for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
-            populateFromBuffer(origin, vertexBuffer, i);
-            populateFromBuffer(normal, normalBuffer, i);
-
-            if (hasParity) {
-                tangent.x = tangentBuffer.get(i * 4);
-                tangent.y = tangentBuffer.get(i * 4 + 1);
-                tangent.z = tangentBuffer.get(i * 4 + 2);
-                tangentW = tangentBuffer.get(i * 4 + 3);
-            } else {
-                populateFromBuffer(tangent, tangentBuffer, i);
-            }
-
-            int index = i * 4;
-
-            int id = i * 6;
-            lineIndex.put(id, index);
-            lineIndex.put(id + 1, index + 1);
-            lineIndex.put(id + 2, index);
-            lineIndex.put(id + 3, index + 2);
-            lineIndex.put(id + 4, index);
-            lineIndex.put(id + 5, index + 3);
-
-            setInBuffer(origin, lineVertex, index);
-            setInBuffer(originColor, lineColor, index);
-
-            point.set(tangent);
-            point.multLocal(scale);
-            point.addLocal(origin);
-            setInBuffer(point, lineVertex, index + 1);
-            setInBuffer(tangentColor, lineColor, index + 1);
-
-            // wvBinormal = cross(wvNormal, wvTangent) * -inTangent.w
-            if (binormalBuffer == null) {
-                normal.cross(tangent, point);
-                point.multLocal(-tangentW);
-                point.normalizeLocal();
-            } else {
-                populateFromBuffer(point, binormalBuffer, i);
-            }
-
-            point.multLocal(scale);
-            point.addLocal(origin);
-            setInBuffer(point, lineVertex, index + 2);
-            setInBuffer(binormalColor, lineColor, index + 2);
-
-            point.set(normal);
-            point.multLocal(scale);
-            point.addLocal(origin);
-            setInBuffer(point, lineVertex, index + 3);
-            setInBuffer(normalColor, lineColor, index + 3);
-        }
-
-        lineMesh.setBuffer(Type.Index, 1, lineIndex);
-        lineMesh.setBuffer(Type.Position, 3, lineVertex);
-        lineMesh.setBuffer(Type.Color, 4, lineColor);
-
-        lineMesh.setStatic();
-        //lineMesh.setInterleaved();
-        return lineMesh;
-    }
 }

+ 148 - 0
jme3-core/src/main/java/com/jme3/util/TangentUtils.java

@@ -31,7 +31,16 @@
  */
 package com.jme3.util;
 
+import static com.jme3.util.BufferUtils.populateFromBuffer;
+import static com.jme3.util.BufferUtils.setInBuffer;
+
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector3f;
 import com.jme3.scene.*;
+import com.jme3.scene.VertexBuffer.Type;
 
 /**
  * Created by Nehon on 03/10/2016.
@@ -63,4 +72,143 @@ public class TangentUtils {
             }
         }
     }
+
+    public static Mesh genTbnLines(Mesh mesh, float scale) {
+        if (mesh.getBuffer(Type.Tangent) == null) {
+            return genNormalLines(mesh, scale);
+        } else {
+            return genTangentLines(mesh, scale);
+        }
+    }
+
+    public static Mesh genNormalLines(Mesh mesh, float scale) {
+        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
+        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
+
+        ColorRGBA originColor = ColorRGBA.White;
+        ColorRGBA normalColor = ColorRGBA.Blue;
+
+        Mesh lineMesh = new Mesh();
+        lineMesh.setMode(Mesh.Mode.Lines);
+
+        Vector3f origin = new Vector3f();
+        Vector3f point = new Vector3f();
+
+        FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 2);
+        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 2);
+
+        for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
+            populateFromBuffer(origin, vertexBuffer, i);
+            populateFromBuffer(point, normalBuffer, i);
+
+            int index = i * 2;
+
+            setInBuffer(origin, lineVertex, index);
+            setInBuffer(originColor, lineColor, index);
+
+            point.multLocal(scale);
+            point.addLocal(origin);
+            setInBuffer(point, lineVertex, index + 1);
+            setInBuffer(normalColor, lineColor, index + 1);
+        }
+
+        lineMesh.setBuffer(Type.Position, 3, lineVertex);
+        lineMesh.setBuffer(Type.Color, 4, lineColor);
+
+        lineMesh.setStatic();
+        // lineMesh.setInterleaved();
+        return lineMesh;
+    }
+
+    public static Mesh genTangentLines(Mesh mesh, float scale) {
+        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
+        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
+        FloatBuffer tangentBuffer = (FloatBuffer) mesh.getBuffer(Type.Tangent).getData();
+
+        FloatBuffer binormalBuffer = null;
+        if (mesh.getBuffer(Type.Binormal) != null) {
+            binormalBuffer = (FloatBuffer) mesh.getBuffer(Type.Binormal).getData();
+        }
+
+        ColorRGBA originColor = ColorRGBA.White;
+        ColorRGBA tangentColor = ColorRGBA.Red;
+        ColorRGBA binormalColor = ColorRGBA.Green;
+        ColorRGBA normalColor = ColorRGBA.Blue;
+
+        Mesh lineMesh = new Mesh();
+        lineMesh.setMode(Mesh.Mode.Lines);
+
+        Vector3f origin = new Vector3f();
+        Vector3f point = new Vector3f();
+        Vector3f tangent = new Vector3f();
+        Vector3f normal = new Vector3f();
+
+        IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6);
+        FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4);
+        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4);
+
+        boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
+        float tangentW = 1;
+
+        for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
+            populateFromBuffer(origin, vertexBuffer, i);
+            populateFromBuffer(normal, normalBuffer, i);
+
+            if (hasParity) {
+                tangent.x = tangentBuffer.get(i * 4);
+                tangent.y = tangentBuffer.get(i * 4 + 1);
+                tangent.z = tangentBuffer.get(i * 4 + 2);
+                tangentW = tangentBuffer.get(i * 4 + 3);
+            } else {
+                populateFromBuffer(tangent, tangentBuffer, i);
+            }
+
+            int index = i * 4;
+
+            int id = i * 6;
+            lineIndex.put(id, index);
+            lineIndex.put(id + 1, index + 1);
+            lineIndex.put(id + 2, index);
+            lineIndex.put(id + 3, index + 2);
+            lineIndex.put(id + 4, index);
+            lineIndex.put(id + 5, index + 3);
+
+            setInBuffer(origin, lineVertex, index);
+            setInBuffer(originColor, lineColor, index);
+
+            point.set(tangent);
+            point.multLocal(scale);
+            point.addLocal(origin);
+            setInBuffer(point, lineVertex, index + 1);
+            setInBuffer(tangentColor, lineColor, index + 1);
+
+            // wvBinormal = cross(wvNormal, wvTangent) * -inTangent.w
+            if (binormalBuffer == null) {
+                normal.cross(tangent, point);
+                point.multLocal(-tangentW);
+                point.normalizeLocal();
+            } else {
+                populateFromBuffer(point, binormalBuffer, i);
+            }
+
+            point.multLocal(scale);
+            point.addLocal(origin);
+            setInBuffer(point, lineVertex, index + 2);
+            setInBuffer(binormalColor, lineColor, index + 2);
+
+            point.set(normal);
+            point.multLocal(scale);
+            point.addLocal(origin);
+            setInBuffer(point, lineVertex, index + 3);
+            setInBuffer(normalColor, lineColor, index + 3);
+        }
+
+        lineMesh.setBuffer(Type.Index, 1, lineIndex);
+        lineMesh.setBuffer(Type.Position, 3, lineVertex);
+        lineMesh.setBuffer(Type.Color, 4, lineColor);
+
+        lineMesh.setStatic();
+        // lineMesh.setInterleaved();
+        return lineMesh;
+    }
 }

+ 48 - 38
jme3-core/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java

@@ -43,19 +43,15 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * This tangent generator is highly experimental.
- * This is the Java translation of the mikktspace generator made by Morten S. Mikkelsen
- * C Source code can be found here
- * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.c
- * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.h
- * 
- * Mikktspace looks like the new standard of tangent generation in 3-D software.
- * Xnormal, Blender, Substance painter, and many more use it.
- * 
- * Usage is :
- * MikktspaceTangentGenerator.generate(spatial);
+ * Mikktspace is a common standard for tangent space used across many 3D software.
  * 
+ * This is the Java translation of the mikktspace generator made by Morten S. Mikkelsen C Source code can be
+ * found here https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.c
+ * https://developer.blender.org/diffusion/B/browse/master/intern/mikktspace/mikktspace.h
  * 
+ * Usage is : <code>
+ *  MikktspaceTangentGenerator.generate(spatial);
+ * </code>
  * 
  * @author Nehon
  */
@@ -116,36 +112,50 @@ public class MikktspaceTangentGenerator {
         } else if (s instanceof Geometry) {
             Geometry g = (Geometry) s;
             Mesh mesh = g.getMesh();
-
-            Mesh.Mode mode = mesh.getMode();
-            boolean hasTriangles;
-            switch (mode) {
-                case Points:
-                case Lines:
-                case LineStrip:
-                case LineLoop:
-                    hasTriangles = false; // skip this mesh
-                    break;
-
-                case Triangles:
-                case TriangleFan:
-                case TriangleStrip:
-                    hasTriangles = true;
-                    break;
-
-                default:
-                    String message = "Tangent generation isn't implemented for mode=" + mode;
-                    throw new UnsupportedOperationException(message);
+            boolean success = generateTangents(mesh);
+            if (!success) {
+                logger.log(Level.SEVERE, "Failed to generate tangents for geometry {0}", g.getName());
             }
+        }
+    }
 
-            if (hasTriangles) {
-                MikkTSpaceImpl context = new MikkTSpaceImpl(mesh);
-                if (!genTangSpaceDefault(context)) {
-                    logger.log(Level.SEVERE, "Failed to generate tangents for geometry {0}", g.getName());
-                }
-                TangentUtils.generateBindPoseTangentsIfNecessary(mesh);
-            }
+    public static void generate(Mesh mesh) {
+        boolean success = generateTangents(mesh);
+        if (!success) {
+            logger.log(Level.SEVERE, "Failed to generate tangents for mesh {0}", mesh);
+        }
+    }
+
+    private static boolean generateTangents(Mesh mesh) {
+        Mesh.Mode mode = mesh.getMode();
+        boolean hasTriangles;
+        switch (mode) {
+            case Points:
+            case Lines:
+            case LineStrip:
+            case LineLoop:
+                hasTriangles = false; // skip this mesh
+                break;
+
+            case Triangles:
+            case TriangleFan:
+            case TriangleStrip:
+            case Patch:
+                hasTriangles = true;
+                break;
+
+            default:
+                logger.log(Level.SEVERE, "Tangent generation isn't implemented for mode={0}", mode);
+                return false;
+        }
+
+        if (hasTriangles) {
+            MikkTSpaceImpl context = new MikkTSpaceImpl(mesh);
+            boolean result = genTangSpaceDefault(context);
+            TangentUtils.generateBindPoseTangentsIfNecessary(mesh);
+            return result;
         }
+        return false;
     }
     
     public static boolean genTangSpaceDefault(MikkTSpaceContext mikkTSpace) {

+ 3 - 3
jme3-examples/src/main/java/jme3test/batching/TestBatchNode.java

@@ -45,7 +45,7 @@ import com.jme3.scene.Spatial;
 import com.jme3.scene.debug.WireFrustum;
 import com.jme3.scene.shape.Box;
 import com.jme3.system.NanoTimer;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 /**
  * A test to demonstrate the usage and functionality of the {@link BatchNode}
@@ -96,8 +96,8 @@ public class TestBatchNode extends SimpleApplication {
         cube2 = new Geometry("cube2", box);
         cube2.setMaterial(mat);
 
-        TangentBinormalGenerator.generate(cube);
-        TangentBinormalGenerator.generate(cube2);
+        MikktspaceTangentGenerator.generate(cube);
+        MikktspaceTangentGenerator.generate(cube2);
 
         batch.attachChild(cube);
         //  batch.attachChild(cube2);

+ 2 - 2
jme3-examples/src/main/java/jme3test/effect/TestEverything.java

@@ -48,7 +48,7 @@ import com.jme3.scene.shape.Box;
 import com.jme3.shadow.DirectionalLightShadowRenderer;
 import com.jme3.texture.Texture;
 import com.jme3.util.SkyFactory;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestEverything extends SimpleApplication {
 
@@ -122,7 +122,7 @@ public class TestEverything extends SimpleApplication {
     public void setupFloor(){
         Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m");
         Box floor = new Box(50, 1f, 50);
-        TangentBinormalGenerator.generate(floor);
+        MikktspaceTangentGenerator.generate(floor);
         floor.scaleTextureCoordinates(new Vector2f(5, 5));
         Geometry floorGeom = new Geometry("Floor", floor);
         floorGeom.setMaterial(mat);

+ 2 - 2
jme3-examples/src/main/java/jme3test/helloworld/HelloMaterial.java

@@ -43,7 +43,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Box;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.texture.Texture;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 /** Sample 6 - how to give an object's surface a material and texture.
  * How to make objects transparent. How to make bumpy and shiny surfaces.  */
@@ -81,7 +81,7 @@ public class HelloMaterial extends SimpleApplication {
     Sphere sphereMesh = new Sphere(32,32, 2f);
     Geometry sphereGeo = new Geometry("Shiny rock", sphereMesh);
     sphereMesh.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres
-    TangentBinormalGenerator.generate(sphereMesh);           // for lighting effect
+    MikktspaceTangentGenerator.generate(sphereMesh); // for lighting effect
     Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
     sphereMat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"));
     sphereMat.setTexture("NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));

+ 3 - 3
jme3-examples/src/main/java/jme3test/light/TestDirectionalLightShadow.java

@@ -58,7 +58,7 @@ import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.util.SkyFactory;
 import com.jme3.util.SkyFactory.EnvMapType;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestDirectionalLightShadow extends SimpleApplication implements ActionListener, AnalogListener {
 
@@ -108,8 +108,8 @@ public class TestDirectionalLightShadow extends SimpleApplication implements Act
         obj[0].setShadowMode(ShadowMode.CastAndReceive);
         obj[1] = new Geometry("cube", new Box(1.0f, 1.0f, 1.0f));
         obj[1].setShadowMode(ShadowMode.CastAndReceive);
-        TangentBinormalGenerator.generate(obj[1]);
-        TangentBinormalGenerator.generate(obj[0]);
+        MikktspaceTangentGenerator.generate(obj[1]);
+        MikktspaceTangentGenerator.generate(obj[0]);
 
         Spatial t = obj[0].clone(false);
         t.setLocalScale(10f);

+ 2 - 2
jme3-examples/src/main/java/jme3test/light/TestShadowsPerf.java

@@ -48,7 +48,7 @@ import com.jme3.scene.shape.Box;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.shadow.DirectionalLightShadowRenderer;
 import com.jme3.shadow.EdgeFilteringMode;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestShadowsPerf extends SimpleApplication {
 
@@ -84,7 +84,7 @@ public class TestShadowsPerf extends SimpleApplication {
         Sphere sphMesh = new Sphere(32, 32, 1);
         sphMesh.setTextureMode(Sphere.TextureMode.Projected);
         sphMesh.updateGeometry(32, 32, 1, false, false);
-        TangentBinormalGenerator.generate(sphMesh);
+        MikktspaceTangentGenerator.generate(sphMesh);
 
         sphere = new Geometry("Rock Ball", sphMesh);
         sphere.setLocalTranslation(0, 5, 0);

+ 2 - 2
jme3-examples/src/main/java/jme3test/light/TestSimpleLighting.java

@@ -43,7 +43,7 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.util.MaterialDebugAppState;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestSimpleLighting extends SimpleApplication {
 
@@ -59,7 +59,7 @@ public class TestSimpleLighting extends SimpleApplication {
     @Override
     public void simpleInitApp() {
         Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");
-        TangentBinormalGenerator.generate(teapot.getMesh(), true);
+        MikktspaceTangentGenerator.generate(teapot.getMesh());
 
         teapot.setLocalScale(2f);
         Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");

+ 3 - 3
jme3-examples/src/main/java/jme3test/light/TestSpotLight.java

@@ -43,7 +43,7 @@ import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.Box;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.texture.Texture.WrapMode;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestSpotLight extends SimpleApplication {
 
@@ -101,7 +101,7 @@ public class TestSpotLight extends SimpleApplication {
         
         
         Box floor = new Box(50, 1f, 50);
-        TangentBinormalGenerator.generate(floor);
+        MikktspaceTangentGenerator.generate(floor);
         floor.scaleTextureCoordinates(new Vector2f(5, 5));
         Geometry floorGeom = new Geometry("Floor", floor);
         floorGeom.setMaterial(mat);
@@ -120,7 +120,7 @@ public class TestSpotLight extends SimpleApplication {
         signpost.setLocalTranslation(12, 3.5f, 30);
         signpost.setLocalScale(4);
         signpost.setShadowMode(ShadowMode.CastAndReceive);
-        TangentBinormalGenerator.generate(signpost);
+        MikktspaceTangentGenerator.generate(signpost);
         rootNode.attachChild(signpost);
     }
 

+ 3 - 3
jme3-examples/src/main/java/jme3test/light/TestSpotLightShadows.java

@@ -49,7 +49,7 @@ import com.jme3.shadow.EdgeFilteringMode;
 import com.jme3.shadow.SpotLightShadowFilter;
 import com.jme3.shadow.SpotLightShadowRenderer;
 import com.jme3.texture.Texture.WrapMode;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestSpotLightShadows extends SimpleApplication {
 
@@ -149,7 +149,7 @@ public class TestSpotLightShadows extends SimpleApplication {
 
 
         Box floor = new Box(50, 1f, 50);
-        TangentBinormalGenerator.generate(floor);
+        MikktspaceTangentGenerator.generate(floor);
         floor.scaleTextureCoordinates(new Vector2f(5, 5));
         Geometry floorGeom = new Geometry("Floor", floor);
         floorGeom.setMaterial(mat);
@@ -166,7 +166,7 @@ public class TestSpotLightShadows extends SimpleApplication {
         signpost.setLocalTranslation(12, 3.5f, 30);
         signpost.setLocalScale(4);
         signpost.setShadowMode(ShadowMode.CastAndReceive);
-        TangentBinormalGenerator.generate(signpost);
+        MikktspaceTangentGenerator.generate(signpost);
         rootNode.attachChild(signpost);
     }
 

+ 2 - 2
jme3-examples/src/main/java/jme3test/light/TestTangentCube.java

@@ -40,7 +40,7 @@ import com.jme3.math.FastMath;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Box;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 /**
  *
@@ -57,7 +57,7 @@ public class TestTangentCube extends SimpleApplication {
     public void simpleInitApp() {
         Box aBox = new Box(1, 1, 1);
         Geometry aGeometry = new Geometry("Box", aBox);
-        TangentBinormalGenerator.generate(aBox);
+        MikktspaceTangentGenerator.generate(aBox);
 
         Material aMaterial = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
         aMaterial.setTexture("DiffuseMap",

+ 5 - 3
jme3-examples/src/main/java/jme3test/light/TestTangentGen.java

@@ -45,7 +45,9 @@ import com.jme3.scene.VertexBuffer.Type;
 import com.jme3.scene.shape.Quad;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.util.BufferUtils;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.TangentUtils;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
+
 import java.nio.FloatBuffer;
 import java.nio.IntBuffer;
 
@@ -79,7 +81,7 @@ public class TestTangentGen extends SimpleApplication {
     }
 
     private void addMesh(String name, Mesh mesh, Vector3f translation) {
-        TangentBinormalGenerator.generate(mesh);
+        MikktspaceTangentGenerator.generate(mesh);
 
         Geometry testGeom = new Geometry(name, mesh);
         Material mat = assetManager.loadMaterial("Textures/BumpMapTest/Tangent.j3m");
@@ -89,7 +91,7 @@ public class TestTangentGen extends SimpleApplication {
 
         Geometry debug = new Geometry(
                 "Debug " + name,
-                TangentBinormalGenerator.genTbnLines(mesh, 0.08f)
+                TangentUtils.genTbnLines(mesh, 0.08f)
         );
         Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m");
         debug.setMaterial(debugMat);

+ 4 - 3
jme3-examples/src/main/java/jme3test/light/TestTangentGenBadUV.java

@@ -42,7 +42,8 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.TangentUtils;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestTangentGenBadUV extends SimpleApplication {
 
@@ -60,7 +61,7 @@ public class TestTangentGenBadUV extends SimpleApplication {
         Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
         if (teapot instanceof Geometry){
             Geometry g = (Geometry) teapot;
-            TangentBinormalGenerator.generate(g.getMesh());
+            MikktspaceTangentGenerator.generate(g.getMesh());
         }else{
             throw new RuntimeException();
         }
@@ -71,7 +72,7 @@ public class TestTangentGenBadUV extends SimpleApplication {
 
         Geometry debug = new Geometry(
                 "Debug Teapot",
-                TangentBinormalGenerator.genTbnLines(((Geometry) teapot).getMesh(), 0.03f)
+                TangentUtils.genTbnLines(((Geometry) teapot).getMesh(), 0.03f)
         );
         Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m");
         debug.setMaterial(debugMat);

+ 2 - 1
jme3-examples/src/main/java/jme3test/light/TestTangentSpace.java

@@ -44,6 +44,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
 import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.TangentUtils;
 import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 /**
@@ -120,7 +121,7 @@ public class TestTangentSpace extends SimpleApplication {
     private void createDebugTangents(Geometry geom) {
         Geometry debug = new Geometry(
                 "Debug " + geom.getName(),
-                TangentBinormalGenerator.genTbnLines(geom.getMesh(), 0.8f)
+                TangentUtils.genTbnLines(geom.getMesh(), 0.8f)
         );
         Material debugMat = assetManager.loadMaterial("Common/Materials/VertexColor.j3m");
         debug.setMaterial(debugMat);

+ 2 - 2
jme3-examples/src/main/java/jme3test/light/TestTransparentShadow.java

@@ -50,7 +50,7 @@ import com.jme3.scene.shape.Sphere;
 import com.jme3.shadow.CompareMode;
 import com.jme3.shadow.DirectionalLightShadowRenderer;
 import com.jme3.shadow.EdgeFilteringMode;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestTransparentShadow extends SimpleApplication {
 
@@ -72,7 +72,7 @@ public class TestTransparentShadow extends SimpleApplication {
                 new Vector3f(-10, 0, -10)
         );
         rm.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10));
-        TangentBinormalGenerator.generate(rm);
+        MikktspaceTangentGenerator.generate(rm);
 
         Geometry geom = new Geometry("floor", rm);
         Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");

+ 2 - 2
jme3-examples/src/main/java/jme3test/light/TestTwoSideLighting.java

@@ -44,7 +44,7 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Quad;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 /**
  * Checks two-sided lighting capability.
@@ -80,7 +80,7 @@ public class TestTwoSideLighting extends SimpleApplication {
         
         quadGeom.setMaterial(mat1);
         // SimpleBump material requires tangents.
-        TangentBinormalGenerator.generate(quadGeom);
+        MikktspaceTangentGenerator.generate(quadGeom);
         rootNode.attachChild(quadGeom);
         
         Geometry teapot = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");

+ 2 - 2
jme3-examples/src/main/java/jme3test/material/TestBumpModel.java

@@ -42,7 +42,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.plugins.ogre.OgreMeshKey;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestBumpModel extends SimpleApplication {
 
@@ -59,7 +59,7 @@ public class TestBumpModel extends SimpleApplication {
     public void simpleInitApp() {
         Spatial signpost = assetManager.loadAsset(new OgreMeshKey("Models/Sign Post/Sign Post.mesh.xml"));
         signpost.setMaterial(assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m"));
-        TangentBinormalGenerator.generate(signpost);
+        MikktspaceTangentGenerator.generate(signpost);
         rootNode.attachChild(signpost);
 
         lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f));

+ 2 - 2
jme3-examples/src/main/java/jme3test/material/TestNormalMapping.java

@@ -41,7 +41,7 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestNormalMapping extends SimpleApplication {
 
@@ -59,7 +59,7 @@ public class TestNormalMapping extends SimpleApplication {
         Sphere sphMesh = new Sphere(32, 32, 1);
         sphMesh.setTextureMode(Sphere.TextureMode.Projected);
         sphMesh.updateGeometry(32, 32, 1, false, false);
-        TangentBinormalGenerator.generate(sphMesh);
+        MikktspaceTangentGenerator.generate(sphMesh);
 
         Geometry sphere = new Geometry("Rock Ball", sphMesh);
         Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");

+ 3 - 3
jme3-examples/src/main/java/jme3test/material/TestParallax.java

@@ -44,7 +44,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.RectangleMesh;
 import com.jme3.util.SkyFactory;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestParallax extends SimpleApplication {
 
@@ -77,7 +77,7 @@ public class TestParallax extends SimpleApplication {
         rm.scaleTextureCoordinates(new Vector2f(10, 10));
 
         Geometry floorGeom = new Geometry("floorGeom", rm);
-        TangentBinormalGenerator.generate(floorGeom);
+        MikktspaceTangentGenerator.generate(floorGeom);
         floorGeom.setMaterial(mat);
 
         rootNode.attachChild(floorGeom);
@@ -86,7 +86,7 @@ public class TestParallax extends SimpleApplication {
     public void setupSignpost() {
         Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml");
         Material matSp = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m");
-        TangentBinormalGenerator.generate(signpost);
+        MikktspaceTangentGenerator.generate(signpost);
         signpost.setMaterial(matSp);
         signpost.rotate(0, FastMath.HALF_PI, 0);
         signpost.setLocalTranslation(12, 23.5f, 30);

+ 3 - 3
jme3-examples/src/main/java/jme3test/material/TestParallaxPBR.java

@@ -44,7 +44,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.RectangleMesh;
 import com.jme3.util.SkyFactory;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestParallaxPBR extends SimpleApplication {
 
@@ -80,7 +80,7 @@ public class TestParallaxPBR extends SimpleApplication {
         rm.scaleTextureCoordinates(new Vector2f(10, 10));
 
         Geometry floorGeom = new Geometry("floorGeom", rm);
-        TangentBinormalGenerator.generate(floorGeom);
+        MikktspaceTangentGenerator.generate(floorGeom);
         //floorGeom.setLocalScale(100);
 
         floorGeom.setMaterial(mat);
@@ -90,7 +90,7 @@ public class TestParallaxPBR extends SimpleApplication {
     public void setupSignpost() {
         Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml");
         Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m");
-        TangentBinormalGenerator.generate(signpost);
+        MikktspaceTangentGenerator.generate(signpost);
         signpost.setMaterial(mat);
         signpost.rotate(0, FastMath.HALF_PI, 0);
         signpost.setLocalTranslation(12, 23.5f, 30);

+ 2 - 2
jme3-examples/src/main/java/jme3test/material/TestSimpleBumps.java

@@ -42,7 +42,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.Quad;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 // phong cutoff for light to normal angle > 90?
 public class TestSimpleBumps extends SimpleApplication {
@@ -63,7 +63,7 @@ public class TestSimpleBumps extends SimpleApplication {
         Geometry sphere = new Geometry("Rock Ball", quadMesh);
         Material mat = assetManager.loadMaterial("Textures/BumpMapTest/SimpleBump.j3m");
         sphere.setMaterial(mat);
-        TangentBinormalGenerator.generate(sphere);
+        MikktspaceTangentGenerator.generate(sphere);
         rootNode.attachChild(sphere);
 
         lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f));

+ 2 - 2
jme3-examples/src/main/java/jme3test/material/TestUnshadedModel.java

@@ -8,7 +8,7 @@ import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Sphere;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestUnshadedModel extends SimpleApplication {
 
@@ -22,7 +22,7 @@ public class TestUnshadedModel extends SimpleApplication {
         Sphere sphMesh = new Sphere(32, 32, 1);
         sphMesh.setTextureMode(Sphere.TextureMode.Projected);
         sphMesh.updateGeometry(32, 32, 1, false, false);
-        TangentBinormalGenerator.generate(sphMesh);
+        MikktspaceTangentGenerator.generate(sphMesh);
 
         Geometry sphere = new Geometry("Rock Ball", sphMesh);
         Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");

+ 2 - 2
jme3-examples/src/main/java/jme3test/model/anim/TestAnimationFactory.java

@@ -12,7 +12,7 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.shape.Box;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestAnimationFactory extends SimpleApplication {
 
@@ -45,7 +45,7 @@ public class TestAnimationFactory extends SimpleApplication {
         childModel.setLocalTranslation(2, 2, 2);
         childModel.attachChild(childGeom);
         model.attachChild(childModel);
-        TangentBinormalGenerator.generate(model);
+        MikktspaceTangentGenerator.generate(model);
 
         // Construct a complex animation using AnimFactory:
         // 6 seconds in duration, named "anim", running at 25 frames per second

+ 2 - 2
jme3-examples/src/main/java/jme3test/post/TestLightScattering.java

@@ -45,7 +45,7 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
 import com.jme3.util.SkyFactory;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestLightScattering extends SimpleApplication {
 
@@ -66,7 +66,7 @@ public class TestLightScattering extends SimpleApplication {
         flyCam.setMoveSpeed(10);
         Material mat = assetManager.loadMaterial("Textures/Terrain/Rocky/Rocky.j3m");
         Spatial scene = assetManager.loadModel("Models/Terrain/Terrain.mesh.xml");
-        TangentBinormalGenerator.generate(((Geometry)((Node)scene).getChild(0)).getMesh());
+        MikktspaceTangentGenerator.generate(((Geometry) ((Node) scene).getChild(0)).getMesh());
         scene.setMaterial(mat);
         scene.setShadowMode(ShadowMode.CastAndReceive);
         scene.setLocalScale(400);

+ 2 - 2
jme3-examples/src/main/java/jme3test/post/TestPostFilters.java

@@ -48,7 +48,7 @@ import com.jme3.scene.shape.Box;
 import com.jme3.texture.Texture;
 import com.jme3.util.SkyFactory;
 import com.jme3.util.SkyFactory.EnvMapType;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestPostFilters extends SimpleApplication implements ActionListener {
 
@@ -111,7 +111,7 @@ public class TestPostFilters extends SimpleApplication implements ActionListener
     public void setupFloor() {
         Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m");
         Box floor = new Box(50, 1f, 50);
-        TangentBinormalGenerator.generate(floor);
+        MikktspaceTangentGenerator.generate(floor);
         floor.scaleTextureCoordinates(new Vector2f(5, 5));
         Geometry floorGeom = new Geometry("Floor", floor);
         floorGeom.setMaterial(mat);

+ 2 - 2
jme3-examples/src/main/java/jme3test/post/TestTransparentSSAO.java

@@ -12,7 +12,7 @@ import com.jme3.renderer.queue.RenderQueue.ShadowMode;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.shape.RectangleMesh;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.mikktspace.MikktspaceTangentGenerator;
 
 public class TestTransparentSSAO extends SimpleApplication {
 
@@ -42,7 +42,7 @@ public class TestTransparentSSAO extends SimpleApplication {
         geom.setMaterial(mat);
 
         geom.setShadowMode(ShadowMode.Receive);
-        TangentBinormalGenerator.generate(geom);
+        MikktspaceTangentGenerator.generate(geom);
         rootNode.attachChild(geom);
 
         // create the geometry and attach it

+ 2 - 2
jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainQuad.java

@@ -56,7 +56,7 @@ import com.jme3.terrain.geomipmap.lodcalc.LodCalculator;
 import com.jme3.terrain.geomipmap.picking.BresenhamTerrainPicker;
 import com.jme3.terrain.geomipmap.picking.TerrainPickData;
 import com.jme3.terrain.geomipmap.picking.TerrainPicker;
-import com.jme3.util.TangentBinormalGenerator;
+import com.jme3.util.TangentUtils;
 import com.jme3.util.clone.Cloner;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -677,7 +677,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.8f));
+                        TangentUtils.genTbnLines(((TerrainPatch) child).getMesh(), 0.8f));
                 attachChild(debug);
                 debug.setLocalTranslation(child.getLocalTranslation());
                 debug.setCullHint(CullHint.Never);