Search code examples
reactjsvitereact-three-fiberreact-three-drei

Loading .obj with React and Three.js


I'm attempting to import a .obj file into react to pass around and show in a viewport. I have created a viewport component that works when using included primitivies. However, I'm not sure how to import an obj. I'm using vite.

import React, { useMemo } from 'react';
import { Canvas, useLoader } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';

const ModelViewer = ({ objModel }) => {
  // Load the OBJ model using the OBJLoader
  const obj = useLoader(OBJLoader, objModel);

  // Calculate the bounding box of the loaded model to center it in the scene
  const center = useMemo(() => {
    if (!obj) return [0, 0, 0];
    const box = new THREE.Box3().setFromObject(obj);
    const centerVector = box.getCenter(new THREE.Vector3());
    return centerVector.toArray();
  }, [obj]);

  return (
    <div style={{ height: '100%', width: '100%' }}>
      <Canvas style={{ height: '100%', width: '100%' }}>
        <ambientLight intensity={0.5} />
        <pointLight position={[10, 10, 10]} />
        {obj && <primitive object={obj} position={center} />}
        <OrbitControls/>
      </Canvas>
    </div>
  );
};

export default ModelViewer;

this is the full component and a simplified representation of implementation in App.jsx

import frame from './assets/230x50.obj'
...
<ModelViewer objModel={frame} />

The error I'm getting is a syntax error stemming from the first line of the obj


Solution

  • I have found the answer; the import [objectName] from [path] syntax expects the file to be a jsx file. Some exceptions have been manually added like the image formats however, because objs are not standard they have not been included. In this case I am using Vite changing the config file resolved this.

    export default defineConfig({
      assetsInclude: ['**/*.stl', '**/*.obj'],
    }) 
    

    https://vitejs.dev/config/shared-options.html#assetsinclude