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

278 Views Asked by At

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

1

There are 1 best solutions below

0
openkmj On BEST ANSWER

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