Created
January 18, 2022 00:13
-
-
Save CodyJasonBennett/4878c8011f21d85ebf5e8aa1108cdcf8 to your computer and use it in GitHub Desktop.
react-native polyfill for usage of three.js loaders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as THREE from 'three' | |
import { Asset } from 'expo-asset' | |
/** | |
* Generates an asset based on input type. | |
*/ | |
const getAsset = (input) => { | |
if (input instanceof Asset) return input | |
switch (typeof input) { | |
case 'string': | |
return Asset.fromURI(input) | |
case 'number': | |
return Asset.fromModule(input) | |
default: | |
throw 'Invalid asset! Must be a URI or module.' | |
} | |
} | |
// Don't pre-process urls, let expo-asset generate an absolute URL | |
THREE.LoaderUtils.extractUrlBase = () => './' | |
// There's no Image in native, so create a data texture instead | |
THREE.TextureLoader.prototype.load = function load(url, onLoad, onProgress, onError) { | |
const texture = new THREE.Texture() | |
texture.isDataTexture = true | |
getAsset(url) | |
.downloadAsync() | |
.then((asset) => { | |
texture.image = { | |
data: asset, | |
width: asset.width, | |
height: asset.height, | |
} | |
texture.needsUpdate = true | |
onLoad?.(texture) | |
}) | |
.catch(onError) | |
return texture | |
} | |
// Fetches assets via XMLHttpRequest | |
THREE.FileLoader.prototype.load = function (url, onLoad, onProgress, onError) { | |
if (this.path) url = this.path + url | |
const request = new XMLHttpRequest() | |
getAsset(url) | |
.downloadAsync() | |
.then((asset) => { | |
request.open('GET', asset.uri, true) | |
request.addEventListener( | |
'load', | |
(event) => { | |
if (request.status === 200) { | |
onLoad?.(request.response) | |
this.manager.itemEnd(url) | |
} else { | |
onError?.(event) | |
this.manager.itemError(url) | |
this.manager.itemEnd(url) | |
} | |
}, | |
false, | |
) | |
request.addEventListener( | |
'progress', | |
(event) => { | |
onProgress?.(event) | |
}, | |
false, | |
) | |
request.addEventListener( | |
'error', | |
(event) => { | |
onError?.(event) | |
this.manager.itemError(url) | |
this.manager.itemEnd(url) | |
}, | |
false, | |
) | |
request.addEventListener( | |
'abort', | |
(event) => { | |
onError?.(event) | |
this.manager.itemError(url) | |
this.manager.itemEnd(url) | |
}, | |
false, | |
) | |
if (this.responseType) request.responseType = this.responseType | |
if (this.withCredentials) request.withCredentials = this.withCredentials | |
for (const header in this.requestHeader) { | |
request.setRequestHeader(header, this.requestHeader[header]) | |
} | |
request.send(null) | |
this.manager.itemStart(url) | |
}) | |
return request | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment