|
@@ -111,7 +111,9 @@ THREE.GLTFExporter.prototype = {
|
|
|
var extensionsUsed = {};
|
|
|
var cachedData = {
|
|
|
|
|
|
+ meshes: new Map(),
|
|
|
attributes: new Map(),
|
|
|
+ attributesNormalized: new Map(),
|
|
|
materials: new Map(),
|
|
|
textures: new Map(),
|
|
|
images: new Map()
|
|
@@ -221,7 +223,7 @@ THREE.GLTFExporter.prototype = {
|
|
|
*/
|
|
|
function isNormalizedNormalAttribute( normal ) {
|
|
|
|
|
|
- if ( cachedData.attributes.has( normal ) ) {
|
|
|
+ if ( cachedData.attributesNormalized.has( normal ) ) {
|
|
|
|
|
|
return false;
|
|
|
|
|
@@ -249,9 +251,9 @@ THREE.GLTFExporter.prototype = {
|
|
|
*/
|
|
|
function createNormalizedNormalAttribute( normal ) {
|
|
|
|
|
|
- if ( cachedData.attributes.has( normal ) ) {
|
|
|
+ if ( cachedData.attributesNormalized.has( normal ) ) {
|
|
|
|
|
|
- return cachedData.attributes.get( normal );
|
|
|
+ return cachedData.attributesNormalized.get( normal );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -278,7 +280,7 @@ THREE.GLTFExporter.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- cachedData.attributes.set( normal, attribute );
|
|
|
+ cachedData.attributesNormalized.set( normal, attribute );
|
|
|
|
|
|
return attribute;
|
|
|
|
|
@@ -1008,6 +1010,13 @@ THREE.GLTFExporter.prototype = {
|
|
|
*/
|
|
|
function processMesh( mesh ) {
|
|
|
|
|
|
+ var cacheKey = mesh.geometry.uuid + ':' + mesh.material.uuid;
|
|
|
+ if ( cachedData.meshes.has( cacheKey ) ) {
|
|
|
+
|
|
|
+ return cachedData.meshes.get( cacheKey );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
var geometry = mesh.geometry;
|
|
|
|
|
|
var mode;
|
|
@@ -1090,23 +1099,32 @@ THREE.GLTFExporter.prototype = {
|
|
|
var attribute = geometry.attributes[ attributeName ];
|
|
|
attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
|
|
|
|
|
|
+ if ( cachedData.attributes.has( attribute ) ) {
|
|
|
+
|
|
|
+ attributes[ attributeName ] = cachedData.attributes.get( attribute );
|
|
|
+ continue;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
|
|
|
+ var modifiedAttribute;
|
|
|
var array = attribute.array;
|
|
|
if ( attributeName === 'JOINTS_0' &&
|
|
|
! ( array instanceof Uint16Array ) &&
|
|
|
! ( array instanceof Uint8Array ) ) {
|
|
|
|
|
|
console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
|
|
|
- attribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
|
|
|
+ modifiedAttribute = new THREE.BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
|
|
|
|
|
|
}
|
|
|
|
|
|
if ( attributeName.substr( 0, 5 ) !== 'MORPH' ) {
|
|
|
|
|
|
- var accessor = processAccessor( attribute, geometry );
|
|
|
+ var accessor = processAccessor( modifiedAttribute || attribute, geometry );
|
|
|
if ( accessor !== null ) {
|
|
|
|
|
|
attributes[ attributeName ] = accessor;
|
|
|
+ cachedData.attributes.set( attribute, accessor );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1165,6 +1183,7 @@ THREE.GLTFExporter.prototype = {
|
|
|
}
|
|
|
|
|
|
var attribute = geometry.morphAttributes[ attributeName ][ i ];
|
|
|
+ var gltfAttributeName = attributeName.toUpperCase();
|
|
|
|
|
|
// Three.js morph attribute has absolute values while the one of glTF has relative values.
|
|
|
//
|
|
@@ -1172,6 +1191,14 @@ THREE.GLTFExporter.prototype = {
|
|
|
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
|
|
|
|
|
|
var baseAttribute = geometry.attributes[ attributeName ];
|
|
|
+
|
|
|
+ if ( cachedData.attributes.has( baseAttribute ) ) {
|
|
|
+
|
|
|
+ target[ gltfAttributeName ] = cachedData.attributes.get( baseAttribute );
|
|
|
+ continue;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// Clones attribute not to override
|
|
|
var relativeAttribute = attribute.clone();
|
|
|
|
|
@@ -1186,7 +1213,8 @@ THREE.GLTFExporter.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
- target[ attributeName.toUpperCase() ] = processAccessor( relativeAttribute, geometry );
|
|
|
+ target[ gltfAttributeName ] = processAccessor( relativeAttribute, geometry );
|
|
|
+ cachedData.attributes.set( baseAttribute, target[ gltfAttributeName ] );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1257,7 +1285,16 @@ THREE.GLTFExporter.prototype = {
|
|
|
|
|
|
if ( geometry.index !== null ) {
|
|
|
|
|
|
- primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
|
|
|
+ if ( cachedData.attributes.has( geometry.index ) ) {
|
|
|
+
|
|
|
+ primitive.indices = cachedData.attributes.get( geometry.index );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
|
|
|
+ cachedData.attributes.set( geometry.index, primitive.indices );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1289,7 +1326,10 @@ THREE.GLTFExporter.prototype = {
|
|
|
|
|
|
outputJSON.meshes.push( gltfMesh );
|
|
|
|
|
|
- return outputJSON.meshes.length - 1;
|
|
|
+ var index = outputJSON.meshes.length - 1;
|
|
|
+ cachedData.meshes.set( cacheKey, index );
|
|
|
+
|
|
|
+ return index;
|
|
|
|
|
|
}
|
|
|
|