expo-three icon indicating copy to clipboard operation
expo-three copied to clipboard

GLTF Loader is not working in mobile version

Open krjk333 opened this issue 3 years ago • 15 comments

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();
  };
}

` ``

krjk333 avatar Nov 17 '20 12:11 krjk333

Facing the same issue with the useGLTF hook expose by https://github.com/react-spring/drei ( https://github.com/pmndrs/drei#usegltf )

hkirat avatar Nov 27 '20 10:11 hkirat

@hkirat do you know, how to get OrbitControls in mobile application ?

krjk333 avatar Nov 27 '20 12:11 krjk333

same issue, i see nothing on mobile on android, but loads on web.

seand88 avatar Dec 01 '20 22:12 seand88

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 avatar Dec 01 '20 22:12 hkirat

@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.

seand88 avatar Dec 02 '20 15:12 seand88

@hkirat @seand88 , then, do you know how to load other 3d formats like .obj, .fbx models in react native or expo ?

krjk333 avatar Dec 08 '20 03:12 krjk333

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 avatar Dec 08 '20 03:12 krjk333

@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 avatar Dec 08 '20 15:12 seand88

@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.

krjk333 avatar Dec 09 '20 09:12 krjk333

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

miazga avatar Jan 09 '21 17:01 miazga

Thanks for the example @miazga. I'm also struggling to load any .obj files at the moment, even with older snacks of expo-three.

wcandillon avatar Feb 19 '21 15:02 wcandillon

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/.

wcandillon avatar Feb 20 '21 10:02 wcandillon

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 avatar May 26 '21 13:05 emileswain

@emileswain thanks for sharing, so did it show the model on android with material? can you please share the repo on Github?

hopewise avatar Jun 07 '21 04:06 hopewise

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 😉

kyaroru avatar Aug 24 '21 11:08 kyaroru