-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to render .glb/.gltf files on mobile #273
Comments
I made a little progress on what is causing the issue. I was able to track down where that function, (readAsArrayBuffer), is located and it quite literally isn't implemented, (which makes sense based on the error, lol). So now my attention turns to a new issue, is there any known implementation of this function? I'm honestly not quite sure how to decipher what's happening in the FileReader.js file to make my own, but it seems weird to build the loadAsync() function based on another function which was never implemented in the first place. Regardless, I'm open to any and all suggestions or advice! Thanks! |
@MrMacTaco Hey, I had this issue earlier today and I figured out a way to do it. I created my own custom function to load the gltf/glb model (which now works in my app), but my new problem is that it appears to be valid but doesn't actually render in threejs. Anyways, here was what my loader looked like: import { loadTextureAsync } from 'expo-three';
import { resolveAsync } from 'expo-asset-utils';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { decode } from 'base64-arraybuffer';
import * as FileSystem from "expo-file-system";
async function loadFileAsync({ asset, funcName }) {
if (!asset)
throw new Error(`ExpoTHREE.${funcName}: Cannot parse a null asset`);
return (await resolveAsync(asset)).localUri ?? null;
}
export async function loadGLTFAsync({ asset, onAssetRequested }) {
const uri = await loadFileAsync({
asset,
funcName: 'loadGLTFAsync',
});
if (!uri) return;
const base64 = await FileSystem.readAsStringAsync(uri, {
encoding: FileSystem.EncodingType.Base64,
});
const arrayBuffer = decode(base64);
const loader = new GLTFLoader();
return new Promise((resolve, reject) => {
loader.parse(
arrayBuffer,
onAssetRequested,
result => {
resolve(result);
},
err => {
reject(err);
},
);
});
}
export const loadModel = async function (item) {
const texturesLength = item.textures?.length || 0;
console.info(`[loadModel] -> Textures length: ${texturesLength}`);
const textures = [];
for (let i = 0; i < texturesLength; i++) {
const texture = await loadTextureAsync({
asset: item.textures[i].image,
});
if (item.type === 'glb')
texture.flipY = false;
textures.push({ name: item.textures[i]?.name || '-', map: texture });
}
console.info(`[loadModel] -> Textures done loading`);
const result = await loadGLTFAsync({ asset: item.model });
console.log(result);
let obj = result;
console.info(`[loadModel] -> Model done loading, adding textures now...`);
if (texturesLength > 0) {
if (texturesLength === 1) {
obj.traverse(function (object) {
if (object instanceof THREE.Mesh) {
object.material.map = textures[0]?.map;
}
});
} else {
obj.traverse(function (object) {
if (object instanceof THREE.Mesh) {
const selected = textures?.find(x => x.name === object.name);
object.material.map = selected?.map;
}
});
}
}
console.info(`[loadModel] -> Textures done applied...`);
return obj;
}; Then in my threejs code I called the loadModel method and it seemed to output the details within the gltf file itself so that bit works... I'm now at the point where no errors are thrown but nothing is still rendered for me (it could be my gltf file so I'm trying to download a different one to test). I came across this code somewhere else, I tweaked it slightly for my use-case. For me, this got rid of the error. You were right in the comment above because that function is used by the The reason this works is because it uses the Hopefully this helps :) |
hey there, after a while, I'm facing memory leaks issue in my app, mostly in older iPads. |
I recently started my journey into app development with React-Native and have been using Expo-Three for all my 3D rendering. Thus far, it's proven more than capable of doing everything I've thrown at it, with the one exception of rendering custom 3D models on mobile devices.
When I add() a new pre-loaded 3D model (.glb & .gltf formats) to my scene, in the app's web view, I can see everything loads correctly and the model info is presented as you'd expect. The issue arises when I attempt to run the app on an actual iOS device or virtual Android device and I'm left with this error and nothing more:
[Unhandled promise rejection: Error: FileReader.readAsArrayBuffer is not implemented]
at node_modules\react-native\Libraries\Blob\FileReader.js:null in readAsArrayBuffer
at node_modules\whatwg-fetch\dist\fetch.umd.js:null in readBlobAsArrayBuffer
at node_modules\react-native\node_modules\promise\setimmediate\core.js:null in tryCallOne
at node_modules\react-native\node_modules\promise\setimmediate\core.js:null in setImmediate$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _allocateCallback$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in _callReactNativeMicrotasksPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:null in callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __callReactNativeMicrotasks
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:null in flushedQueue
I've tried every solution I can find, namely #151, yet I can't seem to get past this particular roadblock.
As for my code, I've tried various different methods of loading my models, using the GLTFLoader(), using ExpoTHREE.loadAsync() and even just using the three.js loadAsync(), plus more, and every method gets me as far as this error.
With this error, my mobile app components all load correctly, but there is no model inside my like there is on the web.
Any help or suggestions are greatly appreciated and I'd be happy to provide more information if you think it would be pertinent to solving the issue!
Thank you!
The text was updated successfully, but these errors were encountered: