diff --git a/packages/core/src/material-library.ts b/packages/core/src/material-library.ts
index 4c58dad9..e0974830 100644
--- a/packages/core/src/material-library.ts
+++ b/packages/core/src/material-library.ts
@@ -123,16 +123,13 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
label: 'Hungarian Parquet 10',
category: 'wood',
description: 'Parquet wood finish',
- previewThumbnailUrl:
- '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
+ previewThumbnailUrl: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
- metalnessMap:
- '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_specularLevel.webp',
+ metalnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_normal.webp',
- roughnessMap:
- '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_roughness.webp',
+ roughnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_roughness.webp',
},
mapProperties: {
color: '#ffffff',
@@ -163,13 +160,11 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
label: 'Hungarian Parquet 2',
category: 'wood',
description: 'Parquet wood finish',
- previewThumbnailUrl:
- '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
+ previewThumbnailUrl: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
preset: {
maps: {
albedoMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
- metalnessMap:
- '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_specularLevel.webp',
+ metalnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_normal.webp',
roughnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_roughness.webp',
},
@@ -210,8 +205,7 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
metalnessMap:
'/material/wood/square_parquet_21/Square Pattern Parquet_21_specularLevel.webp',
normalMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_normal.webp',
- roughnessMap:
- '/material/wood/square_parquet_21/Square Pattern Parquet_21_roughness.webp',
+ roughnessMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_roughness.webp',
},
mapProperties: {
color: '#ffffff',
@@ -246,12 +240,10 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
preset: {
maps: {
- albedoMap:
- '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
+ albedoMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
metalnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_specularLevel.webp',
- normalMap:
- '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_normal.webp',
+ normalMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_normal.webp',
roughnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_roughness.webp',
},
diff --git a/packages/core/src/systems/stair/stair-opening-sync.ts b/packages/core/src/systems/stair/stair-opening-sync.ts
index 1153d61d..5c9b296f 100644
--- a/packages/core/src/systems/stair/stair-opening-sync.ts
+++ b/packages/core/src/systems/stair/stair-opening-sync.ts
@@ -404,12 +404,10 @@ function getCurvedOpeningPolygon(stair: StairNode, offset: number = 0): Point2D[
const totalSweep = stair.sweepAngle ?? Math.PI / 2
const baseOpeningSweep =
Math.abs(totalSweep) *
- Math.max(
- CURVED_STAIR_SLAB_OPENING_RATIO,
- 1 / Math.max(stair.stepCount ?? 1, 1),
- )
+ Math.max(CURVED_STAIR_SLAB_OPENING_RATIO, 1 / Math.max(stair.stepCount ?? 1, 1))
const angleOffset = offset / Math.max(innerRadius, 0.1)
- const openingSweep = Math.sign(totalSweep || 1) * Math.min(Math.abs(totalSweep), baseOpeningSweep + angleOffset * 2)
+ const openingSweep =
+ Math.sign(totalSweep || 1) * Math.min(Math.abs(totalSweep), baseOpeningSweep + angleOffset * 2)
const startAngle = totalSweep / 2 - openingSweep
const endAngle = totalSweep / 2
@@ -562,7 +560,12 @@ function getStairOpeningPolygons(
}
if (stair.stairType === 'curved') {
- return [getCurvedOpeningPolygon(stair, Math.max((stair.openingOffset ?? 0) - STAIR_SLAB_OPENING_TIGHTENING, 0.15))]
+ return [
+ getCurvedOpeningPolygon(
+ stair,
+ Math.max((stair.openingOffset ?? 0) - STAIR_SLAB_OPENING_TIGHTENING, 0.15),
+ ),
+ ]
}
if (stair.stairType === 'spiral') {
diff --git a/packages/editor/src/components/editor-2d/floorplan-registry-move-overlay.tsx b/packages/editor/src/components/editor-2d/floorplan-registry-move-overlay.tsx
index 2eb5f496..29e71cb6 100644
--- a/packages/editor/src/components/editor-2d/floorplan-registry-move-overlay.tsx
+++ b/packages/editor/src/components/editor-2d/floorplan-registry-move-overlay.tsx
@@ -358,7 +358,7 @@ export function FloorplanRegistryMoveOverlay() {
// plan scene; otherwise we'd react to 3D-canvas moves with garbage
// plan coords.
const target = event.target as Element | null
- if (!target || !target.closest('[data-floorplan-scene]')) return
+ if (!target?.closest('[data-floorplan-scene]')) return
const m = toMeters(event.clientX, event.clientY)
if (!m) return
const [sx, sz] = snapPointToGrid([m[0], m[1]], GRID_STEP)
@@ -371,7 +371,7 @@ export function FloorplanRegistryMoveOverlay() {
const onPointerUp = (event: PointerEvent) => {
if (event.button !== 0) return
const target = event.target as Element | null
- if (!target || !target.closest('[data-floorplan-scene]')) return
+ if (!target?.closest('[data-floorplan-scene]')) return
const snapped = lastSnapped
if (snapped) {
diff --git a/packages/editor/src/components/editor-2d/renderers/floorplan-registry-layer.tsx b/packages/editor/src/components/editor-2d/renderers/floorplan-registry-layer.tsx
index 3f1cc341..661ae1ac 100644
--- a/packages/editor/src/components/editor-2d/renderers/floorplan-registry-layer.tsx
+++ b/packages/editor/src/components/editor-2d/renderers/floorplan-registry-layer.tsx
@@ -269,8 +269,6 @@ export const FloorplanRegistryLayer = memo(function FloorplanRegistryLayer() {
levelId,
nodes,
liveTransforms,
- liveOverrides,
- interactiveElevators,
selectedIdSet,
highlightedIdSet,
hoveredId,
@@ -518,9 +516,7 @@ export const FloorplanRegistryLayer = memo(function FloorplanRegistryLayer() {
higher-rank kinds (slabs, then walls / items / shelves) layer
on top in the expected document-order z-stack. */}
- {entries.map(({ id, base }) =>
- base ? renderEntry(id, base, `base-${id}`) : null,
- )}
+ {entries.map(({ id, base }) => (base ? renderEntry(id, base, `base-${id}`) : null))}
{/* Overlay pass — interactive handles (vertex / midpoint / edge /
move) and labels (text / dimensions). Painted after every base
diff --git a/packages/editor/src/components/editor/custom-camera-controls.tsx b/packages/editor/src/components/editor/custom-camera-controls.tsx
index 7392da7b..5050ee4a 100644
--- a/packages/editor/src/components/editor/custom-camera-controls.tsx
+++ b/packages/editor/src/components/editor/custom-camera-controls.tsx
@@ -7,7 +7,7 @@ import {
sceneRegistry,
useScene,
} from '@pascal-app/core'
-import { useViewer, WalkthroughControls, ZONE_LAYER } from '@pascal-app/viewer'
+import { useViewer, ZONE_LAYER } from '@pascal-app/viewer'
import { CameraControls, CameraControlsImpl } from '@react-three/drei'
import { useThree } from '@react-three/fiber'
import { useCallback, useEffect, useMemo, useRef } from 'react'
diff --git a/packages/editor/src/components/editor/first-person/bvh-ecctrl.tsx b/packages/editor/src/components/editor/first-person/bvh-ecctrl.tsx
index 8525f4a1..3c459659 100644
--- a/packages/editor/src/components/editor/first-person/bvh-ecctrl.tsx
+++ b/packages/editor/src/components/editor/first-person/bvh-ecctrl.tsx
@@ -673,7 +673,7 @@ const BVHEcctrl = forwardRef(
rotationDeltaPos.current.copy(totalPlatformDeltaPos.current)
characterGroupRef.current.position.add(rotationDeltaPos.current)
yawQuaternion.current.setFromUnitVectors(upAxis.current, floatHitNormal.current)
- }, [upAxis])
+ }, [])
const updateCharacterAnimation = useCallback(
(run: boolean, jump: boolean): CharacterAnimationStatus => {
@@ -756,7 +756,7 @@ const BVHEcctrl = forwardRef(
moveDirRef.current?.position.copy(characterSegment.current.end)
moveDirRef.current?.setDirection(currentLinVel.current)
moveDirRef.current?.setLength(currentLinVel.current.length() / maxWalkSpeed)
- }, [characterSegment, maxWalkSpeed])
+ }, [maxWalkSpeed])
useFrame((_, delta) => {
elapsedRef.current += delta
diff --git a/packages/editor/src/components/editor/floorplan-panel.tsx b/packages/editor/src/components/editor/floorplan-panel.tsx
index 96af36dc..fc1cd50c 100644
--- a/packages/editor/src/components/editor/floorplan-panel.tsx
+++ b/packages/editor/src/components/editor/floorplan-panel.tsx
@@ -3475,7 +3475,7 @@ function FloorplanZoneLabel({
if (textRef.current) {
setTextWidth(textRef.current.getComputedTextLength())
}
- }, [zone.name])
+ }, [])
const isDeleteMode = mode === 'delete'
@@ -5136,7 +5136,7 @@ export function FloorplanPanel() {
useEffect(() => {
setHoveredGuideCorner(null)
- }, [selectedGuide?.id])
+ }, [])
useEffect(() => {
if (!(selectedGuide && showGuides && canInteractWithGuides)) {
@@ -6087,7 +6087,7 @@ export function FloorplanPanel() {
}
scheduleMovingFloorplanNodeRefresh()
- }, [hasPendingItemMeshFootprints, scheduleMovingFloorplanNodeRefresh])
+ }, [scheduleMovingFloorplanNodeRefresh])
// Subscribe to the live-transforms store so rotation/position changes that
// *don't* go through pointer events still refresh the floorplan — e.g. R/T
@@ -6631,7 +6631,7 @@ export function FloorplanPanel() {
pendingFenceDragRef.current = null
clearWallEndpointDrag()
clearWallCurveDrag()
- }, [clearWallCurveDrag, clearWallEndpointDrag, levelId])
+ }, [clearWallCurveDrag, clearWallEndpointDrag])
useEffect(() => {
if (shouldShowSiteBoundaryHandles) {
diff --git a/packages/editor/src/components/editor/index.tsx b/packages/editor/src/components/editor/index.tsx
index 650bd296..f03cfa96 100644
--- a/packages/editor/src/components/editor/index.tsx
+++ b/packages/editor/src/components/editor/index.tsx
@@ -840,7 +840,7 @@ const ViewerCanvas = memo(function ViewerCanvas({
window.removeEventListener('pointermove', handlePointerMove)
window.removeEventListener('pointerup', handlePointerUp)
}
- }, [])
+ }, [setFloorplanPaneRatio])
useEffect(() => {
setIsCameraControlsHintVisible(!readCameraControlsHintDismissed())
diff --git a/packages/editor/src/components/systems/stair/stair-edit-system.tsx b/packages/editor/src/components/systems/stair/stair-edit-system.tsx
index ef1f9124..1831aaaa 100644
--- a/packages/editor/src/components/systems/stair/stair-edit-system.tsx
+++ b/packages/editor/src/components/systems/stair/stair-edit-system.tsx
@@ -85,7 +85,7 @@ export const StairEditSystem = () => {
}
prevActiveStairIds.current = activeStairIds
- }, [selectedIds, selectedStairSignature])
+ }, [selectedIds])
return null
}
diff --git a/packages/editor/src/components/tools/item/use-placement-coordinator.tsx b/packages/editor/src/components/tools/item/use-placement-coordinator.tsx
index 470a3a75..5b268439 100644
--- a/packages/editor/src/components/tools/item/use-placement-coordinator.tsx
+++ b/packages/editor/src/components/tools/item/use-placement-coordinator.tsx
@@ -1496,7 +1496,16 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
window.removeEventListener('keyup', onKeyUp)
window.removeEventListener('contextmenu', onContextMenu)
}
- }, [asset, canPlaceOnFloor, canPlaceOnWall, canPlaceOnCeiling, draftNode])
+ }, [
+ asset,
+ canPlaceOnFloor,
+ canPlaceOnWall,
+ canPlaceOnCeiling,
+ draftNode,
+ gridSnapStep,
+ updateDimensionGuides,
+ updatePreviewGeometry,
+ ])
// Refresh wireframe when the grid step changes mid-placement so the green/red
// box snaps to the new cell size right away.
@@ -1510,7 +1519,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
)
updatePreviewGeometry(previewBounds)
updateDimensionGuides(previewBounds)
- }, [gridSnapStep, asset, draftNode])
+ }, [gridSnapStep, asset, draftNode, updateDimensionGuides, updatePreviewGeometry])
// Wall/ceiling items are managed by their own surface entry events (ensureDraft / reparent).
const viewerLevelId = useViewer((s) => s.selection.levelId)
useEffect(() => {
@@ -1588,6 +1597,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
initialDimensionBounds.dimensions[0],
initialDimensionBounds.dimensions[1],
initialDimensionBounds.dimensions[2],
+ initialDimensionBounds,
],
)
const basePlaneGeometry = useMemo(() => {
diff --git a/packages/editor/src/components/tools/select/box-select-tool.tsx b/packages/editor/src/components/tools/select/box-select-tool.tsx
index 56362ab3..6275874d 100644
--- a/packages/editor/src/components/tools/select/box-select-tool.tsx
+++ b/packages/editor/src/components/tools/select/box-select-tool.tsx
@@ -546,7 +546,7 @@ const BoxSelectToolInner: React.FC = () => {
canvas.removeEventListener('pointerdown', onCanvasPointerDown)
canvas.removeEventListener('pointerup', onCanvasPointerUp)
}
- }, [camera, gl])
+ }, [gl, raycastToGround, syncPreviewSelectedIds])
// grid:move for cursor tracking + rectangle update during drag
useEffect(() => {
@@ -603,7 +603,7 @@ const BoxSelectToolInner: React.FC = () => {
return () => {
emitter.off('grid:move', onMove)
}
- }, [])
+ }, [syncPreviewSelectedIds])
return (
diff --git a/packages/nodes/src/door/panel.tsx b/packages/nodes/src/door/panel.tsx
index e6b4ba5d..7636636c 100644
--- a/packages/nodes/src/door/panel.tsx
+++ b/packages/nodes/src/door/panel.tsx
@@ -393,10 +393,7 @@ export default function DoorPanel() {
const isGarageDoor = node.doorCategory === 'garage' || doorType.startsWith('garage-')
const isSwingDoor = doorType === 'hinged' || doorType === 'double' || doorType === 'french'
const isSlideFoldDoor =
- doorType === 'folding' ||
- doorType === 'pocket' ||
- doorType === 'barn' ||
- doorType === 'sliding'
+ doorType === 'folding' || doorType === 'pocket' || doorType === 'barn' || doorType === 'sliding'
const isSlidingDoor = doorType === 'pocket' || doorType === 'barn' || doorType === 'sliding'
const isFoldingDoor = doorType === 'folding'
const isSectionalGarageDoor = doorType === 'garage-sectional'
@@ -1027,26 +1024,26 @@ export default function DoorPanel() {
<>
{showFrameSection && (
- handleUpdate({ frameThickness: v })}
- precision={3}
- step={0.01}
- unit="m"
- value={Math.round(node.frameThickness * 1000) / 1000}
- />
- handleUpdate({ frameDepth: v })}
- precision={3}
- step={0.01}
- unit="m"
- value={Math.round(node.frameDepth * 1000) / 1000}
- />
+ handleUpdate({ frameThickness: v })}
+ precision={3}
+ step={0.01}
+ unit="m"
+ value={Math.round(node.frameThickness * 1000) / 1000}
+ />
+ handleUpdate({ frameDepth: v })}
+ precision={3}
+ step={0.01}
+ unit="m"
+ value={Math.round(node.frameDepth * 1000) / 1000}
+ />
)}
diff --git a/packages/nodes/src/elevator/panel.tsx b/packages/nodes/src/elevator/panel.tsx
index 50fefe00..9eb51e3b 100644
--- a/packages/nodes/src/elevator/panel.tsx
+++ b/packages/nodes/src/elevator/panel.tsx
@@ -240,6 +240,7 @@ export default function ElevatorPanel() {
node?.type,
selectedId,
updateNode,
+ node,
])
const previewMetric = useCallback(
@@ -314,7 +315,7 @@ export default function ElevatorPanel() {
}, [clearLivePreview, node, setMovingNode, setSelection])
const handleDuplicate = useCallback(() => {
- if (!(node && node.parentId)) return
+ if (!node?.parentId) return
triggerSFX('sfx:item-pick')
const duplicate = ElevatorNodeSchema.parse({
@@ -596,9 +597,7 @@ export default function ElevatorPanel() {