Files
Dwinzo_Demo/app/src/store/builder/useBuilderStore.ts

414 lines
12 KiB
TypeScript

import { Object3D, Vector3 } from 'three';
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface BuilderState {
// Point & Line Interaction
hoveredPoint: Point | null;
snappedPoint: Point | null;
snappedPosition: [number, number, number] | null;
hoveredLine: [Point, Point] | null;
// Wall Asset
selectedWallAsset: Object3D | null;
deletableWallAsset: Object3D | null;
// Floor Asset
selectedFloorAsset: Object3D | null;
loopAnimation: boolean;
// Wall Settings
selectedWall: Object3D | null;
wallThickness: number;
wallHeight: number;
outsideMaterial: string;
insideMaterial: string;
// Floor Settings
selectedFloor: Object3D | null;
floorDepth: number;
isBeveled: boolean;
bevelStrength: number;
sideMaterial: string;
topMaterial: string;
// Zone Settings
selectedZone: Object3D | null;
zoneHeight: number;
zoneColor: string;
// Decal Settings
selectedDecal: { decalMesh: Object3D | null, decalData: Decal } | null;
deletableDecal: Object3D | null;
decalDragState: {
isDragging: boolean,
draggingDecalUuid: string | null,
dragOffset: Vector3 | null,
},
// Aisle General
selectedAisle: Object3D | null;
aisleType: AisleTypes;
aisleWidth: number;
aisleColor: AisleColors;
// Aisle Specific Styles
dashLength: number;
gapLength: number;
dotRadius: number;
aisleLength: number;
isFlipped: boolean;
// Setters - Point/Line
setHoveredPoint: (point: Point | null) => void;
setSnappedPoint: (point: Point | null) => void;
setSnappedPosition: (position: [number, number, number] | null) => void;
setHoveredLine: (line: [Point, Point] | null) => void;
// Setters - Wall Asset
setSelectedWallAsset: (asset: Object3D | null) => void;
setDeletableWallAsset: (asset: Object3D | null) => void;
// Setters - Floor Asset
setSelectedFloorAsset: (asset: Object3D | null) => void;
setLoopAnimation: (loop: boolean) => void;
// Setters - Wall
setSelectedWall: (wall: Object3D | null) => void;
setWallThickness: (thickness: number) => void;
setWallHeight: (height: number) => void;
setWallMaterial: (material: string, side: 'inside' | 'outside') => void;
// Setters - Floor
setSelectedFloor: (floor: Object3D | null) => void;
setFloorDepth: (depth: number) => void;
setIsBeveled: (isBeveled: boolean) => void;
setBevelStrength: (strength: number) => void;
setFloorMaterial: (material: string, side: 'side' | 'top') => void;
// Setters - Zone
setSelectedZone: (zone: Object3D | null) => void;
setZoneHeight: (height: number) => void;
setZoneColor: (color: string) => void;
// Setters - Decal
setSelectedDecal: (decal: { decalMesh: Object3D | null, decalData: Decal } | null) => void;
setDeletableDecal: (decal: Object3D | null) => void;
setDecalDragState: (isDragging: boolean, draggingDecalUuid: string | null, dragOffset: Vector3 | null) => void;
// Setters - Aisle General
setSelectedAisle: (aisle: Object3D | null) => void;
setAisleType: (type: AisleTypes) => void;
setAisleWidth: (width: number) => void;
setAisleColor: (color: AisleColors) => void;
// Setters - Aisle Specific
setDashLength: (length: number) => void;
setGapLength: (length: number) => void;
setDotRadius: (radius: number) => void;
setAisleLength: (length: number) => void;
setIsFlipped: (isFlipped: boolean) => void;
// Batch Setters
setDashedAisleProperties: (width: number, dashLength: number, gapLength: number) => void;
setDottedAisleProperties: (width: number, dotRadius: number, gapLength: number) => void;
setArrowsAisleProperties: (width: number, aisleLength: number, gapLength: number) => void;
setAisleProperties: (type: AisleTypes, width: number, color: AisleColors) => void;
}
export const useBuilderStore = create<BuilderState>()(
immer((set) => ({
// === Defaults ===
hoveredPoint: null,
snappedPoint: null,
snappedPosition: null,
hoveredLine: null,
selectedWallAsset: null,
deletableWallAsset: null,
selectedFloorAsset: null,
loopAnimation: true,
selectedWall: null,
wallThickness: 0.5,
wallHeight: 7,
outsideMaterial: 'Default Material',
insideMaterial: 'Material 1',
selectedFloor: null,
floorDepth: 0.1,
isBeveled: false,
bevelStrength: 5,
sideMaterial: 'Material 1',
topMaterial: 'Default Material',
selectedZone: null,
zoneHeight: 7,
zoneColor: 'blue',
selectedDecal: null,
deletableDecal: null,
decalDragState: {
isDragging: false,
draggingDecalUuid: null,
dragOffset: null,
},
selectedAisle: null,
aisleType: 'solid-aisle',
aisleWidth: 0.1,
aisleColor: 'yellow',
dashLength: 0.5,
gapLength: 0.3,
dotRadius: 0.1,
aisleLength: 0.6,
isFlipped: false,
// === Setters: Point/Line ===
setHoveredPoint: (point: Point | null) => {
set((state) => {
state.hoveredPoint = point;
});
},
setSnappedPoint: (point: Point | null) => {
set((state) => {
state.snappedPoint = point;
});
},
setSnappedPosition: (position: [number, number, number] | null) => {
set((state) => {
state.snappedPosition = position;
});
},
setHoveredLine: (line: [Point, Point] | null) => {
set((state) => {
state.hoveredLine = line;
})
},
// === Setters: Wall Asset ===
setSelectedWallAsset(asset: Object3D | null) {
set((state) => {
state.selectedWallAsset = asset;
});
},
setDeletableWallAsset(asset: Object3D | null) {
set((state) => {
state.deletableWallAsset = asset;
});
},
// === Setters: Floor Asset ===
setSelectedFloorAsset(asset: Object3D | null) {
set((state) => {
state.selectedFloorAsset = asset;
});
},
setLoopAnimation(loopAnimation: boolean) {
set((state) => {
state.loopAnimation = loopAnimation;
});
},
// === Setters: Wall ===
setSelectedWall: (wall: Object3D | null) => {
set((state) => {
state.selectedWall = wall;
})
},
setWallThickness: (thickness: number) => {
set((state) => {
state.wallThickness = thickness;
})
},
setWallHeight: (height: number) => {
set((state) => {
state.wallHeight = height;
})
},
setWallMaterial: (material: string, side: 'inside' | 'outside') => {
set((state) => {
if (side === 'outside') state.outsideMaterial = material;
else state.insideMaterial = material;
});
},
// === Setters: Floor ===
setSelectedFloor: (floor: Object3D | null) => {
set((state) => {
state.selectedFloor = floor;
});
},
setFloorDepth: (depth: number) => {
set((state) => {
state.floorDepth = depth;
});
},
setIsBeveled: (isBeveled: boolean) => {
set((state) => {
state.isBeveled = isBeveled;
});
},
setBevelStrength: (strength: number) => {
set((state) => {
state.bevelStrength = strength;
});
},
setFloorMaterial: (material: string, side: 'side' | 'top') => {
set((state) => {
if (side === 'side') state.sideMaterial = material;
else state.topMaterial = material;
});
},
// === Setters: Zone ===
setSelectedZone: (zone: Object3D | null) => {
set((state) => {
state.selectedZone = zone;
});
},
setZoneHeight: (height: number) => {
set((state) => {
state.zoneHeight = height;
});
},
setZoneColor: (color: string) => {
set((state) => {
state.zoneColor = color;
});
},
// === Setters: Decal ===
setSelectedDecal: (decal: { decalMesh: Object3D | null, decalData: Decal } | null) => {
set((state) => {
state.selectedDecal = decal;
})
},
setDeletableDecal: (decal: Object3D | null) => {
set((state) => {
state.deletableDecal = decal;
})
},
setDecalDragState: (isDragging: boolean, draggingDecalUuid: string | null, dragOffset: Vector3 | null) => {
set((state) => {
state.decalDragState = {
isDragging,
draggingDecalUuid,
dragOffset,
}
})
},
// === Setters: Aisle General ===
setSelectedAisle: (aisle: Object3D | null) => {
set((state) => {
state.selectedAisle = aisle;
});
},
setAisleType: (type) => {
set((state) => {
state.aisleType = type;
});
},
setAisleWidth: (width) => {
set((state) => {
state.aisleWidth = width;
});
},
setAisleColor: (color) => {
set((state) => {
state.aisleColor = color;
});
},
// === Setters: Aisle Specific ===
setDashLength: (length) => {
set((state) => {
state.dashLength = length;
});
},
setGapLength: (length) => {
set((state) => {
state.gapLength = length;
});
},
setDotRadius: (radius) => {
set((state) => {
state.dotRadius = radius;
});
},
setAisleLength: (length) => {
set((state) => {
state.aisleLength = length;
});
},
setIsFlipped: (isFlipped) => {
set((state) => {
state.isFlipped = isFlipped;
});
},
// === Batch Setters ===
setDashedAisleProperties: (width, dashLength, gapLength) => set((state) => {
state.aisleType = 'dashed-aisle';
state.aisleWidth = width;
state.dashLength = dashLength;
state.gapLength = gapLength;
}),
setDottedAisleProperties: (width, dotRadius, gapLength) => set((state) => {
state.aisleType = 'dotted-aisle';
state.aisleWidth = width;
state.dotRadius = dotRadius;
state.gapLength = gapLength;
}),
setArrowsAisleProperties: (width, aisleLength, gapLength) => set((state) => {
state.aisleType = 'arrows-aisle';
state.aisleWidth = width;
state.aisleLength = aisleLength;
state.gapLength = gapLength;
}),
setAisleProperties: (type, width, color) => set((state) => {
state.aisleType = type;
state.aisleWidth = width;
state.aisleColor = color;
})
}))
);