diff --git a/app/src/modules/builder/Decal/decalInstance.tsx b/app/src/modules/builder/Decal/decalInstance.tsx
new file mode 100644
index 0000000..6ed0490
--- /dev/null
+++ b/app/src/modules/builder/Decal/decalInstance.tsx
@@ -0,0 +1,48 @@
+import * as THREE from 'three';
+import { Decal } from '@react-three/drei'
+import { useLoader } from '@react-three/fiber';
+import { useToggleView } from '../../../store/builder/store';
+import { useBuilderStore } from '../../../store/builder/useBuilderStore';
+
+import defaultMaterial from '../../../assets/textures/floor/wall-tex.png';
+import useModuleStore from '../../../store/useModuleStore';
+
+function DecalInstance({ visible = true, decal }: { visible?: boolean, decal: Decal }) {
+ const { setSelectedWall, selectedDecal, setSelectedDecal } = useBuilderStore();
+ const { togglView } = useToggleView();
+ const { activeModule } = useModuleStore();
+ const material = useLoader(THREE.TextureLoader, defaultMaterial);
+
+ return (
+ {
+ if (visible && !togglView && activeModule === 'builder') {
+ if (e.object.userData.decalUuid) {
+ setSelectedDecal(e.object);
+ setSelectedWall(null);
+ }
+ }
+ }}
+ onPointerMissed={() => {
+ if (selectedDecal && selectedDecal.userData.decalUuid === decal.decalUuid) {
+ setSelectedDecal(null);
+ }
+ }}
+ >
+
+
+ )
+}
+
+export default DecalInstance
\ No newline at end of file
diff --git a/app/src/modules/builder/wall/Instances/instance/wall.tsx b/app/src/modules/builder/wall/Instances/instance/wall.tsx
index 4ada970..037816b 100644
--- a/app/src/modules/builder/wall/Instances/instance/wall.tsx
+++ b/app/src/modules/builder/wall/Instances/instance/wall.tsx
@@ -13,12 +13,13 @@ import { useWallClassification } from './helpers/useWallClassification';
import { useToggleView, useWallVisibility } from '../../../../../store/builder/store';
import { useBuilderStore } from '../../../../../store/builder/useBuilderStore';
import * as Constants from '../../../../../types/world/worldConstants';
+import DecalInstance from '../../../Decal/decalInstance';
function Wall({ wall }: { readonly wall: Wall }) {
const { wallStore } = useSceneContext();
- const { walls } = wallStore();
+ const { walls, addDecal } = wallStore();
+ const { selectedWall, setSelectedWall, setSelectedDecal } = useBuilderStore();
const { togglView } = useToggleView();
- const { setSelectedWall } = useBuilderStore();
const { activeModule } = useModuleStore();
const { camera } = useThree();
const { wallVisibility } = useWallVisibility();
@@ -112,25 +113,6 @@ function Wall({ wall }: { readonly wall: Wall }) {
{materials.map((material, index) => (
))}
-
- {wall.decals.map((decal) => {
- return (
-
-
-
- )
- })}
{
if (visible && !togglView && activeModule === 'builder') {
- setSelectedWall(e.object)
+ if (e.object.userData.wallUuid) {
+ setSelectedWall(e.object);
+ setSelectedDecal(null);
+
+ if (wall.decals.length > 0) return;
+ const decal: Decal = {
+ decalUuid: THREE.MathUtils.generateUUID(),
+ decalName: 'Decal',
+ decalId: 'Default Decal',
+ decalPosition: [0, 0, wall.wallThickness / 2 + 0.001],
+ decalRotation: 0,
+ decalScale: 1,
+ decalType: { type: 'Wall', wallUuid: wall.wallUuid }
+ }
+ addDecal(wall.wallUuid, decal);
+
+ }
+ }
+ }}
+ onPointerMissed={() => {
+ if (selectedWall && selectedWall.userData.wallUuid === wall.wallUuid) {
+ setSelectedWall(null);
}
}}
- onPointerMissed={() => { setSelectedWall(null) }}
>
+
+ {wall.decals.map((decal) => (
+
+ ))}
);
diff --git a/app/src/modules/builder/wall/Instances/wallInstances.tsx b/app/src/modules/builder/wall/Instances/wallInstances.tsx
index b22d0e6..4d5da1e 100644
--- a/app/src/modules/builder/wall/Instances/wallInstances.tsx
+++ b/app/src/modules/builder/wall/Instances/wallInstances.tsx
@@ -42,7 +42,7 @@ function WallInstances() {
return (
<>
- {!toggleView && (
+ {!toggleView && walls.length > 1 && (
<>
diff --git a/app/src/modules/builder/wall/wallGroup.tsx b/app/src/modules/builder/wall/wallGroup.tsx
index 07ef700..aae36b9 100644
--- a/app/src/modules/builder/wall/wallGroup.tsx
+++ b/app/src/modules/builder/wall/wallGroup.tsx
@@ -7,12 +7,13 @@ import useModuleStore from '../../../store/useModuleStore';
function WallGroup() {
const { togglView } = useToggleView();
- const { setSelectedWall } = useBuilderStore();
+ const { setSelectedWall, setSelectedDecal } = useBuilderStore();
const { activeModule } = useModuleStore();
useEffect(() => {
if (togglView || activeModule !== 'builder') {
setSelectedWall(null);
+ setSelectedDecal(null);
}
}, [togglView, activeModule])
diff --git a/app/src/modules/scene/postProcessing/postProcessing.tsx b/app/src/modules/scene/postProcessing/postProcessing.tsx
index 1b91386..25d0e0c 100644
--- a/app/src/modules/scene/postProcessing/postProcessing.tsx
+++ b/app/src/modules/scene/postProcessing/postProcessing.tsx
@@ -15,7 +15,7 @@ export default function PostProcessing() {
const { selectedWallItem } = useSelectedWallItem();
const { selectedFloorItem } = useSelectedFloorItem();
const { selectedEventSphere } = useSelectedEventSphere();
- const { selectedAisle, selectedWall } = useBuilderStore();
+ const { selectedAisle, selectedWall, selectedDecal } = useBuilderStore();
function flattenChildren(children: any[]) {
const allChildren: any[] = [];
@@ -85,6 +85,21 @@ export default function PostProcessing() {
xRay={true}
/>
)}
+ {selectedDecal && (
+
+ )}
{deletableFloorItem && (
void;
setWallMaterial: (material: string, side: 'inside' | 'outside') => void;
+ // Setters - Decal
+ setSelectedDecal: (decal: Object3D | null) => void;
+
// Setters - Aisle General
setSelectedAisle: (aisle: Object3D | null) => void;
setAisleType: (type: AisleTypes) => void;
@@ -75,6 +81,8 @@ export const useBuilderStore = create()(
outsideMaterial: 'Default Material',
insideMaterial: 'Material 1',
+ selectedDecal: null,
+
selectedAisle: null,
aisleType: 'solid-aisle',
aisleWidth: 0.1,
@@ -139,6 +147,14 @@ export const useBuilderStore = create()(
});
},
+ // === Setters: Decal ===
+
+ setSelectedDecal: (decal: Object3D | null) => {
+ set((state) => {
+ state.selectedDecal = decal;
+ })
+ },
+
// === Setters: Aisle General ===
setSelectedAisle: (aisle: Object3D | null) => {
diff --git a/app/src/types/builderTypes.d.ts b/app/src/types/builderTypes.d.ts
index decde1d..17349d7 100644
--- a/app/src/types/builderTypes.d.ts
+++ b/app/src/types/builderTypes.d.ts
@@ -80,11 +80,22 @@ interface Decal {
decalUuid: string;
decalName: string;
decalId: string;
+ decalType: WallDecal | FloorDecal;
decalPosition: [number, number, number];
decalRotation: number;
decalScale: number;
}
+interface WallDecal {
+ type: 'Wall';
+ wallUuid: string;
+}
+
+interface FloorDecal {
+ type: 'Floor';
+ floorUuid: string;
+}
+
interface Wall {
wallUuid: string;
points: [Point, Point];