Package com.l2client.util

Source Code of com.l2client.util.TangentUtil$IndexWrapper

package com.l2client.util;

import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;

/**
* Copyright (c) 2008-2010 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>.
*/

//TODO check used at all? if not remove it
public class TangentUtil {
 
    private static interface IndexWrapper {
        public int get(int i);
        public short getShort(int i);
        public int size();
    }
   
    private static IndexWrapper getIndexWrapper(final Buffer buff) {
        if (buff instanceof ShortBuffer) {
            return new IndexWrapper() {
                private ShortBuffer buf = (ShortBuffer) buff;
                public int get(int i) {
                    return ((int) buf.get(i))&(0x0000FFFF);
                }
                public short getShort(int i){return buf.get(i);}
                public int size() {
                    return buf.capacity();
                }
            };
        }
        else if (buff instanceof IntBuffer) {
            return new IndexWrapper() {
                private IntBuffer buf = (IntBuffer) buff;
                public int get(int i) {
                    return buf.get(i);
                }
                public int size() {
                    return buf.capacity();
                }
        @Override
        public short getShort(int i) {
          return 0;
        }
            };
        } else {
            throw new IllegalArgumentException();
        }
    }
   
    public static FloatBuffer generateTangentBuffer(final Mesh meshData) {
        final FloatBuffer vertexBuffer = (FloatBuffer) meshData.getBuffer(Type.Position).getData();
        final FloatBuffer normalBuffer = (FloatBuffer) meshData.getBuffer(Type.Normal).getData();
        final FloatBuffer textureBuffer = (FloatBuffer) meshData.getBuffer(Type.TexCoord).getData();
        IndexWrapper indexBuffer = getIndexWrapper(meshData.getBuffer(Type.Index).getData());

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

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

        final Vector3f[] vertex = BufferUtils.getVector3Array(vertexBuffer);
        final Vector3f[] normal = BufferUtils.getVector3Array(normalBuffer);
        final Vector2f[] 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 Vector3f v1 = vertex[i1];
            final Vector3f v2 = vertex[i2];
            final Vector3f v3 = vertex[i3];

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

            final float x1 = v2.x - v1.x;
            final float x2 = v3.x - v1.x;
            final float y1 = v2.y - v1.y;
            final float y2 = v3.y - v1.y;
            final float z1 = v2.z - v1.z;
            final float z2 = v3.z - v1.z;

            final float s1 = w2.x - w1.x;
            final float s2 = w3.x - w1.x;
            final float t1 = w2.y - w1.y;
            final float t2 = w3.y - w1.y;

            final float r = 1.0F / (s1 * t2 - s2 * t1);
            final Vector3f sdir = new Vector3f((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
            final Vector3f tdir = new Vector3f((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.createFloatBuffer(vertexCount*4);

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

            // Gram-Schmidt orthogonalize
            float dot = n.dot(t);
            calc1.set(t).subtractLocal(n.mult(dot, calc2)).normalizeLocal();
            tangentBuffer.put(calc1.x).put(calc1.y).put(calc1.z);

            // 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;
    }

  public static void addTangentsToMesh(Mesh mesh) {
    FloatBuffer buf = generateTangentBuffer(mesh);
    mesh.setBuffer(Type.Tangent, 4, buf);
  }
}
TOP

Related Classes of com.l2client.util.TangentUtil$IndexWrapper

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.