From 351d5a32f374318ea5212fcd051f91faaa9c5c2b Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Thu, 2 Apr 2026 20:28:07 +0200 Subject: [PATCH] Configure GLTFLoader with DRACOLoader --- src/assets/gltf-model-import.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/assets/gltf-model-import.ts b/src/assets/gltf-model-import.ts index b82242b6..aa819167 100644 --- a/src/assets/gltf-model-import.ts +++ b/src/assets/gltf-model-import.ts @@ -1,4 +1,5 @@ import { Box3, Group, Mesh, type AnimationClip, type Material, type Object3D, type Texture } from "three"; +import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js"; import { GLTFLoader, type GLTF } from "three/examples/jsm/loaders/GLTFLoader.js"; import { clone as cloneSkeleton } from "three/examples/jsm/utils/SkeletonUtils.js"; @@ -28,6 +29,10 @@ interface ImportedModelFileSet { totalByteLength: number; } +const DRACO_DECODER_PATH = "/draco/gltf/"; + +let sharedDracoLoader: DRACOLoader | null = null; + export interface LoadedModelAsset { assetId: string; storageKey: string; @@ -328,10 +333,25 @@ function createModelAssetRecord( } async function loadGltfFromArrayBuffer(arrayBuffer: ArrayBuffer): Promise { - const loader = new GLTFLoader(); + const loader = createConfiguredGltfLoader(); return loader.parseAsync(arrayBuffer, ""); } +function createConfiguredGltfLoader(): GLTFLoader { + const loader = new GLTFLoader(); + loader.setDRACOLoader(getSharedDracoLoader()); + return loader; +} + +function getSharedDracoLoader(): DRACOLoader { + if (sharedDracoLoader === null) { + sharedDracoLoader = new DRACOLoader(); + sharedDracoLoader.setDecoderPath(DRACO_DECODER_PATH); + } + + return sharedDracoLoader; +} + function createDataUrlForStoredFile(file: ProjectAssetStorageFileRecord): string { const byteArray = new Uint8Array(file.bytes); let binary = ""; @@ -623,7 +643,7 @@ async function loadGltfFromImportedModelFileSet(fileSet: ImportedModelFileSet): throw new Error(`Missing external model resource(s): ${missingUris.join(", ")}.`); } - const loader = new GLTFLoader(); + const loader = createConfiguredGltfLoader(); try { return await loader.parseAsync(JSON.stringify(gltfJson), ""); @@ -758,7 +778,7 @@ export async function loadModelAssetFromStorage( throw new Error(`Missing stored external model resource(s): ${missingUris.join(", ")}.`); } - const loader = new GLTFLoader(); + const loader = createConfiguredGltfLoader(); try { const gltf = await loader.parseAsync(JSON.stringify(gltfJson), "");