• R/O
  • HTTP
  • SSH
  • HTTPS

MikuMikuStudio: Commit

Main repository of MikuMikuStudio


Commit MetaInfo

Revisionf79ace3f4d5f25353288675f1667dcf7ef04dea9 (tree)
Time2013-07-08 06:24:02
Authorremy.bouquet@gmail.com <remy.bouquet@gmai...>
Commiterremy.bouquet@gmail.com

Log Message

- TangentBinormalGenerator now splits vertices with mirrored uvs. This is an optional operation.
It fixes the issue in this thread : http://hub.jmonkeyengine.org/forum/topic/normalmapslighting-issue/
Next step is to split vertices that have triangles with heavily rotated tangent spaces.

git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@10698 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

Change Summary

Incremental Difference

--- a/engine/src/core/com/jme3/util/TangentBinormalGenerator.java
+++ b/engine/src/core/com/jme3/util/TangentBinormalGenerator.java
@@ -35,16 +35,22 @@ import com.jme3.math.ColorRGBA;
3535 import com.jme3.math.FastMath;
3636 import com.jme3.math.Vector2f;
3737 import com.jme3.math.Vector3f;
38-import com.jme3.math.Vector4f;
3938 import com.jme3.scene.*;
4039 import com.jme3.scene.VertexBuffer.Format;
4140 import com.jme3.scene.VertexBuffer.Type;
4241 import com.jme3.scene.VertexBuffer.Usage;
4342 import com.jme3.scene.mesh.IndexBuffer;
4443 import static com.jme3.util.BufferUtils.*;
44+import java.nio.Buffer;
45+import java.nio.ByteBuffer;
46+import java.nio.DoubleBuffer;
4547 import java.nio.FloatBuffer;
4648 import java.nio.IntBuffer;
49+import java.nio.ShortBuffer;
4750 import java.util.ArrayList;
51+import java.util.HashMap;
52+import java.util.List;
53+import java.util.Map;
4854 import java.util.logging.Level;
4955 import java.util.logging.Logger;
5056
@@ -57,13 +63,13 @@ public class TangentBinormalGenerator {
5763 private static final float ZERO_TOLERANCE = 0.0000001f;
5864 private static final Logger log = Logger.getLogger(
5965 TangentBinormalGenerator.class.getName());
60- private static float toleranceAngle;
6166 private static float toleranceDot;
67+ public static boolean debug = false;
6268
6369 static {
6470 setToleranceAngle(45);
6571 }
66-
72+
6773
6874 private static class VertexInfo {
6975 public final Vector3f position;
@@ -91,32 +97,39 @@ public class TangentBinormalGenerator {
9197 public static class TriangleData {
9298 public final Vector3f tangent;
9399 public final Vector3f binormal;
94- public final Vector3f normal;
100+ public final Vector3f normal;
101+ public int[] index = new int[3];
102+ public int triangleOffset;
95103
96104 public TriangleData(Vector3f tangent, Vector3f binormal, Vector3f normal) {
97105 this.tangent = tangent;
98106 this.binormal = binormal;
99107 this.normal = normal;
100108 }
109+ public void setIndex(int[] index) {
110+ for (int i = 0; i < index.length; i++) {
111+ this.index[i] = index[i];
112+ }
113+ }
101114 }
102115
103- private static VertexData[] initVertexData(int size) {
104- VertexData[] vertices = new VertexData[size];
116+ private static List<VertexData> initVertexData(int size) {
117+ List<VertexData> vertices = new ArrayList<VertexData>(size);
105118 for (int i = 0; i < size; i++) {
106- vertices[i] = new VertexData();
119+ vertices.add(new VertexData());
107120 }
108121 return vertices;
109122 }
110123
111124 public static void generate(Mesh mesh) {
112- generate(mesh, true);
125+ generate(mesh, true, false);
113126 }
114127
115- public static void generate(Spatial scene) {
128+ public static void generate(Spatial scene, boolean splitMirrored) {
116129 if (scene instanceof Node) {
117130 Node node = (Node) scene;
118131 for (Spatial child : node.getChildren()) {
119- generate(child);
132+ generate(child, splitMirrored);
120133 }
121134 } else {
122135 Geometry geom = (Geometry) scene;
@@ -125,12 +138,16 @@ public class TangentBinormalGenerator {
125138 // Check to ensure mesh has texcoords and normals before generating
126139 if (mesh.getBuffer(Type.TexCoord) != null
127140 && mesh.getBuffer(Type.Normal) != null){
128- generate(geom.getMesh());
141+ generate(geom.getMesh(),true, splitMirrored);
129142 }
130143 }
131144 }
132145
133- public static void generate(Mesh mesh, boolean approxTangents) {
146+ public static void generate(Spatial scene) {
147+ generate(scene, false);
148+ }
149+
150+ public static void generate(Mesh mesh, boolean approxTangents, boolean splitMirrored) {
134151 int[] index = new int[3];
135152 Vector3f[] v = new Vector3f[3];
136153 Vector2f[] t = new Vector2f[3];
@@ -143,10 +160,13 @@ public class TangentBinormalGenerator {
143160 throw new IllegalArgumentException("The given mesh has no normal data!");
144161 }
145162
146- VertexData[] vertices;
163+ List<VertexData> vertices;
147164 switch (mesh.getMode()) {
148165 case Triangles:
149- vertices = processTriangles(mesh, index, v, t);
166+ vertices = processTriangles(mesh, index, v, t, splitMirrored);
167+ if(splitMirrored){
168+ splitVertices(mesh, vertices, splitMirrored);
169+ }
150170 break;
151171 case TriangleStrip:
152172 vertices = processTriangleStrip(mesh, index, v, t);
@@ -181,8 +201,8 @@ public class TangentBinormalGenerator {
181201 }
182202 }
183203
184- private static VertexData[] processTriangles(Mesh mesh,
185- int[] index, Vector3f[] v, Vector2f[] t) {
204+ private static List<VertexData> processTriangles(Mesh mesh,
205+ int[] index, Vector3f[] v, Vector2f[] t, boolean splitMirrored) {
186206 IndexBuffer indexBuffer = mesh.getIndexBuffer();
187207 FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
188208 if (mesh.getBuffer(Type.TexCoord) == null) {
@@ -192,7 +212,7 @@ public class TangentBinormalGenerator {
192212
193213 FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
194214
195- VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3);
215+ List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
196216
197217 for (int i = 0; i < indexBuffer.size() / 3; i++) {
198218 for (int j = 0; j < 3; j++) {
@@ -202,23 +222,201 @@ public class TangentBinormalGenerator {
202222 }
203223
204224 TriangleData triData = processTriangle(index, v, t);
225+ if(splitMirrored){
226+ triData.setIndex(index);
227+ triData.triangleOffset = i * 3 ;
228+ }
205229 if (triData != null) {
206- vertices[index[0]].triangles.add(triData);
207- vertices[index[1]].triangles.add(triData);
208- vertices[index[2]].triangles.add(triData);
230+ vertices.get(index[0]).triangles.add(triData);
231+ vertices.get(index[1]).triangles.add(triData);
232+ vertices.get(index[2]).triangles.add(triData);
209233 }
210234 }
211235
212236 return vertices;
213237 }
214238
215- private static VertexData[] processTriangleStrip(Mesh mesh,
239+ //Don't remove splitmirorred boolean,It's not used right now, but i intend to
240+ //make this method also split vertice with rotated tangent space and I'll
241+ //add another splitRotated boolean
242+ private static List<VertexData> splitVertices(Mesh mesh, List<VertexData> vertexData, boolean splitMirorred) {
243+ int nbVertices = mesh.getBuffer(Type.Position).getNumElements();
244+ List<VertexData> newVertices = new ArrayList<VertexData>();
245+ Map<Integer, Integer> indiceMap = new HashMap<Integer, Integer>();
246+ FloatBuffer normalBuffer = mesh.getFloatBuffer(Type.Normal);
247+
248+ for (int i = 0; i < vertexData.size(); i++) {
249+ ArrayList<TriangleData> triangles = vertexData.get(i).triangles;
250+ Vector3f givenNormal = new Vector3f();
251+ populateFromBuffer(givenNormal, normalBuffer, i);
252+
253+ ArrayList<TriangleData> trianglesUp = new ArrayList<TriangleData>();
254+ ArrayList<TriangleData> trianglesDown = new ArrayList<TriangleData>();
255+ for (int j = 0; j < triangles.size(); j++) {
256+ TriangleData triangleData = triangles.get(j);
257+ if(parity(givenNormal, triangleData.normal) > 0){
258+ trianglesUp.add(triangleData);
259+ }else{
260+ trianglesDown.add(triangleData);
261+ }
262+ }
263+
264+ //if the vertex has triangles with opposite parity it has to be split
265+ if(!trianglesUp.isEmpty() && !trianglesDown.isEmpty()){
266+ log.log(Level.FINE, "Splitting vertex {0}", i);
267+ //assigning triangle with the same parity to the original vertex
268+ vertexData.get(i).triangles.clear();
269+ vertexData.get(i).triangles.addAll(trianglesUp);
270+
271+ //creating a new vertex
272+ VertexData newVert = new VertexData();
273+ //assigning triangles with opposite parity to it
274+ newVert.triangles.addAll(trianglesDown);
275+
276+ newVertices.add(newVert);
277+ //keep vertex index to fix the index buffers later
278+ indiceMap.put(nbVertices, i);
279+ for (TriangleData tri : newVert.triangles) {
280+ for (int j = 0; j < tri.index.length; j++) {
281+ if(tri.index[j] == i){
282+ tri.index[j] = nbVertices;
283+ }
284+ }
285+ }
286+ nbVertices++;
287+
288+ }
289+
290+
291+ }
292+
293+ if(!newVertices.isEmpty()){
294+
295+ //we have new vertices, we need to update the mesh's buffers.
296+ for (Type type : VertexBuffer.Type.values()) {
297+ //skip tangent buffer as we're gonna overwrite it later
298+ if(type == Type.Tangent || type == Type.BindPoseTangent) continue;
299+ VertexBuffer vb = mesh.getBuffer(type);
300+ //Some buffer (hardware skinning ones) can be there but not
301+ //initialized, they must be skipped.
302+ //They'll be initialized when Hardware Skinning is engaged
303+ if(vb==null || vb.getNumComponents() == 0) continue;
304+
305+ Buffer buffer = vb.getData();
306+ //IndexBuffer has special treatement, only swapping the vertex indices is needed
307+ if(type == Type.Index){
308+ boolean isShortBuffer = vb.getFormat() == VertexBuffer.Format.UnsignedShort;
309+ for (VertexData vertex : newVertices) {
310+ for (TriangleData tri : vertex.triangles) {
311+ for (int i = 0; i < tri.index.length; i++) {
312+ if (isShortBuffer) {
313+ ((ShortBuffer) buffer).put(tri.triangleOffset + i, (short) tri.index[i]);
314+ } else {
315+ ((IntBuffer) buffer).put(tri.triangleOffset + i, tri.index[i]);
316+ }
317+ }
318+ }
319+ }
320+ vb.setUpdateNeeded();
321+ }else{
322+ //copy the buffer in a bigger one and append nex vertices to the end
323+ Buffer newVerts = VertexBuffer.createBuffer(vb.getFormat(), vb.getNumComponents(), nbVertices);
324+ if (buffer != null) {
325+ buffer.rewind();
326+ bulkPut(vb.getFormat(), newVerts,buffer);
327+
328+ int index = vertexData.size();
329+ newVerts.position(vertexData.size() * vb.getNumComponents());
330+ for (int j = 0; j < newVertices.size(); j++) {
331+ int oldInd = indiceMap.get(index) ;
332+ for (int i = 0; i < vb.getNumComponents(); i++) {
333+ putValue(vb.getFormat(), newVerts, buffer, oldInd* vb.getNumComponents() + i);
334+ }
335+ index++;
336+ }
337+ vb.updateData(newVerts);
338+ //destroy previous buffer as it's no longer needed
339+ destroyDirectBuffer(buffer);
340+ }
341+ }
342+ }
343+ vertexData.addAll(newVertices);
344+
345+ mesh.updateCounts();
346+ }
347+
348+ return vertexData;
349+ }
350+
351+ private static void bulkPut(VertexBuffer.Format format, Buffer buf1, Buffer buf2) {
352+ switch (format) {
353+ case Byte:
354+ case Half:
355+ case UnsignedByte:
356+ ((ByteBuffer) buf1).put((ByteBuffer) buf2);
357+ break;
358+ case Short:
359+ case UnsignedShort:
360+
361+ ((ShortBuffer) buf1).put((ShortBuffer) buf2);
362+ break;
363+
364+ case Int:
365+ case UnsignedInt:
366+ ((IntBuffer) buf1).put((IntBuffer) buf2);
367+ break;
368+ case Float:
369+
370+ ((FloatBuffer) buf1).put((FloatBuffer) buf2);
371+ break;
372+ case Double:
373+ ((DoubleBuffer) buf1).put((DoubleBuffer) buf2);
374+ break;
375+
376+ default:
377+ throw new UnsupportedOperationException("Unrecoginized buffer format: " + format);
378+ }
379+ }
380+
381+ private static void putValue(VertexBuffer.Format format, Buffer buf1, Buffer buf2,int index) {
382+ switch (format) {
383+ case Byte:
384+ case Half:
385+ case UnsignedByte:
386+ byte b = ((ByteBuffer) buf2).get(index);
387+ ((ByteBuffer) buf1).put(b);
388+ break;
389+ case Short:
390+ case UnsignedShort:
391+ short s = ((ShortBuffer) buf2).get(index);
392+ ((ShortBuffer) buf1).put(s);
393+ break;
394+
395+ case Int:
396+ case UnsignedInt:
397+ int i = ((IntBuffer) buf2).get(index);
398+ ((IntBuffer) buf1).put(i);
399+ break;
400+ case Float:
401+ float f = ((FloatBuffer) buf2).get(index);
402+ ((FloatBuffer) buf1).put(f);
403+ break;
404+ case Double:
405+ double d = ((DoubleBuffer) buf2).get(index);
406+ ((DoubleBuffer) buf1).put(d);
407+ break;
408+ default:
409+ throw new UnsupportedOperationException("Unrecoginized buffer format: " + format);
410+ }
411+ }
412+
413+ private static List<VertexData> processTriangleStrip(Mesh mesh,
216414 int[] index, Vector3f[] v, Vector2f[] t) {
217415 IndexBuffer indexBuffer = mesh.getIndexBuffer();
218416 FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
219417 FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
220418
221- VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3);
419+ List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
222420
223421 index[0] = indexBuffer.get(0);
224422 index[1] = indexBuffer.get(1);
@@ -238,9 +436,9 @@ public class TangentBinormalGenerator {
238436 TriangleData triData = processTriangle(index, v, t);
239437
240438 if (triData != null && !isDegenerate) {
241- vertices[index[0]].triangles.add(triData);
242- vertices[index[1]].triangles.add(triData);
243- vertices[index[2]].triangles.add(triData);
439+ vertices.get(index[0]).triangles.add(triData);
440+ vertices.get(index[1]).triangles.add(triData);
441+ vertices.get(index[2]).triangles.add(triData);
244442 }
245443
246444 Vector3f vTemp = v[0];
@@ -260,13 +458,13 @@ public class TangentBinormalGenerator {
260458 return vertices;
261459 }
262460
263- private static VertexData[] processTriangleFan(Mesh mesh,
461+ private static List<VertexData> processTriangleFan(Mesh mesh,
264462 int[] index, Vector3f[] v, Vector2f[] t) {
265463 IndexBuffer indexBuffer = mesh.getIndexBuffer();
266464 FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
267465 FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
268466
269- VertexData[] vertices = initVertexData(vertexBuffer.limit() / 3);
467+ List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
270468
271469 index[0] = indexBuffer.get(0);
272470 index[1] = indexBuffer.get(1);
@@ -284,9 +482,9 @@ public class TangentBinormalGenerator {
284482
285483 TriangleData triData = processTriangle(index, v, t);
286484 if (triData != null) {
287- vertices[index[0]].triangles.add(triData);
288- vertices[index[1]].triangles.add(triData);
289- vertices[index[2]].triangles.add(triData);
485+ vertices.get(index[0]).triangles.add(triData);
486+ vertices.get(index[1]).triangles.add(triData);
487+ vertices.get(index[2]).triangles.add(triData);
290488 }
291489
292490 Vector3f vTemp = v[1];
@@ -379,7 +577,6 @@ public class TangentBinormalGenerator {
379577 "The angle must be between 0 and 179 degrees.");
380578 }
381579 toleranceDot = FastMath.cos(angle * FastMath.DEG_TO_RAD);
382- toleranceAngle = angle;
383580 }
384581
385582
@@ -415,18 +612,20 @@ public class TangentBinormalGenerator {
415612 populateFromBuffer(texCoord, texcoordBuffer, i);
416613
417614 boolean found = false;
418-
419- for (int j = 0; j < vertexMap.size(); j++) {
420- VertexInfo vertexInfo = vertexMap.get(j);
421- if (approxEqual(vertexInfo.position, position) &&
422- approxEqual(vertexInfo.normal, normal) &&
423- approxEqual(vertexInfo.texCoord, texCoord))
424- {
425- vertexInfo.indices.add(i);
426- found = true;
427- break;
428- }
429- }
615+ //Nehon 07/07/2013
616+ //Removed this part, joining splitted vertice to compute tangent space makes no sense to me
617+ //separate vertice should have separate tangent space
618+// for (int j = 0; j < vertexMap.size(); j++) {
619+// VertexInfo vertexInfo = vertexMap.get(j);
620+// if (approxEqual(vertexInfo.position, position) &&
621+// approxEqual(vertexInfo.normal, normal) &&
622+// approxEqual(vertexInfo.texCoord, texCoord))
623+// {
624+// vertexInfo.indices.add(i);
625+// found = true;
626+// break;
627+// }
628+// }
430629
431630 if (!found) {
432631 VertexInfo vertexInfo = new VertexInfo(position.clone(), normal.clone(), texCoord.clone());
@@ -438,43 +637,44 @@ public class TangentBinormalGenerator {
438637 return vertexMap;
439638 }
440639
441- private static void processTriangleData(Mesh mesh, VertexData[] vertices,
442- boolean approxTangent)
443- {
640+ private static void processTriangleData(Mesh mesh, List<VertexData> vertices,
641+ boolean approxTangent) {
444642 ArrayList<VertexInfo> vertexMap = linkVertices(mesh);
445-
446- // FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
447-
448- FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.length * 4);
449-// FloatBuffer binormals = BufferUtils.createFloatBuffer(vertices.length * 3);
643+
644+ FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.size() * 4);
645+
646+ ColorRGBA[] cols = null;
647+ if (debug) {
648+ cols = new ColorRGBA[vertices.size()];
649+ }
450650
451651 Vector3f tangent = new Vector3f();
452652 Vector3f binormal = new Vector3f();
453653 //Vector3f normal = new Vector3f();
454654 Vector3f givenNormal = new Vector3f();
455-
655+
456656 Vector3f tangentUnit = new Vector3f();
457657 Vector3f binormalUnit = new Vector3f();
458-
658+
459659 for (int k = 0; k < vertexMap.size(); k++) {
460660 float wCoord = -1;
461-
661+
462662 VertexInfo vertexInfo = vertexMap.get(k);
463-
663+
464664 givenNormal.set(vertexInfo.normal);
465665 givenNormal.normalizeLocal();
466-
467- TriangleData firstTriangle = vertices[vertexInfo.indices.get(0)].triangles.get(0);
666+
667+ TriangleData firstTriangle = vertices.get(vertexInfo.indices.get(0)).triangles.get(0);
468668
469669 // check tangent and binormal consistency
470670 tangent.set(firstTriangle.tangent);
471671 tangent.normalizeLocal();
472672 binormal.set(firstTriangle.binormal);
473673 binormal.normalizeLocal();
474-
674+
475675 for (int i : vertexInfo.indices) {
476- ArrayList<TriangleData> triangles = vertices[i].triangles;
477-
676+ ArrayList<TriangleData> triangles = vertices.get(i).triangles;
677+
478678 for (int j = 0; j < triangles.size(); j++) {
479679 TriangleData triangleData = triangles.get(j);
480680
@@ -499,40 +699,31 @@ public class TangentBinormalGenerator {
499699 }
500700 }
501701 }
502-
503-
702+
703+
504704 // find average tangent
505705 tangent.set(0, 0, 0);
506706 binormal.set(0, 0, 0);
507-
707+
508708 int triangleCount = 0;
509709 for (int i : vertexInfo.indices) {
510- ArrayList<TriangleData> triangles = vertices[i].triangles;
710+ ArrayList<TriangleData> triangles = vertices.get(i).triangles;
511711 triangleCount += triangles.size();
512-
513- // boolean flippedNormal = false;
712+ if (debug) {
713+ cols[i] = ColorRGBA.White;
714+ }
715+
514716 for (int j = 0; j < triangles.size(); j++) {
515717 TriangleData triangleData = triangles.get(j);
516718 tangent.addLocal(triangleData.tangent);
517719 binormal.addLocal(triangleData.binormal);
518720
519-// if (givenNormal.dot(triangleData.normal) < 0) {
520-// flippedNormal = true;
521-// }
522721 }
523-// if (flippedNormal /*&& approxTangent*/) {
524-// // Generated normal is flipped for this vertex,
525-// // so binormal = normal.cross(tangent) will be flipped in the shader
526-// // log.log(Level.WARNING,
527-// // "Binormal is flipped for vertex {0}.", i);
528-//
529-// wCoord = 1;
530-// }
531722 }
532723
533-
724+
534725 int blameVertex = vertexInfo.indices.get(0);
535-
726+
536727 if (tangent.length() < ZERO_TOLERANCE) {
537728 log.log(Level.WARNING,
538729 "Shared tangent is zero for vertex {0}.", blameVertex);
@@ -587,21 +778,21 @@ public class TangentBinormalGenerator {
587778 "Tangent and binormal are parallel for vertex {0}.", blameVertex);
588779 }
589780 }
590-
781+
591782 Vector3f finalTangent = new Vector3f();
592783 Vector3f tmp = new Vector3f();
593784 for (int i : vertexInfo.indices) {
594785 if (approxTangent) {
595786 // Gram-Schmidt orthogonalize
596- finalTangent.set(tangent).subtractLocal(tmp.set(givenNormal).multLocal(givenNormal.dot(tangent)));
787+ finalTangent.set(tangent).subtractLocal(tmp.set(givenNormal).multLocal(givenNormal.dot(tangent)));
597788 finalTangent.normalizeLocal();
598-
599- wCoord = tmp.set(givenNormal).crossLocal(tangent).dot(binormal) <0f? -1f:1f;
789+
790+ wCoord = tmp.set(givenNormal).crossLocal(tangent).dot(binormal) < 0f ? -1f : 1f;
600791
601792 tangents.put((i * 4), finalTangent.x);
602793 tangents.put((i * 4) + 1, finalTangent.y);
603794 tangents.put((i * 4) + 2, finalTangent.z);
604- tangents.put((i * 4) + 3, wCoord);
795+ tangents.put((i * 4) + 3, wCoord);
605796 } else {
606797 tangents.put((i * 4), tangent.x);
607798 tangents.put((i * 4) + 1, tangent.y);
@@ -612,13 +803,49 @@ public class TangentBinormalGenerator {
612803 }
613804 }
614805 }
615-
806+ tangents.limit(tangents.capacity());
616807 // If the model already had a tangent buffer, replace it with the regenerated one
617- mesh.clearBuffer(Type.Tangent);
808+ mesh.clearBuffer(Type.Tangent);
618809 mesh.setBuffer(Type.Tangent, 4, tangents);
619-// if (!approxTangent) mesh.setBuffer(Type.Binormal, 3, binormals);
620- }
810+
811+
812+
813+ if(mesh.isAnimated()){
814+ mesh.clearBuffer(Type.BindPoseNormal);
815+ mesh.clearBuffer(Type.BindPosePosition);
816+ mesh.clearBuffer(Type.BindPoseTangent);
817+ mesh.generateBindPose(true);
818+ }
819+
820+ if (debug) {
821+ writeColorBuffer( vertices, cols, mesh);
822+ }
823+ mesh.updateBound();
824+ mesh.updateCounts();
825+ }
621826
827+ private static void writeColorBuffer(List<VertexData> vertices, ColorRGBA[] cols, Mesh mesh) {
828+ FloatBuffer colors = BufferUtils.createFloatBuffer(vertices.size() * 4);
829+ colors.rewind();
830+ for (ColorRGBA color : cols) {
831+ colors.put(color.r);
832+ colors.put(color.g);
833+ colors.put(color.b);
834+ colors.put(color.a);
835+ }
836+ mesh.clearBuffer(Type.Color);
837+ mesh.setBuffer(Type.Color, 4, colors);
838+ }
839+
840+ private static int parity(Vector3f n1, Vector3f n) {
841+ if (n1.dot(n) < 0) {
842+ return -1;
843+ } else {
844+ return 1;
845+ }
846+
847+ }
848+
622849 public static Mesh genTbnLines(Mesh mesh, float scale) {
623850 if (mesh.getBuffer(Type.Tangent) == null) {
624851 return genNormalLines(mesh, scale);
Show on old repository browser