From 38cd0970372a5dca9863e99258ab4b85f80e28b1 Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Thu, 24 May 2018 16:27:44 -0700 Subject: [PATCH 01/14] Replace accessor properties values with Draco values --- lib/compressDracoMeshes.js | 5 ++- lib/replaceWithDecompressedPrimitive.js | 59 +++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 lib/replaceWithDecompressedPrimitive.js diff --git a/lib/compressDracoMeshes.js b/lib/compressDracoMeshes.js index 4a926afd..d3ac4993 100644 --- a/lib/compressDracoMeshes.js +++ b/lib/compressDracoMeshes.js @@ -8,6 +8,7 @@ var ForEach = require('./ForEach'); var numberOfComponentsForType = require('./numberOfComponentsForType'); var readAccessorPacked = require('./readAccessorPacked'); var removeUnusedElements = require('./removeUnusedElements'); +var replaceWithDecompressedPrimitive = require('./replaceWithDecompressedPrimitive'); var splitPrimitives = require('./splitPrimitives'); var arrayFill = Cesium.arrayFill; @@ -246,6 +247,8 @@ function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, enco bufferView: bufferViewId, attributes: attributeToId }; + + gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedData, primitive.extensions.KHR_draco_mesh_compression); } function copyCompressedExtensionToPrimitive(primitive, compressedPrimitive) { @@ -295,4 +298,4 @@ compressDracoMeshes.defaults = { quantizeSkinBits: 12, quantizeGenericBits: 12, unifiedQuantization: false -}; \ No newline at end of file +}; diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js new file mode 100644 index 00000000..480bca5a --- /dev/null +++ b/lib/replaceWithDecompressedPrimitive.js @@ -0,0 +1,59 @@ +'use strict'; +var draco3d = require('draco3d'); +var ForEach = require('./ForEach'); + +var decoderModule = draco3d.createDecoderModule({}); + +module.exports = replaceWithDecompressedPrimitive; + +function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, dracoExtension) { + var dracoGeometry = decompressDracoBuffer(compressedData); + var numFaces = dracoGeometry.num_faces(); + var numPoints = dracoGeometry.num_points(); + + // Add decompressed indices data to indices accessor. + var indicesAccessorId = primitive.indices; + var indicesAccessor = gltf.accessors[indicesAccessorId]; + indicesAccessor.count = numFaces * 3; + + var dracoAttributes = dracoExtension.attributes; + for (var semantic in dracoAttributes) { + if (dracoAttributes.hasOwnProperty(semantic)) { + var gltfAttributeId = primitive.attributes[semantic]; + var attributeAccessor = gltf.accessors[gltfAttributeId]; + attributeAccessor.count = numPoints; + } + } + + decoderModule.destroy(dracoGeometry); + return gltf; +} + +function decompressDracoBuffer(compressedData) { + var source = new Uint8Array(compressedData.buffer); + var dracoBuffer = new decoderModule.DecoderBuffer(); + dracoBuffer.Init(source, source.length); + + var decoder = new decoderModule.Decoder(); + var geometryType = decoder.GetEncodedGeometryType(dracoBuffer); + if (geometryType !== decoderModule.TRIANGULAR_MESH) { + var errorMsg = 'Compressed data is not a mesh.'; + console.error(errorMsg); + decoderModule.destroy(decoder); + throw new Error(errorMsg); + } + var dracoGeometry = new decoderModule.Mesh(); + var decodingStatus = decoder.DecodeBufferToMesh(dracoBuffer, dracoGeometry); + if (!decodingStatus.ok() || dracoGeometry.ptr == 0) { + var errorMsg = 'Draco decoding failed: '; + errorMsg += decodingStatus.error_msg(); + console.error(errorMsg); + decoderModule.destroy(decoder); + throw new Error(errorMsg); + } + + decoderModule.destroy(dracoBuffer); + decoderModule.destroy(decoder); + return dracoGeometry; +} + From d5889faf379e358d1806091c61959f8a483b4bd7 Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Thu, 24 May 2018 20:08:36 -0700 Subject: [PATCH 02/14] Add function comment --- lib/replaceWithDecompressedPrimitive.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index 480bca5a..c8727e13 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -6,6 +6,17 @@ var decoderModule = draco3d.createDecoderModule({}); module.exports = replaceWithDecompressedPrimitive; +/** + * Replace the accessor properties of the original primitive with the values from the decompressed primitive. + * + * @param {Object} gltf A javascript object containing a glTF asset. + * @param {Object} primitive A javascript object containing a glTF primitive. + * @param {Buffer} compressedData A Buffer object containing a Draco compressed mesh. + * @param {Object} dracoExtension A javascript object containing KHR_draco_mesh_compression. + * @returns {Object} The glTF asset with the decompressed primitive. + * + * @private + */ function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, dracoExtension) { var dracoGeometry = decompressDracoBuffer(compressedData); var numFaces = dracoGeometry.num_faces(); From 6fae638ba0e3699a9aaf9556c2436f15398a0b8e Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Tue, 29 May 2018 20:53:14 -0700 Subject: [PATCH 03/14] Remove calls to console --- lib/replaceWithDecompressedPrimitive.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index c8727e13..ecef61a0 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -1,6 +1,5 @@ 'use strict'; var draco3d = require('draco3d'); -var ForEach = require('./ForEach'); var decoderModule = draco3d.createDecoderModule({}); @@ -49,7 +48,6 @@ function decompressDracoBuffer(compressedData) { var geometryType = decoder.GetEncodedGeometryType(dracoBuffer); if (geometryType !== decoderModule.TRIANGULAR_MESH) { var errorMsg = 'Compressed data is not a mesh.'; - console.error(errorMsg); decoderModule.destroy(decoder); throw new Error(errorMsg); } @@ -58,7 +56,6 @@ function decompressDracoBuffer(compressedData) { if (!decodingStatus.ok() || dracoGeometry.ptr == 0) { var errorMsg = 'Draco decoding failed: '; errorMsg += decodingStatus.error_msg(); - console.error(errorMsg); decoderModule.destroy(decoder); throw new Error(errorMsg); } From a5c38bbc6dd183eb909a9fbb112f72fd18ca0a37 Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Tue, 29 May 2018 21:14:42 -0700 Subject: [PATCH 04/14] Fix Travis errors --- lib/replaceWithDecompressedPrimitive.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index ecef61a0..a34e9994 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -1,6 +1,9 @@ 'use strict'; +var Cesium = require('cesium'); var draco3d = require('draco3d'); +var RuntimeError = Cesium.RuntimeError; + var decoderModule = draco3d.createDecoderModule({}); module.exports = replaceWithDecompressedPrimitive; @@ -47,17 +50,14 @@ function decompressDracoBuffer(compressedData) { var decoder = new decoderModule.Decoder(); var geometryType = decoder.GetEncodedGeometryType(dracoBuffer); if (geometryType !== decoderModule.TRIANGULAR_MESH) { - var errorMsg = 'Compressed data is not a mesh.'; decoderModule.destroy(decoder); - throw new Error(errorMsg); + throw new RuntimeError('Compressed data is not a mesh.'); } var dracoGeometry = new decoderModule.Mesh(); var decodingStatus = decoder.DecodeBufferToMesh(dracoBuffer, dracoGeometry); - if (!decodingStatus.ok() || dracoGeometry.ptr == 0) { - var errorMsg = 'Draco decoding failed: '; - errorMsg += decodingStatus.error_msg(); + if (!decodingStatus.ok() || dracoGeometry.ptr === 0) { decoderModule.destroy(decoder); - throw new Error(errorMsg); + throw new RuntimeError('Draco decoding failed: ' + decodingStatus.error_msg()); } decoderModule.destroy(dracoBuffer); From 80e78558964e4ec54dd27d9256055268872b6a8f Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Tue, 12 Jun 2018 10:27:21 -0700 Subject: [PATCH 05/14] WIP adding encoded count support --- lib/compressDracoMeshes.js | 10 +++++++--- lib/replaceWithDecompressedPrimitive.js | 13 ++++++++----- package.json | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/compressDracoMeshes.js b/lib/compressDracoMeshes.js index d3ac4993..2f02f6a2 100644 --- a/lib/compressDracoMeshes.js +++ b/lib/compressDracoMeshes.js @@ -184,16 +184,20 @@ function compressDracoMeshes(gltf, options) { encoder.SetEncodingMethod(encoderModule.MESH_SEQUENTIAL_ENCODING); } + encoder.SetTrackEncodedProperties(true); var encodedLength = encoder.EncodeMeshToDracoBuffer(mesh, encodedDracoDataArray); if (encodedLength <= 0) { throw new RuntimeError('Error: Draco encoding failed.'); } + var encodedPointsCount = encoder.GetNumberOfEncodedPoints(); + var encodedFacesCount = encoder.GetNumberOfEncodedFaces(); + console.log('numPoints:' + encodedPointsCount.toString() + ' numFaces:' + encodedFacesCount.toString()); var encodedData = Buffer.alloc(encodedLength); for (var i = 0; i < encodedLength; ++i) { encodedData[i] = encodedDracoDataArray.GetValue(i); } - addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, encodedLength, encodedData); + addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, encodedLength, encodedData, encodedPointsCount, encodedFacesCount); encoderModule.destroy(encodedDracoDataArray); encoderModule.destroy(mesh); @@ -210,7 +214,7 @@ function compressDracoMeshes(gltf, options) { return gltf; } -function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, encodedLength, encodedData) { +function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, encodedLength, encodedData, encodedPointsCount, encodedFacesCount) { // Remove properties from accessors. // Remove indices bufferView. var indicesAccessor = clone(gltf.accessors[primitive.indices]); @@ -248,7 +252,7 @@ function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, enco attributes: attributeToId }; - gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedData, primitive.extensions.KHR_draco_mesh_compression); + gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedData, encodedPointsCount, encodedFacesCount, primitive.extensions.KHR_draco_mesh_compression); } function copyCompressedExtensionToPrimitive(primitive, compressedPrimitive) { diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index a34e9994..8145f431 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -19,10 +19,13 @@ module.exports = replaceWithDecompressedPrimitive; * * @private */ -function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, dracoExtension) { - var dracoGeometry = decompressDracoBuffer(compressedData); - var numFaces = dracoGeometry.num_faces(); - var numPoints = dracoGeometry.num_points(); +function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, encodedPointsCount, encodedFacesCount, dracoExtension) { + //var dracoGeometry = decompressDracoBuffer(compressedData); + //var numFaces = dracoGeometry.num_faces(); + //var numPoints = dracoGeometry.num_points(); + var numFaces = encodedFacesCount; + var numPoints = encodedPointsCount; + // Add decompressed indices data to indices accessor. var indicesAccessorId = primitive.indices; @@ -38,7 +41,7 @@ function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, draco } } - decoderModule.destroy(dracoGeometry); + //decoderModule.destroy(dracoGeometry); return gltf; } diff --git a/package.json b/package.json index 0c36e618..30edb4ed 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "bluebird": "^3.5.1", "cesium": "^1.43.0", - "draco3d": "^1.3.0", + "draco3d": "^1.3.2", "fs-extra": "^5.0.0", "jimp": "^0.2.28", "mime": "^2.2.2", From 44f04203fb7dc62c0fc56db570591959715b156c Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Fri, 15 Jun 2018 16:25:57 -0700 Subject: [PATCH 06/14] Use new encoder api to get decompressed info --- lib/compressDracoMeshes.js | 1 - lib/replaceWithDecompressedPrimitive.js | 38 +++---------------------- package.json | 2 +- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/lib/compressDracoMeshes.js b/lib/compressDracoMeshes.js index 2f02f6a2..42a46d1a 100644 --- a/lib/compressDracoMeshes.js +++ b/lib/compressDracoMeshes.js @@ -191,7 +191,6 @@ function compressDracoMeshes(gltf, options) { } var encodedPointsCount = encoder.GetNumberOfEncodedPoints(); var encodedFacesCount = encoder.GetNumberOfEncodedFaces(); - console.log('numPoints:' + encodedPointsCount.toString() + ' numFaces:' + encodedFacesCount.toString()); var encodedData = Buffer.alloc(encodedLength); for (var i = 0; i < encodedLength; ++i) { encodedData[i] = encodedDracoDataArray.GetValue(i); diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index 8145f431..b61f5108 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -14,57 +14,27 @@ module.exports = replaceWithDecompressedPrimitive; * @param {Object} gltf A javascript object containing a glTF asset. * @param {Object} primitive A javascript object containing a glTF primitive. * @param {Buffer} compressedData A Buffer object containing a Draco compressed mesh. + * @param {Number} encodedPointsCount Number of points after the mesh is decompressed. + * @param {Number} encodedFacesCount Number of faces after the mesh is decompressed. * @param {Object} dracoExtension A javascript object containing KHR_draco_mesh_compression. * @returns {Object} The glTF asset with the decompressed primitive. * * @private */ function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, encodedPointsCount, encodedFacesCount, dracoExtension) { - //var dracoGeometry = decompressDracoBuffer(compressedData); - //var numFaces = dracoGeometry.num_faces(); - //var numPoints = dracoGeometry.num_points(); - var numFaces = encodedFacesCount; - var numPoints = encodedPointsCount; - - // Add decompressed indices data to indices accessor. var indicesAccessorId = primitive.indices; var indicesAccessor = gltf.accessors[indicesAccessorId]; - indicesAccessor.count = numFaces * 3; + indicesAccessor.count = encodedFacesCount * 3; var dracoAttributes = dracoExtension.attributes; for (var semantic in dracoAttributes) { if (dracoAttributes.hasOwnProperty(semantic)) { var gltfAttributeId = primitive.attributes[semantic]; var attributeAccessor = gltf.accessors[gltfAttributeId]; - attributeAccessor.count = numPoints; + attributeAccessor.count = encodedPointsCount; } } - //decoderModule.destroy(dracoGeometry); return gltf; } - -function decompressDracoBuffer(compressedData) { - var source = new Uint8Array(compressedData.buffer); - var dracoBuffer = new decoderModule.DecoderBuffer(); - dracoBuffer.Init(source, source.length); - - var decoder = new decoderModule.Decoder(); - var geometryType = decoder.GetEncodedGeometryType(dracoBuffer); - if (geometryType !== decoderModule.TRIANGULAR_MESH) { - decoderModule.destroy(decoder); - throw new RuntimeError('Compressed data is not a mesh.'); - } - var dracoGeometry = new decoderModule.Mesh(); - var decodingStatus = decoder.DecodeBufferToMesh(dracoBuffer, dracoGeometry); - if (!decodingStatus.ok() || dracoGeometry.ptr === 0) { - decoderModule.destroy(decoder); - throw new RuntimeError('Draco decoding failed: ' + decodingStatus.error_msg()); - } - - decoderModule.destroy(dracoBuffer); - decoderModule.destroy(decoder); - return dracoGeometry; -} - diff --git a/package.json b/package.json index 30edb4ed..6ea27176 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "dependencies": { "bluebird": "^3.5.1", "cesium": "^1.43.0", - "draco3d": "^1.3.2", + "draco3d": "^1.3.3", "fs-extra": "^5.0.0", "jimp": "^0.2.28", "mime": "^2.2.2", From 37cc70acf2a9e784164549f4da7e17f845c3fe99 Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Fri, 15 Jun 2018 17:54:37 -0700 Subject: [PATCH 07/14] Remove unused vars --- lib/compressDracoMeshes.js | 2 +- lib/replaceWithDecompressedPrimitive.js | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/compressDracoMeshes.js b/lib/compressDracoMeshes.js index 42a46d1a..ac83f957 100644 --- a/lib/compressDracoMeshes.js +++ b/lib/compressDracoMeshes.js @@ -251,7 +251,7 @@ function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, enco attributes: attributeToId }; - gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedData, encodedPointsCount, encodedFacesCount, primitive.extensions.KHR_draco_mesh_compression); + gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount, primitive.extensions.KHR_draco_mesh_compression); } function copyCompressedExtensionToPrimitive(primitive, compressedPrimitive) { diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index b61f5108..471b55d0 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -2,10 +2,6 @@ var Cesium = require('cesium'); var draco3d = require('draco3d'); -var RuntimeError = Cesium.RuntimeError; - -var decoderModule = draco3d.createDecoderModule({}); - module.exports = replaceWithDecompressedPrimitive; /** @@ -13,7 +9,6 @@ module.exports = replaceWithDecompressedPrimitive; * * @param {Object} gltf A javascript object containing a glTF asset. * @param {Object} primitive A javascript object containing a glTF primitive. - * @param {Buffer} compressedData A Buffer object containing a Draco compressed mesh. * @param {Number} encodedPointsCount Number of points after the mesh is decompressed. * @param {Number} encodedFacesCount Number of faces after the mesh is decompressed. * @param {Object} dracoExtension A javascript object containing KHR_draco_mesh_compression. @@ -21,7 +16,7 @@ module.exports = replaceWithDecompressedPrimitive; * * @private */ -function replaceWithDecompressedPrimitive(gltf, primitive, compressedData, encodedPointsCount, encodedFacesCount, dracoExtension) { +function replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount, dracoExtension) { // Add decompressed indices data to indices accessor. var indicesAccessorId = primitive.indices; var indicesAccessor = gltf.accessors[indicesAccessorId]; From bfad18c35efc080e89304e3c46a77d98076b8da8 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 2 Jul 2018 09:32:06 -0400 Subject: [PATCH 08/14] Require min/max only for accessors containing position attributes --- lib/updateVersion.js | 5 +++-- specs/lib/updateVersionSpec.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/updateVersion.js b/lib/updateVersion.js index 3402d593..ab607be5 100644 --- a/lib/updateVersion.js +++ b/lib/updateVersion.js @@ -803,7 +803,8 @@ function moveByteStrideToBufferView(gltf) { } function requireAccessorMinMax(gltf) { - ForEach.accessor(gltf, function(accessor) { + ForEach.accessorWithSemantic(gltf, 'POSITION', function(accessorId) { + var accessor = gltf.accessors[accessorId]; if (!defined(accessor.min) || !defined(accessor.max)) { var minMax = findAccessorMinMax(gltf, accessor); accessor.min = minMax.min; @@ -829,7 +830,7 @@ function glTF10to20(gltf) { requireByteLength(gltf); // byteStride moved from accessor to bufferView moveByteStrideToBufferView(gltf); - // accessor.min and accessor.max must be defined + // accessor.min and accessor.max must be defined for accessors containing POSITION attributes requireAccessorMinMax(gltf); // buffer.type is unnecessary and should be removed removeBufferType(gltf); diff --git a/specs/lib/updateVersionSpec.js b/specs/lib/updateVersionSpec.js index 1c5c661d..1a17091b 100644 --- a/specs/lib/updateVersionSpec.js +++ b/specs/lib/updateVersionSpec.js @@ -626,8 +626,9 @@ describe('updateVersion', function() { var bufferView = gltf.bufferViews[0]; expect(bufferView.byteLength).toEqual(source.length); - // Min and max are added to all accessors - ForEach.accessor(gltf, function(accessor) { + // Min and max are added to all POSITION accessors + ForEach.accessorWithSemantic(gltf, 'POSITION', function(accessorId) { + var accessor = gltf.accessors[accessorId]; expect(accessor.min.length).toEqual(numberOfComponentsForType(accessor.type)); expect(accessor.max.length).toEqual(numberOfComponentsForType(accessor.type)); }); From 3d233c7afe8bea37b8ebbf96fc811c8da6287ecb Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 2 Jul 2018 21:27:31 -0400 Subject: [PATCH 09/14] Update name --- lib/updateVersion.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/updateVersion.js b/lib/updateVersion.js index ab607be5..5227ec35 100644 --- a/lib/updateVersion.js +++ b/lib/updateVersion.js @@ -802,7 +802,7 @@ function moveByteStrideToBufferView(gltf) { removeUnusedElements(gltf); } -function requireAccessorMinMax(gltf) { +function requirePositionAccessorMinMax(gltf) { ForEach.accessorWithSemantic(gltf, 'POSITION', function(accessorId) { var accessor = gltf.accessors[accessorId]; if (!defined(accessor.min) || !defined(accessor.max)) { @@ -831,7 +831,7 @@ function glTF10to20(gltf) { // byteStride moved from accessor to bufferView moveByteStrideToBufferView(gltf); // accessor.min and accessor.max must be defined for accessors containing POSITION attributes - requireAccessorMinMax(gltf); + requirePositionAccessorMinMax(gltf); // buffer.type is unnecessary and should be removed removeBufferType(gltf); // Remove format, internalFormat, target, and type From 9438f4b2c4f474f321bf23532080e4b2bb823a6a Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Mon, 2 Jul 2018 21:31:06 -0400 Subject: [PATCH 10/14] Remove .js endings from includes --- lib/readAccessorPacked.js | 2 +- lib/removeUnusedElements.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/readAccessorPacked.js b/lib/readAccessorPacked.js index dd771830..63b52bec 100644 --- a/lib/readAccessorPacked.js +++ b/lib/readAccessorPacked.js @@ -1,7 +1,7 @@ 'use strict'; var Cesium = require('cesium'); var getAccessorByteStride = require('./getAccessorByteStride'); -var getComponentReader = require('./getComponentReader.js'); +var getComponentReader = require('./getComponentReader'); var numberOfComponentsForType = require('./numberOfComponentsForType'); var arrayFill = Cesium.arrayFill; diff --git a/lib/removeUnusedElements.js b/lib/removeUnusedElements.js index da876e2c..0efb776e 100644 --- a/lib/removeUnusedElements.js +++ b/lib/removeUnusedElements.js @@ -1,7 +1,7 @@ 'use strict'; var Cesium = require('cesium'); var ForEach = require('./ForEach'); -var hasExtension = require('./hasExtension.js'); +var hasExtension = require('./hasExtension'); var defined = Cesium.defined; From db07a76e739d71f23ad41bc5cafc5eab65e3ee40 Mon Sep 17 00:00:00 2001 From: ggetz Date: Tue, 3 Jul 2018 13:43:57 -0400 Subject: [PATCH 11/14] Allow for early returns in ForEach functions --- lib/ForEach.js | 272 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 179 insertions(+), 93 deletions(-) diff --git a/lib/ForEach.js b/lib/ForEach.js index 2e7b54f5..22dbb426 100644 --- a/lib/ForEach.js +++ b/lib/ForEach.js @@ -20,12 +20,16 @@ function ForEach() { * Fallback for glTF 1.0 * @private */ -ForEach.objectLegacy = function(objects, handler) { +ForEach.objectLegacy = function (objects, handler) { if (defined(objects)) { for (var objectId in objects) { if (objects.hasOwnProperty(objectId)) { var object = objects[objectId]; - handler(object, objectId); + var value = handler(object, objectId); + + if (defined(value)) { + return value; + } } } } @@ -34,12 +38,16 @@ ForEach.objectLegacy = function(objects, handler) { /** * @private */ -ForEach.object = function(arrayOfObjects, handler) { +ForEach.object = function (arrayOfObjects, handler) { if (defined(arrayOfObjects)) { var length = arrayOfObjects.length; for (var i = 0; i < length; i++) { var object = arrayOfObjects[i]; - handler(object, i); + var value = handler(object, i); + + if (defined(value)) { + return value; + } } } }; @@ -48,34 +56,48 @@ ForEach.object = function(arrayOfObjects, handler) { * Supports glTF 1.0 and 2.0 * @private */ -ForEach.topLevel = function(gltf, name, handler) { +ForEach.topLevel = function (gltf, name, handler) { var gltfProperty = gltf[name]; if (defined(gltfProperty) && !isArray(gltfProperty)) { - ForEach.objectLegacy(gltfProperty, handler); - } else { - ForEach.object(gltfProperty, handler); + return ForEach.objectLegacy(gltfProperty, handler); } + + return ForEach.object(gltfProperty, handler); }; -ForEach.accessor = function(gltf, handler) { - ForEach.topLevel(gltf, 'accessors', handler); +ForEach.accessor = function (gltf, handler) { + return ForEach.topLevel(gltf, 'accessors', handler); }; -ForEach.accessorWithSemantic = function(gltf, semantic, handler) { +ForEach.accessorWithSemantic = function (gltf, semantic, handler) { var visited = {}; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function(primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { + return ForEach.mesh(gltf, function (mesh) { + return ForEach.meshPrimitive(mesh, function (primitive) { + var value; + value = ForEach.meshPrimitiveAttribute(primitive, function (accessorId, attributeSemantic) { if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { visited[accessorId] = true; - handler(accessorId); + value = handler(accessorId); + + if (defined(value)) { + return value; + } } }); - ForEach.meshPrimitiveTarget(primitive, function(target) { - ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, attributeSemantic) { + + if (defined(value)) { + return value; + } + + return ForEach.meshPrimitiveTarget(primitive, function (target) { + return ForEach.meshPrimitiveTargetAttribute(target, function (accessorId, attributeSemantic) { if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { visited[accessorId] = true; - handler(accessorId); + value = handler(accessorId); + + if (defined(value)) { + return value; + } } }); }); @@ -83,21 +105,35 @@ ForEach.accessorWithSemantic = function(gltf, semantic, handler) { }); }; -ForEach.accessorContainingVertexAttributeData = function(gltf, handler) { +ForEach.accessorContainingVertexAttributeData = function (gltf, handler) { var visited = {}; - ForEach.mesh(gltf, function(mesh) { - ForEach.meshPrimitive(mesh, function (primitive) { - ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { + return ForEach.mesh(gltf, function (mesh) { + return ForEach.meshPrimitive(mesh, function (primitive) { + var value; + value = ForEach.meshPrimitiveAttribute(primitive, function (accessorId) { if (!defined(visited[accessorId])) { visited[accessorId] = true; - handler(accessorId); + value = handler(accessorId); + + if (defined(value)) { + return value; + } } }); - ForEach.meshPrimitiveTarget(primitive, function(target) { - ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { + + if (defined(value)) { + return value; + } + + return ForEach.meshPrimitiveTarget(primitive, function (target) { + return ForEach.meshPrimitiveTargetAttribute(target, function (accessorId) { if (!defined(visited[accessorId])) { visited[accessorId] = true; - handler(accessorId); + value = handler(accessorId); + + if (defined(value)) { + return value; + } } }); }); @@ -105,66 +141,74 @@ ForEach.accessorContainingVertexAttributeData = function(gltf, handler) { }); }; -ForEach.accessorContainingIndexData = function(gltf, handler) { +ForEach.accessorContainingIndexData = function (gltf, handler) { var visited = {}; - ForEach.mesh(gltf, function (mesh) { - ForEach.meshPrimitive(mesh, function (primitive) { + return ForEach.mesh(gltf, function (mesh) { + return ForEach.meshPrimitive(mesh, function (primitive) { var indices = primitive.indices; if (defined(indices) && !defined(visited[indices])) { visited[indices] = true; - handler(indices); + var value = handler(indices); + + if (defined(value)) { + return value; + } } }); }); }; -ForEach.animation = function(gltf, handler) { - ForEach.topLevel(gltf, 'animations', handler); +ForEach.animation = function (gltf, handler) { + return ForEach.topLevel(gltf, 'animations', handler); }; -ForEach.animationChannel = function(animation, handler) { +ForEach.animationChannel = function (animation, handler) { var channels = animation.channels; - ForEach.object(channels, handler); + return ForEach.object(channels, handler); }; -ForEach.animationSampler = function(animation, handler) { +ForEach.animationSampler = function (animation, handler) { var samplers = animation.samplers; - ForEach.object(samplers, handler); + return ForEach.object(samplers, handler); }; -ForEach.buffer = function(gltf, handler) { - ForEach.topLevel(gltf, 'buffers', handler); +ForEach.buffer = function (gltf, handler) { + return ForEach.topLevel(gltf, 'buffers', handler); }; -ForEach.bufferView = function(gltf, handler) { - ForEach.topLevel(gltf, 'bufferViews', handler); +ForEach.bufferView = function (gltf, handler) { + return ForEach.topLevel(gltf, 'bufferViews', handler); }; -ForEach.camera = function(gltf, handler) { - ForEach.topLevel(gltf, 'cameras', handler); +ForEach.camera = function (gltf, handler) { + return ForEach.topLevel(gltf, 'cameras', handler); }; -ForEach.image = function(gltf, handler) { - ForEach.topLevel(gltf, 'images', handler); +ForEach.image = function (gltf, handler) { + return ForEach.topLevel(gltf, 'images', handler); }; -ForEach.compressedImage = function(image, handler) { +ForEach.compressedImage = function (image, handler) { if (defined(image.extras)) { var compressedImages = image.extras.compressedImage3DTiles; for (var type in compressedImages) { if (compressedImages.hasOwnProperty(type)) { var compressedImage = compressedImages[type]; - handler(compressedImage, type); + var value = handler(compressedImage, type); + + if (defined(value)) { + return value; + } } } } }; -ForEach.material = function(gltf, handler) { - ForEach.topLevel(gltf, 'materials', handler); +ForEach.material = function (gltf, handler) { + return ForEach.topLevel(gltf, 'materials', handler); }; -ForEach.materialValue = function(material, handler) { +ForEach.materialValue = function (material, handler) { var values = material.values; if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) { values = material.extensions.KHR_techniques_webgl.values; @@ -172,59 +216,79 @@ ForEach.materialValue = function(material, handler) { for (var name in values) { if (values.hasOwnProperty(name)) { - handler(values[name], name); + var value = handler(values[name], name); + + if (defined(value)) { + return value; + } } } }; -ForEach.mesh = function(gltf, handler) { - ForEach.topLevel(gltf, 'meshes', handler); +ForEach.mesh = function (gltf, handler) { + return ForEach.topLevel(gltf, 'meshes', handler); }; -ForEach.meshPrimitive = function(mesh, handler) { +ForEach.meshPrimitive = function (mesh, handler) { var primitives = mesh.primitives; if (defined(primitives)) { var primitivesLength = primitives.length; for (var i = 0; i < primitivesLength; i++) { var primitive = primitives[i]; - handler(primitive, i); + var value = handler(primitive, i); + + if (defined(value)) { + return value; + } } } }; -ForEach.meshPrimitiveAttribute = function(primitive, handler) { +ForEach.meshPrimitiveAttribute = function (primitive, handler) { var attributes = primitive.attributes; for (var semantic in attributes) { if (attributes.hasOwnProperty(semantic)) { - handler(attributes[semantic], semantic); + var value = handler(attributes[semantic], semantic); + + if (defined(value)) { + return value; + } } } }; -ForEach.meshPrimitiveTarget = function(primitive, handler) { +ForEach.meshPrimitiveTarget = function (primitive, handler) { var targets = primitive.targets; if (defined(targets)) { var length = targets.length; for (var i = 0; i < length; ++i) { - handler(targets[i], i); + var value = handler(targets[i], i); + + if (defined(value)) { + return value; + } } } }; -ForEach.meshPrimitiveTargetAttribute = function(target, handler) { +ForEach.meshPrimitiveTargetAttribute = function (target, handler) { for (var semantic in target) { if (target.hasOwnProperty(semantic)) { var accessorId = target[semantic]; - handler(accessorId, semantic); + var value = handler(accessorId, semantic); + + if (defined(value)) { + return value; + } } } }; -ForEach.node = function(gltf, handler) { - ForEach.topLevel(gltf, 'nodes', handler); +ForEach.node = function (gltf, handler) { + return ForEach.topLevel(gltf, 'nodes', handler); }; -ForEach.nodeInTree = function(gltf, nodeIds, handler) { +ForEach.nodeInTree = function (gltf, nodeIds, handler) { var nodes = gltf.nodes; if (defined(nodes)) { var length = nodeIds.length; @@ -232,86 +296,108 @@ ForEach.nodeInTree = function(gltf, nodeIds, handler) { var nodeId = nodeIds[i]; var node = nodes[nodeId]; if (defined(node)) { - handler(node, nodeId); + var value; + value = handler(node, nodeId); + + if (defined(value)) { + return value; + } + var children = node.children; if (defined(children)) { - ForEach.nodeInTree(gltf, children, handler); + value = ForEach.nodeInTree(gltf, children, handler); + + if (defined(value)) { + return value; + } } } } } }; -ForEach.nodeInScene = function(gltf, scene, handler) { +ForEach.nodeInScene = function (gltf, scene, handler) { var sceneNodeIds = scene.nodes; if (defined(sceneNodeIds)) { - ForEach.nodeInTree(gltf, sceneNodeIds, handler); + return ForEach.nodeInTree(gltf, sceneNodeIds, handler); } }; -ForEach.program = function(gltf, handler) { +ForEach.program = function (gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { - ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler); - } else { - ForEach.topLevel(gltf, 'programs', handler); + return ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler); } + + return ForEach.topLevel(gltf, 'programs', handler); }; -ForEach.sampler = function(gltf, handler) { - ForEach.topLevel(gltf, 'samplers', handler); +ForEach.sampler = function (gltf, handler) { + return ForEach.topLevel(gltf, 'samplers', handler); }; -ForEach.scene = function(gltf, handler) { - ForEach.topLevel(gltf, 'scenes', handler); +ForEach.scene = function (gltf, handler) { + return ForEach.topLevel(gltf, 'scenes', handler); }; -ForEach.shader = function(gltf, handler) { +ForEach.shader = function (gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { - ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler); - } else { - ForEach.topLevel(gltf, 'shaders', handler); + return ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler); } + + return ForEach.topLevel(gltf, 'shaders', handler); }; -ForEach.skin = function(gltf, handler) { - ForEach.topLevel(gltf, 'skins', handler); +ForEach.skin = function (gltf, handler) { + return ForEach.topLevel(gltf, 'skins', handler); }; -ForEach.techniqueAttribute = function(technique, handler) { +ForEach.techniqueAttribute = function (technique, handler) { var attributes = technique.attributes; for (var attributeName in attributes) { if (attributes.hasOwnProperty(attributeName)) { - handler(attributes[attributeName], attributeName); + var value = handler(attributes[attributeName], attributeName); + + if (defined(value)) { + return value; + } } } }; -ForEach.techniqueUniform = function(technique, handler) { +ForEach.techniqueUniform = function (technique, handler) { var uniforms = technique.uniforms; for (var uniformName in uniforms) { if (uniforms.hasOwnProperty(uniformName)) { - handler(uniforms[uniformName], uniformName); + var value = handler(uniforms[uniformName], uniformName); + + if (defined(value)) { + return value; + } } } }; -ForEach.techniqueParameter = function(technique, handler) { +ForEach.techniqueParameter = function (technique, handler) { var parameters = technique.parameters; for (var parameterName in parameters) { if (parameters.hasOwnProperty(parameterName)) { - handler(parameters[parameterName], parameterName); + var value = handler(parameters[parameterName], parameterName); + + if (defined(value)) { + return value; + } } } }; -ForEach.technique = function(gltf, handler) { +ForEach.technique = function (gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { - ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler); - } else { - ForEach.topLevel(gltf, 'techniques', handler); + return ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler); } + + return ForEach.topLevel(gltf, 'techniques', handler); }; -ForEach.texture = function(gltf, handler) { - ForEach.topLevel(gltf, 'textures', handler); +ForEach.texture = function (gltf, handler) { + return ForEach.topLevel(gltf, 'textures', handler); }; From 54eee61fe2320f451ff3871a5108bf16d6d0b5f4 Mon Sep 17 00:00:00 2001 From: Frank Galligan Date: Tue, 3 Jul 2018 14:35:16 -0700 Subject: [PATCH 12/14] Remove function parameter --- lib/compressDracoMeshes.js | 2 +- lib/replaceWithDecompressedPrimitive.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compressDracoMeshes.js b/lib/compressDracoMeshes.js index ac83f957..8f89fb56 100644 --- a/lib/compressDracoMeshes.js +++ b/lib/compressDracoMeshes.js @@ -251,7 +251,7 @@ function addCompressionExtensionToPrimitive(gltf, primitive, attributeToId, enco attributes: attributeToId }; - gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount, primitive.extensions.KHR_draco_mesh_compression); + gltf = replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount); } function copyCompressedExtensionToPrimitive(primitive, compressedPrimitive) { diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index 471b55d0..c05ff478 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -11,18 +11,17 @@ module.exports = replaceWithDecompressedPrimitive; * @param {Object} primitive A javascript object containing a glTF primitive. * @param {Number} encodedPointsCount Number of points after the mesh is decompressed. * @param {Number} encodedFacesCount Number of faces after the mesh is decompressed. - * @param {Object} dracoExtension A javascript object containing KHR_draco_mesh_compression. * @returns {Object} The glTF asset with the decompressed primitive. * * @private */ -function replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount, dracoExtension) { +function replaceWithDecompressedPrimitive(gltf, primitive, encodedPointsCount, encodedFacesCount) { // Add decompressed indices data to indices accessor. var indicesAccessorId = primitive.indices; var indicesAccessor = gltf.accessors[indicesAccessorId]; indicesAccessor.count = encodedFacesCount * 3; - var dracoAttributes = dracoExtension.attributes; + var dracoAttributes = primitive.extensions.KHR_draco_mesh_compression.attributes; for (var semantic in dracoAttributes) { if (dracoAttributes.hasOwnProperty(semantic)) { var gltfAttributeId = primitive.attributes[semantic]; From bbb120527fef677ae2bea4cab86573951a557cc4 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 5 Jul 2018 11:10:15 -0400 Subject: [PATCH 13/14] Fix eslint errors --- lib/replaceWithDecompressedPrimitive.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/replaceWithDecompressedPrimitive.js b/lib/replaceWithDecompressedPrimitive.js index c05ff478..0972bf8d 100644 --- a/lib/replaceWithDecompressedPrimitive.js +++ b/lib/replaceWithDecompressedPrimitive.js @@ -1,6 +1,4 @@ 'use strict'; -var Cesium = require('cesium'); -var draco3d = require('draco3d'); module.exports = replaceWithDecompressedPrimitive; From 6d4e7b84244998cc5c9ceb4d5db715412c553fab Mon Sep 17 00:00:00 2001 From: ggetz Date: Thu, 5 Jul 2018 12:52:49 -0400 Subject: [PATCH 14/14] Added specs for ForEach early returns --- lib/ForEach.js | 99 +++++++------- lib/writeResources.js | 6 +- specs/lib/ForEachSpec.js | 272 +++++++++++++++++++++++++++++++++------ 3 files changed, 282 insertions(+), 95 deletions(-) diff --git a/lib/ForEach.js b/lib/ForEach.js index 22dbb426..67204371 100644 --- a/lib/ForEach.js +++ b/lib/ForEach.js @@ -20,7 +20,7 @@ function ForEach() { * Fallback for glTF 1.0 * @private */ -ForEach.objectLegacy = function (objects, handler) { +ForEach.objectLegacy = function(objects, handler) { if (defined(objects)) { for (var objectId in objects) { if (objects.hasOwnProperty(objectId)) { @@ -38,7 +38,7 @@ ForEach.objectLegacy = function (objects, handler) { /** * @private */ -ForEach.object = function (arrayOfObjects, handler) { +ForEach.object = function(arrayOfObjects, handler) { if (defined(arrayOfObjects)) { var length = arrayOfObjects.length; for (var i = 0; i < length; i++) { @@ -56,7 +56,7 @@ ForEach.object = function (arrayOfObjects, handler) { * Supports glTF 1.0 and 2.0 * @private */ -ForEach.topLevel = function (gltf, name, handler) { +ForEach.topLevel = function(gltf, name, handler) { var gltfProperty = gltf[name]; if (defined(gltfProperty) && !isArray(gltfProperty)) { return ForEach.objectLegacy(gltfProperty, handler); @@ -65,16 +65,15 @@ ForEach.topLevel = function (gltf, name, handler) { return ForEach.object(gltfProperty, handler); }; -ForEach.accessor = function (gltf, handler) { +ForEach.accessor = function(gltf, handler) { return ForEach.topLevel(gltf, 'accessors', handler); }; -ForEach.accessorWithSemantic = function (gltf, semantic, handler) { +ForEach.accessorWithSemantic = function(gltf, semantic, handler) { var visited = {}; - return ForEach.mesh(gltf, function (mesh) { - return ForEach.meshPrimitive(mesh, function (primitive) { - var value; - value = ForEach.meshPrimitiveAttribute(primitive, function (accessorId, attributeSemantic) { + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { + var value = ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeSemantic) { if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { visited[accessorId] = true; value = handler(accessorId); @@ -89,8 +88,8 @@ ForEach.accessorWithSemantic = function (gltf, semantic, handler) { return value; } - return ForEach.meshPrimitiveTarget(primitive, function (target) { - return ForEach.meshPrimitiveTargetAttribute(target, function (accessorId, attributeSemantic) { + return ForEach.meshPrimitiveTarget(primitive, function(target) { + return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, attributeSemantic) { if (attributeSemantic.indexOf(semantic) === 0 && !defined(visited[accessorId])) { visited[accessorId] = true; value = handler(accessorId); @@ -105,12 +104,11 @@ ForEach.accessorWithSemantic = function (gltf, semantic, handler) { }); }; -ForEach.accessorContainingVertexAttributeData = function (gltf, handler) { +ForEach.accessorContainingVertexAttributeData = function(gltf, handler) { var visited = {}; - return ForEach.mesh(gltf, function (mesh) { - return ForEach.meshPrimitive(mesh, function (primitive) { - var value; - value = ForEach.meshPrimitiveAttribute(primitive, function (accessorId) { + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { + var value = ForEach.meshPrimitiveAttribute(primitive, function(accessorId) { if (!defined(visited[accessorId])) { visited[accessorId] = true; value = handler(accessorId); @@ -125,8 +123,8 @@ ForEach.accessorContainingVertexAttributeData = function (gltf, handler) { return value; } - return ForEach.meshPrimitiveTarget(primitive, function (target) { - return ForEach.meshPrimitiveTargetAttribute(target, function (accessorId) { + return ForEach.meshPrimitiveTarget(primitive, function(target) { + return ForEach.meshPrimitiveTargetAttribute(target, function(accessorId) { if (!defined(visited[accessorId])) { visited[accessorId] = true; value = handler(accessorId); @@ -141,10 +139,10 @@ ForEach.accessorContainingVertexAttributeData = function (gltf, handler) { }); }; -ForEach.accessorContainingIndexData = function (gltf, handler) { +ForEach.accessorContainingIndexData = function(gltf, handler) { var visited = {}; - return ForEach.mesh(gltf, function (mesh) { - return ForEach.meshPrimitive(mesh, function (primitive) { + return ForEach.mesh(gltf, function(mesh) { + return ForEach.meshPrimitive(mesh, function(primitive) { var indices = primitive.indices; if (defined(indices) && !defined(visited[indices])) { visited[indices] = true; @@ -158,37 +156,37 @@ ForEach.accessorContainingIndexData = function (gltf, handler) { }); }; -ForEach.animation = function (gltf, handler) { +ForEach.animation = function(gltf, handler) { return ForEach.topLevel(gltf, 'animations', handler); }; -ForEach.animationChannel = function (animation, handler) { +ForEach.animationChannel = function(animation, handler) { var channels = animation.channels; return ForEach.object(channels, handler); }; -ForEach.animationSampler = function (animation, handler) { +ForEach.animationSampler = function(animation, handler) { var samplers = animation.samplers; return ForEach.object(samplers, handler); }; -ForEach.buffer = function (gltf, handler) { +ForEach.buffer = function(gltf, handler) { return ForEach.topLevel(gltf, 'buffers', handler); }; -ForEach.bufferView = function (gltf, handler) { +ForEach.bufferView = function(gltf, handler) { return ForEach.topLevel(gltf, 'bufferViews', handler); }; -ForEach.camera = function (gltf, handler) { +ForEach.camera = function(gltf, handler) { return ForEach.topLevel(gltf, 'cameras', handler); }; -ForEach.image = function (gltf, handler) { +ForEach.image = function(gltf, handler) { return ForEach.topLevel(gltf, 'images', handler); }; -ForEach.compressedImage = function (image, handler) { +ForEach.compressedImage = function(image, handler) { if (defined(image.extras)) { var compressedImages = image.extras.compressedImage3DTiles; for (var type in compressedImages) { @@ -204,11 +202,11 @@ ForEach.compressedImage = function (image, handler) { } }; -ForEach.material = function (gltf, handler) { +ForEach.material = function(gltf, handler) { return ForEach.topLevel(gltf, 'materials', handler); }; -ForEach.materialValue = function (material, handler) { +ForEach.materialValue = function(material, handler) { var values = material.values; if (defined(material.extensions) && defined(material.extensions.KHR_techniques_webgl)) { values = material.extensions.KHR_techniques_webgl.values; @@ -225,11 +223,11 @@ ForEach.materialValue = function (material, handler) { } }; -ForEach.mesh = function (gltf, handler) { +ForEach.mesh = function(gltf, handler) { return ForEach.topLevel(gltf, 'meshes', handler); }; -ForEach.meshPrimitive = function (mesh, handler) { +ForEach.meshPrimitive = function(mesh, handler) { var primitives = mesh.primitives; if (defined(primitives)) { var primitivesLength = primitives.length; @@ -244,7 +242,7 @@ ForEach.meshPrimitive = function (mesh, handler) { } }; -ForEach.meshPrimitiveAttribute = function (primitive, handler) { +ForEach.meshPrimitiveAttribute = function(primitive, handler) { var attributes = primitive.attributes; for (var semantic in attributes) { if (attributes.hasOwnProperty(semantic)) { @@ -257,7 +255,7 @@ ForEach.meshPrimitiveAttribute = function (primitive, handler) { } }; -ForEach.meshPrimitiveTarget = function (primitive, handler) { +ForEach.meshPrimitiveTarget = function(primitive, handler) { var targets = primitive.targets; if (defined(targets)) { var length = targets.length; @@ -271,7 +269,7 @@ ForEach.meshPrimitiveTarget = function (primitive, handler) { } }; -ForEach.meshPrimitiveTargetAttribute = function (target, handler) { +ForEach.meshPrimitiveTargetAttribute = function(target, handler) { for (var semantic in target) { if (target.hasOwnProperty(semantic)) { var accessorId = target[semantic]; @@ -284,11 +282,11 @@ ForEach.meshPrimitiveTargetAttribute = function (target, handler) { } }; -ForEach.node = function (gltf, handler) { +ForEach.node = function(gltf, handler) { return ForEach.topLevel(gltf, 'nodes', handler); }; -ForEach.nodeInTree = function (gltf, nodeIds, handler) { +ForEach.nodeInTree = function(gltf, nodeIds, handler) { var nodes = gltf.nodes; if (defined(nodes)) { var length = nodeIds.length; @@ -296,8 +294,7 @@ ForEach.nodeInTree = function (gltf, nodeIds, handler) { var nodeId = nodeIds[i]; var node = nodes[nodeId]; if (defined(node)) { - var value; - value = handler(node, nodeId); + var value = handler(node, nodeId); if (defined(value)) { return value; @@ -316,14 +313,14 @@ ForEach.nodeInTree = function (gltf, nodeIds, handler) { } }; -ForEach.nodeInScene = function (gltf, scene, handler) { +ForEach.nodeInScene = function(gltf, scene, handler) { var sceneNodeIds = scene.nodes; if (defined(sceneNodeIds)) { return ForEach.nodeInTree(gltf, sceneNodeIds, handler); } }; -ForEach.program = function (gltf, handler) { +ForEach.program = function(gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { return ForEach.object(gltf.extensions.KHR_techniques_webgl.programs, handler); } @@ -331,15 +328,15 @@ ForEach.program = function (gltf, handler) { return ForEach.topLevel(gltf, 'programs', handler); }; -ForEach.sampler = function (gltf, handler) { +ForEach.sampler = function(gltf, handler) { return ForEach.topLevel(gltf, 'samplers', handler); }; -ForEach.scene = function (gltf, handler) { +ForEach.scene = function(gltf, handler) { return ForEach.topLevel(gltf, 'scenes', handler); }; -ForEach.shader = function (gltf, handler) { +ForEach.shader = function(gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { return ForEach.object(gltf.extensions.KHR_techniques_webgl.shaders, handler); } @@ -347,11 +344,11 @@ ForEach.shader = function (gltf, handler) { return ForEach.topLevel(gltf, 'shaders', handler); }; -ForEach.skin = function (gltf, handler) { +ForEach.skin = function(gltf, handler) { return ForEach.topLevel(gltf, 'skins', handler); }; -ForEach.techniqueAttribute = function (technique, handler) { +ForEach.techniqueAttribute = function(technique, handler) { var attributes = technique.attributes; for (var attributeName in attributes) { if (attributes.hasOwnProperty(attributeName)) { @@ -364,7 +361,7 @@ ForEach.techniqueAttribute = function (technique, handler) { } }; -ForEach.techniqueUniform = function (technique, handler) { +ForEach.techniqueUniform = function(technique, handler) { var uniforms = technique.uniforms; for (var uniformName in uniforms) { if (uniforms.hasOwnProperty(uniformName)) { @@ -377,7 +374,7 @@ ForEach.techniqueUniform = function (technique, handler) { } }; -ForEach.techniqueParameter = function (technique, handler) { +ForEach.techniqueParameter = function(technique, handler) { var parameters = technique.parameters; for (var parameterName in parameters) { if (parameters.hasOwnProperty(parameterName)) { @@ -390,7 +387,7 @@ ForEach.techniqueParameter = function (technique, handler) { } }; -ForEach.technique = function (gltf, handler) { +ForEach.technique = function(gltf, handler) { if (hasExtension(gltf, 'KHR_techniques_webgl')) { return ForEach.object(gltf.extensions.KHR_techniques_webgl.techniques, handler); } @@ -398,6 +395,6 @@ ForEach.technique = function (gltf, handler) { return ForEach.topLevel(gltf, 'techniques', handler); }; -ForEach.texture = function (gltf, handler) { +ForEach.texture = function(gltf, handler) { return ForEach.topLevel(gltf, 'textures', handler); }; diff --git a/lib/writeResources.js b/lib/writeResources.js index b72d560e..4792ec83 100644 --- a/lib/writeResources.js +++ b/lib/writeResources.js @@ -139,16 +139,14 @@ function writeBufferView(gltf, object) { } function getProgram(gltf, shaderIndex) { - var programInfo; - ForEach.program(gltf, function(program, index) { + return ForEach.program(gltf, function(program, index) { if (program.fragmentShader === shaderIndex || program.vertexShader === shaderIndex) { - programInfo = { + return { program: program, index: index }; } }); - return programInfo; } function getName(gltf, object, index, extension, options) { diff --git a/specs/lib/ForEachSpec.js b/specs/lib/ForEachSpec.js index 6aaa5196..2baa64c2 100644 --- a/specs/lib/ForEachSpec.js +++ b/specs/lib/ForEachSpec.js @@ -126,33 +126,56 @@ describe('ForEach', function() { ForEach.accessor(gltfAccessors, function(accessor, index) { expect(accessor.bufferView).toBe(index); }); + + var returnValue = ForEach.accessor(gltfAccessors, function(accessor, index) { + if (index === 1) { + return accessor; + } + }); + + expect(returnValue).toBe(gltfAccessors.accessors[1]); }); it('loops over accessor with semantic', function() { var positionAccessorLength = 0; - ForEach.accessorWithSemantic(gltfAccessors, 'POSITION', function(accessorId) { + var returnValue = ForEach.accessorWithSemantic(gltfAccessors, 'POSITION', function(accessorId) { expect(gltfAccessors.accessors[accessorId].bufferView).toBe(accessorId); positionAccessorLength++; + + if (positionAccessorLength === 5) { + return accessorId; + } }); expect(positionAccessorLength).toBe(5); + expect(returnValue).toBe(10); }); it('loops over accessors containing vertex data', function() { var vertexAccessorsLength = 0; - ForEach.accessorContainingVertexAttributeData(gltfAccessors, function(accessorId) { + var returnValue = ForEach.accessorContainingVertexAttributeData(gltfAccessors, function(accessorId) { expect(gltfAccessors.accessors[accessorId].bufferView).toBe(accessorId); vertexAccessorsLength++; + + if (vertexAccessorsLength === 10) { + return accessorId; + } }); expect(vertexAccessorsLength).toBe(10); + expect(returnValue).toBe(11); }); it('loops over accessors containing index data', function() { var indicesAccessorsLength = 0; - ForEach.accessorContainingIndexData(gltfAccessors, function(accessorId) { + var returnValue = ForEach.accessorContainingIndexData(gltfAccessors, function(accessorId) { expect(gltfAccessors.accessors[accessorId].bufferView).toBe(accessorId); indicesAccessorsLength++; + + if (indicesAccessorsLength === 2) { + return accessorId; + } }); expect(indicesAccessorsLength).toBe(2); + expect(returnValue).toBe(1); }); var gltfAnimations = { @@ -206,21 +229,39 @@ describe('ForEach', function() { }; it('loops over animations', function() { - ForEach.animation(gltfAnimations, function(animation, index) { + var returnValue = ForEach.animation(gltfAnimations, function(animation, index) { expect(animation.channels[0].target.node).toBe(index); + + if (index === 1) { + return animation; + } }); + + expect(returnValue).toBe(gltfAnimations.animations[1]); }); it('loops over animation channel', function() { - ForEach.animationChannel(gltfAnimations.animations[0], function(channel, index) { + var returnValue = ForEach.animationChannel(gltfAnimations.animations[0], function(channel, index) { expect(channel.sampler).toBe(index); + + if (index === 1) { + return channel; + } }); + + expect(returnValue).toBe(gltfAnimations.animations[0].channels[1]); }); it('loops over animation samplers', function() { - ForEach.animationSampler(gltfAnimations.animations[0], function(sampler, index) { + var returnValue = ForEach.animationSampler(gltfAnimations.animations[0], function(sampler, index) { expect(sampler.input).toBe(index); + + if (index === 1) { + return sampler; + } }); + + expect(returnValue).toBe(gltfAnimations.animations[0].samplers[1]); }); it('loops over buffers', function() { @@ -236,9 +277,13 @@ describe('ForEach', function() { } ] }; - ForEach.buffer(gltf, function(buffer, index) { + var returnValue = ForEach.buffer(gltf, function(buffer, index) { expect(buffer.uri).toBe(index + '.bin'); + if (index === 1) { + return buffer; + } }); + expect(returnValue).toBe(gltf.buffers[1]); }); it('loops over buffers (gltf 1.0)', function() { @@ -252,9 +297,13 @@ describe('ForEach', function() { } } }; - ForEach.buffer(gltf, function(buffer, name) { + var returnValue = ForEach.buffer(gltf, function(buffer, name) { expect(buffer.uri).toBe(name + '.bin'); + if (name === '1.bin') { + return buffer; + } }); + expect(returnValue).toBe(gltf.buffers[1]); }); it('loops over buffer views', function() { @@ -270,9 +319,13 @@ describe('ForEach', function() { } ] }; - ForEach.bufferView(gltf, function(bufferView, index) { + var returnValue = ForEach.bufferView(gltf, function(bufferView, index) { expect(bufferView.buffer).toBe(index); + if (index === 1) { + return bufferView; + } }); + expect(returnValue).toBe(gltf.bufferViews[1]); }); it('loops over cameras', function() { @@ -292,10 +345,14 @@ describe('ForEach', function() { } ] }; - ForEach.camera(gltf, function(camera, index) { + var returnValue = ForEach.camera(gltf, function(camera, index) { expect(camera.perspective.yfov).toBe(index); expect(camera.perspective.znear).toBe(index); + if (index === 1) { + return camera; + } }); + expect(returnValue).toBe(gltf.cameras[1]); }); it('loops over images', function() { @@ -309,9 +366,13 @@ describe('ForEach', function() { } ] }; - ForEach.image(gltf, function(image, index) { + var returnValue = ForEach.image(gltf, function(image, index) { expect(image.bufferView).toBe(index); + if (index === 1) { + return image; + } }); + expect(returnValue).toBe(gltf.images[1]); }); it('loops over images (gltf 1.0)', function() { @@ -325,9 +386,13 @@ describe('ForEach', function() { } } }; - ForEach.image(gltf, function(image, name) { + var returnValue = ForEach.image(gltf, function(image, name) { expect(image.uri).toBe(name + '.png'); + if (name === 'image1') { + return image; + } }); + expect(returnValue).toBe(gltf.images['image1']); }); it('loops over compressed images', function() { @@ -347,10 +412,13 @@ describe('ForEach', function() { } ] }; - - ForEach.compressedImage(gltf.images[0], function(compressedImage, type) { + var returnValue = ForEach.compressedImage(gltf.images[0], function(compressedImage, type) { expect(compressedImage.uri).toBe(type + '.ktx'); + if (type === 'etc1') { + return compressedImage; + } }); + expect(returnValue).toBe(gltf.images[0].extras.compressedImage3DTiles['etc1']); }); it('loops over materials', function() { @@ -364,9 +432,13 @@ describe('ForEach', function() { } ] }; - ForEach.material(gltf, function(material, index) { + var returnValue = ForEach.material(gltf, function(material, index) { expect(material.emissiveTexture).toBe(index); + if (index === 1) { + return material; + } }); + expect(returnValue).toBe(gltf.materials[1]); }); it('loops over material values', function () { @@ -392,12 +464,16 @@ describe('ForEach', function() { }; var count = 0; - ForEach.materialValue(material, function (value, uniformName) { + var returnValue = ForEach.materialValue(material, function (value, uniformName) { expect(value).toBeDefined(); expect(uniformName.indexOf('u_')).toBe(0); count++; + if (uniformName === 'u_specular') { + return value; + } }); expect(count).toBe(3); + expect(returnValue).toBe(material.extensions.KHR_techniques_webgl.values['u_specular']); }); it('loops over legacy material values', function () { @@ -418,11 +494,15 @@ describe('ForEach', function() { }; var count = 0; - ForEach.materialValue(material, function (value) { + var returnValue = ForEach.materialValue(material, function (value, materialId) { expect(value).toBeDefined(); count++; + if (materialId === 'specular') { + return value; + } }); expect(count).toBe(3); + expect(returnValue).toBe(material.values['specular']); }); it('loops over meshes', function() { @@ -451,9 +531,13 @@ describe('ForEach', function() { ] }; - ForEach.mesh(gltf, function(mesh, index) { + var returnValue = ForEach.mesh(gltf, function(mesh, index) { expect(mesh.primitives[0].attributes.POSITION).toBe(index); + if (index === 1) { + return mesh; + } }); + expect(returnValue).toBe(gltf.meshes[1]); }); var gltfPrimitives = { @@ -479,16 +563,24 @@ describe('ForEach', function() { it('loops over primitives', function() { var mesh = gltfPrimitives.meshes[0]; - ForEach.meshPrimitive(mesh, function(primitive, index) { + var returnValue = ForEach.meshPrimitive(mesh, function(primitive, index) { expect(primitive.attributes.POSITION).toBe(index); + if (index === 1) { + return primitive; + } }); + expect(returnValue).toBe(gltfPrimitives.meshes[0].primitives[1]); }); it('loops over attributes', function() { var primitive = gltfPrimitives.meshes[0].primitives[0]; - ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { + var returnValue = ForEach.meshPrimitiveAttribute(primitive, function(accessorId, semantic) { expect(primitive.attributes[semantic]).toBe(accessorId); + if (semantic === 'NORMAL') { + return accessorId; + } }); + expect(returnValue).toBe(gltfPrimitives.meshes[0].primitives[0].attributes['NORMAL']); }); var gltfTargets = { @@ -518,16 +610,24 @@ describe('ForEach', function() { it('loops over targets', function() { var primitive = gltfTargets.meshes[0].primitives[0]; - ForEach.meshPrimitiveTarget(primitive, function(target, index) { + var returnValue = ForEach.meshPrimitiveTarget(primitive, function(target, index) { expect(target.POSITION).toBe(index); + if (index === 1) { + return target; + } }); + expect(returnValue).toBe(gltfTargets.meshes[0].primitives[0].targets[1]); }); it('loops over target attributes', function() { var target = gltfTargets.meshes[0].primitives[0].targets[0]; - ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, semantic) { + var returnValue = ForEach.meshPrimitiveTargetAttribute(target, function(accessorId, semantic) { expect(target[semantic]).toBe(accessorId); + if (semantic === 'NORMAL') { + return accessorId; + } }); + expect(returnValue).toBe(gltfTargets.meshes[0].primitives[0].targets[0]['NORMAL']); }); var gltfNodes = { @@ -565,23 +665,33 @@ describe('ForEach', function() { it('loops over nodes', function() { var nodesLength = 0; - ForEach.node(gltfNodes, function(node, index) { + var returnValue = ForEach.node(gltfNodes, function(node, index) { expect(node.matrix[12]).toBe(index); nodesLength++; + + if (nodesLength === 6) { + return node; + } }); expect(nodesLength).toBe(6); + expect(returnValue).toBe(gltfNodes.nodes[5]); }); it('loops over nodes in tree', function() { var nodesInTree = 0; - ForEach.nodeInTree(gltfNodes, gltfNodes.scenes[0].nodes, function(node, index) { + var returnValue = ForEach.nodeInTree(gltfNodes, gltfNodes.scenes[0].nodes, function(node, index) { expect(node.matrix[12]).toBe(index); nodesInTree++; + + if (nodesInTree === 5) { + return node; + } }); expect(nodesInTree).toBe(5); + expect(returnValue).toBe(gltfNodes.nodes[2]); }); it('loops over nodes in scene', function() { @@ -592,13 +702,18 @@ describe('ForEach', function() { expect(node.matrix[12]).toBe(index); nodesInScene0++; }); - ForEach.nodeInScene(gltfNodes, gltfNodes.scenes[1], function(node, index) { + var returnValue = ForEach.nodeInScene(gltfNodes, gltfNodes.scenes[1], function(node, index) { expect(node.matrix[12]).toBe(index); nodesInScene1++; + + if (nodesInScene1 === 1) { + return node; + } }); expect(nodesInScene0).toBe(5); expect(nodesInScene1).toBe(1); + expect(returnValue).toBe(gltfNodes.nodes[3]); }); it('loops over samplers', function() { @@ -616,11 +731,17 @@ describe('ForEach', function() { ] }; var count = 0; - ForEach.sampler(gltf, function(sampler, index) { + var returnValue = ForEach.sampler(gltf, function(sampler, index) { expect(sampler.magFilter).toBe(filters[index]); expect(sampler.minFilter).toBe(filters[index]); expect(index).toBe(count++); + + if (index === 1) { + return sampler; + } }); + + expect(returnValue).toBe(gltf.samplers[1]); }); it('loops over scenes', function() { @@ -634,9 +755,14 @@ describe('ForEach', function() { } ] }; - ForEach.scene(gltf, function(scene, index) { + var returnValue = ForEach.scene(gltf, function(scene, index) { expect(scene.nodes[0]).toBe(index); + + if (index === 1) { + return scene; + } }); + expect(returnValue).toBe(gltf.scenes[1]); }); it('loops over shaders (gltf 1.0)', function() { @@ -652,9 +778,15 @@ describe('ForEach', function() { } } }; - ForEach.shader(gltf, function(shader, name) { + var returnValue = ForEach.shader(gltf, function(shader, name) { expect(shader.uri).toBe(name + '.glsl'); + + if (name === 'frag') { + return shader; + } }); + + expect(returnValue).toBe(gltf.shaders['frag']); }); it('loops over KHR_techniques_webgl shaders (gltf 2.0)', function () { @@ -679,11 +811,16 @@ describe('ForEach', function() { }; var count = 0; - ForEach.shader(gltf, function (shader) { + var returnValue = ForEach.shader(gltf, function (shader) { expect(shader.uri).toBe(shader.name + '.glsl'); count++; + + if (count === 2) { + return shader; + } }); expect(count).toBe(2); + expect(returnValue).toBe(gltf.extensions.KHR_techniques_webgl.shaders[1]); gltf = {}; @@ -716,12 +853,17 @@ describe('ForEach', function() { }; var count = 0; - ForEach.program(gltf, function (program) { + var returnValue = ForEach.program(gltf, function (program) { expect(program.fragmentShader).toBeDefined(); expect(program.vertexShader).toBeDefined(); count++; + + if (count === 2) { + return program; + } }); expect(count).toBe(2); + expect(returnValue).toBe(gltf.extensions.KHR_techniques_webgl.programs[1]); gltf = {}; @@ -747,12 +889,17 @@ describe('ForEach', function() { }; var count = 0; - ForEach.program(gltf, function (program) { + var returnValue = ForEach.program(gltf, function (program) { expect(program.fragmentShader).toBeDefined(); expect(program.vertexShader).toBeDefined(); count++; + + if (count === 2) { + return program; + } }); expect(count).toBe(2); + expect(returnValue).toBe(gltf.programs['program_1']); }); it('loops over KHR_techniques_webgl techniques (gltf 2.0)', function () { @@ -779,11 +926,16 @@ describe('ForEach', function() { }; var count = 0; - ForEach.technique(gltf, function (technique, index) { + var returnValue = ForEach.technique(gltf, function (technique, index) { expect(technique.name).toBe('technique' + index); count++; + + if (count === 2) { + return technique; + } }); expect(count).toBe(2); + expect(returnValue).toBe(gltf.extensions.KHR_techniques_webgl.techniques[1]); gltf = {}; @@ -811,11 +963,16 @@ describe('ForEach', function() { }; var count = 0; - ForEach.technique(gltf, function (technique) { + var returnValue = ForEach.technique(gltf, function (technique) { expect(technique.program).toBeDefined(); count++; + + if (count === 2) { + return technique; + } }); expect(count).toBe(2); + expect(returnValue).toBe(gltf.techniques['technique1']); }); it('loops over technique attributes', function () { @@ -837,13 +994,18 @@ describe('ForEach', function() { }; var count = 0; - ForEach.techniqueAttribute(technique, function (attribute, attributeName) { + var returnValue = ForEach.techniqueAttribute(technique, function (attribute, attributeName) { expect(attribute.semantic).toBeDefined(); expect(attributeName.indexOf('a_')).toBe(0); count++; + + if (count === 3) { + return attribute; + } }); expect(count).toBe(3); + expect(returnValue).toBe(technique.attributes['a_texcoord0']); }); it('loops over legacy technique attributes', function () { @@ -860,12 +1022,17 @@ describe('ForEach', function() { }; var count = 0; - ForEach.techniqueAttribute(technique, function (parameterName, attributeName) { + var returnValue = ForEach.techniqueAttribute(technique, function (parameterName, attributeName) { expect(parameterName).toBe(attributeName.substring(2)); count++; + + if (count === 3) { + return parameterName; + } }); expect(count).toBe(3); + expect(returnValue).toBe(technique.attributes['a_texcoord0']); }); it('loops over technique uniforms', function () { @@ -889,13 +1056,18 @@ describe('ForEach', function() { }; var count = 0; - ForEach.techniqueUniform(technique, function (uniform, uniformName) { + var returnValue = ForEach.techniqueUniform(technique, function (uniform, uniformName) { expect(uniform.type).toBeDefined(); expect(uniformName.indexOf('u_')).toBe(0); count++; + + if (count === 3) { + return uniform; + } }); expect(count).toBe(3); + expect(returnValue).toBe(technique.uniforms['u_normalMatrix']); }); it('loops over legacy technique uniforms', function () { @@ -912,12 +1084,17 @@ describe('ForEach', function() { }; var count = 0; - ForEach.techniqueUniform(technique, function (parameterName, uniformName) { + var returnValue = ForEach.techniqueUniform(technique, function (parameterName, uniformName) { expect(parameterName).toBe(uniformName.substring(2)); count++; + + if (count === 3) { + return parameterName; + } }); expect(count).toBe(3); + expect(returnValue).toBe(technique.uniforms['u_normalMatrix']); }); it('loops over legacy technique parameters', function () { @@ -942,13 +1119,18 @@ describe('ForEach', function() { }; var count = 0; - ForEach.techniqueParameter(technique, function (parameter, parameterName) { + var returnValue = ForEach.techniqueParameter(technique, function (parameter, parameterName) { expect(parameter.type).toBeDefined(); expect(parameterName).toBeDefined(); count++; + + if (count === 3) { + return parameter; + } }); expect(count).toBe(3); + expect(returnValue).toBe(technique.parameters['normal']); }); it('loops over each skin', function() { @@ -962,9 +1144,14 @@ describe('ForEach', function() { } ] }; - ForEach.skin(gltf, function(skin, index) { + var returnValue = ForEach.skin(gltf, function(skin, index) { expect(skin.joints[0]).toBe(index); + + if (index === 1) { + return skin; + } }); + expect(returnValue).toBe(gltf.skins[1]); }); it('loops over each texture', function() { @@ -978,8 +1165,13 @@ describe('ForEach', function() { } ] }; - ForEach.texture(gltf, function(texture, index) { + var returnValue = ForEach.texture(gltf, function(texture, index) { expect(texture.source).toBe(index); + + if (index === 1) { + return texture; + } }); + expect(returnValue).toBe(gltf.textures[1]); }); });