Skip to content

Commit d7736be

Browse files
committed
fix: fallback to full download on HTTP range request failure
1 parent fbcc6f6 commit d7736be

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/model/modelLoader.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import '@babylonjs/core/Materials/Textures/Loaders/basisTextureLoader';
1818
import '@babylonjs/core/Materials/Textures/Loaders/ktxTextureLoader';
1919
import '@babylonjs/loaders/glTF';
20+
import { AssetContainer } from '@babylonjs/core/assetContainer';
2021
import { LoadAssetContainerAsync, LoadAssetContainerOptions } from '@babylonjs/core/Loading/sceneLoader';
2122
import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
2223
import { IDisposable } from '@babylonjs/core/scene';
@@ -121,7 +122,18 @@ export class ModelLoader implements IDisposable {
121122
this._sceneManager.scene.getEngine().displayLoadingUI();
122123
}
123124

124-
const container = await LoadAssetContainerAsync(url, this._sceneManager.scene, loadAssetContainerOptions);
125+
let container: AssetContainer;
126+
try {
127+
container = await LoadAssetContainerAsync(url, this._sceneManager.scene, loadAssetContainerOptions);
128+
} catch (error) {
129+
// Fallback to full download on range request failure
130+
if (error instanceof Error && error.message.includes('RangeError')) {
131+
loadAssetContainerOptions.pluginOptions!.gltf!.useRangeRequests = false;
132+
container = await LoadAssetContainerAsync(url, this._sceneManager.scene, loadAssetContainerOptions);
133+
} else {
134+
throw error;
135+
}
136+
}
125137

126138
// Add everything from the container into the scene
127139
container.addAllToScene();

test/model/modelLoader.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ describe('ModelLoader', () => {
4646
});
4747

4848
afterEach(() => {
49+
nock.cleanAll();
4950
modelLoader?.dispose();
5051
sceneManager?.dispose();
5152
observableManager?.dispose();
@@ -89,6 +90,22 @@ describe('ModelLoader', () => {
8990
await modelLoader?.loadGltf('http://localhost/public/model/mannequin.glb', true);
9091

9192
expect(sceneManager?.models.size).toBe(1);
92-
nock.restore();
93+
});
94+
95+
it('should be able to load glb asset with full download when HTTP range requests failed', async () => {
96+
const data = fs.readFileSync('public/model/mannequin.glb');
97+
nock('http://localhost')
98+
.get('/public/model/mannequin.glb')
99+
.matchHeader('range', 'bytes=0-19')
100+
.reply(206, Buffer.from(''), {
101+
'content-Range': 'bytes 0-19/760664',
102+
'content-length': '20',
103+
})
104+
.get('/public/model/mannequin.glb')
105+
.reply(200, data);
106+
107+
await modelLoader?.loadGltf('http://localhost/public/model/mannequin.glb', true);
108+
109+
expect(sceneManager?.models.size).toBe(1);
93110
});
94111
});

0 commit comments

Comments
 (0)