/*
 * Copyright (c) 2009-2010 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.jme3.util;

import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.*;
import com.jme3.scene.VertexBuffer.Format;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.scene.VertexBuffer.Usage;
import com.jme3.scene.mesh.IndexBuffer;
import static com.jme3.util.BufferUtils.*;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 
 * @author Lex (Aleksey Nikiforov)
  */
public class TangentBinormalGenerator {
    
    private static final float ZERO_TOLERANCE = 0.0000001f;
    private static final Logger log = Logger.getLogger(
            TangentBinormalGenerator.class.getName());
    private static float toleranceAngle;
    private static float toleranceDot;
    
    static {
        setToleranceAngle(45);
    }
    
    
    private static class VertexInfo {
        public final Vector3f position;
        public final Vector3f normal;
        public final ArrayList<Integer> indices = new ArrayList<Integer>();
        
        public VertexInfo(Vector3f position, Vector3f normal) {
            this.position = position;
            this.normal = normal;
        }
    }
    
    /** Collects all the triangle data for one vertex.
     */
    private static class VertexData {
        public final ArrayList<TriangleData> triangles = new ArrayList<TriangleData>();
        
        public VertexData() { }
    }
    
    /** Keeps track of tangent, binormal, and normal for one triangle.
     */
    public static class TriangleData {
        public final Vector3f tangent;
        public final Vector3f binormal;
        public final Vector3f normal;
        
        public TriangleData(Vector3f tangent, Vector3f binormal, Vector3f normal) {
            this.tangent = tangent;
            this.binormal = binormal;
            this.normal = normal;
        }
    }
    
    private static VertexData[] initVertexData(int size) {
        VertexData[] vertices = new VertexData[size];
        for (int i = 0; i < size; i++) {
            vertices[i] = new VertexData();
        }
        return vertices;
    }
    
    public static void generate(Mesh mesh) {
        generate(mesh, true);
    }
    
    public static void generate(Spatial scene) {
        if (scene instanceof Node) {
            Node node = (Node) scene;
            for (Spatial child : node.getChildren()) {
                generate(child);
            }
        } else {
            Geometry geom = (Geometry) scene;
            generate(geom.getMesh());
        }
    }
    
    public static void generate(Mesh mesh, boolean approxTangents) {
        int[] index = new int[3];
        Vector3f[] v = new Vector3f[3];
        Vector2f[] t = new Vector2f[3];
        for (int i = 0; i < 3; i++) {
            v[i] = new Vector3f();
            t[i] = new Vector2f();
        }
        
        if (mesh.getBuffer(Type.Normal) == null) {
            throw new IllegalArgumentException("The given mesh has no normal data!");
        }
        
        VertexData[] vertices;
        switch (mesh.getMode()) {
            case Triangles:
                vertices = processTriangles(mesh, index, v, t);
                break;
            case TriangleStrip:
                vertices = processTriangleStrip(mesh, index, v, t);
                break;
            case TriangleFan:
                vertices = processTriangleFan(mesh, index, v, t);
                break;
            default:
                throw new UnsupportedOperationException(
                        mesh.getMode() + " is not supported.");
        }
        
        processTriangleData(mesh, vertices, approxTangents);

        //if the mesh has a bind pose, we need to generate the bind pose for the tangent buffer
        if (mesh.getBuffer(Type.BindPosePosition) != null) {
            
            VertexBuffer tangents = mesh.getBuffer(Type.Tangent);
            if (tangents != null) {
                VertexBuffer bindTangents = new VertexBuffer(Type.BindPoseTangent);
                bindTangents.setupData(Usage.CpuOnly,
                        4,
                        Format.Float,
                        BufferUtils.clone(tangents.getData()));
                
                if (mesh.getBuffer(Type.BindPoseTangent) != null) {
                    mesh.clearBuffer(Type.BindPoseTangent);
                }
                mesh.setBuffer(bindTangents);
                tangents.setUsage(Usage.Stream);
            }
        }
    }
    
    private static VertexData[] processTriangles(Mesh mesh,
            int[] index, Vector3f[] v, Vector2f[] t) {
        IndexBuffer indexBuffer = mesh.getIndexBuffer();
        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
        if (mesh.getBuffer(Type.TexCoord) == null) {
            throw new IllegalArgumentException("Can only generate tangents for "
                    + "meshes with texture coordinates");
        }
        
        FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
        
        VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3);
        
        for (int i = 0; i < indexBuffer.size() / 3; i++) {
            for (int j = 0; j < 3; j++) {
                index[j] = indexBuffer.get(i * 3 + j);
                populateFromBuffer(v[j], vertexBuffer, index[j]);
                populateFromBuffer(t[j], textureBuffer, index[j]);
            }
            
            TriangleData triData = processTriangle(index, v, t);
            if (triData != null) {
                vertices[index[0]].triangles.add(triData);
                vertices[index[1]].triangles.add(triData);
                vertices[index[2]].triangles.add(triData);
            }
        }
        
        return vertices;
    }
    
    private static VertexData[] processTriangleStrip(Mesh mesh,
            int[] index, Vector3f[] v, Vector2f[] t) {
        IndexBuffer indexBuffer = mesh.getIndexBuffer();
        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
        FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
        
        VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3);
        
        index[0] = indexBuffer.get(0);
        index[1] = indexBuffer.get(1);
        
        populateFromBuffer(v[0], vertexBuffer, index[0]);
        populateFromBuffer(v[1], vertexBuffer, index[1]);
        
        populateFromBuffer(t[0], textureBuffer, index[0]);
        populateFromBuffer(t[1], textureBuffer, index[1]);
        
        for (int i = 2; i < indexBuffer.size(); i++) {
            index[2] = indexBuffer.get(i);
            BufferUtils.populateFromBuffer(v[2], vertexBuffer, index[2]);
            BufferUtils.populateFromBuffer(t[2], textureBuffer, index[2]);
            
            boolean isDegenerate = isDegenerateTriangle(v[0], v[1], v[2]);
            TriangleData triData = processTriangle(index, v, t);
            
            if (triData != null && !isDegenerate) {
                vertices[index[0]].triangles.add(triData);
                vertices[index[1]].triangles.add(triData);
                vertices[index[2]].triangles.add(triData);
            }
            
            Vector3f vTemp = v[0];
            v[0] = v[1];
            v[1] = v[2];
            v[2] = vTemp;
            
            Vector2f tTemp = t[0];
            t[0] = t[1];
            t[1] = t[2];
            t[2] = tTemp;
            
            index[0] = index[1];
            index[1] = index[2];
        }
        
        return vertices;
    }
    
    private static VertexData[] processTriangleFan(Mesh mesh,
            int[] index, Vector3f[] v, Vector2f[] t) {
        IndexBuffer indexBuffer = mesh.getIndexBuffer();
        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
        FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
        
        VertexData[] vertices = initVertexData(vertexBuffer.capacity() / 3);
        
        index[0] = indexBuffer.get(0);
        index[1] = indexBuffer.get(1);
        
        populateFromBuffer(v[0], vertexBuffer, index[0]);
        populateFromBuffer(v[1], vertexBuffer, index[1]);
        
        populateFromBuffer(t[0], textureBuffer, index[0]);
        populateFromBuffer(t[1], textureBuffer, index[1]);
        
        for (int i = 2; i < vertexBuffer.capacity() / 3; i++) {
            index[2] = indexBuffer.get(i);
            populateFromBuffer(v[2], vertexBuffer, index[2]);
            populateFromBuffer(t[2], textureBuffer, index[2]);
            
            TriangleData triData = processTriangle(index, v, t);
            if (triData != null) {
                vertices[index[0]].triangles.add(triData);
                vertices[index[1]].triangles.add(triData);
                vertices[index[2]].triangles.add(triData);
            }
            
            Vector3f vTemp = v[1];
            v[1] = v[2];
            v[2] = vTemp;
            
            Vector2f tTemp = t[1];
            t[1] = t[2];
            t[2] = tTemp;
            
            index[1] = index[2];
        }
        
        return vertices;
    }

    // check if the area is greater than zero
    private static boolean isDegenerateTriangle(Vector3f a, Vector3f b, Vector3f c) {
        return (a.subtract(b).cross(c.subtract(b))).lengthSquared() == 0;
    }
    
    public static TriangleData processTriangle(int[] index,
            Vector3f[] v, Vector2f[] t) {
        Vector3f edge1 = new Vector3f();
        Vector3f edge2 = new Vector3f();
        Vector2f edge1uv = new Vector2f();
        Vector2f edge2uv = new Vector2f();
        
        Vector3f tangent = new Vector3f();
        Vector3f binormal = new Vector3f();
        Vector3f normal = new Vector3f();
        
        t[1].subtract(t[0], edge1uv);
        t[2].subtract(t[0], edge2uv);
        float det = edge1uv.x * edge2uv.y - edge1uv.y * edge2uv.x;
        
        boolean normalize = false;
        if (Math.abs(det) < ZERO_TOLERANCE) {
            log.log(Level.WARNING, "Colinear uv coordinates for triangle "
                    + "[{0}, {1}, {2}]; tex0 = [{3}, {4}], "
                    + "tex1 = [{5}, {6}], tex2 = [{7}, {8}]",
                    new Object[]{index[0], index[1], index[2],
                        t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y});
            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();
        
        if (Math.abs(Math.abs(tangent.dot(binormal)) - 1)
                < ZERO_TOLERANCE) {
            log.log(Level.WARNING, "Vertices are on the same line "
                    + "for triangle [{0}, {1}, {2}].",
                    new Object[]{index[0], index[1], index[2]});
        }
        
        float factor = 1 / det;
        tangent.x = (edge2uv.y * edge1.x - edge1uv.y * edge2.x) * factor;
        tangent.y = (edge2uv.y * edge1.y - edge1uv.y * edge2.y) * factor;
        tangent.z = (edge2uv.y * edge1.z - edge1uv.y * edge2.z) * factor;
        if (normalize) {
            tangent.normalizeLocal();
        }
        
        binormal.x = (edge1uv.x * edge2.x - edge2uv.x * edge1.x) * factor;
        binormal.y = (edge1uv.x * edge2.y - edge2uv.x * edge1.y) * factor;
        binormal.z = (edge1uv.x * edge2.z - edge2uv.x * edge1.z) * factor;
        if (normalize) {
            binormal.normalizeLocal();
        }
        
        tangent.cross(binormal, normal);
        normal.normalizeLocal();
        
        return new TriangleData(
                tangent,
                binormal,
                normal);
    }
    
    public static void setToleranceAngle(float angle) {
        if (angle < 0 || angle > 179) {
            throw new IllegalArgumentException(
                    "The angle must be between 0 and 179 degrees.");
        }
        toleranceDot = FastMath.cos(angle * FastMath.DEG_TO_RAD);
        toleranceAngle = angle;
    }
    
    
    private static boolean approxEqual(Vector3f u, Vector3f v) {
        float tolerance = 1E-4f;
        return (FastMath.abs(u.x - v.x) < tolerance) &&
               (FastMath.abs(u.y - v.y) < tolerance) &&
               (FastMath.abs(u.z - v.z) < tolerance);
    }
    
    private static ArrayList<VertexInfo> linkVertices(Mesh mesh) {
        ArrayList<VertexInfo> vertexMap = new ArrayList<VertexInfo>();
        
        FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
        
        Vector3f position = new Vector3f();
        Vector3f normal = new Vector3f();
        
        final int size = vertexBuffer.capacity() / 3;
        for (int i = 0; i < size; i++) {
            
            populateFromBuffer(position, vertexBuffer, i);
            populateFromBuffer(normal, normalBuffer, i);
            
            boolean found = false;
            
            for (int j = 0; j < vertexMap.size(); j++) {
                VertexInfo vertexInfo = vertexMap.get(j);
                if (approxEqual(vertexInfo.position, position) &&
                    approxEqual(vertexInfo.normal, normal))
                {
                    vertexInfo.indices.add(i);
                    found = true;
                    break;  
                }
            }
            
            if (!found) {
                VertexInfo vertexInfo = new VertexInfo(position.clone(), normal.clone());
                vertexInfo.indices.add(i);
                vertexMap.add(vertexInfo);
            }
        }
        
        return vertexMap;
    }
    
    private static void processTriangleData(Mesh mesh, VertexData[] vertices,
            boolean approxTangent)
    {
        ArrayList<VertexInfo> vertexMap = linkVertices(mesh);
        
        FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
        
        FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.length * 4);
//        FloatBuffer binormals = BufferUtils.createFloatBuffer(vertices.length * 3);

        Vector3f tangent = new Vector3f();
        Vector3f binormal = new Vector3f();
        Vector3f normal = new Vector3f();
        Vector3f givenNormal = new Vector3f();
        
        Vector3f tangentUnit = new Vector3f();
        Vector3f binormalUnit = new Vector3f();
        
        for (int k = 0; k < vertexMap.size(); k++) {
            float wCoord = -1;
            
            VertexInfo vertexInfo = vertexMap.get(k);
            
            givenNormal.set(vertexInfo.normal);
            givenNormal.normalizeLocal();
            
            TriangleData firstTriangle = vertices[vertexInfo.indices.get(0)].triangles.get(0);

            // check tangent and binormal consistency
            tangent.set(firstTriangle.tangent);
            tangent.normalizeLocal();
            binormal.set(firstTriangle.binormal);
            binormal.normalizeLocal();
            
            for (int i : vertexInfo.indices) {
                ArrayList<TriangleData> triangles = vertices[i].triangles;
                
                for (int j = 0; j < triangles.size(); j++) {
                    TriangleData triangleData = triangles.get(j);

                    tangentUnit.set(triangleData.tangent);
                    tangentUnit.normalizeLocal();
                    if (tangent.dot(tangentUnit) < toleranceDot) {
                        log.log(Level.WARNING,
                                "Angle between tangents exceeds tolerance "
                                + "for vertex {0}.", i);
                        break;
                    }

                    if (!approxTangent) {
                        binormalUnit.set(triangleData.binormal);
                        binormalUnit.normalizeLocal();
                        if (binormal.dot(binormalUnit) < toleranceDot) {
                            log.log(Level.WARNING,
                                    "Angle between binormals exceeds tolerance "
                                    + "for vertex {0}.", i);
                            break;
                        }
                    }
                }
            }
            
            
            // find average tangent
            tangent.set(0, 0, 0);
            binormal.set(0, 0, 0);
            
            int triangleCount = 0;
            for (int i : vertexInfo.indices) {
                ArrayList<TriangleData> triangles = vertices[i].triangles;
                triangleCount += triangles.size();
                
                boolean flippedNormal = false;
                for (int j = 0; j < triangles.size(); j++) {
                    TriangleData triangleData = triangles.get(j);
                    tangent.addLocal(triangleData.tangent);
                    binormal.addLocal(triangleData.binormal);

                    if (givenNormal.dot(triangleData.normal) < 0) {
                        flippedNormal = true;
                    }
                }
                if (flippedNormal /*&& approxTangent*/) {
                    // Generated normal is flipped for this vertex,
                    // so binormal = normal.cross(tangent) will be flipped in the shader
    //                log.log(Level.WARNING,
    //                        "Binormal is flipped for vertex {0}.", i);

                    wCoord = 1;
                }
            }

            
            int blameVertex = vertexInfo.indices.get(0);
            
            if (tangent.length() < ZERO_TOLERANCE) {
                log.log(Level.WARNING,
                        "Shared tangent is zero for vertex {0}.", blameVertex);
                // attempt to fix from binormal
                if (binormal.length() >= ZERO_TOLERANCE) {
                    binormal.cross(givenNormal, tangent);
                    tangent.normalizeLocal();
                } // if all fails use the tangent from the first triangle
                else {
                    tangent.set(firstTriangle.tangent);
                }
            } else {
                tangent.divideLocal(triangleCount);
            }

            tangentUnit.set(tangent);
            tangentUnit.normalizeLocal();
            if (Math.abs(Math.abs(tangentUnit.dot(givenNormal)) - 1)
                    < ZERO_TOLERANCE) {
                log.log(Level.WARNING,
                        "Normal and tangent are parallel for vertex {0}.", blameVertex);
            }


            if (!approxTangent) {
                if (binormal.length() < ZERO_TOLERANCE) {
                    log.log(Level.WARNING,
                            "Shared binormal is zero for vertex {0}.", blameVertex);
                    // attempt to fix from tangent
                    if (tangent.length() >= ZERO_TOLERANCE) {
                        givenNormal.cross(tangent, binormal);
                        binormal.normalizeLocal();
                    } // if all fails use the binormal from the first triangle
                    else {
                        binormal.set(firstTriangle.binormal);
                    }
                } else {
                    binormal.divideLocal(triangleCount);
                }

                binormalUnit.set(binormal);
                binormalUnit.normalizeLocal();
                if (Math.abs(Math.abs(binormalUnit.dot(givenNormal)) - 1)
                        < ZERO_TOLERANCE) {
                    log.log(Level.WARNING,
                            "Normal and binormal are parallel for vertex {0}.", blameVertex);
                }

                if (Math.abs(Math.abs(binormalUnit.dot(tangentUnit)) - 1)
                        < ZERO_TOLERANCE) {
                    log.log(Level.WARNING,
                            "Tangent and binormal are parallel for vertex {0}.", blameVertex);
                }
            }
            
            for (int i : vertexInfo.indices) {
                if (approxTangent) {
                    // This calculation ensures that normal and tagent have a 90 degree angle.
                    // Removing this will lead to visual artifacts.
                    givenNormal.cross(tangent, binormal);
                    binormal.cross(givenNormal, tangent);

                    tangent.normalizeLocal();

                    tangents.put((i * 4), tangent.x);
                    tangents.put((i * 4) + 1, tangent.y);
                    tangents.put((i * 4) + 2, tangent.z);
                    tangents.put((i * 4) + 3, wCoord);
                } else {
                    tangents.put((i * 4), tangent.x);
                    tangents.put((i * 4) + 1, tangent.y);
                    tangents.put((i * 4) + 2, tangent.z);
                    tangents.put((i * 4) + 3, wCoord);

                    //setInBuffer(binormal, binormals, i);
                }
            }
        }
        
        mesh.setBuffer(Type.Tangent, 4, tangents);
//        if (!approxTangent) mesh.setBuffer(Type.Binormal, 3, binormals);
    }
    
    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.capacity() * 2);
        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.capacity() / 3 * 4 * 2);
        
        for (int i = 0; i < vertexBuffer.capacity() / 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;
    }
    
    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.capacity() / 3 * 6);
        FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.capacity() * 4);
        FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.capacity() / 3 * 4 * 4);
        
        boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
        float tangentW = 1;
        
        for (int i = 0; i < vertexBuffer.capacity() / 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;
    }
}
