|
@@ -744,7 +744,6 @@ THREE.BufferGeometryUtils = {
|
|
|
newIndices.push( index.getX( i + 1 ) );
|
|
|
newIndices.push( index.getX( i + 2 ) );
|
|
|
|
|
|
-
|
|
|
} else {
|
|
|
|
|
|
newIndices.push( index.getX( i + 2 ) );
|
|
@@ -778,6 +777,318 @@ THREE.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
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
}
|
|
|
|
|
|
};
|