Dwinzo_dev/app/src/modules/builder/IntialLoad/loadInitialWallItems.ts

103 lines
3.8 KiB
TypeScript

import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import * as THREE from 'three';
import * as Types from "../../../types/world/worldTypes";
import { getWallItems } from '../../../services/factoryBuilder/assest/wallAsset/getWallItemsApi';
import { retrieveGLTF, storeGLTF } from '../../../utils/indexDB/idbUtils';
async function loadInitialWallItems(
setWallItems: Types.setWallItemSetState,
projectId?: string
): Promise<void> {
try {
const email = localStorage.getItem('email');
if (!email) {
throw new Error('No email found in localStorage');
}
const organization = email.split("@")[1].split(".")[0];
const items = await getWallItems(organization, projectId);
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`;
if (!items || items.length === 0) {
localStorage.removeItem("WallItems");
return;
}
localStorage.setItem("WallItems", JSON.stringify(items));
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/');
loader.setDRACOLoader(dracoLoader);
const loadedWallItems = await Promise.all(items.map(async (item: Types.WallItem) => {
// Check THREE.js cache first
const cachedModel = THREE.Cache.get(item.assetId!);
if (cachedModel) {
return processModel(cachedModel, item);
}
// Check IndexedDB cache
const cachedModelBlob = await retrieveGLTF(item.assetId!);
if (cachedModelBlob) {
const blobUrl = URL.createObjectURL(cachedModelBlob);
return new Promise<Types.WallItem>((resolve) => {
loader.load(blobUrl, (gltf) => {
URL.revokeObjectURL(blobUrl);
THREE.Cache.add(item.assetId!, gltf);
resolve(processModel(gltf, item));
});
});
}
// Load from original URL if not cached
const modelUrl = `${url_Backend_dwinzo}/api/v2/AssetFile/${item.assetId!}`;
return new Promise<Types.WallItem>((resolve) => {
loader.load(modelUrl, async (gltf) => {
try {
// Cache the model
const modelBlob = await fetch(modelUrl).then((res) => res.blob());
await storeGLTF(item.assetId!, modelBlob);
THREE.Cache.add(item.assetId!, gltf);
resolve(processModel(gltf, item));
} catch (error) {
console.error('Failed to cache model:', error);
resolve(processModel(gltf, item));
}
});
});
}));
setWallItems(loadedWallItems);
} catch (error) {
console.error('Failed to load wall items:', error);
}
}
function processModel(gltf: GLTF, item: Types.WallItem): Types.WallItem {
const model = gltf.scene.clone();
model.uuid = item.modelUuid!;
model.children[0]?.children?.forEach((child: THREE.Object3D) => {
if (child.name !== "CSG_REF") {
child.castShadow = true;
child.receiveShadow = true;
}
});
return {
type: item.type,
model: model,
modelName: item.modelName,
assetId: item.assetId,
scale: item.scale,
csgscale: item.csgscale,
csgposition: item.csgposition,
position: item.position,
quaternion: item.quaternion,
};
}
export default loadInitialWallItems;