Skip to content

Commit

Permalink
BufferGeometryUtils: Add MikkTSpace version of .computeTangents() (mr…
Browse files Browse the repository at this point in the history
…doob#23716)

* BufferGeometryUtils: Add MikkTSpace version of .computeTangents()

* Lint

* BufferGeometryUtils: Fix .denormalize() usage.
  • Loading branch information
donmccurdy authored and abernier committed Sep 16, 2022
1 parent 8db2f10 commit 9b96f7c
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 8 deletions.
121 changes: 121 additions & 0 deletions examples/jsm/libs/mikktspace.module.js

Large diffs are not rendered by default.

82 changes: 74 additions & 8 deletions examples/jsm/utils/BufferGeometryUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,91 @@ import {
Float32BufferAttribute,
InterleavedBuffer,
InterleavedBufferAttribute,
MathUtils,
TriangleFanDrawMode,
TriangleStripDrawMode,
TrianglesDrawMode,
Vector3
Vector3,
} from 'three';
import { generateTangents } from '../libs/mikktspace.module.js';


function computeTangents( geometry ) {
function computeTangents( geometry, negateSign = true ) {

geometry.computeTangents();
console.warn( 'THREE.BufferGeometryUtils: .computeTangents() has been removed. Use BufferGeometry.computeTangents() instead.' );
function getAttributeArray( attribute ) {

if ( attribute.normalized || attribute.isInterleavedBufferAttribute ) {

const srcArray = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
const dstArray = new Float32Array( attribute.getCount() * attribute.itemSize );

for ( let i = 0, j = 0; i < attribute.getCount(); i ++ ) {

dstArray[ j ++ ] = MathUtils.denormalize( attribute.getX( i ), srcArray );
dstArray[ j ++ ] = MathUtils.denormalize( attribute.getY( i ), srcArray );

if ( attribute.itemSize > 2 ) {

dstArray[ j ++ ] = MathUtils.denormalize( attribute.getZ( i ), srcArray );

}

}

return dstArray;

}

if ( attribute.array instanceof Float32Array ) {

return attribute.array;

}

return new Float32Array( attribute.array );

}

// MikkTSpace algorithm requires non-indexed input.

const _geometry = geometry.index ? geometry.toNonIndexed() : geometry;

// Compute vertex tangents.

const tangents = generateTangents(

getAttributeArray( _geometry.attributes.position ),
getAttributeArray( _geometry.attributes.normal ),
getAttributeArray( _geometry.attributes.uv )

);

// Texture coordinate convention of glTF differs from the apparent
// default of the MikkTSpace library; .w component must be flipped.

if ( negateSign ) {

for ( let i = 3; i < tangents.length; i += 4 ) {

tangents[ i ] *= -1;

}

}

//

_geometry.setAttribute( 'tangent', new BufferAttribute( tangents, 4 ) );

return geometry.copy( _geometry );

}

/**
* @param {Array<BufferGeometry>} geometries
* @param {Boolean} useGroups
* @return {BufferGeometry}
*/
* @param {Array<BufferGeometry>} geometries
* @param {Boolean} useGroups
* @return {BufferGeometry}
*/
function mergeBufferGeometries( geometries, useGroups = false ) {

const isIndexed = geometries[ 0 ].index !== null;
Expand Down
65 changes: 65 additions & 0 deletions src/math/MathUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,69 @@ function setQuaternionFromProperEuler( q, a, b, c, order ) {

}

function denormalize( value, array ) {

switch ( array.constructor ) {

case Float32Array:

return value;

case Uint16Array:

return value / 65535.0;

case Uint8Array:

return value / 255.0;

case Int16Array:

return Math.max( value / 32767.0, - 1.0 );

case Int8Array:

return Math.max( value / 127.0, - 1.0 );

default:

throw new Error( 'Invalid component type.' );

}

}

function normalize( value, array ) {

switch ( array.constructor ) {

case Float32Array:

return value;

case Uint16Array:

return Math.round( value * 65535.0 );

case Uint8Array:

return Math.round( value * 255.0 );

case Int16Array:

return Math.round( value * 32767.0 );

case Int8Array:

return Math.round( value * 127.0 );

default:

throw new Error( 'Invalid component type.' );

}

}



Expand All @@ -259,4 +322,6 @@ export {
ceilPowerOfTwo,
floorPowerOfTwo,
setQuaternionFromProperEuler,
normalize,
denormalize,
};

0 comments on commit 9b96f7c

Please sign in to comment.