Răsfoiți Sursa

BufferGeometryUtils: Fixed computeMorphedBufferGeometry()

Mr.doob 4 ani în urmă
părinte
comite
f21ecafb48

+ 312 - 1
examples/js/utils/BufferGeometryUtils.js

@@ -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
+
+		};
+
 	}
 
 };

+ 12 - 11
examples/jsm/utils/BufferGeometryUtils.js

@@ -1,6 +1,7 @@
 import {
 	BufferAttribute,
 	BufferGeometry,
+	Float32BufferAttribute,
 	InterleavedBuffer,
 	InterleavedBufferAttribute,
 	TriangleFanDrawMode,
@@ -820,17 +821,17 @@ var BufferGeometryUtils = {
 
 		}
 
-		var _vA = new THREE.Vector3();
-		var _vB = new THREE.Vector3();
-		var _vC = new THREE.Vector3();
+		var _vA = new Vector3();
+		var _vB = new Vector3();
+		var _vC = new Vector3();
 
-		var _tempA = new THREE.Vector3();
-		var _tempB = new THREE.Vector3();
-		var _tempC = new THREE.Vector3();
+		var _tempA = new Vector3();
+		var _tempB = new Vector3();
+		var _tempC = new Vector3();
 
-		var _morphA = new THREE.Vector3();
-		var _morphB = new THREE.Vector3();
-		var _morphC = new THREE.Vector3();
+		var _morphA = new Vector3();
+		var _morphB = new Vector3();
+		var _morphC = new Vector3();
 
 		function _calculateMorphedAttributeData(
 			object,
@@ -1089,8 +1090,8 @@ var BufferGeometryUtils = {
 
 		}
 
-		var morphedPositionAttribute = new THREE.Float32BufferAttribute( modifiedPosition, 3 );
-		var morphedNormalAttribute = new THREE.Float32BufferAttribute( modifiedNormal, 3 );
+		var morphedPositionAttribute = new Float32BufferAttribute( modifiedPosition, 3 );
+		var morphedNormalAttribute = new Float32BufferAttribute( modifiedNormal, 3 );
 
 		return {