docs: function addMorphTargets ( mesh, meshDef, primitiveDef, dependencies ) {
  
  			var geometry = mesh.geometry;
  			var material = mesh.material;
  
  			var targets = primitiveDef.targets;
  			var morphAttributes = geometry.morphAttributes;
  
  			morphAttributes.position = [];
  			morphAttributes.normal = [];
  
  			material.morphTargets = true;
  
  			for ( var i = 0, il = targets.length; i < il; i ++ ) {
  
  				var target = targets[ i ];
  				var attributeName = 'morphTarget' + i;
  
  				var positionAttribute, normalAttribute;
  
  				if ( target.POSITION !== undefined ) {
  
  					// Three.js morph formula is
  					//   position
  					//     + weight0 * ( morphTarget0 - position )
  					//     + weight1 * ( morphTarget1 - position )
  					//     ...
  					// while the glTF one is
  					//   position
  					//     + weight0 * morphTarget0
  					//     + weight1 * morphTarget1
  					//     ...
  					// then adding position to morphTarget.
  					// So morphTarget value will depend on mesh's position, then cloning attribute
  					// for the case if attribute is shared among two or more meshes.
  
  					positionAttribute = dependencies.accessors[ target.POSITION ].clone();
  					var position = geometry.attributes.position;
  
  					for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) {
  
  						positionAttribute.setXYZ(
  							j,
  							positionAttribute.getX( j ) + position.getX( j ),
  							positionAttribute.getY( j ) + position.getY( j ),
  							positionAttribute.getZ( j ) + position.getZ( j )
  						);
  
  					}
  
  				} else {
  
  					// Copying the original position not to affect the final position.
  					// See the formula above.
  					positionAttribute = geometry.attributes.position.clone();
  
  				}
  
  				if ( target.NORMAL !== undefined ) {
  
  					material.morphNormals = true;
  
  					// see target.POSITION's comment
  
  					normalAttribute = dependencies.accessors[ target.NORMAL ].clone();
  					var normal = geometry.attributes.normal;
  
  					for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) {
  
  						normalAttribute.setXYZ(
  							j,
  							normalAttribute.getX( j ) + normal.getX( j ),
  							normalAttribute.getY( j ) + normal.getY( j ),
  							normalAttribute.getZ( j ) + normal.getZ( j )
  						);
  
  					}
  
  				} else {
  
  					normalAttribute = geometry.attributes.normal.clone();
  
  				}
  
  				if ( target.TANGENT !== undefined ) {
  
  					// TODO: implement
  
  				}
  
  				positionAttribute.name = attributeName;
  				normalAttribute.name = attributeName;
  
  				morphAttributes.position.push( positionAttribute );
  				morphAttributes.normal.push( normalAttribute );
  
  			}
  
  			mesh.updateMorphTargets();
  
  			if ( meshDef.weights !== undefined ) {
  
  				for ( var i = 0, il = meshDef.weights.length; i < il; i ++ ) {
  
  					mesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];
  
  				}
  
  			}
  
  		}