Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useGLTF with multiple Draco models fails to load in iOS #615

Closed
ffdead opened this issue Nov 4, 2021 · 5 comments · Fixed by #616
Closed

useGLTF with multiple Draco models fails to load in iOS #615

ffdead opened this issue Nov 4, 2021 · 5 comments · Fixed by #616
Labels
bug Something isn't working released

Comments

@ffdead
Copy link
Contributor

ffdead commented Nov 4, 2021

Problem description:

Multiple DRACOLoader instances are known to cause problems on iOS: mrdoob/three.js#22445

The useGLTF hook seems to be creating a new instance every time the hook is used.

Suggested solution:

Could we cache the DRACOLoader instance as a local variable in the hook and check if it's already defined?

@ffdead ffdead added the bug Something isn't working label Nov 4, 2021
@drcmda
Copy link
Member

drcmda commented Nov 4, 2021

a workaround would be

const [a, b, c] = useGLTF(['a.glb', 'b.glb', 'c.glb'])
return (
  <>
    <Model {...a} />
    <Model {...b} />
    <Model {...c} />

function Model({ scene, nodes, materials }) {
  ...

ideally drei would cache meshopt and draco. i believe it's already doing that with meshopt. though it was probably solved in three-stdlib.

@ffdead
Copy link
Contributor Author

ffdead commented Nov 4, 2021

Could we add something like this? It seems to do the trick but I'm not quite sure of the implications.

import { Loader } from "three";
// @ts-ignore
import { GLTFLoader, DRACOLoader, MeshoptDecoder } from "three-stdlib";
import { useLoader } from "@react-three/fiber";


// cached instance
let dracoLoader = null;


function extensions(
  useDraco: boolean | string,
  useMeshopt: boolean,
  extendLoader?: (loader: GLTFLoader) => void
) {
  return (loader: Loader) => {
    if (extendLoader) {
      extendLoader(loader as GLTFLoader);
    }
    if (useDraco) {

      
      // check if instance exists
      if (!dracoLoader) {
        dracoLoader = new DRACOLoader();
      }


      dracoLoader.setDecoderPath(
        typeof useDraco === "string"
          ? useDraco
          : "https://www.gstatic.com/draco/versioned/decoders/1.4.0/"
      );
      (loader as GLTFLoader).setDRACOLoader(dracoLoader);
    }
    if (useMeshopt) {
      (loader as GLTFLoader).setMeshoptDecoder(
        typeof MeshoptDecoder === "function" ? MeshoptDecoder() : MeshoptDecoder
      );
    }
  };
}

@drcmda
Copy link
Member

drcmda commented Nov 4, 2021

yes, that would make sense. you do the honours?

@github-actions
Copy link

github-actions bot commented Nov 8, 2021

🎉 This issue has been resolved in version 7.20.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@hengjiUSTC
Copy link

I am also getting multiple KTX loaders warning when using useKTX2 hook. Should the patten be allied to other loaders as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants