-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #167 from AnalyticalGraphicsInc/uint32-indices
Added utility for changing accessor componentType
- Loading branch information
Showing
3 changed files
with
247 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
'use strict'; | ||
var Cesium = require('cesium'); | ||
|
||
var AccessorReader = require('./AccessorReader'); | ||
var byteLengthForComponentType = require('./byteLengthForComponentType'); | ||
var getUniqueId = require('./getUniqueId'); | ||
var numberOfComponentsForType = require('./numberOfComponentsForType'); | ||
var writeBufferComponent = require('./writeBufferComponent'); | ||
|
||
var defined = Cesium.defined; | ||
|
||
module.exports = changeAccessorComponentType; | ||
|
||
/** | ||
* Changes the component type of a specified accessor. | ||
* If the new component type is smaller than the old one, it will be written in place on the buffer. | ||
* If it is larger, a new buffer will be created and written. | ||
* | ||
* The data is copied as-is, so it must be within the bounds of the target data type. | ||
* | ||
* The glTF asset must be initialized for the pipeline. | ||
* | ||
* @param {Object} gltf A javascript object containing a glTF asset. | ||
* @param {Object} accessor A glTF accessor to be changed. | ||
* @param {Integer} newComponentType The componentType to change to from WebGLConstants. | ||
* @returns {Object} The glTF with the accessor's componentType changed. | ||
* | ||
* @see addPipelineExtras | ||
* @see loadGltfUris | ||
*/ | ||
function changeAccessorComponentType(gltf, accessor, newComponentType) { | ||
var componentType = accessor.componentType; | ||
if (componentType !== newComponentType) { | ||
var bufferViews = gltf.bufferViews; | ||
var buffers = gltf.buffers; | ||
var bufferViewId = accessor.bufferView; | ||
var bufferView = bufferViews[bufferViewId]; | ||
var bufferId = bufferView.buffer; | ||
var buffer = buffers[bufferId]; | ||
var componentByteLength = byteLengthForComponentType(componentType); | ||
var newComponentByteLength = byteLengthForComponentType(newComponentType); | ||
var numberOfComponents = numberOfComponentsForType(accessor.type); | ||
var writeBuffer; | ||
if (newComponentByteLength > componentByteLength) { | ||
writeBuffer = new Buffer(accessor.count * numberOfComponents * newComponentByteLength); | ||
} | ||
var accessorReader = new AccessorReader(gltf, accessor); | ||
var components = []; | ||
while (accessorReader.hasNext()) { | ||
accessorReader.read(components); | ||
if (defined(writeBuffer)) { | ||
for (var i = 0; i < numberOfComponents; i++) { | ||
writeBufferComponent(writeBuffer, newComponentType, components[i], accessorReader.index * newComponentByteLength * numberOfComponents + i * newComponentByteLength); | ||
} | ||
} else { | ||
accessorReader.write(components, newComponentType); | ||
} | ||
accessorReader.next(); | ||
} | ||
accessor.componentType = newComponentType; | ||
|
||
if (defined(writeBuffer)) { | ||
var newBufferViewId = getUniqueId(gltf, 'bufferView'); | ||
var newBufferId = getUniqueId(gltf, 'buffer'); | ||
accessor.bufferView = newBufferViewId; | ||
accessor.byteOffset = 0; | ||
accessor.byteStride = 0; | ||
bufferViews[newBufferViewId] = { | ||
buffer: newBufferId, | ||
byteLength: writeBuffer.length, | ||
byteOffset: 0, | ||
target: bufferView.target, | ||
extras: { | ||
_pipeline: {} | ||
} | ||
}; | ||
buffers[newBufferId] = { | ||
byteLength: writeBuffer.length, | ||
type: buffer.type, | ||
extras: { | ||
_pipeline: { | ||
source: writeBuffer | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
return gltf; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
'use strict'; | ||
var Cesium = require('cesium'); | ||
var AccessorReader = require('../../lib/AccessorReader'); | ||
var changeAccessorComponentType = require('../../lib/changeAccessorComponentType'); | ||
|
||
var WebGLConstants = Cesium.WebGLConstants; | ||
|
||
describe('changeAccessorComponentType', function() { | ||
it('does nothing if the accessor is already the target componentType', function() { | ||
var gltf = { | ||
accessors : { | ||
accessor : { | ||
componentType: WebGLConstants.FLOAT | ||
} | ||
} | ||
}; | ||
var accessor = gltf.accessors.accessor; | ||
changeAccessorComponentType(gltf, accessor, WebGLConstants.FLOAT); | ||
expect(accessor.componentType).toBe(WebGLConstants.FLOAT); | ||
}); | ||
|
||
it('overwrites the existing data if the target component type is smaller', function() { | ||
var data = new Uint16Array([0, 1, 2, 3, 4, 5]); | ||
var dataBuffer = new Buffer(data.buffer); | ||
var gltf = { | ||
accessors : { | ||
accessor : { | ||
bufferView : 'bufferView', | ||
byteOffset : 0, | ||
byteStride : 0, | ||
componentType : WebGLConstants.UNSIGNED_SHORT, | ||
count : data.length, | ||
type : "SCALAR" | ||
} | ||
}, | ||
bufferViews : { | ||
bufferView : { | ||
buffer : 'buffer', | ||
byteLength : dataBuffer.length, | ||
byteOffset : 0 | ||
} | ||
}, | ||
buffers : { | ||
buffer : { | ||
byteLength: dataBuffer.length, | ||
extras: { | ||
_pipeline: { | ||
source: dataBuffer | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var accessor = gltf.accessors.accessor; | ||
changeAccessorComponentType(gltf, accessor, WebGLConstants.UNSIGNED_BYTE); | ||
expect(accessor.componentType).toBe(WebGLConstants.UNSIGNED_BYTE); | ||
expect(Object.keys(gltf.buffers).length).toBe(1); | ||
var accessorReader = new AccessorReader(gltf, accessor); | ||
var components = []; | ||
while (accessorReader.hasNext()) { | ||
accessorReader.read(components); | ||
expect(components[0]).toBe(accessorReader.index); | ||
accessorReader.next(); | ||
} | ||
}); | ||
|
||
it('overwrites the existing data if the target component type is the same size', function() { | ||
var data = new Float32Array([0, 1, 2, 3, 4, 5]); | ||
var dataBuffer = new Buffer(data.buffer); | ||
var gltf = { | ||
accessors : { | ||
accessor : { | ||
bufferView : 'bufferView', | ||
byteOffset : 0, | ||
byteStride : 0, | ||
componentType : WebGLConstants.FLOAT, | ||
count : data.length, | ||
type : "SCALAR" | ||
} | ||
}, | ||
bufferViews : { | ||
bufferView : { | ||
buffer : 'buffer', | ||
byteLength : dataBuffer.length, | ||
byteOffset : 0 | ||
} | ||
}, | ||
buffers : { | ||
buffer : { | ||
byteLength: dataBuffer.length, | ||
extras: { | ||
_pipeline: { | ||
source: dataBuffer | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var accessor = gltf.accessors.accessor; | ||
changeAccessorComponentType(gltf, accessor, WebGLConstants.UNSIGNED_INT); | ||
expect(accessor.componentType).toBe(WebGLConstants.UNSIGNED_INT); | ||
expect(Object.keys(gltf.buffers).length).toBe(1); | ||
var accessorReader = new AccessorReader(gltf, accessor); | ||
var components = []; | ||
while (accessorReader.hasNext()) { | ||
accessorReader.read(components); | ||
expect(components[0]).toBe(accessorReader.index); | ||
accessorReader.next(); | ||
} | ||
}); | ||
|
||
it('creates a new buffer if the target component type is larger', function() { | ||
var data = new Uint16Array([0, 1, 2, 3, 4, 5]); | ||
var dataBuffer = new Buffer(data.buffer); | ||
var gltf = { | ||
accessors : { | ||
accessor : { | ||
bufferView : 'bufferView', | ||
byteOffset : 0, | ||
byteStride : 0, | ||
componentType : WebGLConstants.UNSIGNED_SHORT, | ||
count : data.length, | ||
type : "SCALAR" | ||
} | ||
}, | ||
bufferViews : { | ||
bufferView : { | ||
buffer : 'buffer', | ||
byteLength : dataBuffer.length, | ||
byteOffset : 0 | ||
} | ||
}, | ||
buffers : { | ||
buffer : { | ||
byteLength: dataBuffer.length, | ||
extras: { | ||
_pipeline: { | ||
source: dataBuffer | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
var accessor = gltf.accessors.accessor; | ||
changeAccessorComponentType(gltf, accessor, WebGLConstants.UNSIGNED_INT); | ||
expect(accessor.componentType).toBe(WebGLConstants.UNSIGNED_INT); | ||
expect(Object.keys(gltf.buffers).length).toBe(2); | ||
var accessorReader = new AccessorReader(gltf, accessor); | ||
var components = []; | ||
while (accessorReader.hasNext()) { | ||
accessorReader.read(components); | ||
expect(components[0]).toBe(accessorReader.index); | ||
accessorReader.next(); | ||
} | ||
}); | ||
}); |