From fc138b8345ec5838713f086dd48756af5ac007aa Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Thu, 18 Sep 2025 15:54:21 +0530 Subject: [PATCH] decal bug fix --- app/src/functions/objectDeepEqual.ts | 19 +++++ .../Decal/decalInstance/decalInstance.tsx | 84 +++++++++++-------- .../collaboration/socket/builderResponses.tsx | 1 + 3 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 app/src/functions/objectDeepEqual.ts diff --git a/app/src/functions/objectDeepEqual.ts b/app/src/functions/objectDeepEqual.ts new file mode 100644 index 0000000..3239d88 --- /dev/null +++ b/app/src/functions/objectDeepEqual.ts @@ -0,0 +1,19 @@ +const deepEqual = (a: any, b: any): boolean => { + if (a === b) return true; + + if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) return false; + + const keysA = Object.keys(a); + const keysB = Object.keys(b); + + if (keysA.length !== keysB.length) return false; + + for (const key of keysA) { + if (!keysB.includes(key)) return false; + if (!deepEqual(a[key], b[key])) return false; + } + + return true; +}; + +export default deepEqual; diff --git a/app/src/modules/builder/Decal/decalInstance/decalInstance.tsx b/app/src/modules/builder/Decal/decalInstance/decalInstance.tsx index 85d6c3e..602ac25 100644 --- a/app/src/modules/builder/Decal/decalInstance/decalInstance.tsx +++ b/app/src/modules/builder/Decal/decalInstance/decalInstance.tsx @@ -1,16 +1,17 @@ -import * as THREE from 'three'; -import { Decal } from '@react-three/drei' -import { useToggleView, useToolMode } from '../../../../store/builder/store'; -import { useBuilderStore } from '../../../../store/builder/useBuilderStore'; -import { retrieveImage, storeImage } from '../../../../utils/indexDB/idbUtils'; +import * as THREE from "three"; +import { Decal } from "@react-three/drei"; +import { useToggleView, useToolMode } from "../../../../store/builder/store"; +import { useBuilderStore } from "../../../../store/builder/useBuilderStore"; +import { retrieveImage, storeImage } from "../../../../utils/indexDB/idbUtils"; +import deepEqual from "../../../../functions/objectDeepEqual"; -import defaultMaterial from '../../../../assets/image/fallback/fallback decal 1.png'; -import useModuleStore from '../../../../store/ui/useModuleStore'; -import { useEffect, useRef, useState } from 'react'; +import defaultMaterial from "../../../../assets/image/fallback/fallback decal 1.png"; +import useModuleStore from "../../../../store/ui/useModuleStore"; +import { useEffect, useRef, useState } from "react"; -import { useDecalEventHandlers } from '../eventHandler/useDecalEventHandlers'; +import { useDecalEventHandlers } from "../eventHandler/useDecalEventHandlers"; -function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalPosition[2] }: Readonly<{ parent: Wall | Floor; visible?: boolean, decal: Decal, zPosition?: number }>) { +function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalPosition[2] }: Readonly<{ parent: Wall | Floor; visible?: boolean; decal: Decal; zPosition?: number }>) { const url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_MARKETPLACE_URL}`; const { selectedDecal, deletableDecal, setSelectedDecal, setDeletableDecal } = useBuilderStore(); const { toolMode } = useToolMode(); @@ -23,7 +24,19 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP setSelectedDecal({ decalData: selectedDecal.decalData, decalMesh: decalRef.current }); } // eslint-disable-next-line - }, [selectedDecal]) + }, [selectedDecal]); + + useEffect(() => { + if (selectedDecal?.decalData.decalUuid === decal.decalUuid && selectedDecal.decalMesh) { + if (!deepEqual(selectedDecal.decalData, decal)) { + setSelectedDecal({ + decalData: decal, + decalMesh: selectedDecal.decalMesh, + }); + } + } + // eslint-disable-next-line + }, [decal, selectedDecal]); const { handlePointerMissed, handlePointerLeave, handleClick, handlePointerDown, handlePointerEnter } = useDecalEventHandlers({ parent, decal, visible }); @@ -31,7 +44,7 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP const logDecalStatus = (decalId: string, status: string) => { // console.log(decalId, status); - } + }; const loadDefaultTexture = () => { const textureLoader = new THREE.TextureLoader(); @@ -40,7 +53,7 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP (fallbackTex) => { fallbackTex.name = "default-decal"; setTexture(fallbackTex); - logDecalStatus(decal.decalId, 'default-loaded'); + logDecalStatus(decal.decalId, "default-loaded"); }, undefined, (error) => { @@ -50,12 +63,11 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP }; const loadDecalTexture = async (decalId: string) => { - try { const cachedTexture = THREE.Cache.get(decalId); if (cachedTexture) { setTexture(cachedTexture); - logDecalStatus(decalId, 'cache-loaded'); + logDecalStatus(decalId, "cache-loaded"); return; } @@ -70,7 +82,7 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP tex.name = decalId; THREE.Cache.add(decalId, tex); setTexture(tex); - logDecalStatus(decalId, 'indexedDB-loaded'); + logDecalStatus(decalId, "indexedDB-loaded"); }, undefined, (error) => { @@ -90,7 +102,6 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP }; const loadFromBackend = (decalId: string) => { - const textureUrl = `${url_Backend_dwinzo}/api/v1/DecalImage/${decalId}`; const textureLoader = new THREE.TextureLoader(); @@ -100,7 +111,7 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP tex.name = decalId; THREE.Cache.add(decalId, tex); setTexture(tex); - logDecalStatus(decalId, 'backend-loaded'); + logDecalStatus(decalId, "backend-loaded"); try { const response = await fetch(textureUrl); @@ -128,11 +139,11 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP }, [decal.decalId]); useEffect(() => { - if (!toggleView && activeModule === 'builder') { - if (toolMode !== 'cursor' && selectedDecal) { + if (!toggleView && activeModule === "builder") { + if (toolMode !== "cursor" && selectedDecal) { setSelectedDecal(null); } - if (toolMode !== '3D-Delete' && deletableDecal) { + if (toolMode !== "3D-Delete" && deletableDecal) { setDeletableDecal(null); } } else { @@ -149,24 +160,25 @@ function DecalInstance({ parent, visible = true, decal, zPosition = decal.decalP ref={decalRef} position={[decal.decalPosition[0], decal.decalPosition[1], zPosition]} rotation={[0, 0, decal.decalRotation * (Math.PI / 180)]} - scale={[(decal.decalType.type === 'Floor' || zPosition < 0) ? -decal.decalScale : decal.decalScale, decal.decalScale, 0.01]} + scale={[decal.decalType.type === "Floor" || zPosition < 0 ? -decal.decalScale : decal.decalScale, decal.decalScale, 0.01]} userData={decal} - onPointerDown={(e) => { if (e.button === 0) handlePointerDown(e) }} - onClick={(e) => { handleClick(e) }} - onPointerEnter={(e) => { handlePointerEnter(e) }} - onPointerLeave={(e) => { handlePointerLeave(e) }} + onPointerDown={(e) => { + if (e.button === 0) handlePointerDown(e); + }} + onClick={(e) => { + handleClick(e); + }} + onPointerEnter={(e) => { + handlePointerEnter(e); + }} + onPointerLeave={(e) => { + handlePointerLeave(e); + }} onPointerMissed={() => handlePointerMissed()} > - + - ) + ); } -export default DecalInstance \ No newline at end of file +export default DecalInstance; diff --git a/app/src/modules/collaboration/socket/builderResponses.tsx b/app/src/modules/collaboration/socket/builderResponses.tsx index 78f0529..07c7716 100644 --- a/app/src/modules/collaboration/socket/builderResponses.tsx +++ b/app/src/modules/collaboration/socket/builderResponses.tsx @@ -254,6 +254,7 @@ function BuilderResponses() { echo.log(`Added wall: ${wall.wallUuid}`); }); } else if (data.message === "Wall Updated Successfully") { + console.log('data: ', data.data.decals); const wall: Wall = { wallUuid: data.data.wallUuid, points: data.data.points,