use of net.drewke.tdme.math.Vector2 in project tdme by andreasdr.
the class ModelHelper method createNormalTangentsAndBitangents.
/**
* Create normal tangents and bitangents for groups with normal mapping
* @see http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/
* @param group
*/
public static void createNormalTangentsAndBitangents(Group group) {
// what we need
ArrayList<Vector3> tangentsArrayList = new ArrayList<Vector3>();
ArrayList<Vector3> bitangentsArrayList = new ArrayList<Vector3>();
// temporary variables
Vector2 uv0 = new Vector2();
Vector2 uv1 = new Vector2();
Vector2 uv2 = new Vector2();
Vector3 deltaPos1 = new Vector3();
Vector3 deltaPos2 = new Vector3();
Vector2 deltaUV1 = new Vector2();
Vector2 deltaUV2 = new Vector2();
Vector3 tmpVector3 = new Vector3();
// create it
Vector3[] vertices = group.getVertices();
Vector3[] normals = group.getNormals();
TextureCoordinate[] textureCoordinates = group.getTextureCoordinates();
for (FacesEntity faceEntity : group.getFacesEntities()) if (faceEntity.getMaterial() != null && faceEntity.getMaterial().hasNormalTexture() == true) {
for (Face face : faceEntity.getFaces()) {
// Shortcuts for vertices
int[] verticesIndexes = face.getVertexIndices();
Vector3 v0 = vertices[verticesIndexes[0]];
Vector3 v1 = vertices[verticesIndexes[1]];
Vector3 v2 = vertices[verticesIndexes[2]];
// shortcuts for UVs
int[] textureCoordinatesIndexes = face.getTextureCoordinateIndices();
uv0.set(textureCoordinates[textureCoordinatesIndexes[0]].getArray());
uv0.setY(1f - uv0.getY());
uv1.set(textureCoordinates[textureCoordinatesIndexes[1]].getArray());
uv1.setY(1f - uv1.getY());
uv2.set(textureCoordinates[textureCoordinatesIndexes[2]].getArray());
uv2.setY(1f - uv2.getY());
// edges of the triangle : position delta
deltaPos1.set(v1).sub(v0);
deltaPos2.set(v2).sub(v0);
// UV delta
deltaUV1.set(uv1).sub(uv0);
deltaUV2.set(uv2).sub(uv0);
// compute tangent and bitangent
float r = 1.0f / (deltaUV1.getX() * deltaUV2.getY() - deltaUV1.getY() * deltaUV2.getX());
Vector3 tangent = new Vector3(deltaPos1).scale(deltaUV2.getY()).sub(tmpVector3.set(deltaPos2).scale(deltaUV1.getY())).scale(r);
Vector3 bitangent = new Vector3(deltaPos2).scale(deltaUV1.getX()).sub(tmpVector3.set(deltaPos1).scale(deltaUV2.getX())).scale(r);
// set up tangent face indices
face.setTangentIndices(tangentsArrayList.size() + 0, tangentsArrayList.size() + 1, tangentsArrayList.size() + 2);
// set up bitangent face indices
face.setBitangentIndices(bitangentsArrayList.size() + 0, bitangentsArrayList.size() + 1, bitangentsArrayList.size() + 2);
// add to group tangents, bitangents
tangentsArrayList.add(tangent);
tangentsArrayList.add(tangent);
tangentsArrayList.add(tangent);
bitangentsArrayList.add(bitangent);
bitangentsArrayList.add(bitangent);
bitangentsArrayList.add(bitangent);
}
}
// set up tangents and bitangents if we have any
if (tangentsArrayList.size() > 0 && bitangentsArrayList.size() > 0) {
group.setTangents(tangentsArrayList);
group.setBitangents(bitangentsArrayList);
// going further
Vector3[] tangents = group.getTangents();
Vector3[] bitangents = group.getBitangents();
for (FacesEntity faceEntity : group.getFacesEntities()) if (faceEntity.getMaterial() != null && faceEntity.getMaterial().hasNormalTexture() == true) {
for (Face face : faceEntity.getFaces()) for (int i = 0; i < 3; i++) {
Vector3 normal = normals[face.getNormalIndices()[i]];
Vector3 tangent = tangents[face.getTangentIndices()[i]];
Vector3 bitangent = bitangents[face.getBitangentIndices()[i]];
tangent.sub(tmpVector3.set(normal).scale(Vector3.computeDotProduct(normal, tangent))).normalize();
if (Vector3.computeDotProduct(Vector3.computeCrossProduct(normal, tangent, tmpVector3), bitangent) < 0f) {
tangent.scale(-1f);
}
bitangent.normalize();
}
}
}
}