I have a use case in which I am trying to load a GLTF file which is compressed using DRACO-Compression. I am able to run it using plain javascript but I am facing issues integrating the loader with ReactJs.
What I am doing:
The error I am getting - DracoDecoderModule is not defined
In my app, this is how I am importing:
import DRACOLoader from './DRACOLoader'
DRACOLoader.setDecoderPath('./draco/')
It is recommended to use https://www.gstatic.com/draco/v1/decoders/ as the decoder source directory, e.g.:
const draco = new DRACOLoader();
draco.setDecoderConfig({ type: 'js' });
draco.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
See example https://github.com/google/draco/tree/master/javascript/example.
I like the answer from @marrion luaka (and upvoted it) but referencing locally.
Only changed:
dracoLoader.setDecoderPath('https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/'); // use a full url path
To this:
dracoLoader.setDecoderPath( '../node_modules/three/examples/js/libs/draco/gltf/' );
Relative paths won't work. One way to achieve this is by either hosting your draco_wasm_wrapper.js
on like aws or something like that or you could try the following:
npm i -S three // make sure you have the latest threejs package v2 and up
Import your dependencies:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
Create and configue your draco loader:
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/js/libs/draco/'); // use a full url path
Create and configure your gltf loader:
const gltf = new GLTFLoader();
gltf.setDRACOLoader(dracoLoader);
// then you can load your glb file
const glbPath = 'your glb file'
gltf.load(glbPath, function(gltf) {
console.log(gltf)
})
Host the draco folder in cloud then
import DRACOLoader from './DRACOLoader';
DRACOLoader.setDecoderPath(path to hosted draco folder);
worked for me.
if you do like this,
DRACOLoader.setDecoderPath('./draco/')
then react will take it as,
DRACOLoader.setDecoderPath('localhost:3000/draco/');
so it wont work.
None of the above worked directly for me on [email protected] so I used:
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import * as THREE from 'three';
// draco
const draco = new DRACOLoader()
draco.setDecoderPath('../node_modules/three/examples/js/libs/draco/gltf/');
draco.setDecoderConfig({ type: 'js' });
export const dracoLoader = draco;
// gltf
const gltf = new GLTFLoader();
gltf.setDRACOLoader( dracoLoader );
export const gltfLoader = gltf;
BONUS for those who like promises, I've also been making my loaders return promises with the following:
function promisify(loader, onProgress) {
function promiseLoader(url) {
return new Promise((resolve, reject) => {
loader.load(url, resolve, onProgress, reject);
});
}
return {
originalLoader: loader,
load: promiseLoader,
};
}
Example usage:
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
export const fbxLoader = promisify(new FBXLoader());
Then elsewhere:
import { fbxLoader } from './loaders'
fbxLoader.load('cat.fbx').then(model => {
console.log(model)
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With