|
@@ -5,176 +5,15 @@ import {
|
|
|
InterleavedBufferAttribute,
|
|
|
TriangleFanDrawMode,
|
|
|
TriangleStripDrawMode,
|
|
|
- TrianglesDrawMode,
|
|
|
- Vector2,
|
|
|
- Vector3
|
|
|
+ TrianglesDrawMode
|
|
|
} from '../../../build/three.module.js';
|
|
|
|
|
|
var BufferGeometryUtils = {
|
|
|
|
|
|
computeTangents: function ( geometry ) {
|
|
|
|
|
|
- var index = geometry.index;
|
|
|
- var attributes = geometry.attributes;
|
|
|
-
|
|
|
- // based on http://www.terathon.com/code/tangent.html
|
|
|
- // (per vertex tangents)
|
|
|
-
|
|
|
- if ( index === null ||
|
|
|
- attributes.position === undefined ||
|
|
|
- attributes.normal === undefined ||
|
|
|
- attributes.uv === undefined ) {
|
|
|
-
|
|
|
- console.error( 'THREE.BufferGeometryUtils: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' );
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var indices = index.array;
|
|
|
- var positions = attributes.position.array;
|
|
|
- var normals = attributes.normal.array;
|
|
|
- var uvs = attributes.uv.array;
|
|
|
-
|
|
|
- var nVertices = positions.length / 3;
|
|
|
-
|
|
|
- if ( attributes.tangent === undefined ) {
|
|
|
-
|
|
|
- geometry.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * nVertices ), 4 ) );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var tangents = attributes.tangent.array;
|
|
|
-
|
|
|
- var tan1 = [], tan2 = [];
|
|
|
-
|
|
|
- for ( var i = 0; i < nVertices; i ++ ) {
|
|
|
-
|
|
|
- tan1[ i ] = new Vector3();
|
|
|
- tan2[ i ] = new Vector3();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var vA = new Vector3(),
|
|
|
- vB = new Vector3(),
|
|
|
- vC = new Vector3(),
|
|
|
-
|
|
|
- uvA = new Vector2(),
|
|
|
- uvB = new Vector2(),
|
|
|
- uvC = new Vector2(),
|
|
|
-
|
|
|
- sdir = new Vector3(),
|
|
|
- tdir = new Vector3();
|
|
|
-
|
|
|
- function handleTriangle( a, b, c ) {
|
|
|
-
|
|
|
- vA.fromArray( positions, a * 3 );
|
|
|
- vB.fromArray( positions, b * 3 );
|
|
|
- vC.fromArray( positions, c * 3 );
|
|
|
-
|
|
|
- uvA.fromArray( uvs, a * 2 );
|
|
|
- uvB.fromArray( uvs, b * 2 );
|
|
|
- uvC.fromArray( uvs, c * 2 );
|
|
|
-
|
|
|
- vB.sub( vA );
|
|
|
- vC.sub( vA );
|
|
|
-
|
|
|
- uvB.sub( uvA );
|
|
|
- uvC.sub( uvA );
|
|
|
-
|
|
|
- var r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y );
|
|
|
-
|
|
|
- // silently ignore degenerate uv triangles having coincident or colinear vertices
|
|
|
-
|
|
|
- if ( ! isFinite( r ) ) return;
|
|
|
-
|
|
|
- sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r );
|
|
|
- tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r );
|
|
|
-
|
|
|
- tan1[ a ].add( sdir );
|
|
|
- tan1[ b ].add( sdir );
|
|
|
- tan1[ c ].add( sdir );
|
|
|
-
|
|
|
- tan2[ a ].add( tdir );
|
|
|
- tan2[ b ].add( tdir );
|
|
|
- tan2[ c ].add( tdir );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var groups = geometry.groups;
|
|
|
-
|
|
|
- if ( groups.length === 0 ) {
|
|
|
-
|
|
|
- groups = [ {
|
|
|
- start: 0,
|
|
|
- count: indices.length
|
|
|
- } ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- for ( var i = 0, il = groups.length; i < il; ++ i ) {
|
|
|
-
|
|
|
- var group = groups[ i ];
|
|
|
-
|
|
|
- var start = group.start;
|
|
|
- var count = group.count;
|
|
|
-
|
|
|
- for ( var j = start, jl = start + count; j < jl; j += 3 ) {
|
|
|
-
|
|
|
- handleTriangle(
|
|
|
- indices[ j + 0 ],
|
|
|
- indices[ j + 1 ],
|
|
|
- indices[ j + 2 ]
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var tmp = new Vector3(), tmp2 = new Vector3();
|
|
|
- var n = new Vector3(), n2 = new Vector3();
|
|
|
- var w, t, test;
|
|
|
-
|
|
|
- function handleVertex( v ) {
|
|
|
-
|
|
|
- n.fromArray( normals, v * 3 );
|
|
|
- n2.copy( n );
|
|
|
-
|
|
|
- t = tan1[ v ];
|
|
|
-
|
|
|
- // Gram-Schmidt orthogonalize
|
|
|
-
|
|
|
- tmp.copy( t );
|
|
|
- tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize();
|
|
|
-
|
|
|
- // Calculate handedness
|
|
|
-
|
|
|
- tmp2.crossVectors( 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 ( var i = 0, il = groups.length; i < il; ++ i ) {
|
|
|
-
|
|
|
- var group = groups[ i ];
|
|
|
-
|
|
|
- var start = group.start;
|
|
|
- var count = group.count;
|
|
|
-
|
|
|
- for ( var j = start, jl = start + count; j < jl; j += 3 ) {
|
|
|
-
|
|
|
- handleVertex( indices[ j + 0 ] );
|
|
|
- handleVertex( indices[ j + 1 ] );
|
|
|
- handleVertex( indices[ j + 2 ] );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
+ geometry.computeTangents();
|
|
|
+ console.warn( 'THREE.BufferGeometryUtils: .computeTangents() has been removed. Use BufferGeometry.computeTangents() instead.' );
|
|
|
|
|
|
},
|
|
|
|
|
@@ -756,6 +595,7 @@ var BufferGeometryUtils = {
|
|
|
newIndices.push( index.getX( i + 1 ) );
|
|
|
newIndices.push( index.getX( i + 2 ) );
|
|
|
|
|
|
+
|
|
|
} else {
|
|
|
|
|
|
newIndices.push( index.getX( i + 2 ) );
|
|
@@ -789,318 +629,6 @@ var BufferGeometryUtils = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Calculates the morphed attributes of a morphed/skinned BufferGeometry.
|
|
|
- * Helpful for Raytracing or Decals.
|
|
|
- * @param {Object3D} object
|
|
|
- * @return {Object} An Object with original position/normal attributes and morphed ones.
|
|
|
- */
|
|
|
- computeMorphedBufferGeometry: function ( object ) {
|
|
|
-
|
|
|
- if ( ! object ) {
|
|
|
-
|
|
|
- console.error( 'Please provide an object' );
|
|
|
- return null;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( ! object.geometry ) {
|
|
|
-
|
|
|
- console.error( 'Please provide an object with a geometry' );
|
|
|
- return null;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( ! object.geometry.isBufferGeometry ) {
|
|
|
-
|
|
|
- console.error( 'Geometry is not a BufferGeometry' );
|
|
|
- return null;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var _vA = new THREE.Vector3();
|
|
|
- var _vB = new THREE.Vector3();
|
|
|
- var _vC = new THREE.Vector3();
|
|
|
-
|
|
|
- var _tempA = new THREE.Vector3();
|
|
|
- var _tempB = new THREE.Vector3();
|
|
|
- var _tempC = new THREE.Vector3();
|
|
|
-
|
|
|
- var _morphA = new THREE.Vector3();
|
|
|
- var _morphB = new THREE.Vector3();
|
|
|
- var _morphC = new THREE.Vector3();
|
|
|
-
|
|
|
- function _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- material,
|
|
|
- attribute,
|
|
|
- morphAttribute,
|
|
|
- morphTargetsRelative,
|
|
|
- a,
|
|
|
- b,
|
|
|
- c,
|
|
|
- modifiedAttributeArray
|
|
|
- ) {
|
|
|
-
|
|
|
- _vA.fromBufferAttribute( attribute, a );
|
|
|
- _vB.fromBufferAttribute( attribute, b );
|
|
|
- _vC.fromBufferAttribute( attribute, c );
|
|
|
-
|
|
|
- var morphInfluences = object.morphTargetInfluences;
|
|
|
-
|
|
|
- if ( material.morphTargets && morphAttribute && morphInfluences ) {
|
|
|
-
|
|
|
- _morphA.set( 0, 0, 0 );
|
|
|
- _morphB.set( 0, 0, 0 );
|
|
|
- _morphC.set( 0, 0, 0 );
|
|
|
-
|
|
|
- for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var influence = morphInfluences[ i ];
|
|
|
- var morphAttribute = morphAttribute[ i ];
|
|
|
-
|
|
|
- if ( influence === 0 ) continue;
|
|
|
-
|
|
|
- _tempA.fromBufferAttribute( morphAttribute, a );
|
|
|
- _tempB.fromBufferAttribute( morphAttribute, b );
|
|
|
- _tempC.fromBufferAttribute( morphAttribute, c );
|
|
|
-
|
|
|
- if ( morphTargetsRelative ) {
|
|
|
-
|
|
|
- _morphA.addScaledVector( _tempA, influence );
|
|
|
- _morphB.addScaledVector( _tempB, influence );
|
|
|
- _morphC.addScaledVector( _tempC, influence );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _morphA.addScaledVector( _tempA.sub( _vA ), influence );
|
|
|
- _morphB.addScaledVector( _tempB.sub( _vB ), influence );
|
|
|
- _morphC.addScaledVector( _tempC.sub( _vC ), influence );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _vA.add( _morphA );
|
|
|
- _vB.add( _morphB );
|
|
|
- _vC.add( _morphC );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( object.isSkinnedMesh ) {
|
|
|
-
|
|
|
- object.boneTransform( a, _vA );
|
|
|
- object.boneTransform( b, _vB );
|
|
|
- object.boneTransform( c, _vC );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- modifiedAttributeArray[ a * 3 + 0 ] = _vA.x;
|
|
|
- modifiedAttributeArray[ a * 3 + 1 ] = _vA.y;
|
|
|
- modifiedAttributeArray[ a * 3 + 2 ] = _vA.z;
|
|
|
- modifiedAttributeArray[ b * 3 + 0 ] = _vB.x;
|
|
|
- modifiedAttributeArray[ b * 3 + 1 ] = _vB.y;
|
|
|
- modifiedAttributeArray[ b * 3 + 2 ] = _vB.z;
|
|
|
- modifiedAttributeArray[ c * 3 + 0 ] = _vC.x;
|
|
|
- modifiedAttributeArray[ c * 3 + 1 ] = _vC.y;
|
|
|
- modifiedAttributeArray[ c * 3 + 2 ] = _vC.z;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var geometry = object.geometry;
|
|
|
- var material = object.material;
|
|
|
-
|
|
|
- var a, b, c;
|
|
|
- var index = geometry.index;
|
|
|
- var positionAttribute = geometry.attributes.position;
|
|
|
- var morphPosition = geometry.morphAttributes.position;
|
|
|
- var morphTargetsRelative = geometry.morphTargetsRelative;
|
|
|
- var normalAttribute = geometry.attributes.normal;
|
|
|
- var morphNormal = geometry.morphAttributes.position;
|
|
|
-
|
|
|
- var groups = geometry.groups;
|
|
|
- var drawRange = geometry.drawRange;
|
|
|
- var i, j, il, jl;
|
|
|
- var group, groupMaterial;
|
|
|
- var start, end;
|
|
|
-
|
|
|
- var modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize );
|
|
|
- var modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize );
|
|
|
-
|
|
|
- if ( index !== null ) {
|
|
|
-
|
|
|
- // indexed buffer geometry
|
|
|
-
|
|
|
- if ( Array.isArray( material ) ) {
|
|
|
-
|
|
|
- for ( i = 0, il = groups.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- group = groups[ i ];
|
|
|
- groupMaterial = material[ group.materialIndex ];
|
|
|
-
|
|
|
- start = Math.max( group.start, drawRange.start );
|
|
|
- end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
|
|
|
-
|
|
|
- for ( j = start, jl = end; j < jl; j += 3 ) {
|
|
|
-
|
|
|
- a = index.getX( j );
|
|
|
- b = index.getX( j + 1 );
|
|
|
- c = index.getX( j + 2 );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- groupMaterial,
|
|
|
- positionAttribute,
|
|
|
- morphPosition,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedPosition
|
|
|
- );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- groupMaterial,
|
|
|
- normalAttribute,
|
|
|
- morphNormal,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedNormal
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- start = Math.max( 0, drawRange.start );
|
|
|
- end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
|
|
|
-
|
|
|
- for ( i = start, il = end; i < il; i += 3 ) {
|
|
|
-
|
|
|
- a = index.getX( i );
|
|
|
- b = index.getX( i + 1 );
|
|
|
- c = index.getX( i + 2 );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- material,
|
|
|
- positionAttribute,
|
|
|
- morphPosition,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedPosition
|
|
|
- );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- material,
|
|
|
- normalAttribute,
|
|
|
- morphNormal,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedNormal
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else if ( positionAttribute !== undefined ) {
|
|
|
-
|
|
|
- // non-indexed buffer geometry
|
|
|
-
|
|
|
- if ( Array.isArray( material ) ) {
|
|
|
-
|
|
|
- for ( i = 0, il = groups.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- group = groups[ i ];
|
|
|
- groupMaterial = material[ group.materialIndex ];
|
|
|
-
|
|
|
- start = Math.max( group.start, drawRange.start );
|
|
|
- end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
|
|
|
-
|
|
|
- for ( j = start, jl = end; j < jl; j += 3 ) {
|
|
|
-
|
|
|
- a = j;
|
|
|
- b = j + 1;
|
|
|
- c = j + 2;
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- groupMaterial,
|
|
|
- positionAttribute,
|
|
|
- morphPosition,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedPosition
|
|
|
- );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- groupMaterial,
|
|
|
- normalAttribute,
|
|
|
- morphNormal,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedNormal
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- start = Math.max( 0, drawRange.start );
|
|
|
- end = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );
|
|
|
-
|
|
|
- for ( i = start, il = end; i < il; i += 3 ) {
|
|
|
-
|
|
|
- a = i;
|
|
|
- b = i + 1;
|
|
|
- c = i + 2;
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- material,
|
|
|
- positionAttribute,
|
|
|
- morphPosition,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedPosition
|
|
|
- );
|
|
|
-
|
|
|
- _calculateMorphedAttributeData(
|
|
|
- object,
|
|
|
- material,
|
|
|
- normalAttribute,
|
|
|
- morphNormal,
|
|
|
- morphTargetsRelative,
|
|
|
- a, b, c,
|
|
|
- modifiedNormal
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var morphedPositionAttribute = new THREE.Float32BufferAttribute( modifiedPosition, 3 );
|
|
|
- var morphedNormalAttribute = new THREE.Float32BufferAttribute( modifiedNormal, 3 );
|
|
|
-
|
|
|
- return {
|
|
|
-
|
|
|
- positionAttribute: positionAttribute,
|
|
|
- normalAttribute: normalAttribute,
|
|
|
- morphedPositionAttribute: morphedPositionAttribute,
|
|
|
- morphedNormalAttribute: morphedNormalAttribute
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
}
|
|
|
|
|
|
};
|