added cache and indexdb loading for decal

This commit is contained in:
2025-08-26 17:39:45 +05:30
parent d4f12d230f
commit d129a86885
2 changed files with 103 additions and 6 deletions

View File

@@ -1,13 +1,14 @@
import * as THREE from 'three';
import { CameraControls, Decal } from '@react-three/drei'
import { useLoader, useThree } from '@react-three/fiber';
import { useThree } from '@react-three/fiber';
import { useSocketStore, useToggleView, useToolMode } from '../../../../store/builder/store';
import { useBuilderStore } from '../../../../store/builder/useBuilderStore';
import { retrieveImage, storeImage } from '../../../../utils/indexDB/idbUtils';
import defaultMaterial from '../../../../assets/textures/floor/wall-tex.png';
import useModuleStore from '../../../../store/useModuleStore';
import { useSceneContext } from '../../../scene/sceneContext';
import { useEffect, useRef } from 'react';
import { useEffect, useRef, useState } from 'react';
import { getUserData } from '../../../../functions/getUserData';
import { useVersionContext } from '../../version/versionContext';
import { useParams } from 'react-router-dom';
@@ -28,12 +29,108 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP
const { selectedVersion } = selectedVersionStore();
const { projectId } = useParams();
const { socket } = useSocketStore();
const material = useLoader(THREE.TextureLoader, defaultMaterial);
const { raycaster, pointer, camera, scene, gl, controls } = useThree();
const isDraggingRef = useRef(false);
const dragOffsetRef = useRef<THREE.Vector3 | null>(null);
const [texture, setTexture] = useState<THREE.Texture | null>(null);
const [isLoading, setIsLoading] = useState(true);
const loadDefaultTexture = () => {
const textureLoader = new THREE.TextureLoader();
textureLoader.load(
defaultMaterial,
(fallbackTex) => {
fallbackTex.name = "default-decal";
setTexture(fallbackTex);
setIsLoading(false);
},
undefined,
(error) => {
console.error("Error loading default decal texture:", error);
setIsLoading(false);
}
);
};
const loadDecalTexture = async (decalId: string) => {
setIsLoading(true);
try {
const cachedTexture = THREE.Cache.get(decalId);
if (cachedTexture) {
setTexture(cachedTexture);
setIsLoading(false);
return;
}
const indexedDBTexture = await retrieveImage(decalId);
if (indexedDBTexture) {
const blobUrl = URL.createObjectURL(indexedDBTexture);
const textureLoader = new THREE.TextureLoader();
textureLoader.load(
blobUrl,
(tex) => {
URL.revokeObjectURL(blobUrl);
tex.name = decalId;
THREE.Cache.add(decalId, tex);
setTexture(tex);
setIsLoading(false);
},
undefined,
(error) => {
console.error(`Error loading texture from IndexedDB:`, error);
URL.revokeObjectURL(blobUrl);
loadFromBackend(decalId);
}
);
return;
}
loadFromBackend(decalId);
} catch (error) {
console.error("Error loading decal texture:", error);
loadDefaultTexture();
}
};
const loadFromBackend = (decalId: string) => {
console.log('decalId: ', decalId);
const textureUrl = `${process.env.REACT_APP_SERVER_MARKETPLACE_URL}/api/v2/DecalFile/${decalId}`;
const textureLoader = new THREE.TextureLoader();
textureLoader.load(
textureUrl,
async (tex) => {
tex.name = decalId;
THREE.Cache.add(decalId, tex);
setTexture(tex);
setIsLoading(false);
try {
const response = await fetch(textureUrl);
const blob = await response.blob();
await storeImage(decalId, blob);
} catch (error) {
console.error("Error storing texture in IndexedDB:", error);
}
},
undefined,
(error) => {
console.error(`Error loading texture from backend:`, error);
loadDefaultTexture();
}
);
};
useEffect(() => {
if (decal.decalId) {
loadDecalTexture(decal.decalId);
} else {
loadDefaultTexture();
}
}, [decal.decalId]);
useEffect(() => {
if (!toggleView && activeModule === 'builder') {
if (toolMode !== 'cursor') {
@@ -227,7 +324,7 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP
}}
>
<meshBasicMaterial
map={material}
map={texture}
side={THREE.DoubleSide}
polygonOffset
polygonOffsetFactor={-1}

View File

@@ -164,7 +164,7 @@ function Wall({ wall }: { readonly wall: Wall }) {
const decal: Decal = {
decalUuid: THREE.MathUtils.generateUUID(),
decalName: 'Decal',
decalId: 'Default Decal',
decalId: "68abe2f771863f0888b0d35d",
decalPosition: [0, 0, wall.wallThickness / 2 + 0.001],
decalRotation: 0,
decalOpacity: 1,