How to clean up A-Frame resources for an "WebAssembly.instantiate(): Out of memory" error?

47 views Asked by At

I'm building a web application with AR and VR experiences using A-Frame and React.js. I have a page that loads an a-scene with its model. After leaving the page, I'm cleaning up the model and entity, as well as removing the camera. When I try to come back to the page, I get a couple of warnings and an error message BEFORE the program even attempts to load the model (that never gets to load): Warning and Error

The aframe-ar comes from the aframe dependencies that allows A-Frame in React.js.

This is my a-scene (there might be variables names in portuguese, sorry):

 <a-scene renderer="antialias: true; logarithmicDepthBuffer: true; colorManagement: false; sortObjects: true;" vr-mode-ui='enabled: false'>
          <a-camera rotation-reader look-controls="touchEnabled: false; mouseEnabled: false;" />
          {modelAligned &&
            <a-entity
              ref={entityRef}
            />}
          {/*isLoading && <div>Loading model...</div>*/}
          {!modelAligned &&
            <div className="alignElements">
              <img className="alignImage" src={sondagem4Img} />
              <button className="alignedBtn" onClick={handleButtonClick}>
                Alinhado
              </button>
            </div>}
          {modelAligned &&
            <div className="alignElements">
              <img className="backgroundImage" src={sondagem4Img} />
            </div>}
 </a-scene>

This is how I load the model to have a hold of its reference:

 useEffect(() => {
    if (modelAligned && !modelLoaded) {
      setIsLoading(true);
      const loader = new GLTFLoader();

      // load the custom 3D model
      loader.load(process.env.PUBLIC_URL + "/models/sondagem4.smaller.glb", (glb) => {
        const model = glb.scene;
        setModel(model);

        if (entityRef.current) {
          entityRef.current.object3D.add(model);
          entityRef.current.setAttribute('position', '-45 -90 -500');
          entityRef.current.setAttribute('scale', '1.3 1.3 1.3');
          entityRef.current.setAttribute('rotation', '0 -50 0');

          setIsLoading(false);
          setModelLoaded(true);
        }
      });
    }
  }, [modelAligned]);

And this is my clean up code, triggered when I use the back button:

const handleCleanup = () => {
    //clean up model
    let entity = entityRef.current;
    if (entity) {
      const object3D = entityRef.current.object3D.children.find(child => child === model);
      if (object3D) {
        // dispose geometry and materials
        object3D.traverse((node) => {
          if (node.isMesh) {
            node.geometry.dispose();
            node.material.dispose();
          }
        });

        // remove the model from the entity
        entity.object3D.remove(object3D);
        setModel(null);
      }
    }
    // clear references
    entity = null;
    entityRef.current = null;

    // clean up camera
    const elementType = 'video';
    const elementsToRemove = document.querySelectorAll(elementType);
    elementsToRemove.forEach(element => {
      if (!element.paused) {
        element.pause();
      }
      element.remove();
    });
  };

I can confirm the model does disappear from the screen, and the camera element stops after, running the clean up method. Since the errorsa appear before loading the model, there is already lack of memory to add the a-scene?

Since the model does load for the first time I enter the page, I was hoping the issue would just be that I'm not cleaning up everything. What am I missing?

0

There are 0 answers