Package com.ardor3d.util.geom

Source Code of com.ardor3d.util.geom.TangentUtil

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.util.geom;

import java.nio.FloatBuffer;

import com.ardor3d.math.Vector2;
import com.ardor3d.math.Vector3;
import com.ardor3d.scenegraph.IndexBufferData;
import com.ardor3d.scenegraph.MeshData;

public class TangentUtil {
    public static FloatBuffer generateTangentBuffer(final MeshData meshData) {
        return generateTangentBuffer(meshData, 0);
    }

    public static FloatBuffer generateTangentBuffer(final MeshData meshData, final int uvUnit) {
        final FloatBuffer vertexBuffer = meshData.getVertexBuffer();
        if (vertexBuffer == null) {
            throw new IllegalArgumentException("Vertex buffer is null!");
        }

        final FloatBuffer normalBuffer = meshData.getNormalBuffer();
        if (normalBuffer == null) {
            throw new IllegalArgumentException("Normal buffer is null!");
        }

        FloatBuffer textureBuffer = meshData.getTextureBuffer(uvUnit);
        if (textureBuffer == null && uvUnit != 0) {
            textureBuffer = meshData.getTextureBuffer(0);
        }
        if (textureBuffer == null) {
            throw new IllegalArgumentException("Texture buffer is null!");
        }

        final IndexBufferData<?> indexBuffer = meshData.getIndices();
        if (indexBuffer == null) {
            throw new IllegalArgumentException("Index buffer is null!");
        }

        final int vertexCount = meshData.getVertexCount();
        final int triangleCount = meshData.getTotalPrimitiveCount();

        final Vector3[] tan1 = new Vector3[vertexCount];
        final Vector3[] tan2 = new Vector3[vertexCount];
        for (int i = 0; i < vertexCount; i++) {
            tan1[i] = new Vector3();
            tan2[i] = new Vector3();
        }

        final Vector3[] vertex = BufferUtils.getVector3Array(vertexBuffer);
        final Vector3[] normal = BufferUtils.getVector3Array(normalBuffer);
        final Vector2[] texcoord = BufferUtils.getVector2Array(textureBuffer);

        for (int a = 0; a < triangleCount; a++) {
            final int i1 = indexBuffer.get(a * 3);
            final int i2 = indexBuffer.get(a * 3 + 1);
            final int i3 = indexBuffer.get(a * 3 + 2);

            final Vector3 v1 = vertex[i1];
            final Vector3 v2 = vertex[i2];
            final Vector3 v3 = vertex[i3];

            final Vector2 w1 = texcoord[i1];
            final Vector2 w2 = texcoord[i2];
            final Vector2 w3 = texcoord[i3];

            final float x1 = v2.getXf() - v1.getXf();
            final float x2 = v3.getXf() - v1.getXf();
            final float y1 = v2.getYf() - v1.getYf();
            final float y2 = v3.getYf() - v1.getYf();
            final float z1 = v2.getZf() - v1.getZf();
            final float z2 = v3.getZf() - v1.getZf();

            final float s1 = w2.getXf() - w1.getXf();
            final float s2 = w3.getXf() - w1.getXf();
            final float t1 = w2.getYf() - w1.getYf();
            final float t2 = w3.getYf() - w1.getYf();

            final float r = 1.0F / (s1 * t2 - s2 * t1);
            if (Float.isNaN(r) || Float.isInfinite(r)) {
                continue;
            }
            final Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
            final Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

            tan1[i1].addLocal(sdir);
            tan1[i2].addLocal(sdir);
            tan1[i3].addLocal(sdir);

            tan2[i1].addLocal(tdir);
            tan2[i2].addLocal(tdir);
            tan2[i3].addLocal(tdir);
        }

        final FloatBuffer tangentBuffer = BufferUtils.createVector4Buffer(vertexCount);

        final Vector3 calc1 = new Vector3();
        final Vector3 calc2 = new Vector3();
        for (int a = 0; a < vertexCount; a++) {
            final Vector3 n = normal[a];
            final Vector3 t = tan1[a];

            // Gram-Schmidt orthogonalize
            double dot = n.dot(t);
            calc1.set(t).subtractLocal(n.multiply(dot, calc2)).normalizeLocal();
            tangentBuffer.put(calc1.getXf()).put(calc1.getYf()).put(calc1.getZf());

            // Calculate handedness
            dot = calc1.set(n).crossLocal(t).dot(tan2[a]);
            final float w = dot < 0.0f ? -1.0f : 1.0f;
            tangentBuffer.put(w);
        }

        return tangentBuffer;
    }
}
TOP

Related Classes of com.ardor3d.util.geom.TangentUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.