Unable to load .obj file using require

I am trying to load an .obj file using require() but it keeps saying that it can not find the file.

As per instruction on expo-three I have added the extra file extensions to app.js.

I created a very simple project using $ expo init and choosing the empty project template.

The metro bundler seems to ignore packagerOpts as they are not being shown in the console output (see below). I’m not sure if I have it in the right place.

Error: Unable to resolve "./assets/simple.obj" from "App.js"

Any ideas greatly appreciated.

app.json

{
  "expo": {
    "name": "expoar",
    "description": "This project is really great.",
    "slug": "expoar",
    "privacy": "unlisted",
    "sdkVersion": "31.0.0",
    "platforms": ["ios", "android"],
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png", 
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": true
    },
    "packagerOpts": {
      "assetExts": [
        "dae",
        "obj",
        "mtl",
        "png",
        "jpg"
      ]
    }
  }
}

App.js (Mostly copy paste from expo documentation example)

import React from 'react';
import { AR, Asset } from 'expo';
// Let's alias ExpoTHREE.AR as ThreeAR so it doesn't collide with Expo.AR.
import ExpoTHREE, { AR as ThreeAR, THREE } from 'expo-three';
// Let's also import `expo-graphics`
// expo-graphics manages the setup/teardown of the gl context/ar session, creates a frame-loop, and observes size/orientation changes.
// it also provides debug information with `isArCameraStateEnabled`
import { View as GraphicsView } from 'expo-graphics';

export default class App extends React.Component {
  componentDidMount() {
    // Turn off extra warnings
    THREE.suppressExpoWarnings(true)
    ThreeAR.suppressWarnings()
  }
  
  render() {
    // You need to add the `isArEnabled` & `arTrackingConfiguration` props.
    // `isArRunningStateEnabled` Will show us the play/pause button in the corner.
    // `isArCameraStateEnabled` Will render the camera tracking information on the screen.
    // `arTrackingConfiguration` denotes which camera the AR Session will use. 
    // World for rear, Face for front (iPhone X only)
    return (
      <GraphicsView
        style={{ flex: 1 }}
        onContextCreate={this.onContextCreate}
        onRender={this.onRender}
        onResize={this.onResize}
        isArEnabled
        isArRunningStateEnabled
        isArCameraStateEnabled
        arTrackingConfiguration={AR.TrackingConfiguration.World}
      />
    );
  }

  // When our context is built we can start coding 3D things.
  onContextCreate = async ({ gl, scale: pixelRatio, width, height }) => {
    // This will allow ARKit to collect Horizontal surfaces
    AR.setPlaneDetection(AR.PlaneDetection.Horizontal);

    // Create a 3D renderer
    this.renderer = new ExpoTHREE.Renderer({
      gl,
      pixelRatio,
      width,
      height,
    });

    this.scene = new THREE.Scene();
    this.scene.background = new ThreeAR.BackgroundTexture(this.renderer);
    this.camera = new ThreeAR.Camera(width, height, 0.01, 1000);
    

    const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);

    const material = new THREE.MeshPhongMaterial({
      color: 0xff00ff,
    });

    
    const mesh = await ExpoTHREE.loadAsync([
      require('./assets/simple.obj')
    ]);
    


    this.cube = new THREE.Mesh(geometry, material);
    this.cube.position.z = -0.5
    this.scene.add(this.cube);
    
    this.scene.add(new THREE.AmbientLight(0xffffff));

    this.points = new ThreeAR.Points();
    this.scene.add(this.points)
  };

  // When the phone rotates, or the view changes size, this method will be called.
  onResize = ({ x, y, scale, width, height }) => {
    // Let's stop the function if we haven't setup our scene yet
    if (!this.renderer) {
      return;
    }
    this.camera.aspect = width / height;
    this.camera.updateProjectionMatrix();
    this.renderer.setPixelRatio(scale);
    this.renderer.setSize(width, height);
  };

  // Called every frame.
  onRender = () => {
    this.points.update()
    this.renderer.render(this.scene, this.camera);
  };
}

Console output when running expo start
Missing the assetExts from app.json file…

[10:09:34] Running application "main" with appParams: {"rootTag":1,"initialProps":{"exp":{"manifest":{"description":"This project is really great.","developer":{"projectRoot":"/Users/lucas/apps/expoar","tool":"expo-cli"},"loadedFromCache":false,"orientation":"portrait","env":{},"platforms":["ios","android"],"xde":true,"id":"..","hostUri":"127.0.0.1:19000","iconUrl":"http://127.0.0.1:19001/assets/./assets/icon.png","assetBundlePatterns":["**/*"],"mainModuleName":"node_modules/expo/AppEntry","sdkVersion":"31.0.0","isVerified":true,"packagerOpts":{"lanType":"ip","dev":true,"minify":false,"urlRandomness":"..","hostType":"lan"},"ios":{"supportsTablet":true},"updates":{"fallbackToCacheTimeout":0},"bundleUrl":"http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false&assetPlugin=%2FUsers%2Flucas%2Fapps%2Fexpoar%2Fnode_modules%2Fexpo%2Ftools%2FhashAssetFiles","version":"1.0.0","debuggerHost":"127.0.0.1:19001","icon":"./assets/icon.png","slug":"expoar","name":"expoar","privacy":"unlisted","logUrl":"http://127.0.0.1:19000/logs","splash":{"resizeMode":"contain","image":"./assets/splash.png","backgroundColor":"#ffffff","imageUrl":"http://127.0.0.1:19001/assets/./assets/splash.png"}},"initialUri":"exp://127.0.0.1:19000","appOwnership":"expo","shell":0}}}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF

Error Screen

File System

.expo/
assets/
    |-icon.png
    |-simple.obj
    |-splash.png    
node_modules/
    ...
.gitignore
.watchmanconfig
App-test.js
App.js
app.json
babel.config.js
package.json
yarn.lock

For anyone else encountering this issue there’s a bug in react native cli which ignores assetExts passed through via cli parameters.

Looks like there’s a PR that has been approved so this should get fixed soon.

2 Likes

Glad you got to the bottom of it, @lucas-tm. Thanks for sharing the solution with the community as well!

Cheers,

Adam

had the same issue, creating a metro.config.js file with your assetExts fix the problem

module.exports = {
  resolver: {
    assetExts: ["db", "mp3", "ttf"]
  }
}
5 Likes

@michaldatberg that fixed it, thank you SO MUCH!

Not work with me

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.