style: apply biome lint fixes after portforward

This commit is contained in:
open-pascal
2026-05-20 00:54:11 +00:00
parent d48be77f5d
commit 3adae8acea
22 changed files with 92 additions and 98 deletions
+8 -16
View File
@@ -123,16 +123,13 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
label: 'Hungarian Parquet 10', label: 'Hungarian Parquet 10',
category: 'wood', category: 'wood',
description: 'Parquet wood finish', description: 'Parquet wood finish',
previewThumbnailUrl: previewThumbnailUrl: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
'/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
preset: { preset: {
maps: { maps: {
albedoMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp', albedoMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_baseColor.webp',
metalnessMap: metalnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_specularLevel.webp',
'/material/wood/hungarian_parquet_10/Hungarian Parquet_10_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_normal.webp', normalMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_normal.webp',
roughnessMap: roughnessMap: '/material/wood/hungarian_parquet_10/Hungarian Parquet_10_roughness.webp',
'/material/wood/hungarian_parquet_10/Hungarian Parquet_10_roughness.webp',
}, },
mapProperties: { mapProperties: {
color: '#ffffff', color: '#ffffff',
@@ -163,13 +160,11 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
label: 'Hungarian Parquet 2', label: 'Hungarian Parquet 2',
category: 'wood', category: 'wood',
description: 'Parquet wood finish', description: 'Parquet wood finish',
previewThumbnailUrl: previewThumbnailUrl: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
'/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
preset: { preset: {
maps: { maps: {
albedoMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp', albedoMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_baseColor.webp',
metalnessMap: metalnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_specularLevel.webp',
'/material/wood/hungarian_parquet_2/Hungarian Parquet_2_specularLevel.webp',
normalMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_normal.webp', normalMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_normal.webp',
roughnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_roughness.webp', roughnessMap: '/material/wood/hungarian_parquet_2/Hungarian Parquet_2_roughness.webp',
}, },
@@ -210,8 +205,7 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
metalnessMap: metalnessMap:
'/material/wood/square_parquet_21/Square Pattern Parquet_21_specularLevel.webp', '/material/wood/square_parquet_21/Square Pattern Parquet_21_specularLevel.webp',
normalMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_normal.webp', normalMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_normal.webp',
roughnessMap: roughnessMap: '/material/wood/square_parquet_21/Square Pattern Parquet_21_roughness.webp',
'/material/wood/square_parquet_21/Square Pattern Parquet_21_roughness.webp',
}, },
mapProperties: { mapProperties: {
color: '#ffffff', color: '#ffffff',
@@ -246,12 +240,10 @@ export const MATERIAL_CATALOG: MaterialCatalogItem[] = [
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp', '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
preset: { preset: {
maps: { maps: {
albedoMap: albedoMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_baseColor.webp',
metalnessMap: metalnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_specularLevel.webp', '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_specularLevel.webp',
normalMap: normalMap: '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_normal.webp',
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_normal.webp',
roughnessMap: roughnessMap:
'/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_roughness.webp', '/material/wood/square_wood_parquet_23/Square Pattern Parquet_23_roughness.webp',
}, },
@@ -404,12 +404,10 @@ function getCurvedOpeningPolygon(stair: StairNode, offset: number = 0): Point2D[
const totalSweep = stair.sweepAngle ?? Math.PI / 2 const totalSweep = stair.sweepAngle ?? Math.PI / 2
const baseOpeningSweep = const baseOpeningSweep =
Math.abs(totalSweep) * Math.abs(totalSweep) *
Math.max( Math.max(CURVED_STAIR_SLAB_OPENING_RATIO, 1 / Math.max(stair.stepCount ?? 1, 1))
CURVED_STAIR_SLAB_OPENING_RATIO,
1 / Math.max(stair.stepCount ?? 1, 1),
)
const angleOffset = offset / Math.max(innerRadius, 0.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 startAngle = totalSweep / 2 - openingSweep
const endAngle = totalSweep / 2 const endAngle = totalSweep / 2
@@ -562,7 +560,12 @@ function getStairOpeningPolygons(
} }
if (stair.stairType === 'curved') { 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') { if (stair.stairType === 'spiral') {
@@ -358,7 +358,7 @@ export function FloorplanRegistryMoveOverlay() {
// plan scene; otherwise we'd react to 3D-canvas moves with garbage // plan scene; otherwise we'd react to 3D-canvas moves with garbage
// plan coords. // plan coords.
const target = event.target as Element | null 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) const m = toMeters(event.clientX, event.clientY)
if (!m) return if (!m) return
const [sx, sz] = snapPointToGrid([m[0], m[1]], GRID_STEP) const [sx, sz] = snapPointToGrid([m[0], m[1]], GRID_STEP)
@@ -371,7 +371,7 @@ export function FloorplanRegistryMoveOverlay() {
const onPointerUp = (event: PointerEvent) => { const onPointerUp = (event: PointerEvent) => {
if (event.button !== 0) return if (event.button !== 0) return
const target = event.target as Element | null 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 const snapped = lastSnapped
if (snapped) { if (snapped) {
@@ -269,8 +269,6 @@ export const FloorplanRegistryLayer = memo(function FloorplanRegistryLayer() {
levelId, levelId,
nodes, nodes,
liveTransforms, liveTransforms,
liveOverrides,
interactiveElevators,
selectedIdSet, selectedIdSet,
highlightedIdSet, highlightedIdSet,
hoveredId, hoveredId,
@@ -518,9 +516,7 @@ export const FloorplanRegistryLayer = memo(function FloorplanRegistryLayer() {
higher-rank kinds (slabs, then walls / items / shelves) layer higher-rank kinds (slabs, then walls / items / shelves) layer
on top in the expected document-order z-stack. */} on top in the expected document-order z-stack. */}
<g className="floorplan-registry-base"> <g className="floorplan-registry-base">
{entries.map(({ id, base }) => {entries.map(({ id, base }) => (base ? renderEntry(id, base, `base-${id}`) : null))}
base ? renderEntry(id, base, `base-${id}`) : null,
)}
</g> </g>
{/* Overlay pass — interactive handles (vertex / midpoint / edge / {/* Overlay pass — interactive handles (vertex / midpoint / edge /
move) and labels (text / dimensions). Painted after every base move) and labels (text / dimensions). Painted after every base
@@ -7,7 +7,7 @@ import {
sceneRegistry, sceneRegistry,
useScene, useScene,
} from '@pascal-app/core' } 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 { CameraControls, CameraControlsImpl } from '@react-three/drei'
import { useThree } from '@react-three/fiber' import { useThree } from '@react-three/fiber'
import { useCallback, useEffect, useMemo, useRef } from 'react' import { useCallback, useEffect, useMemo, useRef } from 'react'
@@ -673,7 +673,7 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
rotationDeltaPos.current.copy(totalPlatformDeltaPos.current) rotationDeltaPos.current.copy(totalPlatformDeltaPos.current)
characterGroupRef.current.position.add(rotationDeltaPos.current) characterGroupRef.current.position.add(rotationDeltaPos.current)
yawQuaternion.current.setFromUnitVectors(upAxis.current, floatHitNormal.current) yawQuaternion.current.setFromUnitVectors(upAxis.current, floatHitNormal.current)
}, [upAxis]) }, [])
const updateCharacterAnimation = useCallback( const updateCharacterAnimation = useCallback(
(run: boolean, jump: boolean): CharacterAnimationStatus => { (run: boolean, jump: boolean): CharacterAnimationStatus => {
@@ -756,7 +756,7 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
moveDirRef.current?.position.copy(characterSegment.current.end) moveDirRef.current?.position.copy(characterSegment.current.end)
moveDirRef.current?.setDirection(currentLinVel.current) moveDirRef.current?.setDirection(currentLinVel.current)
moveDirRef.current?.setLength(currentLinVel.current.length() / maxWalkSpeed) moveDirRef.current?.setLength(currentLinVel.current.length() / maxWalkSpeed)
}, [characterSegment, maxWalkSpeed]) }, [maxWalkSpeed])
useFrame((_, delta) => { useFrame((_, delta) => {
elapsedRef.current += delta elapsedRef.current += delta
@@ -3475,7 +3475,7 @@ function FloorplanZoneLabel({
if (textRef.current) { if (textRef.current) {
setTextWidth(textRef.current.getComputedTextLength()) setTextWidth(textRef.current.getComputedTextLength())
} }
}, [zone.name]) }, [])
const isDeleteMode = mode === 'delete' const isDeleteMode = mode === 'delete'
@@ -5136,7 +5136,7 @@ export function FloorplanPanel() {
useEffect(() => { useEffect(() => {
setHoveredGuideCorner(null) setHoveredGuideCorner(null)
}, [selectedGuide?.id]) }, [])
useEffect(() => { useEffect(() => {
if (!(selectedGuide && showGuides && canInteractWithGuides)) { if (!(selectedGuide && showGuides && canInteractWithGuides)) {
@@ -6087,7 +6087,7 @@ export function FloorplanPanel() {
} }
scheduleMovingFloorplanNodeRefresh() scheduleMovingFloorplanNodeRefresh()
}, [hasPendingItemMeshFootprints, scheduleMovingFloorplanNodeRefresh]) }, [scheduleMovingFloorplanNodeRefresh])
// Subscribe to the live-transforms store so rotation/position changes that // 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 // *don't* go through pointer events still refresh the floorplan — e.g. R/T
@@ -6631,7 +6631,7 @@ export function FloorplanPanel() {
pendingFenceDragRef.current = null pendingFenceDragRef.current = null
clearWallEndpointDrag() clearWallEndpointDrag()
clearWallCurveDrag() clearWallCurveDrag()
}, [clearWallCurveDrag, clearWallEndpointDrag, levelId]) }, [clearWallCurveDrag, clearWallEndpointDrag])
useEffect(() => { useEffect(() => {
if (shouldShowSiteBoundaryHandles) { if (shouldShowSiteBoundaryHandles) {
@@ -840,7 +840,7 @@ const ViewerCanvas = memo(function ViewerCanvas({
window.removeEventListener('pointermove', handlePointerMove) window.removeEventListener('pointermove', handlePointerMove)
window.removeEventListener('pointerup', handlePointerUp) window.removeEventListener('pointerup', handlePointerUp)
} }
}, []) }, [setFloorplanPaneRatio])
useEffect(() => { useEffect(() => {
setIsCameraControlsHintVisible(!readCameraControlsHintDismissed()) setIsCameraControlsHintVisible(!readCameraControlsHintDismissed())
@@ -85,7 +85,7 @@ export const StairEditSystem = () => {
} }
prevActiveStairIds.current = activeStairIds prevActiveStairIds.current = activeStairIds
}, [selectedIds, selectedStairSignature]) }, [selectedIds])
return null return null
} }
@@ -1496,7 +1496,16 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
window.removeEventListener('keyup', onKeyUp) window.removeEventListener('keyup', onKeyUp)
window.removeEventListener('contextmenu', onContextMenu) 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 // Refresh wireframe when the grid step changes mid-placement so the green/red
// box snaps to the new cell size right away. // box snaps to the new cell size right away.
@@ -1510,7 +1519,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
) )
updatePreviewGeometry(previewBounds) updatePreviewGeometry(previewBounds)
updateDimensionGuides(previewBounds) updateDimensionGuides(previewBounds)
}, [gridSnapStep, asset, draftNode]) }, [gridSnapStep, asset, draftNode, updateDimensionGuides, updatePreviewGeometry])
// Wall/ceiling items are managed by their own surface entry events (ensureDraft / reparent). // Wall/ceiling items are managed by their own surface entry events (ensureDraft / reparent).
const viewerLevelId = useViewer((s) => s.selection.levelId) const viewerLevelId = useViewer((s) => s.selection.levelId)
useEffect(() => { useEffect(() => {
@@ -1588,6 +1597,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
initialDimensionBounds.dimensions[0], initialDimensionBounds.dimensions[0],
initialDimensionBounds.dimensions[1], initialDimensionBounds.dimensions[1],
initialDimensionBounds.dimensions[2], initialDimensionBounds.dimensions[2],
initialDimensionBounds,
], ],
) )
const basePlaneGeometry = useMemo(() => { const basePlaneGeometry = useMemo(() => {
@@ -546,7 +546,7 @@ const BoxSelectToolInner: React.FC = () => {
canvas.removeEventListener('pointerdown', onCanvasPointerDown) canvas.removeEventListener('pointerdown', onCanvasPointerDown)
canvas.removeEventListener('pointerup', onCanvasPointerUp) canvas.removeEventListener('pointerup', onCanvasPointerUp)
} }
}, [camera, gl]) }, [gl, raycastToGround, syncPreviewSelectedIds])
// grid:move for cursor tracking + rectangle update during drag // grid:move for cursor tracking + rectangle update during drag
useEffect(() => { useEffect(() => {
@@ -603,7 +603,7 @@ const BoxSelectToolInner: React.FC = () => {
return () => { return () => {
emitter.off('grid:move', onMove) emitter.off('grid:move', onMove)
} }
}, []) }, [syncPreviewSelectedIds])
return ( return (
<group> <group>
+21 -24
View File
@@ -393,10 +393,7 @@ export default function DoorPanel() {
const isGarageDoor = node.doorCategory === 'garage' || doorType.startsWith('garage-') const isGarageDoor = node.doorCategory === 'garage' || doorType.startsWith('garage-')
const isSwingDoor = doorType === 'hinged' || doorType === 'double' || doorType === 'french' const isSwingDoor = doorType === 'hinged' || doorType === 'double' || doorType === 'french'
const isSlideFoldDoor = const isSlideFoldDoor =
doorType === 'folding' || doorType === 'folding' || doorType === 'pocket' || doorType === 'barn' || doorType === 'sliding'
doorType === 'pocket' ||
doorType === 'barn' ||
doorType === 'sliding'
const isSlidingDoor = doorType === 'pocket' || doorType === 'barn' || doorType === 'sliding' const isSlidingDoor = doorType === 'pocket' || doorType === 'barn' || doorType === 'sliding'
const isFoldingDoor = doorType === 'folding' const isFoldingDoor = doorType === 'folding'
const isSectionalGarageDoor = doorType === 'garage-sectional' const isSectionalGarageDoor = doorType === 'garage-sectional'
@@ -1027,26 +1024,26 @@ export default function DoorPanel() {
<> <>
{showFrameSection && ( {showFrameSection && (
<PanelSection title="Frame"> <PanelSection title="Frame">
<SliderControl <SliderControl
label="Thickness" label="Thickness"
max={0.2} max={0.2}
min={0.01} min={0.01}
onChange={(v) => handleUpdate({ frameThickness: v })} onChange={(v) => handleUpdate({ frameThickness: v })}
precision={3} precision={3}
step={0.01} step={0.01}
unit="m" unit="m"
value={Math.round(node.frameThickness * 1000) / 1000} value={Math.round(node.frameThickness * 1000) / 1000}
/> />
<SliderControl <SliderControl
label="Depth" label="Depth"
max={0.3} max={0.3}
min={0.01} min={0.01}
onChange={(v) => handleUpdate({ frameDepth: v })} onChange={(v) => handleUpdate({ frameDepth: v })}
precision={3} precision={3}
step={0.01} step={0.01}
unit="m" unit="m"
value={Math.round(node.frameDepth * 1000) / 1000} value={Math.round(node.frameDepth * 1000) / 1000}
/> />
</PanelSection> </PanelSection>
)} )}
+3 -4
View File
@@ -240,6 +240,7 @@ export default function ElevatorPanel() {
node?.type, node?.type,
selectedId, selectedId,
updateNode, updateNode,
node,
]) ])
const previewMetric = useCallback( const previewMetric = useCallback(
@@ -314,7 +315,7 @@ export default function ElevatorPanel() {
}, [clearLivePreview, node, setMovingNode, setSelection]) }, [clearLivePreview, node, setMovingNode, setSelection])
const handleDuplicate = useCallback(() => { const handleDuplicate = useCallback(() => {
if (!(node && node.parentId)) return if (!node?.parentId) return
triggerSFX('sfx:item-pick') triggerSFX('sfx:item-pick')
const duplicate = ElevatorNodeSchema.parse({ const duplicate = ElevatorNodeSchema.parse({
@@ -596,9 +597,7 @@ export default function ElevatorPanel() {
</div> </div>
<select <select
className="h-9 w-full rounded-lg border border-border/50 bg-[#2C2C2E] px-2 text-sm text-foreground" className="h-9 w-full rounded-lg border border-border/50 bg-[#2C2C2E] px-2 text-sm text-foreground"
onChange={(event) => onChange={(event) => handleServiceBoundaryChange('fromLevelId', event.target.value)}
handleServiceBoundaryChange('fromLevelId', event.target.value)
}
value={fromLevelId} value={fromLevelId}
> >
{levels.map((level) => ( {levels.map((level) => (
+1 -1
View File
@@ -5,8 +5,8 @@ import {
constrainWallMoveDeltaToAxis, constrainWallMoveDeltaToAxis,
emitter, emitter,
type FenceNode, type FenceNode,
getPerpendicularWallMoveAxis,
type GridEvent, type GridEvent,
getPerpendicularWallMoveAxis,
type LevelNode, type LevelNode,
useScene, useScene,
type WallMoveAxis, type WallMoveAxis,
-2
View File
@@ -11,9 +11,7 @@ import {
import { import {
ActionButton, ActionButton,
ActionGroup, ActionGroup,
buildRoofSurfaceMaterialPatch,
duplicateRoofSubtree, duplicateRoofSubtree,
MaterialPicker,
PanelSection, PanelSection,
PanelWrapper, PanelWrapper,
SliderControl, SliderControl,
+1 -1
View File
@@ -34,7 +34,7 @@ export default function SpawnPanel() {
setDraftRotation(node.rotation) setDraftRotation(node.rotation)
useLiveTransforms.getState().clear(node.id) useLiveTransforms.getState().clear(node.id)
}, [node?.id, node?.rotation, node?.type]) }, [node?.id, node?.rotation, node?.type, node])
const handleUpdate = useCallback( const handleUpdate = useCallback(
(updates: Partial<SpawnNode>) => { (updates: Partial<SpawnNode>) => {
@@ -45,6 +45,8 @@ export const StairSegmentRenderer = ({ node }: { node: StairSegmentNode }) => {
parentNode?.sideMaterial, parentNode?.sideMaterial,
parentNode?.treadMaterialPreset, parentNode?.treadMaterialPreset,
parentNode?.treadMaterial, parentNode?.treadMaterial,
node,
parentNode,
]) ])
const placeholderGeometry = useMemo(() => { const placeholderGeometry = useMemo(() => {
-2
View File
@@ -16,10 +16,8 @@ import {
import { import {
ActionButton, ActionButton,
ActionGroup, ActionGroup,
buildStairSurfaceMaterialPatch,
DEFAULT_SPIRAL_STAIR_SWEEP_ANGLE, DEFAULT_SPIRAL_STAIR_SWEEP_ANGLE,
duplicateStairSubtree, duplicateStairSubtree,
MaterialPicker,
MetricControl, MetricControl,
PanelSection, PanelSection,
PanelWrapper, PanelWrapper,
+1 -1
View File
@@ -18,9 +18,9 @@ import {
getAngleToSegmentReference, getAngleToSegmentReference,
getSegmentAngleReferenceAtPoint, getSegmentAngleReferenceAtPoint,
markToolCancelConsumed, markToolCancelConsumed,
type SegmentAngleReference,
snapWallDraftPoint, snapWallDraftPoint,
triggerSFX, triggerSFX,
type SegmentAngleReference,
type WallPlanPoint, type WallPlanPoint,
} from '@pascal-app/editor' } from '@pascal-app/editor'
import { useViewer } from '@pascal-app/viewer' import { useViewer } from '@pascal-app/viewer'
+18 -18
View File
@@ -842,24 +842,24 @@ export default function WindowPanel() {
<> <>
{showFrameSection && ( {showFrameSection && (
<PanelSection title="Frame"> <PanelSection title="Frame">
<SliderControl <SliderControl
label="Thickness" label="Thickness"
min={0} min={0}
onChange={(v) => handleUpdate({ frameThickness: v })} onChange={(v) => handleUpdate({ frameThickness: v })}
precision={3} precision={3}
step={0.01} step={0.01}
unit="m" unit="m"
value={Math.round(node.frameThickness * 1000) / 1000} value={Math.round(node.frameThickness * 1000) / 1000}
/> />
<SliderControl <SliderControl
label="Depth" label="Depth"
min={0} min={0}
onChange={(v) => handleUpdate({ frameDepth: v })} onChange={(v) => handleUpdate({ frameDepth: v })}
precision={3} precision={3}
step={0.01} step={0.01}
unit="m" unit="m"
value={Math.round(node.frameDepth * 1000) / 1000} value={Math.round(node.frameDepth * 1000) / 1000}
/> />
</PanelSection> </PanelSection>
)} )}
+1 -1
View File
@@ -1,10 +1,10 @@
import { type NodeDefinition, ZoneNode as ZoneNodeSchema } from '@pascal-app/core' import { type NodeDefinition, ZoneNode as ZoneNodeSchema } from '@pascal-app/core'
import { buildZoneFloorplan } from './floorplan'
import { import {
zoneAddVertexAffordance, zoneAddVertexAffordance,
zoneMoveEdgeAffordance, zoneMoveEdgeAffordance,
zoneMoveVertexAffordance, zoneMoveVertexAffordance,
} from './floorplan-affordances' } from './floorplan-affordances'
import { buildZoneFloorplan } from './floorplan'
import { zoneParametrics } from './parametrics' import { zoneParametrics } from './parametrics'
import { ZoneNode } from './schema' import { ZoneNode } from './schema'
@@ -9,7 +9,6 @@ import {
useScene, useScene,
} from '@pascal-app/core' } from '@pascal-app/core'
import { useFrame } from '@react-three/fiber' import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'
import * as THREE from 'three' import * as THREE from 'three'
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js' import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
@@ -610,7 +609,7 @@ function generateStairRailingGeometry(
for (let index = 1; index < segmentRailPaths.length; index++) { for (let index = 1; index < segmentRailPaths.length; index++) {
const previousPath = segmentRailPaths[index - 1] const previousPath = segmentRailPaths[index - 1]
const currentPath = segmentRailPaths[index] const currentPath = segmentRailPaths[index]
if (!(previousPath && currentPath && currentPath.connectFromPrevious)) continue if (!(previousPath && currentPath?.connectFromPrevious)) continue
if (previousPath.segment.segmentType === 'landing') continue if (previousPath.segment.segmentType === 'landing') continue
for (const sidePath of currentPath.sidePaths) { for (const sidePath of currentPath.sidePaths) {