Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193import { readFileSync } from "node:fs";
import { toByteArray } from "base64-js";import { Loader } from "three";
const loading: { [key: string]: { onLoad?: (response: string | ArrayBuffer) => void; onProgress?: (event: ProgressEvent<EventTarget>) => void; onError?: (err: Error) => void; }[];} = {};
export class FileLoader extends Loader { mimeType!: string; responseType!: string;
async load( urlInput: string, onLoad?: (response: string | ArrayBuffer) => void, onProgress?: (event: ProgressEvent<EventTarget>) => void, onError?: (err: Error) => void, ) { let url = urlInput; if (url === undefined) url = "";
if (this.path !== undefined) url = this.path + url;
url = this.manager.resolveURL(url);
// Check if request is duplicate
if (loading[url] !== undefined) { loading[url].push({ onLoad, onProgress, onError, });
return; }
// Initialise array for duplicate requests loading[url] = [];
loading[url].push({ onLoad, onProgress, onError, });
const mimeType = this.mimeType; const responseType = this.responseType;
let result: string | ArrayBuffer;
try { if (!/^https?:\/\//.test(url) && !url.startsWith("data:")) { const buffer = readFileSync(url); switch (responseType) { case "arraybuffer": { const ab = new ArrayBuffer(buffer.length); const view = new Uint8Array(ab); for (let i = 0; i < buffer.length; i++) { view[i] = buffer[i]; } result = ab; break; }
case "document": { const text = buffer.toString(); const parser = new DOMParser(); // @ts-expect-error result = parser.parseFromString(text, mimeType); break; }
case "json": result = JSON.parse(buffer.toString()); break; default: result = buffer.toString(); break; } } else if (url.startsWith("data:application/octet-stream;base64,")) { const base64 = url.split(";base64,").pop() || ""; const buffer = toByteArray(base64);
result = buffer.buffer as ArrayBuffer; } else { // create request const req = new Request(url, { headers: new Headers(this.requestHeader), credentials: this.withCredentials ? "include" : "same-origin", // An abort controller could be added within a future PR });
// start the fetch result = await fetch(req) .then((response) => { if (response.status === 200 || response.status === 0) { // Some browsers return HTTP Status 0 when using non-http protocol // e.g. 'file://' or 'data://'. Handle as success.
if (response.status === 0) { console.warn("THREE.FileLoader: HTTP Status 0 received."); }
return response; } throw Error( `fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, ); }) .then((response) => { switch (responseType) { case "arraybuffer": return response.arrayBuffer();
case "blob": return response.blob();
case "document": return response.text().then((text) => { const parser = new DOMParser(); // @ts-expect-error return parser.parseFromString(text, mimeType); });
case "json": return response.json();
default: if (mimeType === undefined) { return response.text(); } { // sniff encoding const re = /charset="?([^;"\s]*)"?/i; const exec = re.exec(mimeType); const label = exec?.[1]?.toLowerCase(); const decoder = new TextDecoder(label); return response.arrayBuffer().then((ab) => decoder.decode(ab)); } } }); }
const callbacks = loading[url]; delete loading[url];
for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onLoad) callback.onLoad(result); } } catch (err) { // Abort errors and other errors are handled the same
const callbacks = loading[url];
if (callbacks === undefined) { // When onLoad was called and url was deleted in `loading` this.manager.itemError(url); throw err; }
delete loading[url];
for (let i = 0, il = callbacks.length; i < il; i++) { const callback = callbacks[i]; if (callback.onError) callback.onError(err as Error); }
this.manager.itemError(url); } finally { this.manager.itemEnd(url); }
this.manager.itemStart(url); }
setResponseType(value: string): FileLoader { this.responseType = value; return this; }
setMimeType(value: string): FileLoader { this.mimeType = value; return this; }}