feat: improve collaboration feedback and previews

This commit is contained in:
Aymeric Rabot
2026-07-20 20:25:30 +02:00
parent 10c9c6ad27
commit e1a4dba740
27 changed files with 535 additions and 39 deletions
+17 -1
View File
@@ -9,7 +9,7 @@ import {
sceneRegistry,
useScene,
} from '@pascal-app/core'
import { triggerSFX } from '@pascal-app/editor'
import { triggerSFX, usePlacementPreview } from '@pascal-app/editor'
import { useViewer } from '@pascal-app/viewer'
import { useEffect, useMemo, useRef, useState } from 'react'
import * as THREE from 'three'
@@ -90,6 +90,16 @@ const SolarPanelTool = () => {
setPreviewSurfaceQuat(surfaceQuatFromNormal(normal, new THREE.Quaternion()))
setPreviewYaw((event.node.rotation ?? 0) + (hit.segment.rotation ?? 0))
setPreviewPos(worldToBuildingLocal(wx, wy, wz))
usePlacementPreview.getState().set(
SolarPanelNode.parse({
...previewNode,
parentId: hit.segment.id,
position: [hit.localX, hit.localY, hit.localZ],
roofSegmentId: hit.segment.id,
surfaceNormal: [normal.x, normal.y, normal.z],
}),
hit.segment,
)
publishRoofSurfacePlacementGuides({
roof: event.node as RoofNode,
segment: hit.segment,
@@ -128,6 +138,8 @@ const SolarPanelTool = () => {
state.dirtyNodes.add(hit.segment.id as AnyNodeId)
setSelection({ selectedIds: [panel.id] })
triggerSFX('sfx:item-place')
const placementPreview = usePlacementPreview.getState()
if (placementPreview.node?.id === previewNode.id) placementPreview.clear()
clearRoofSurfacePlacementGuides()
event.stopPropagation()
}
@@ -140,6 +152,8 @@ const SolarPanelTool = () => {
emitter.off('roof:move', updatePreview)
emitter.off('roof:enter', updatePreview)
emitter.off('roof:click', onClick)
const placementPreview = usePlacementPreview.getState()
if (placementPreview.node?.id === previewNode.id) placementPreview.clear()
clearRoofSurfacePlacementGuides()
}
}, [activeBuildingId, setSelection, previewNode])
@@ -152,6 +166,8 @@ const SolarPanelTool = () => {
onInvalidTarget={() => {
setPreviewPos(null)
setPreviewSurfaceQuat(null)
const placementPreview = usePlacementPreview.getState()
if (placementPreview.node?.id === previewNode.id) placementPreview.clear()
clearRoofSurfacePlacementGuides()
}}
/>