@ -29,9 +29,11 @@
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
package com.jme3.util ;
import com.jme3.scene.VertexBuffer ;
import com.jme3.scene.VertexBuffer.Format ;
import com.jme3.scene.VertexBuffer.Usage ;
import java.util.logging.Level ;
import com.jme3.scene.mesh.IndexBuffer ;
import com.jme3.scene.Geometry ;
@ -55,41 +57,40 @@ import static com.jme3.util.BufferUtils.*;
* @author Lex
* /
public class TangentBinormalGenerator {
private static final float ZERO_TOLERANCE = 0 . 0000001f ;
private static final Logger log = Logger . getLogger (
TangentBinormalGenerator . class . getName ( ) ) ;
TangentBinormalGenerator . class . getName ( ) ) ;
private static float toleranceAngle ;
private static float toleranceDot ;
static {
setToleranceAngle ( 45 ) ;
}
private static class VertexData {
public final Vector3f tangent = new Vector3f ( ) ;
public final Vector3f binormal = new Vector3f ( ) ;
public final List < TriangleData > triangles =
new ArrayList < TriangleData > ( ) ;
new ArrayList < TriangleData > ( ) ;
public VertexData ( ) {
}
}
public static class TriangleData {
public final Vector3f tangent ;
public final Vector3f binormal ;
public final Vector3f normal ;
public int index0 ;
public int index1 ;
public int index2 ;
public TriangleData ( Vector3f tangent , Vector3f binormal ,
Vector3f normal ,
int index0 , int index1 , int index2 )
{
Vector3f normal ,
int index0 , int index1 , int index2 ) {
this . tangent = tangent ;
this . binormal = binormal ;
this . normal = normal ;
@ -99,7 +100,7 @@ public class TangentBinormalGenerator {
this . index2 = index2 ;
}
}
private static VertexData [ ] initVertexData ( int size ) {
VertexData [ ] vertices = new VertexData [ size ] ;
for ( int i = 0 ; i < size ; i + + ) {
@ -107,23 +108,23 @@ public class TangentBinormalGenerator {
}
return vertices ;
}
public static void generate ( Mesh mesh ) {
generate ( mesh , true ) ;
}
public static void generate ( Spatial scene ) {
if ( scene instanceof Node ) {
public static void generate ( Spatial scene ) {
if ( scene instanceof Node ) {
Node node = ( Node ) scene ;
for ( Spatial child : node . getChildren ( ) ) {
for ( Spatial child : node . getChildren ( ) ) {
generate ( child ) ;
}
} else {
} else {
Geometry geom = ( Geometry ) scene ;
generate ( geom . getMesh ( ) ) ;
}
}
public static void generate ( Mesh mesh , boolean approxTangents ) {
int [ ] index = new int [ 3 ] ;
Vector3f [ ] v = new Vector3f [ 3 ] ;
@ -133,45 +134,68 @@ public class TangentBinormalGenerator {
t [ i ] = new Vector2f ( ) ;
}
if ( mesh . getBuffer ( Type . Normal ) = = null ) {
if ( mesh . getBuffer ( Type . Normal ) = = null ) {
throw new IllegalArgumentException ( "The given mesh has no normal data!" ) ;
}
VertexData [ ] vertices ;
switch ( mesh . getMode ( ) ) {
case Triangles :
vertices = processTriangles ( mesh , index , v , t ) ; break ;
vertices = processTriangles ( mesh , index , v , t ) ;
break ;
case TriangleStrip :
vertices = processTriangleStrip ( mesh , index , v , t ) ; break ;
vertices = processTriangleStrip ( mesh , index , v , t ) ;
break ;
case TriangleFan :
vertices = processTriangleFan ( mesh , index , v , t ) ; break ;
default : throw new UnsupportedOperationException (
mesh . getMode ( ) + " is not supported." ) ;
vertices = processTriangleFan ( mesh , index , v , t ) ;
break ;
default :
throw new UnsupportedOperationException (
mesh . getMode ( ) + " is not supported." ) ;
}
processTriangleData ( mesh , vertices , approxTangents ) ;
}
//if the mesh has a bind pose, we need to generate the bind pose for the tangent buffer
if ( mesh . getBuffer ( Type . BindPosePosition ) ! = null ) {
VertexBuffer tangents = mesh . getBuffer ( Type . Tangent ) ;
if ( tangents ! = null ) {
VertexBuffer bindTangents = new VertexBuffer ( Type . BindPoseTangent ) ;
bindTangents . setupData ( Usage . CpuOnly ,
4 ,
Format . Float ,
BufferUtils . clone ( tangents . getData ( ) ) ) ;
if ( mesh . getBuffer ( Type . BindPoseTangent ) ! = null ) {
mesh . clearBuffer ( Type . BindPoseTangent ) ;
}
mesh . setBuffer ( bindTangents ) ;
tangents . setUsage ( Usage . Stream ) ;
}
}
}
private static VertexData [ ] processTriangles ( Mesh mesh ,
int [ ] index , Vector3f [ ] v , Vector2f [ ] t )
{
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
int [ ] index , Vector3f [ ] v , Vector2f [ ] t ) {
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
FloatBuffer vertexBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Position ) . getData ( ) ;
if ( mesh . getBuffer ( Type . TexCoord ) = = null )
if ( mesh . getBuffer ( Type . TexCoord ) = = null ) {
throw new IllegalArgumentException ( "Can only generate tangents for "
+ "meshes with texture coordinates" ) ;
+ "meshes with texture coordinates" ) ;
}
FloatBuffer textureBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . TexCoord ) . getData ( ) ;
VertexData [ ] vertices = initVertexData ( vertexBuffer . capacity ( ) / 3 ) ;
for ( int i = 0 ; i < indexBuffer . size ( ) / 3 ; i + + ) {
for ( int j = 0 ; j < 3 ; j + + ) {
index [ j ] = indexBuffer . get ( i * 3 + j ) ;
index [ j ] = indexBuffer . get ( i * 3 + j ) ;
populateFromBuffer ( v [ j ] , vertexBuffer , index [ j ] ) ;
populateFromBuffer ( t [ j ] , textureBuffer , index [ j ] ) ;
}
TriangleData triData = processTriangle ( index , v , t ) ;
if ( triData ! = null ) {
vertices [ index [ 0 ] ] . triangles . add ( triData ) ;
@ -182,21 +206,21 @@ public class TangentBinormalGenerator {
return vertices ;
}
private static VertexData [ ] processTriangleStrip ( Mesh mesh ,
int [ ] index , Vector3f [ ] v , Vector2f [ ] t )
{
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
int [ ] index , Vector3f [ ] v , Vector2f [ ] t ) {
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
FloatBuffer vertexBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Position ) . getData ( ) ;
FloatBuffer textureBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . TexCoord ) . getData ( ) ;
VertexData [ ] vertices = initVertexData ( vertexBuffer . capacity ( ) / 3 ) ;
index [ 0 ] = indexBuffer . get ( 0 ) ;
index [ 1 ] = indexBuffer . get ( 1 ) ;
populateFromBuffer ( v [ 0 ] , vertexBuffer , index [ 0 ] ) ;
populateFromBuffer ( v [ 1 ] , vertexBuffer , index [ 1 ] ) ;
populateFromBuffer ( t [ 0 ] , textureBuffer , index [ 0 ] ) ;
populateFromBuffer ( t [ 1 ] , textureBuffer , index [ 1 ] ) ;
@ -213,64 +237,64 @@ public class TangentBinormalGenerator {
vertices [ index [ 1 ] ] . triangles . add ( triData ) ;
vertices [ index [ 2 ] ] . triangles . add ( triData ) ;
}
Vector3f vTemp = v [ 0 ] ;
v [ 0 ] = v [ 1 ] ;
v [ 1 ] = v [ 2 ] ;
v [ 2 ] = vTemp ;
Vector2f tTemp = t [ 0 ] ;
t [ 0 ] = t [ 1 ] ;
t [ 1 ] = t [ 2 ] ;
t [ 2 ] = tTemp ;
index [ 0 ] = index [ 1 ] ;
index [ 1 ] = index [ 2 ] ;
}
return vertices ;
}
private static VertexData [ ] processTriangleFan ( Mesh mesh ,
int [ ] index , Vector3f [ ] v , Vector2f [ ] t )
{
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
int [ ] index , Vector3f [ ] v , Vector2f [ ] t ) {
IndexBuffer indexBuffer = mesh . getIndexBuffer ( ) ;
FloatBuffer vertexBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Position ) . getData ( ) ;
FloatBuffer textureBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . TexCoord ) . getData ( ) ;
VertexData [ ] vertices = initVertexData ( vertexBuffer . capacity ( ) / 3 ) ;
index [ 0 ] = indexBuffer . get ( 0 ) ;
index [ 1 ] = indexBuffer . get ( 1 ) ;
populateFromBuffer ( v [ 0 ] , vertexBuffer , index [ 0 ] ) ;
populateFromBuffer ( v [ 1 ] , vertexBuffer , index [ 1 ] ) ;
populateFromBuffer ( t [ 0 ] , textureBuffer , index [ 0 ] ) ;
populateFromBuffer ( t [ 1 ] , textureBuffer , index [ 1 ] ) ;
for ( int i = 2 ; i < vertexBuffer . capacity ( ) / 3 ; i + + ) {
index [ 2 ] = indexBuffer . get ( i ) ;
populateFromBuffer ( v [ 2 ] , vertexBuffer , index [ 2 ] ) ;
populateFromBuffer ( t [ 2 ] , textureBuffer , index [ 2 ] ) ;
TriangleData triData = processTriangle ( index , v , t ) ;
if ( triData ! = null ) {
vertices [ index [ 0 ] ] . triangles . add ( triData ) ;
vertices [ index [ 1 ] ] . triangles . add ( triData ) ;
vertices [ index [ 2 ] ] . triangles . add ( triData ) ;
}
Vector3f vTemp = v [ 1 ] ;
v [ 1 ] = v [ 2 ] ;
v [ 2 ] = vTemp ;
Vector2f tTemp = t [ 1 ] ;
t [ 1 ] = t [ 2 ] ;
t [ 2 ] = tTemp ;
index [ 1 ] = index [ 2 ] ;
}
return vertices ;
}
@ -278,87 +302,86 @@ public class TangentBinormalGenerator {
private static boolean isDegenerateTriangle ( Vector3f a , Vector3f b , Vector3f c ) {
return ( a . subtract ( b ) . cross ( c . subtract ( b ) ) ) . lengthSquared ( ) = = 0 ;
}
public static TriangleData processTriangle ( int [ ] index ,
Vector3f [ ] v , Vector2f [ ] t )
{
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 ;
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 } ) ;
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 ] } ) ;
< 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 ( ) ;
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 ,
index [ 0 ] , index [ 1 ] , index [ 2 ]
) ;
tangent ,
binormal ,
normal ,
index [ 0 ] , index [ 1 ] , index [ 2 ] ) ;
}
public static void setToleranceAngle ( float angle ) {
if ( angle < 0 | | angle > 179 ) {
throw new IllegalArgumentException (
"The angle must be between 0 and 179 degrees." ) ;
"The angle must be between 0 and 179 degrees." ) ;
}
toleranceDot = FastMath . cos ( angle * FastMath . DEG_TO_RAD ) ;
toleranceDot = FastMath . cos ( angle * FastMath . DEG_TO_RAD ) ;
toleranceAngle = angle ;
}
private static void processTriangleData ( Mesh mesh , VertexData [ ] vertices ,
boolean approxTangent )
{
boolean approxTangent ) {
FloatBuffer normalBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Normal ) . getData ( ) ;
FloatBuffer tangents = BufferUtils . createFloatBuffer ( vertices . length * 4 ) ;
// FloatBuffer binormals = BufferUtils.createFloatBuffer(vertices.length * 3);
@ -366,7 +389,7 @@ public class TangentBinormalGenerator {
Vector3f binormal = new Vector3f ( ) ;
Vector3f normal = new Vector3f ( ) ;
Vector3f givenNormal = new Vector3f ( ) ;
Vector3f tangentUnit = new Vector3f ( ) ;
Vector3f binormalUnit = new Vector3f ( ) ;
@ -375,7 +398,7 @@ public class TangentBinormalGenerator {
populateFromBuffer ( givenNormal , normalBuffer , i ) ;
givenNormal . normalizeLocal ( ) ;
VertexData currentVertex = vertices [ i ] ;
List < TriangleData > triangles = currentVertex . triangles ;
@ -384,26 +407,26 @@ public class TangentBinormalGenerator {
tangent . normalizeLocal ( ) ;
binormal . set ( triangles . get ( 0 ) . binormal ) ;
binormal . normalizeLocal ( ) ;
for ( int j = 1 ; j < triangles . size ( ) ; j + + ) {
TriangleData triangleData = triangles . get ( j ) ;
tangentUnit . set ( triangleData . tangent ) ;
tangentUnit . normalizeLocal ( ) ;
if ( tangent . dot ( tangentUnit ) < toleranceDot ) {
log . log ( Level . WARNING ,
"Angle between tangents exceeds tolerance " +
"for vertex {0}." , i ) ;
"Angle between tangents exceeds tolerance "
+ "for vertex {0}." , i ) ;
break ;
}
if ( ! approxTangent ) {
binormalUnit . set ( triangleData . binormal ) ;
binormalUnit . normalizeLocal ( ) ;
if ( binormal . dot ( binormalUnit ) < toleranceDot ) {
log . log ( Level . WARNING ,
"Angle between binormals exceeds tolerance " +
"for vertex {0}." , i ) ;
"Angle between binormals exceeds tolerance "
+ "for vertex {0}." , i ) ;
break ;
}
}
@ -412,13 +435,13 @@ public class TangentBinormalGenerator {
// find average tangent
tangent . set ( 0 , 0 , 0 ) ;
binormal . set ( 0 , 0 , 0 ) ;
boolean flippedNormal = false ;
for ( int j = 0 ; j < triangles . size ( ) ; j + + ) {
TriangleData triangleData = triangles . get ( j ) ;
tangent . addLocal ( triangleData . tangent ) ;
binormal . addLocal ( triangleData . binormal ) ;
if ( givenNormal . dot ( triangleData . normal ) < 0 ) {
flippedNormal = true ;
}
@ -428,10 +451,10 @@ public class TangentBinormalGenerator {
// so binormal = normal.cross(tangent) will be flipped in the shader
// log.log(Level.WARNING,
// "Binormal is flipped for vertex {0}.", i);
wCoord = 1 ;
}
if ( tangent . length ( ) < ZERO_TOLERANCE ) {
log . log ( Level . WARNING ,
"Shared tangent is zero for vertex {0}." , i ) ;
@ -439,25 +462,22 @@ public class TangentBinormalGenerator {
if ( binormal . length ( ) > = ZERO_TOLERANCE ) {
binormal . cross ( givenNormal , tangent ) ;
tangent . normalizeLocal ( ) ;
}
// if all fails use the tangent from the first triangle
} // if all fails use the tangent from the first triangle
else {
tangent . set ( triangles . get ( 0 ) . tangent ) ;
}
}
else {
} else {
tangent . divideLocal ( triangles . size ( ) ) ;
}
tangentUnit . set ( tangent ) ;
tangentUnit . normalizeLocal ( ) ;
if ( Math . abs ( Math . abs ( tangentUnit . dot ( givenNormal ) ) - 1 )
< ZERO_TOLERANCE )
{
< ZERO_TOLERANCE ) {
log . log ( Level . WARNING ,
"Normal and tangent are parallel for vertex {0}." , i ) ;
}
if ( ! approxTangent ) {
if ( binormal . length ( ) < ZERO_TOLERANCE ) {
@ -467,33 +487,29 @@ public class TangentBinormalGenerator {
if ( tangent . length ( ) > = ZERO_TOLERANCE ) {
givenNormal . cross ( tangent , binormal ) ;
binormal . normalizeLocal ( ) ;
}
// if all fails use the binormal from the first triangle
} // if all fails use the binormal from the first triangle
else {
binormal . set ( triangles . get ( 0 ) . binormal ) ;
}
}
else {
} else {
binormal . divideLocal ( triangles . size ( ) ) ;
}
binormalUnit . set ( binormal ) ;
binormalUnit . normalizeLocal ( ) ;
if ( Math . abs ( Math . abs ( binormalUnit . dot ( givenNormal ) ) - 1 )
< ZERO_TOLERANCE )
{
< ZERO_TOLERANCE ) {
log . log ( Level . WARNING ,
"Normal and binormal are parallel for vertex {0}." , i ) ;
}
if ( Math . abs ( Math . abs ( binormalUnit . dot ( tangentUnit ) ) - 1 )
< ZERO_TOLERANCE )
{
< ZERO_TOLERANCE ) {
log . log ( Level . WARNING ,
"Tangent and binormal are parallel for vertex {0}." , i ) ;
}
}
if ( approxTangent ) {
// givenNormal.cross(tangent, binormal);
// binormal.cross(givenNormal, tangent);
@ -503,67 +519,67 @@ public class TangentBinormalGenerator {
tangents . put ( ( i * 4 ) + 1 , tangent . y ) ;
tangents . put ( ( i * 4 ) + 2 , tangent . z ) ;
tangents . put ( ( i * 4 ) + 3 , wCoord ) ;
}
else {
} else {
tangents . put ( ( i * 4 ) , tangent . x ) ;
tangents . put ( ( i * 4 ) + 1 , tangent . y ) ;
tangents . put ( ( i * 4 ) + 2 , tangent . z ) ;
tangents . put ( ( i * 4 ) + 3 , wCoord ) ;
// setInBuffer(binormal, binormals, i);
}
}
mesh . setBuffer ( Type . Tangent , 4 , tangents ) ;
mesh . setBuffer ( Type . Tangent , 4 , tangents ) ;
// if (!approxTangent) mesh.setBuffer(Type.Binormal, 3, binormals);
}
public static Mesh genTbnLines ( Mesh mesh , float scale ) {
if ( mesh . getBuffer ( Type . Tangent ) = = null )
if ( mesh . getBuffer ( Type . Tangent ) = = null ) {
return genNormalLines ( mesh , scale ) ;
else
} else {
return genTangentLines ( mesh , scale ) ;
}
}
public static Mesh genNormalLines ( Mesh mesh , float scale ) {
FloatBuffer vertexBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Position ) . getData ( ) ;
FloatBuffer normalBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Normal ) . getData ( ) ;
ColorRGBA originColor = ColorRGBA . White ;
ColorRGBA normalColor = ColorRGBA . Blue ;
Mesh lineMesh = new Mesh ( ) ;
lineMesh . setMode ( Mesh . Mode . Lines ) ;
Vector3f origin = new Vector3f ( ) ;
Vector3f point = new Vector3f ( ) ;
FloatBuffer lineVertex = BufferUtils . createFloatBuffer ( vertexBuffer . capacity ( ) * 2 ) ;
FloatBuffer lineColor = BufferUtils . createFloatBuffer ( vertexBuffer . capacity ( ) / 3 * 4 * 2 ) ;
for ( int i = 0 ; i < vertexBuffer . capacity ( ) / 3 ; i + + ) {
populateFromBuffer ( origin , vertexBuffer , i ) ;
populateFromBuffer ( point , normalBuffer , i ) ;
int index = i * 2 ;
setInBuffer ( origin , lineVertex , index ) ;
setInBuffer ( originColor , lineColor , index ) ;
point . multLocal ( scale ) ;
point . addLocal ( origin ) ;
setInBuffer ( point , lineVertex , index + 1 ) ;
setInBuffer ( normalColor , lineColor , index + 1 ) ;
}
lineMesh . setBuffer ( Type . Position , 3 , lineVertex ) ;
lineMesh . setBuffer ( Type . Color , 4 , lineColor ) ;
lineMesh . setStatic ( ) ;
lineMesh . setInterleaved ( ) ;
return lineMesh ;
}
private static Mesh genTangentLines ( Mesh mesh , float scale ) {
FloatBuffer vertexBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Position ) . getData ( ) ;
FloatBuffer normalBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Normal ) . getData ( ) ;
@ -573,15 +589,15 @@ public class TangentBinormalGenerator {
if ( mesh . getBuffer ( Type . Binormal ) ! = null ) {
binormalBuffer = ( FloatBuffer ) mesh . getBuffer ( Type . Binormal ) . getData ( ) ;
}
ColorRGBA originColor = ColorRGBA . White ;
ColorRGBA tangentColor = ColorRGBA . Red ;
ColorRGBA binormalColor = ColorRGBA . Green ;
ColorRGBA normalColor = ColorRGBA . Blue ;
Mesh lineMesh = new Mesh ( ) ;
lineMesh . setMode ( Mesh . Mode . Lines ) ;
Vector3f origin = new Vector3f ( ) ;
Vector3f point = new Vector3f ( ) ;
Vector3f tangent = new Vector3f ( ) ;
@ -598,17 +614,17 @@ public class TangentBinormalGenerator {
populateFromBuffer ( origin , vertexBuffer , i ) ;
populateFromBuffer ( normal , normalBuffer , i ) ;
if ( hasParity ) {
if ( hasParity ) {
tangent . x = tangentBuffer . get ( i * 4 ) ;
tangent . y = tangentBuffer . get ( i * 4 + 1 ) ;
tangent . z = tangentBuffer . get ( i * 4 + 2 ) ;
tangentW = tangentBuffer . get ( i * 4 + 3 ) ;
} else {
tangentW = tangentBuffer . get ( i * 4 + 3 ) ;
} else {
populateFromBuffer ( tangent , tangentBuffer , i ) ;
}
int index = i * 4 ;
int id = i * 6 ;
lineIndex . put ( id , index ) ;
lineIndex . put ( id + 1 , index + 1 ) ;
@ -616,7 +632,7 @@ public class TangentBinormalGenerator {
lineIndex . put ( id + 3 , index + 2 ) ;
lineIndex . put ( id + 4 , index ) ;
lineIndex . put ( id + 5 , index + 3 ) ;
setInBuffer ( origin , lineVertex , index ) ;
setInBuffer ( originColor , lineColor , index ) ;
@ -627,7 +643,7 @@ public class TangentBinormalGenerator {
setInBuffer ( tangentColor , lineColor , index + 1 ) ;
// wvBinormal = cross(wvNormal, wvTangent) * -inTangent.w
if ( binormalBuffer = = null ) {
normal . cross ( tangent , point ) ;
point . multLocal ( - tangentW ) ;
@ -640,18 +656,18 @@ public class TangentBinormalGenerator {
point . addLocal ( origin ) ;
setInBuffer ( point , lineVertex , index + 2 ) ;
setInBuffer ( binormalColor , lineColor , index + 2 ) ;
point . set ( normal ) ;
point . multLocal ( scale ) ;
point . addLocal ( origin ) ;
setInBuffer ( point , lineVertex , index + 3 ) ;
setInBuffer ( normalColor , lineColor , index + 3 ) ;
}
lineMesh . setBuffer ( Type . Index , 1 , lineIndex ) ;
lineMesh . setBuffer ( Type . Position , 3 , lineVertex ) ;
lineMesh . setBuffer ( Type . Color , 4 , lineColor ) ;
lineMesh . setStatic ( ) ;
lineMesh . setInterleaved ( ) ;
return lineMesh ;