I am unable to load the meshopt compressed file in react native can anyone help me in this. I have tried “MeshoptDecoder” from both “three-stdlib” and “three/examples/jsm/libs/meshopt_decoder.module.js” package but nothing working out, the error says: Error: THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files
Here is my code:
import React, { useRef, useState, useCallback } from "react";
import { GLTFLoader } from "three-stdlib";
import { DRACOLoader } from "three-stdlib";
import { MeshoptDecoder } from "three-stdlib";
import { Graphics_Key } from "@/constants/constants";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { glb_Loading_Time_Metrics } from "@/services/apiServices";
const useMeshLoader = () => {
const [meshes, setMeshes] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [isAssetReplacing, setIsAssetReplacing] = useState(false);
const loader = useRef(new GLTFLoader()).current;
const dracoLoader = useRef(new DRACOLoader()).current;
dracoLoader.setDecoderPath(
"https://www.gstatic.com/draco/versioned/decoders/1.5.7/"
);
loader.setDRACOLoader(dracoLoader);
loader.setMeshoptDecoder(MeshoptDecoder);
const prevAssetObject = useRef({});
const loadQueue = useRef(Promise.resolve());
const LoadMeshes = useCallback(
(assetsObject) => {
const loadEverything = async () => {
if (assetsObject) {
const promiseArray = [];
const keyToLoad = [];
const avatarMetrics = {} as any;
for (let key of Object.keys(assetsObject)) {
if (
assetsObject[key] &&
(!meshes ||
prevAssetObject.current?.[key] !== assetsObject?.[key])
) {
if (key === "avatar") {
const startTime = performance.now();
keyToLoad.push(key);
const { lowPolyGlbUrl, highPolyGlbUrl, name, bodyType } =
assetsObject[key];
const isHighGraphics = await AsyncStorage.getItem(Graphics_Key);
promiseArray.push(
new Promise(async (resolve, reject) => {
console.log(loader, "loader");
loader
.loadAsync(
isHighGraphics ? highPolyGlbUrl : lowPolyGlbUrl
)
.then((result) => {
resolve(result);
const endTime = performance.now();
avatarMetrics.time = (endTime - startTime) / 1000;
avatarMetrics.model_Name = name;
avatarMetrics.bodyType = bodyType;
avatarMetrics.deviceType = "Mobile-App";
avatarMetrics.graphics = isHighGraphics
? "High"
: "Low";
glb_Loading_Time_Metrics(avatarMetrics);
})
.catch((error) => {
console.error(error);
});
})
);
setIsLoading(true);
continue;
}
setIsAssetReplacing(true);
keyToLoad.push(key); // Only the keys which are going to be loaded
const { glbUrl } = assetsObject[key];
promiseArray.push(loader.loadAsync(glbUrl));
}
}
prevAssetObject.current = { ...assetsObject }; // Copy to prevent mutation issues
const results = await Promise.all(promiseArray);
// Accumulate results and update state once to avoid multiple renders
const newMeshes = {};
for (let i = 0; i < results.length; i++) {
newMeshes[keyToLoad[i]] = results[i];
}
setMeshes((prev) => ({
...prev,
...newMeshes,
}));
setIsAssetReplacing(false);
setIsLoading(false);
}
};
loadQueue.current = loadQueue.current
.then(loadEverything)
.catch(console.error);
},
[meshes]
);
return {
LoadMeshes,
meshes,
isLoading,
isAssetReplacing,
};
};
export default useMeshLoader;