expo-three
Version:
Utilities for using THREE.js with Expo
114 lines (107 loc) • 3.54 kB
text/typescript
import { resolveAsync } from 'expo-asset-utils';
import {
loaderClassForExtension,
loaderClassForUri,
} from './loaderClassForExtension';
import {
loadDaeAsync,
loadObjAsync,
loadMtlAsync,
loadArrayBufferAsync,
} from './loaders/loadModelsAsync';
import './polyfillTextureLoader.fx';
import { loadTextureAsync } from './loaders/loadTextureAsync';
import { ProgressCallback } from './loading.types';
import resolveAsset, { stringFromAsset } from './resolveAsset';
import { matchUrlExtension, matchUrlExtensions } from './utils';
export async function loadBasicModelAsync(options: {
uri: string;
onProgress?: ProgressCallback;
onAssetRequested: any;
loader?: any;
LoaderClass: any;
}) {
const { uri, onProgress, onAssetRequested, loader, LoaderClass } = options;
const _loader = loader || new LoaderClass();
if (_loader.setPath) {
_loader.setPath(onAssetRequested);
}
return new Promise((res, rej) => _loader.load(uri, res, onProgress, rej));
}
export default async function loadAsync(
res,
onProgress?: ProgressCallback,
onAssetRequested: (...args: any[]) => any = function () {}
) {
const urls = await resolveAsset(res);
if (!urls) {
throw new Error(
`ExpoTHREE.loadAsync: Cannot parse undefined assets. Please pass valid resources for: ${res}.`
);
}
const asset = urls[0];
const url: string | null = (await resolveAsync(asset)).localUri;
if (url == null) {
throw new Error(
`ExpoTHREE.loadAsync: this asset couldn't be downloaded. Be sure that your app.json contains the correct extensions.`
);
}
if (urls.length === 1) {
if (matchUrlExtensions(url, ['jpeg', 'jpg', 'gif', 'png'])) {
return loadTextureAsync({ asset });
} else if (matchUrlExtension(url, 'dae')) {
return loadDaeAsync({
asset: url,
onProgress,
onAssetRequested,
});
} else if (matchUrlExtensions(url, ['glb', 'gltf'])) {
const arrayBuffer = await loadArrayBufferAsync({ uri: url, onProgress });
const GLTFLoader = loaderClassForExtension('gltf');
const loader = new GLTFLoader();
return new Promise((res, rej) =>
loader.parse(arrayBuffer, onAssetRequested, res, rej)
);
} else if (matchUrlExtension(url, 'json')) {
throw new Error(
'loadAsync: Please use ExpoTHREE.parseAsync({json}) instead, json can be loaded in lots of different ways.'
);
} else if (matchUrlExtension(url, 'obj')) {
console.log('loading obj');
return loadObjAsync({ asset: url, onAssetRequested });
} else if (matchUrlExtension(url, 'mtl')) {
return loadMtlAsync({ asset: url, onAssetRequested });
} else {
const LoaderClass = loaderClassForUri(url);
return loadBasicModelAsync({
uri: url,
onProgress,
onAssetRequested,
LoaderClass,
});
}
} else if (urls.length === 2) {
const urlB = await stringFromAsset(urls[1]);
if (urlB != null) {
if (matchUrlExtension(url, 'mtl') && matchUrlExtension(urlB, 'obj')) {
return loadObjAsync({
asset: urlB,
mtlAsset: url,
onAssetRequested,
});
} else if (
matchUrlExtension(url, 'obj') &&
matchUrlExtension(urlB, 'mtl')
) {
return loadObjAsync({
asset: url,
mtlAsset: urlB,
onAssetRequested,
});
}
}
throw new Error('Unrecognized File Type: ' + url);
} else {
throw new Error('Too many arguments passed: ' + urls);
}
}