diff --git a/examples/js/exporters/GLTFExporter.js b/examples/js/exporters/GLTFExporter.js index 7f6f4bbf523ed5b271276d55da268cb6495d9847..9048bcc5bdcfeb518d3ce3d1baebeddac51f4252 100644 --- a/examples/js/exporters/GLTFExporter.js +++ b/examples/js/exporters/GLTFExporter.js @@ -59,7 +59,8 @@ THREE.GLTFExporter.prototype = { var DEFAULT_OPTIONS = { trs: false, - onlyVisible: true + onlyVisible: true, + truncateDrawRange: true }; options = Object.assign( {}, DEFAULT_OPTIONS, options ); @@ -132,7 +133,7 @@ THREE.GLTFExporter.prototype = { * @param {Integer} componentType Component type (Unsigned short, unsigned int or float) * @return {Integer} Index of the buffer created (Currently always 0) */ - function processBuffer ( attribute, componentType ) { + function processBuffer ( attribute, componentType, start, count ) { if ( !outputJSON.buffers ) { @@ -149,13 +150,15 @@ THREE.GLTFExporter.prototype = { } + var offset = 0; + var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4; + // Create a new dataview and dump the attribute's array into it - var dataView = new DataView( new ArrayBuffer( attribute.array.byteLength ) ); + var byteLength = count * attribute.itemSize * componentSize; - var offset = 0; - var offsetInc = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4; + var dataView = new DataView( new ArrayBuffer( byteLength ) ); - for ( var i = 0; i < attribute.count; i++ ) { + for ( var i = start; i < start + count; i++ ) { for (var a = 0; a < attribute.itemSize; a++ ) { @@ -175,7 +178,7 @@ THREE.GLTFExporter.prototype = { } - offset += offsetInc; + offset += componentSize; } @@ -193,7 +196,7 @@ THREE.GLTFExporter.prototype = { * @param {[type]} data [description] * @return {[type]} [description] */ - function processBufferView ( data, componentType ) { + function processBufferView ( data, componentType, start, count ) { var isVertexAttributes = componentType === WEBGL_CONSTANTS.FLOAT; @@ -203,17 +206,22 @@ THREE.GLTFExporter.prototype = { } + var componentSize = componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4; + + // Create a new dataview and dump the attribute's array into it + var byteLength = count * data.itemSize * componentSize; + var gltfBufferView = { - buffer: processBuffer( data, componentType ), + buffer: processBuffer( data, componentType, start, count ), byteOffset: byteOffset, - byteLength: data.array.byteLength, - byteStride: data.itemSize * ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ? 2 : 4 ), + byteLength: byteLength, + byteStride: data.itemSize * componentSize, target: isVertexAttributes ? WEBGL_CONSTANTS.ARRAY_BUFFER : WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER }; - byteOffset += data.array.byteLength; + byteOffset += byteLength; outputJSON.bufferViews.push( gltfBufferView ); @@ -234,7 +242,7 @@ THREE.GLTFExporter.prototype = { * @param {THREE.WebGLAttribute} attribute Attribute to process * @return {Integer} Index of the processed accessor on the "accessors" array */ - function processAccessor ( attribute ) { + function processAccessor ( attribute, geometry ) { if ( !outputJSON.accessors ) { @@ -273,14 +281,24 @@ THREE.GLTFExporter.prototype = { } var minMax = getMinMax( attribute ); - var bufferView = processBufferView( attribute, componentType ); + + var start = 0; + var count = attribute.count; + + // @TODO Indexed buffer geometry with drawRange not supported yet + if ( options.truncateDrawRange && geometry.index === null ) { + start = geometry.drawRange.start; + count = geometry.drawRange.count !== Infinity ? geometry.drawRange.count : attribute.count; + } + + var bufferView = processBufferView( attribute, componentType, start, count ); var gltfAccessor = { bufferView: bufferView.id, byteOffset: bufferView.byteOffset, componentType: componentType, - count: attribute.count, + count: count, max: minMax.max, min: minMax.min, type: types[ attribute.itemSize - 1 ] @@ -559,7 +577,7 @@ THREE.GLTFExporter.prototype = { } else { - if ( !( geometry instanceof THREE.BufferGeometry) ) { + if ( !geometry.isBufferGeometry ) { var geometryTemp = new THREE.BufferGeometry(); geometryTemp.fromGeometry( geometry ); @@ -603,7 +621,7 @@ THREE.GLTFExporter.prototype = { if ( geometry.index ) { - gltfMesh.primitives[ 0 ].indices = processAccessor( geometry.index ); + gltfMesh.primitives[ 0 ].indices = processAccessor( geometry.index, geometry ); } @@ -628,7 +646,7 @@ THREE.GLTFExporter.prototype = { var attribute = geometry.attributes[ attributeName ]; attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase(); - gltfAttributes[ attributeName ] = processAccessor( attribute ); + gltfAttributes[ attributeName ] = processAccessor( attribute, geometry ); } diff --git a/examples/misc_exporter_gltf.html b/examples/misc_exporter_gltf.html index 887b0144fdad3c98bbecc59d0e7c67be5f84b8e6..9abe2a33a88461e5f0436ae1f8d6d5d5edb104d2 100644 --- a/examples/misc_exporter_gltf.html +++ b/examples/misc_exporter_gltf.html @@ -31,6 +31,7 @@
+ @@ -47,6 +48,7 @@ var options = { trs: document.getElementById('option_trs').checked, onlyVisible: document.getElementById('option_visible').checked, + truncateDrawRange: document.getElementById('option_drawrange').checked } gltfExporter.parse( input, function( result ) { @@ -345,6 +347,44 @@ scene1.add( object ); + // --------------------------------------------------------------------- + // Buffer geometry truncated (DrawRange) + // --------------------------------------------------------------------- + var geometry = new THREE.BufferGeometry(); + var numElements = 6; + var outOfRange = 3; + + var positions = new Float32Array( ( numElements + outOfRange ) * 3 ); + var colors = new Float32Array( ( numElements + outOfRange ) * 3 ); + + positions.set([ + 0, 0, 0, + 0, 80, 0, + 80, 0, 0, + 80, 0, 0, + 0, 80, 0, + 80, 80, 0 + ]); + + colors.set([ + 1, 0, 0, + 1, 0, 0, + 1, 1, 0, + 1, 1, 0, + 0, 0, 1, + 0, 0, 1, + ]); + + geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) ); + geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) ); + geometry.setDrawRange( 0, numElements ); + + object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { side: THREE.DoubleSide, vertexColors: THREE.VertexColors } ) ); + object.name = 'Custom buffered truncated'; + object.position.set( 340, -40, -200 ); + + scene1.add( object ); + // --------------------------------------------------------------------- // Points // ---------------------------------------------------------------------