提交 a2ca7ab9 编写于 作者: A alteredq

Added computeTangents to BufferGeometry.

上级 01c31ae9
因为 它太大了无法显示 source diff 。你可以改为 查看blob
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -19,6 +19,8 @@ THREE.BufferGeometry = function () {
this.boundingBox = null;
this.boundingSphere = null;
this.hasTangents = false;
// for compatibility
this.morphTargets = [];
......@@ -162,15 +164,15 @@ THREE.BufferGeometry.prototype = {
var i, il;
var j, jl;
var nVertices = this.attributes[ "position" ].array.length;
var nVertexElements = this.attributes[ "position" ].array.length;
if ( this.attributes[ "normal" ] === undefined ) {
this.attributes[ "normal" ] = {
itemSize: 3,
array: new Float32Array( nVertices ),
numItems: nVertices * 3
array: new Float32Array( nVertexElements ),
numItems: nVertexElements
};
......@@ -268,6 +270,206 @@ THREE.BufferGeometry.prototype = {
}
},
computeTangents: function () {
// based on http://www.terathon.com/code/tangent.html
// (per vertex tangents)
if ( this.attributes[ "index" ] === undefined ||
this.attributes[ "position" ] === undefined ||
this.attributes[ "normal" ] === undefined ||
this.attributes[ "uv" ] === undefined ) {
console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
return;
}
var indices = this.attributes[ "index" ].array;
var positions = this.attributes[ "position" ].array;
var normals = this.attributes[ "normal" ].array;
var uvs = this.attributes[ "uv" ].array;
var nVertices = positions.length / 3;
if ( this.attributes[ "tangent" ] === undefined ) {
var nTangentElements = 4 * nVertices;
this.attributes[ "tangent" ] = {
itemSize: 4,
array: new Float32Array( nTangentElements ),
numItems: nTangentElements
};
}
var tangents = this.attributes[ "tangent" ].array;
var tan1 = [], tan2 = [];
for ( var k = 0; k < nVertices; k ++ ) {
tan1[ k ] = new THREE.Vector3();
tan2[ k ] = new THREE.Vector3();
}
var xA, yA, zA,
xB, yB, zB,
xC, yC, zC,
uA, vA,
uB, vB,
uC, vC,
x1, x2, y1, y2, z1, z2,
s1, s2, t1, t2, r;
var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
function handleTriangle( a, b, c ) {
xA = positions[ a * 3 ];
yA = positions[ a * 3 + 1 ];
zA = positions[ a * 3 + 2 ];
xB = positions[ b * 3 ];
yB = positions[ b * 3 + 1 ];
zB = positions[ b * 3 + 2 ];
xC = positions[ c * 3 ];
yC = positions[ c * 3 + 1 ];
zC = positions[ c * 3 + 2 ];
uA = uvs[ a * 2 ];
vA = uvs[ a * 2 + 1 ];
uB = uvs[ b * 2 ];
vB = uvs[ b * 2 + 1 ];
uC = uvs[ c * 2 ];
vC = uvs[ c * 2 + 1 ];
x1 = xB - xA;
x2 = xC - xA;
y1 = yB - yA;
y2 = yC - yA;
z1 = zB - zA;
z2 = zC - zA;
s1 = uB - uA;
s2 = uC - uA;
t1 = vB - vA;
t2 = vC - vA;
r = 1.0 / ( s1 * t2 - s2 * t1 );
sdir.set( ( t2 * x1 - t1 * x2 ) * r,
( t2 * y1 - t1 * y2 ) * r,
( t2 * z1 - t1 * z2 ) * r );
tdir.set( ( s1 * x2 - s2 * x1 ) * r,
( s1 * y2 - s2 * y1 ) * r,
( s1 * z2 - s2 * z1 ) * r );
tan1[ a ].addSelf( sdir );
tan1[ b ].addSelf( sdir );
tan1[ c ].addSelf( sdir );
tan2[ a ].addSelf( tdir );
tan2[ b ].addSelf( tdir );
tan2[ c ].addSelf( tdir );
}
var i, il;
var j, jl;
var iA, iB, iC;
var offsets = this.offsets;
for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
var start = offsets[ j ].start;
var count = offsets[ j ].count;
var index = offsets[ j ].index;
for ( i = start, il = start + count; i < il; i += 3 ) {
iA = index + indices[ i ];
iB = index + indices[ i + 1 ];
iC = index + indices[ i + 2 ];
handleTriangle( iA, iB, iC );
}
}
var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
var n = new THREE.Vector3(), n2 = new THREE.Vector3();
var w, t, test;
var nx, ny, nz;
function handleVertex( v ) {
n.x = normals[ v * 3 ];
n.y = normals[ v * 3 + 1 ];
n.z = normals[ v * 3 + 2 ];
n2.copy( n );
t = tan1[ v ];
// Gram-Schmidt orthogonalize
tmp.copy( t );
tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
// Calculate handedness
tmp2.cross( n2, t );
test = tmp2.dot( tan2[ v ] );
w = ( test < 0.0 ) ? -1.0 : 1.0;
tangents[ v * 4 ] = tmp.x;
tangents[ v * 4 + 1 ] = tmp.y;
tangents[ v * 4 + 2 ] = tmp.z;
tangents[ v * 4 + 3 ] = w;
}
for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
var start = offsets[ j ].start;
var count = offsets[ j ].count;
var index = offsets[ j ].index;
for ( i = start, il = start + count; i < il; i += 3 ) {
iA = index + indices[ i ];
iB = index + indices[ i + 1 ];
iC = index + indices[ i + 2 ];
handleVertex( iA );
handleVertex( iB );
handleVertex( iC );
}
}
this.hasTangents = true;
this.tangentsNeedUpdate = true;
}
};
......
......@@ -2916,6 +2916,7 @@ THREE.WebGLRenderer = function ( parameters ) {
var normal = attributes[ "normal" ];
var uv = attributes[ "uv" ];
var color = attributes[ "color" ];
var tangent = attributes[ "tangent" ];
if ( geometry.elementsNeedUpdate && index !== undefined ) {
......@@ -2952,6 +2953,12 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
_gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );
}
if ( dispose ) {
......@@ -3154,6 +3161,18 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
_gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
}
// tangents
var tangent = geometry.attributes[ "tangent" ];
if ( attributes.tangent >= 0 && tangent ) {
var tangentSize = tangent.itemSize;
_gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
_gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
}
......@@ -4260,7 +4279,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
geometry.colorsNeedUpdate ) {
geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
......@@ -4271,6 +4290,7 @@ THREE.WebGLRenderer = function ( parameters ) {
geometry.uvsNeedUpdate = false;
geometry.normalsNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.tangentsNeedUpdate = false;
} else {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册