reactjsmaterial-uithree.js.obj3d-model

How to show an OBJ file inside MUI component with three.js?


I am facing an issue while trying to display an OBJ file (or any type of 3d model) in the UI. The thing is the obj is perfectly loading. But how can I show it inside the MUI component?

I am using three.js

Here is the code,

const View3DWound = (props) => {
  const [woundModel, setWoundModel] = useState(null);

  const { id } = useParams();
  const classes = useStyles();

  const loader = new OBJLoader();
  const scene = new Scene();

  useEffect(() => {
    loader.load(
      "./assets/TechnicLEGO_CAR_1.obj",

      // called when resource is loaded
      function (object) {
        setWoundModel(scene.add(object));

        if (woundModel) {
          console.log("woundModel", woundModel);
        }
      },

      // called when loading is in progresses
      function (xhr) {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },

      // called when loading has errors
      function (error) {
        console.log("An error happened");
      }
    );
  }, []);

  console.log(woundModel);

  return (
    <Container className={classes.container}>
      <Typography variant="h4">View 3D Wound of patient {id}</Typography>
      <Box className={classes.canvas}>
        
      </Box>
    </Container>
  );
};

This is the variable woundModel after loading,

enter image description here


Solution

  • To show 3d object with three.js:

    1. Create scene, camera and renderer
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    const renderer = new THREE.WebGLRenderer();
    
    1. Append renderer.domElement inside your MUI component
    canvasRef.current.appendChild( renderer.domElement );
    
    // ...
    
    return (
        <Box className={classes.canvas} ref={canvasRef} />
    );
    
    1. Add the object in the scene(like your code)
    2. Render the scene
    function animate() {
        requestAnimationFrame( animate );
        renderer.render( scene, camera );
    }
    animate();
    

    Another choice is to use React Three Fiber.

    React three fiber is three.js wrapper for React.
    With React three fiber,

    import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
    import { Canvas, useLoader } from '@react-three/fiber'
    
    // ...
    
    const obj = useLoader(OBJLoader, './assets/TechnicLEGO_CAR_1.obj')
    
    // ...
    
    return (
        <Container className={classes.container}>
            <Typography variant="h4">View 3D Wound of patient {id}</Typography>
                <Box className={classes.canvas}>
                    <Canvas>
                        <ambientLight />
                        <primitive object={obj} />
                    </Canvas>
                </Box>
        </Container>
    );