genGeometry method

dynamic genGeometry(
  1. Map geoNode,
  2. dynamic skeleton,
  3. dynamic morphTargets,
  4. dynamic preTransform,
)

Implementation

genGeometry( Map geoNode, skeleton, morphTargets, preTransform ) {

	var geo = new BufferGeometry();
	if ( geoNode["attrName"] != null ) geo.name = geoNode["attrName"];

	var geoInfo = this.parseGeoNode( geoNode, skeleton );
	var buffers = this.genBuffers( geoInfo );

	var positionAttribute = new Float32BufferAttribute( Float32Array.fromList(List<double>.from(buffers["vertex"])), 3 );

	positionAttribute.applyMatrix4( preTransform );

	geo.setAttribute( 'position', positionAttribute );

	if ( buffers["colors"].length > 0 ) {

		geo.setAttribute( 'color', new Float32BufferAttribute( buffers["colors"], 3 ) );

	}

	if ( skeleton != null ) {
		geo.setAttribute( 'skinIndex', new Uint16BufferAttribute( Uint16Array.fromList( List<int>.from(buffers["weightsIndices"]) ), 4 ) );

		geo.setAttribute( 'skinWeight', new Float32BufferAttribute( Float32Array.fromList( List<double>.from(buffers["vertexWeights"].map((e) => e.toDouble())) ), 4 ) );

		// used later to bind the skeleton to the model
		geo.userData["FBX_Deformer"] = skeleton;

	}

	if ( buffers["normal"].length > 0 ) {

		var normalMatrix = new Matrix3().getNormalMatrix( preTransform );

		var normalAttribute = new Float32BufferAttribute( Float32Array.fromList( List<double>.from(buffers["normal"]) ), 3 );
		normalAttribute.applyNormalMatrix( normalMatrix );

		geo.setAttribute( 'normal', normalAttribute );

	}

	buffers["uvs"].asMap().forEach( ( i, uvBuffer ) {

		// subsequent uv buffers are called 'uv1', 'uv2', ...
		var name = 'uv' + ( i + 1 ).toString();

		// the first uv buffer is just called 'uv'
		if ( i == 0 ) {

			name = 'uv';

		}

		geo.setAttribute( name, new Float32BufferAttribute( Float32Array.fromList( List<double>.from(buffers["uvs"][ i ]) ), 2 ) );

	} );

	if ( geoInfo["material"] != null && geoInfo["material"]["mappingType"] != 'AllSame' ) {

		// Convert the material indices of each vertex into rendering groups on the geometry.
		var prevMaterialIndex = buffers["materialIndex"][ 0 ];
		var startIndex = 0;

		buffers["materialIndex"].asMap().forEach( ( i, currentIndex ) {

			if ( currentIndex != prevMaterialIndex ) {

				geo.addGroup( startIndex, i - startIndex, prevMaterialIndex );

				prevMaterialIndex = currentIndex;
				startIndex = i;

			}

		} );

		// the loop above doesn't add the last group, do that here.
		if ( geo.groups.length > 0 ) {

			var lastGroup = geo.groups[ geo.groups.length - 1 ];
			var lastIndex = lastGroup["start"] + lastGroup["count"];

			if ( lastIndex != buffers["materialIndex"].length ) {

				geo.addGroup( lastIndex, buffers["materialIndex"].length - lastIndex, prevMaterialIndex );

			}

		}

		// case where there are multiple materials but the whole geometry is only
		// using one of them
		if ( geo.groups.length == 0 ) {

			geo.addGroup( 0, buffers["materialIndex"].length, buffers["materialIndex"][ 0 ].toInt() );

		}

	}

	this.addMorphTargets( geo, geoNode, morphTargets, preTransform );

	return geo;

}