expo-three
expo-three copied to clipboard
GLTF Loader is not working in mobile version
I tried to load a .glb file using GLTFLoader. It is working in Web version. But the object is not visible in mobile version. I couldn't find any error messages too. I am using following script.
import Expo from "expo";
import React, { Component } from "react";
//import * as THREE from "three";
import { THREE } from "expo-three";
import ExpoTHREE from "expo-three";
import { GLView } from "expo-gl";
import { Renderer } from "expo-three";
//import GLTFLoader from "three-gltf-loader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { Asset } from "expo-asset";
export default class App extends Component {
render() {
return (
<GLView style={{ flex: 1 }} onContextCreate={this._onGLContextCreate} />
);
}
_onGLContextCreate = async (gl) => {
var model;
// 1. Scene
const asset = Asset.fromModule(require("./assets/RSQ8_V4.glb"));
await asset.downloadAsync();
var scene = new THREE.Scene();
// 2. Camera
const camera = new THREE.PerspectiveCamera(
75,
gl.drawingBufferWidth / gl.drawingBufferHeight,
0.1,
1000
);
// 3. Renderer
const renderer = new Renderer({ gl });
renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
var light = new THREE.DirectionalLight(0xffffff, 1.0);
light.position.set(0, 1, 3);
scene.add(light);
const loader = new GLTFLoader();
loader.load(
asset.localUri,
function (gltf) {
model = gltf.scene;
scene.add(model);
},
function (xhr) {},
function (error) {}
);
// const loader = new GLTFLoader();
// loader.load(
// "assets/UC_EXT_Bodypaint_A.glb",
// (gltf) => {
// model = gltf.scene;
// scene.add(model);
// },
// (xhr) => {
// // called while loading is progressing
// console.log(`${(xhr.loaded / xhr.total) * 100}% loaded`);
// },
// (error) => {
// // called when loading has errors
// console.error("An error happened", error);
// }
// );
// Define our shape (Below is a tetrahedron, but can be whatever)
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
//scene.add(cube);
camera.position.z = 5;
camera.position.y = 1.5;
const animate = () => {
requestAnimationFrame(animate);
if (model) {
model.rotation.y += 0.004;
}
renderer.render(scene, camera);
gl.endFrameEXP();
};
animate();
};
}
` ``
Facing the same issue with the useGLTF
hook expose by https://github.com/react-spring/drei ( https://github.com/pmndrs/drei#usegltf )
@hkirat do you know, how to get OrbitControls in mobile application ?
same issue, i see nothing on mobile on android, but loads on web.
I think there is a PR for this https://github.com/expo/expo-three/pull/165 but has gotten stale. @EvanBacon If that looks okay I can file for a new PR with the same diff up to date with main, or bring that branch up to date.
@hkirat @EvanBacon seems like there are multiple issues with gltf, when trying to load via a URL directly, nothing happens. When trying to load via a downloaded asset it returns with the isTrusted: false, error message on failure.
Spent a few hours trying to get a gltf file loading but no luck. I think this will be more important as time goes as as gltf is now the three.js preferred format.
Listed on the threejs website https://threejs.org/docs/#manual/en/introduction/Loading-3D-models it states gltf/glb is the recommended format.
I can help setup some test to showcase the errors that are happening if needed. Not sure what issue the PR resolves specifically.
@hkirat @seand88 , then, do you know how to load other 3d formats like .obj, .fbx models in react native or expo ?
I couldn't load any formats of 3d models. So if it is possible to load some other formats also will be helpful to me @EvanBacon @seand88 @hkirat
@krjk333 i was able to load 3d models with obj format successfully. I think this library is fine for obj but lacks in other support. I need gltf format so i switched to babylon react native, which has first class support for gltf 2.0
Unfortunately I can't use it with expo, but I can still achieve what I was going after atleast.
@seand88 Thank you so much for your comment. How to load 3d models with obj format in expo-three for mobile version. Can you please share the sample code please. I have spent some days for this. But still I couldn't find solution. So if you help me. That will be very good for me.
I was able to load GLTF files on both iOS and WEB. Here is an example repository Note: I had to add base-64 package and update metro.config.js with the correct file format. I am still struggling with running the app on Android
EDIT: I was able to run the loader on all 3 platforms by changing loader path from asset.localUri to asset.uri: https://github.com/miazga/three-expo-gltf-loader/commit/ca541322ec5bf0d08167c9592e22fe0a3433f6ae
Thanks for the example @miazga. I'm also struggling to load any .obj files at the moment, even with older snacks of expo-three.
Thanks to @miazga I am now able to load gltf models. These are the only types of model that worked. The model also needed to have 0 validation errors which I checked using https://sandbox.babylonjs.com/.
i saw the base-64 suggestion above and used the same process to get around an error with the MTLLoader.load returning isTrusted:false as well. I instead did
// import the assets.
const asset_mat = Asset.fromModule(
require('../../assets/3d/model_materials.mtl'),
);
const asset_obj = Asset.fromModule(
require('../../assets/3d/model_object.obj'),
);
// download the material data.
await asset_mat.downloadAsync();
const matLoader = new MTLLoader();
// Rather than using matloader.load which failes, manually load the data.
const fileData = await FileSystem.readAsStringAsync(
asset_mat.localUri,
{
encoding: FileSystem.EncodingType.UTF8,
},
);
console.log('fileData : ', fileData);
// Now parse the data
const mtl = matLoader.parse(fileData, '../../assets/3d/');
mtl.preload();
await asset_obj.downloadAsync();
const loader = new OBJLoader();
loader.setMaterials(mtl);
// Note that we don't have a problem using the OBJLoader.load() method.
loader.load(
asset_obj.uri,
(model) => {
console.log('Obj loaded.');
scene.add(model);
},
(xhr) => {},
(error) => {
console.log('OBJ error', error);
},
);
@emileswain thanks for sharing, so did it show the model on android with material? can you please share the repo on Github?
Whoever struggling with isTrusted: false
issue or FBX, OBJ, GLTF models not loading issue on Android Release APK can have a look here: https://github.com/expo/expo-three/issues/151#issuecomment-904532776
Hopefully it resolves your issues 😉