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
// ---------------------------------------------------------------------