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

setMeshoptDecoder must be called before loading compressed files #13

Open
fax1ty opened this issue May 7, 2024 · 6 comments
Open

setMeshoptDecoder must be called before loading compressed files #13

fax1ty opened this issue May 7, 2024 · 6 comments

Comments

@fax1ty
Copy link

fax1ty commented May 7, 2024

import {
  DRACOLoader,
  GLTFLoader,
  loadGltf as loadAsync,
} from "node-three-gltf";
import { MeshoptDecoder } from "three-stdlib";

export const loadGltf = async (url: string) => {
  const gltf = new GLTFLoader();
  const draco = new DRACOLoader();
  gltf.setDRACOLoader(draco);
  gltf.setMeshoptDecoder(MeshoptDecoder);

  return await loadAsync(url);
};

results in

Error: THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files

How can I load compressed gltfs?

@Brakebein
Copy link
Owner

I found out that the MeshoptDecoder from three-stdlib is exported differently than from three/examples/libs. three-stdlib returns a function, and three/examples/libs returns this function already executed.

So you might need to try:

gltf.setMeshoptDecoder(MeshoptDecoder());

https://github.com/mrdoob/three.js/blob/master/examples/jsm/libs/meshopt_decoder.module.js
https://github.com/pmndrs/three-stdlib/blob/main/src/libs/MeshoptDecoder.ts

@fax1ty
Copy link
Author

fax1ty commented May 7, 2024

@Brakebein Nope( Same error

player.glb
player-draco.glb
player-meshopt.glb

@Brakebein
Copy link
Owner

Now, I see the problem: you are using this small utility function loadGtlf. However, this doesn't set the MeshoptDecoder. You need to use the load method of the GLTFLoader you've already instantiated. So, instead of return await loadAsync(url); you need to call return await gltf.loadAsync(url); (and omit the import loadGltf as loadAsync).

That's how it worked for me:

import { GLTFLoader } from 'node-three-gltf';
import { MeshoptDecoder } from 'three-stdlib';

const loader = new GLTFLoader();
loader.setMeshoptDecoder(MeshoptDecoder());
loader.load('player-meshopt.glb', (gltf) => {
  console.log(gltf);
}, null, (err) => {
  console.error(err);
});

@fax1ty
Copy link
Author

fax1ty commented May 7, 2024

import { DRACOLoader, GLTFLoader } from "node-three-gltf";
import { type GLTF, MeshoptDecoder } from "three-stdlib";

export const loadGltf = async (url: string) => {
  const loader = new GLTFLoader();
  const draco = new DRACOLoader();
  const meshopt = MeshoptDecoder();
  loader.setDRACOLoader(draco);
  loader.setMeshoptDecoder(meshopt);

  const gltf = await loader.loadAsync(url);

  return gltf as GLTF;
};

Worked as well. Big thanks, @Brakebein

@fax1ty
Copy link
Author

fax1ty commented May 7, 2024

It may be worth nothing that node-three-gltf/loadGltf does not support meshopt out of the box
You may specify this in the Readme file

@Brakebein
Copy link
Owner

Well, the readme states that it instantiates GLTFLoader and DRACOLoader, but doesn't mention anything else.

// there is also a small utility function that instantiates GLTFLoader and DRACOLoader

Fact is that I only worked with draco-compressed gltf files so far, I haven't done yet anything with the MeshoptDecoder. So maybe, I will update the readme in this regard next time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants