|
@@ -40,7 +40,9 @@ 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.Buffer;
|
|
|
import java.nio.ByteBuffer;
|
|
|
import java.nio.DoubleBuffer;
|
|
@@ -49,8 +51,12 @@ import java.nio.IntBuffer;
|
|
|
import java.nio.ShortBuffer;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Future;
|
|
|
import java.util.logging.Level;
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
@@ -147,6 +153,44 @@ public class TangentBinormalGenerator {
|
|
|
generate(scene, false);
|
|
|
}
|
|
|
|
|
|
+ public static void generateParallel(Spatial scene, ExecutorService executor) {
|
|
|
+ final Set<Mesh> meshes = new HashSet<Mesh>();
|
|
|
+ scene.breadthFirstTraversal(new SceneGraphVisitor() {
|
|
|
+ @Override
|
|
|
+ public void visit(Spatial spatial) {
|
|
|
+ if (spatial instanceof Geometry) {
|
|
|
+ Geometry geom = (Geometry) spatial;
|
|
|
+ Mesh mesh = geom.getMesh();
|
|
|
+
|
|
|
+ // Check to ensure mesh has texcoords and normals before generating
|
|
|
+ if (mesh.getBuffer(Type.TexCoord) != null
|
|
|
+ && mesh.getBuffer(Type.Normal) != null) {
|
|
|
+ meshes.add(mesh);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ List<Future<?>> futures = new ArrayList<Future<?>>();
|
|
|
+ for (final Mesh m : meshes) {
|
|
|
+ futures.add(executor.submit(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ generate(m, true, false);
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ for (Future<?> f : futures) {
|
|
|
+ try {
|
|
|
+ f.get();
|
|
|
+ } catch (Exception exc) {
|
|
|
+ log.log(Level.WARNING, "Error while computing tangents", exc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public static void generate(Mesh mesh, boolean approxTangents, boolean splitMirrored) {
|
|
|
int[] index = new int[3];
|
|
|
Vector3f[] v = new Vector3f[3];
|
|
@@ -512,67 +556,72 @@ public class TangentBinormalGenerator {
|
|
|
|
|
|
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) {
|
|
|
+ TempVars tmp = TempVars.get();
|
|
|
+ try {
|
|
|
+ Vector3f edge1 = tmp.vect1;
|
|
|
+ Vector3f edge2 = tmp.vect2;
|
|
|
+ Vector2f edge1uv = tmp.vect2d;
|
|
|
+ Vector2f edge2uv = tmp.vect2d2;
|
|
|
+
|
|
|
+ Vector3f tangent = tmp.vect3;
|
|
|
+ Vector3f binormal = tmp.vect4;
|
|
|
+ Vector3f normal = tmp.vect5;
|
|
|
+
|
|
|
+ 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.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.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);
|
|
|
+ } finally {
|
|
|
+ tmp.release();
|
|
|
}
|
|
|
-
|
|
|
- tangent.cross(binormal, normal);
|
|
|
- normal.normalizeLocal();
|
|
|
-
|
|
|
- return new TriangleData(
|
|
|
- tangent,
|
|
|
- binormal,
|
|
|
- normal);
|
|
|
}
|
|
|
|
|
|
public static void setToleranceAngle(float angle) {
|