Skip to content

Commit

Permalink
Merge pull request #90 from takahirox/GLBRangeRequestsReuseFullconten…
Browse files Browse the repository at this point in the history
…tBuffer

GLBRangeRequests: Avoid duplicated full content download
  • Loading branch information
takahirox authored Oct 26, 2022
2 parents 416a552 + 6fee333 commit 3824fd7
Showing 1 changed file with 55 additions and 11 deletions.
66 changes: 55 additions & 11 deletions loaders/GLB_range_requests/GLB_range_requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,39 @@ const loadPartially = (fileLoader, url, offset, length) => {
});
};

// Based on the code in FileLoader
// Used if server doesn't support HTTP range requests.
const loadArrayBufferFromResponse = (response, onProgress) => {
const reader = response.body.getReader();
const contentLength = response.headers.get('Content-Length');
const total = contentLength ? parseInt(contentLength) : 0;
const lengthComputable = total !== 0;
let loaded = 0;

// periodically read data into the new stream tracking while download progress
return new Response(
new ReadableStream({
start(controller) {
readData();
function readData() {
reader.read().then(({done, value}) => {
if (done) {
controller.close();
} else {
loaded += value.byteLength;
const event = new ProgressEvent('progress', {lengthComputable, loaded, total});
if (onProgress) onProgress(event);
controller.enqueue(value);
readData();
}
});
}
}
})
).arrayBuffer();
};


// GLB File Format handlers
// Specification: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#glb-file-format-specification

Expand All @@ -34,16 +67,16 @@ export default class GLBRangeRequests {

static load(url, loader, onLoad, onProgress, onError, fileLoader = null) {
const assetUrl = (loader.path || '') + url;
GLBRangeRequests.loadContent(assetUrl, fileLoader).then(content => {
let resourcePath;
if (loader.resourcePath !== '') {
resourcePath = loader.resourcePath;
} else if (loader.path !== '') {
resourcePath = loader.path;
} else {
resourcePath = LoaderUtils.extractUrlBase(assetUrl);
}
let resourcePath;
if (loader.resourcePath !== '') {
resourcePath = loader.resourcePath;
} else if (loader.path !== '') {
resourcePath = loader.path;
} else {
resourcePath = LoaderUtils.extractUrlBase(assetUrl);
}

GLBRangeRequests.loadContent(assetUrl, fileLoader).then(content => {
loader
.register(parser => new GLBRangeRequests(
parser,
Expand All @@ -52,10 +85,21 @@ export default class GLBRangeRequests {
))
.parse(content.jsonContent, resourcePath, onLoad, onError);
}).catch((error) => {
// If server doesn't support range requests.
// Response has full range content.
// Parse with the full range content as fallback.
if (error.response && error.response.status === 200) {
loadArrayBufferFromResponse(error.response, onProgress).then(buffer => {
loader.parse(buffer, resourcePath, onLoad, onError);
}).catch(error => {
if (onError) onError(error);
});
return;
}

// Perhaps rejected due to the either one
// 1. The asset is not GLB (but glTF)
// 2. Server may not support HTTP range requests
// 3. The asset includes EXT_meshopt_compression extension that the
// 2. The asset includes EXT_meshopt_compression extension that the
// this plugin can't handle
// so load in the regular way as fallback.
// @TODO: Check the error reason and don't run the fallback loading
Expand Down

0 comments on commit 3824fd7

Please sign in to comment.