123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import Check from "../Core/Check.js";
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import hasExtension from "./hasExtension.js";
- import { MeshoptDecoder } from "meshoptimizer";
- import ResourceLoader from "./ResourceLoader.js";
- import ResourceLoaderState from "./ResourceLoaderState.js";
- /**
- * Loads a glTF buffer view.
- * <p>
- * Implements the {@link ResourceLoader} interface.
- * </p>
- *
- * @alias GltfBufferViewLoader
- * @constructor
- * @augments ResourceLoader
- *
- * @param {object} options Object with the following properties:
- * @param {ResourceCache} options.resourceCache The {@link ResourceCache} (to avoid circular dependencies).
- * @param {object} options.gltf The glTF JSON.
- * @param {number} options.bufferViewId The buffer view ID.
- * @param {Resource} options.gltfResource The {@link Resource} containing the glTF.
- * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to.
- * @param {string} [options.cacheKey] The cache key of the resource.
- *
- * @private
- */
- function GltfBufferViewLoader(options) {
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- const resourceCache = options.resourceCache;
- const gltf = options.gltf;
- const bufferViewId = options.bufferViewId;
- const gltfResource = options.gltfResource;
- const baseResource = options.baseResource;
- const cacheKey = options.cacheKey;
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.func("options.resourceCache", resourceCache);
- Check.typeOf.object("options.gltf", gltf);
- Check.typeOf.number("options.bufferViewId", bufferViewId);
- Check.typeOf.object("options.gltfResource", gltfResource);
- Check.typeOf.object("options.baseResource", baseResource);
- //>>includeEnd('debug');
- const bufferView = gltf.bufferViews[bufferViewId];
- let bufferId = bufferView.buffer;
- let byteOffset = bufferView.byteOffset;
- let byteLength = bufferView.byteLength;
- let hasMeshopt = false;
- let meshoptByteStride;
- let meshoptCount;
- let meshoptMode;
- let meshoptFilter;
- if (hasExtension(bufferView, "EXT_meshopt_compression")) {
- const meshopt = bufferView.extensions.EXT_meshopt_compression;
- bufferId = meshopt.buffer;
- byteOffset = defaultValue(meshopt.byteOffset, 0);
- byteLength = meshopt.byteLength;
- hasMeshopt = true;
- meshoptByteStride = meshopt.byteStride;
- meshoptCount = meshopt.count;
- meshoptMode = meshopt.mode;
- meshoptFilter = defaultValue(meshopt.filter, "NONE");
- }
- const buffer = gltf.buffers[bufferId];
- this._hasMeshopt = hasMeshopt;
- this._meshoptByteStride = meshoptByteStride;
- this._meshoptCount = meshoptCount;
- this._meshoptMode = meshoptMode;
- this._meshoptFilter = meshoptFilter;
- this._resourceCache = resourceCache;
- this._gltfResource = gltfResource;
- this._baseResource = baseResource;
- this._buffer = buffer;
- this._bufferId = bufferId;
- this._byteOffset = byteOffset;
- this._byteLength = byteLength;
- this._cacheKey = cacheKey;
- this._bufferLoader = undefined;
- this._typedArray = undefined;
- this._state = ResourceLoaderState.UNLOADED;
- this._promise = undefined;
- }
- if (defined(Object.create)) {
- GltfBufferViewLoader.prototype = Object.create(ResourceLoader.prototype);
- GltfBufferViewLoader.prototype.constructor = GltfBufferViewLoader;
- }
- Object.defineProperties(GltfBufferViewLoader.prototype, {
- /**
- * The cache key of the resource.
- *
- * @memberof GltfBufferViewLoader.prototype
- *
- * @type {string}
- * @readonly
- * @private
- */
- cacheKey: {
- get: function () {
- return this._cacheKey;
- },
- },
- /**
- * The typed array containing buffer view data.
- *
- * @memberof GltfBufferViewLoader.prototype
- *
- * @type {Uint8Array}
- * @readonly
- * @private
- */
- typedArray: {
- get: function () {
- return this._typedArray;
- },
- },
- });
- async function loadResources(loader) {
- try {
- const bufferLoader = getBufferLoader(loader);
- loader._bufferLoader = bufferLoader;
- await bufferLoader.load();
- if (loader.isDestroyed()) {
- return;
- }
- const bufferTypedArray = bufferLoader.typedArray;
- const bufferViewTypedArray = new Uint8Array(
- bufferTypedArray.buffer,
- bufferTypedArray.byteOffset + loader._byteOffset,
- loader._byteLength
- );
- // Unload the buffer
- loader.unload();
- loader._typedArray = bufferViewTypedArray;
- if (loader._hasMeshopt) {
- const count = loader._meshoptCount;
- const byteStride = loader._meshoptByteStride;
- const result = new Uint8Array(count * byteStride);
- MeshoptDecoder.decodeGltfBuffer(
- result,
- count,
- byteStride,
- loader._typedArray,
- loader._meshoptMode,
- loader._meshoptFilter
- );
- loader._typedArray = result;
- }
- loader._state = ResourceLoaderState.READY;
- return loader;
- } catch (error) {
- if (loader.isDestroyed()) {
- return;
- }
- loader.unload();
- loader._state = ResourceLoaderState.FAILED;
- const errorMessage = "Failed to load buffer view";
- throw loader.getError(errorMessage, error);
- }
- }
- /**
- * Loads the resource.
- * @returns {Promise<GltfBufferViewLoader>} A promise which resolves to the loader when the resource loading is completed.
- * @private
- */
- GltfBufferViewLoader.prototype.load = async function () {
- if (defined(this._promise)) {
- return this._promise;
- }
- this._state = ResourceLoaderState.LOADING;
- this._promise = loadResources(this);
- return this._promise;
- };
- function getBufferLoader(bufferViewLoader) {
- const resourceCache = bufferViewLoader._resourceCache;
- const buffer = bufferViewLoader._buffer;
- if (defined(buffer.uri)) {
- const baseResource = bufferViewLoader._baseResource;
- const resource = baseResource.getDerivedResource({
- url: buffer.uri,
- });
- return resourceCache.getExternalBufferLoader({
- resource: resource,
- });
- }
- return resourceCache.getEmbeddedBufferLoader({
- parentResource: bufferViewLoader._gltfResource,
- bufferId: bufferViewLoader._bufferId,
- });
- }
- /**
- * Unloads the resource.
- * @private
- */
- GltfBufferViewLoader.prototype.unload = function () {
- if (defined(this._bufferLoader) && !this._bufferLoader.isDestroyed()) {
- this._resourceCache.unload(this._bufferLoader);
- }
- this._bufferLoader = undefined;
- this._typedArray = undefined;
- };
- export default GltfBufferViewLoader;
|