From b382a2b90c944f9de1b7908e15e0ba001e8bdc1f Mon Sep 17 00:00:00 2001 From: Wassim SAMAD Date: Fri, 16 Oct 2026 08:21:44 -0400 Subject: [PATCH 1/2] distribution: the editor's run tool names no kind; duct and pipe specifics live in nodes The run-authoring tool moved to @pascal-app/editor/distribution so node packs can share it without importing the built-in plugin (E-001, E-017). It came with what only the built-in kinds mean: - The port systems (duct supply/return, DWV waste/vent, refrigerant) and the nominal-inch section size are the built-in kinds' conventions: they move to nodes/src/shared/port-systems.ts, where those kinds' tools import them. - The run-body queries required no kinds and fell back to 'duct-segment'; every caller now says which kinds it snaps to (the duct tool already meant ducts, and a node pack's runs no longer read as ducts by default). No behaviour changes; the public editor/distribution entry keeps every export a node pack uses. Co-Authored-By: Claude Opus 5.5 --- .../distribution-run-tool.test.ts | 6 ---- .../distribution/distribution-run-tool.tsx | 4 --- .../components/tools/distribution/ports.ts | 29 +++++++------------ packages/nodes/src/duct-fitting/tool.tsx | 2 +- packages/nodes/src/duct-segment/move-tool.tsx | 3 +- packages/nodes/src/duct-segment/selection.tsx | 7 ++--- packages/nodes/src/duct-segment/tool.tsx | 12 +++++--- packages/nodes/src/duct-terminal/tool.tsx | 2 +- packages/nodes/src/lineset/tool.tsx | 2 +- packages/nodes/src/liquid-line/tool.tsx | 2 +- packages/nodes/src/pipe-fitting/tool.tsx | 2 +- packages/nodes/src/pipe-segment/selection.tsx | 7 ++--- packages/nodes/src/pipe-segment/tool.tsx | 3 +- .../nodes/src/shared/port-systems.test.ts | 7 +++++ packages/nodes/src/shared/port-systems.ts | 11 +++++++ .../src/shared/refrigerant-line-selection.tsx | 7 ++--- .../nodes/src/shared/run-crossing.test.ts | 9 ++++-- 17 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 packages/nodes/src/shared/port-systems.test.ts create mode 100644 packages/nodes/src/shared/port-systems.ts diff --git a/packages/editor/src/components/tools/distribution/distribution-run-tool.test.ts b/packages/editor/src/components/tools/distribution/distribution-run-tool.test.ts index 8c99247ee6..cf9e926abd 100644 --- a/packages/editor/src/components/tools/distribution/distribution-run-tool.test.ts +++ b/packages/editor/src/components/tools/distribution/distribution-run-tool.test.ts @@ -10,7 +10,6 @@ import { type RunCursorRay, type RunPoint, runDistanceSquared, - runSectionHalfSizeM, snapRunLength, snapRunPointToSurface, snapRunValue, @@ -217,11 +216,6 @@ describe('distribution run drafting helpers', () => { expect(runDistanceSquared([1, 2, 3], [4, 6, 3])).toBe(25) }) - test('places a run centerline half its section above the support plane', () => { - expect(runSectionHalfSizeM(2)).toBeCloseTo(0.0254) - expect(runSectionHalfSizeM(8)).toBeCloseTo(0.1016) - }) - test('projects and snaps a run in a vertical wall plane', () => { const wall = createRunSurfaceFrame([4, 2, 6], [0, 0, 1]) diff --git a/packages/editor/src/components/tools/distribution/distribution-run-tool.tsx b/packages/editor/src/components/tools/distribution/distribution-run-tool.tsx index a7348efd25..3a772abd50 100644 --- a/packages/editor/src/components/tools/distribution/distribution-run-tool.tsx +++ b/packages/editor/src/components/tools/distribution/distribution-run-tool.tsx @@ -242,10 +242,6 @@ const ALT_PIXELS_PER_METER = 100 export const RUN_PREVIEW_OPACITY = 0.55 export const RUN_SNAP_CURSOR_COLOR = '#22c55e' -export function runSectionHalfSizeM(nominalInches: number): number { - return (nominalInches * 0.0254) / 2 -} - export function snapRunValue(value: number, step: number): number { if (step <= 0) return value return Math.round(value / step) * step diff --git a/packages/editor/src/components/tools/distribution/ports.ts b/packages/editor/src/components/tools/distribution/ports.ts index ff06836ad9..fcacae37cc 100644 --- a/packages/editor/src/components/tools/distribution/ports.ts +++ b/packages/editor/src/components/tools/distribution/ports.ts @@ -11,13 +11,6 @@ import type { RunSurfaceTarget } from './distribution-run-contract' /** A port plus the scene node that owns it. */ export type ScenePort = NodePort & { nodeId: AnyNodeId } -/** Air-loop port systems — what duct runs and fittings snap to. */ -export const DUCT_PORT_SYSTEMS = ['supply', 'return'] as const -/** DWV port systems — what drain / waste / vent pipe runs snap to. */ -export const DWV_PORT_SYSTEMS = ['waste', 'vent'] as const -/** Refrigerant-loop port system — what linesets snap to. */ -export const REFRIGERANT_PORT_SYSTEMS = ['refrigerant'] as const - /** * Filter narrowing which ports a tool will snap to. * - `excludeNodeId` skips the node currently being drawn/placed so a @@ -119,7 +112,7 @@ export function findNearestPort3D( // ─── Run-body hits ─────────────────────────────────────────────────── -/** Closest-point hit on a duct run's centerline (not its end ports). */ +/** Closest-point hit on a run's centerline (not its end ports). */ export type RunBodyHit = { nodeId: AnyNodeId /** Polyline segment hit — between `path[segmentIndex]` and `path[segmentIndex + 1]`. */ @@ -129,20 +122,20 @@ export type RunBodyHit = { } /** - * Nearest point on any duct-segment CENTERLINE within `radius` of `point` + * Nearest point on any run CENTERLINE of the given kinds within `radius` of `point` * on the XZ plane — how a branch taps the side of a trunk. Same XZ-only * distance convention as `findNearestPortXZ` (grid events ride the floor, - * runs hang at duct height); the hit adopts the centerline's full 3D + * runs hang above it); the hit adopts the centerline's full 3D * position. Vertical risers project to a point in XZ and are skipped — * tapping those isn't meaningful. */ export function findNearestRunBodyXZ( point: readonly [number, number, number], radius: number, - filter: { excludeNodeId?: AnyNodeId; kinds?: readonly string[]; levelId?: AnyNodeId } = {}, + filter: { excludeNodeId?: AnyNodeId; kinds: readonly string[]; levelId?: AnyNodeId }, sceneNodes?: Readonly>, ): RunBodyHit | null { - const kinds = filter.kinds ?? ['duct-segment'] + const { kinds } = filter const nodes = sceneNodes ?? useScene.getState().nodes let best: RunBodyHit | null = null let bestDistSq = radius * radius @@ -184,11 +177,11 @@ export function findNearestRunBodyXZ( export function findNearestRunBody3D( point: readonly [number, number, number], radius: number, - filter: { excludeNodeId?: AnyNodeId; kinds?: readonly string[]; levelId?: AnyNodeId } = {}, + filter: { excludeNodeId?: AnyNodeId; kinds: readonly string[]; levelId?: AnyNodeId }, surface?: RunSurfaceTarget | null, sceneNodes?: Readonly>, ): RunBodyHit | null { - const kinds = filter.kinds ?? ['duct-segment'] + const { kinds } = filter const nodes = sceneNodes ?? useScene.getState().nodes let best: RunBodyHit | null = null let bestDistSq = radius * radius @@ -255,9 +248,9 @@ export function findRunBodyCrossingXZ( start: readonly [number, number, number], end: readonly [number, number, number], endMargin: number, - filter: { excludeNodeId?: AnyNodeId; kinds?: readonly string[] } = {}, + filter: { excludeNodeId?: AnyNodeId; kinds: readonly string[] }, ): RunBodyHit | null { - const kinds = filter.kinds ?? ['duct-segment'] + const { kinds } = filter const { nodes } = useScene.getState() const dx = end[0] - start[0] const dz = end[2] - start[2] @@ -313,7 +306,7 @@ export function findRunBodyCrossingSurface( end: readonly [number, number, number], endMargin: number, surface: RunSurfaceTarget, - filter: { excludeNodeId?: AnyNodeId; kinds?: readonly string[] } = {}, + filter: { excludeNodeId?: AnyNodeId; kinds: readonly string[] }, ): RunBodyHit | null { const project = (p: readonly [number, number, number]): [number, number, number] => { const d: [number, number, number] = [ @@ -340,7 +333,7 @@ export function findRunBodyCrossingSurface( const drawnLen = Math.hypot(dx, dy) if (drawnLen < 1e-8) return null const drawnPad = Math.min(0.45, endMargin / drawnLen) - const kinds = filter.kinds ?? ['duct-segment'] + const { kinds } = filter const { nodes } = useScene.getState() let best: RunBodyHit | null = null let bestScore = Number.POSITIVE_INFINITY diff --git a/packages/nodes/src/duct-fitting/tool.tsx b/packages/nodes/src/duct-fitting/tool.tsx index 70605dbf4b..f89058219d 100644 --- a/packages/nodes/src/duct-fitting/tool.tsx +++ b/packages/nodes/src/duct-fitting/tool.tsx @@ -15,7 +15,6 @@ import { alignDrawPoint, clearDrawAlignment, collectScenePorts, - DUCT_PORT_SYSTEMS, type ScenePort, } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' @@ -42,6 +41,7 @@ import { } from '../shared/fitting-rotation' import { createFittingSurfaceSupport } from '../shared/fitting-surface-support' import { LevelOffsetGroup } from '../shared/level-offset-group' +import { DUCT_PORT_SYSTEMS } from '../shared/port-systems' import { ductFittingDefinition } from './definition' import { buildDuctFittingGeometry } from './geometry' import { localFittingPorts } from './ports' diff --git a/packages/nodes/src/duct-segment/move-tool.tsx b/packages/nodes/src/duct-segment/move-tool.tsx index 26821c2812..256ad6b9b2 100644 --- a/packages/nodes/src/duct-segment/move-tool.tsx +++ b/packages/nodes/src/duct-segment/move-tool.tsx @@ -25,7 +25,7 @@ import { useAlignmentGuides, useEditor, } from '@pascal-app/editor' -import { collectScenePorts, DUCT_PORT_SYSTEMS } from '@pascal-app/editor/distribution' +import { collectScenePorts } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { useEffect, useRef, useState } from 'react' import { Matrix4, Vector3 } from 'three' @@ -35,6 +35,7 @@ import { resolveGhostAlignment, } from '../shared/ghost-alignment' import { DuctSegmentGhost, FittingGhost } from '../shared/mep-ghost' +import { DUCT_PORT_SYSTEMS } from '../shared/port-systems' import { type RunMoveConnectivity, startRunMoveConnectivity } from '../shared/run-move-connectivity' import { planRunTranslationOffsets, diff --git a/packages/nodes/src/duct-segment/selection.tsx b/packages/nodes/src/duct-segment/selection.tsx index 406b071c4c..c1a302d1e1 100644 --- a/packages/nodes/src/duct-segment/selection.tsx +++ b/packages/nodes/src/duct-segment/selection.tsx @@ -25,11 +25,7 @@ import { triggerSFX, useEditor, } from '@pascal-app/editor' -import { - collectScenePorts, - DUCT_PORT_SYSTEMS, - findNearestPortXZ, -} from '@pascal-app/editor/distribution' +import { collectScenePorts, findNearestPortXZ } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { Html } from '@react-three/drei' import { createPortal, type ThreeEvent, useFrame, useThree } from '@react-three/fiber' @@ -60,6 +56,7 @@ import { planFittingEndpointReaim, } from '../shared/fitting-endpoint-reaim' import { DuctSegmentGhost, FittingGhost } from '../shared/mep-ghost' +import { DUCT_PORT_SYSTEMS } from '../shared/port-systems' import { planRunTranslationOffsets } from '../shared/run-translation-offset' import { ContinuePlusHandle, HandleCube, MoveChevron, RotateArc } from '../shared/selection-handles' import { planVerticalOffsets, type VerticalOffsetResult } from '../shared/vertical-offset' diff --git a/packages/nodes/src/duct-segment/tool.tsx b/packages/nodes/src/duct-segment/tool.tsx index fc58741024..16e6608aa7 100644 --- a/packages/nodes/src/duct-segment/tool.tsx +++ b/packages/nodes/src/duct-segment/tool.tsx @@ -12,13 +12,11 @@ import { collectScenePorts, createRunWallAttachment, DistributionRunCursor, - DUCT_PORT_SYSTEMS, runDistanceSquared as dist2, findNearestRunBody3D, findRunBodyCrossingSurface, type RunBodyHit, type RunSurfaceTarget, - runSectionHalfSizeM, type ScenePort, stepNominalRunSize, useDistributionRunTool, @@ -42,6 +40,7 @@ import { ductProfilesMatch, planDuctAdapter } from '../shared/duct-adapter' import { FITTING_CLEARANCE_MESSAGE, hasFittingClearance } from '../shared/fitting-clearance' import { LevelOffsetGroup } from '../shared/level-offset-group' import { DuctSegmentGhost, FittingGhost } from '../shared/mep-ghost' +import { DUCT_PORT_SYSTEMS, runSectionHalfSizeM } from '../shared/port-systems' import { RunHangerPreview } from '../shared/run-hanger-controls' import { useRunHangerMode } from '../shared/run-hanger-mode' import { currentDuctContinuationSeed, ductEndpointPort } from './continuation' @@ -415,7 +414,9 @@ export function planDuctDraw( const realigns = [startRealign, endRealign].filter((p) => p !== null) const crossHit = surface - ? findRunBodyCrossingSurface(start, end, BODY_SNAP_RADIUS_M, surface) + ? findRunBodyCrossingSurface(start, end, BODY_SNAP_RADIUS_M, surface, { + kinds: ['duct-segment'], + }) : null const crossOwner = crossHit ? nodes[crossHit.nodeId] : null const crossTappedElsewhere = @@ -566,7 +567,10 @@ const DuctSegmentTool = () => { : null, getPorts: () => getConnectionPorts(activeLevelId, sceneApi.nodes()), findBody: (point) => - findNearestRunBody3D(point, BODY_SNAP_RADIUS_M, { levelId: activeLevelId ?? undefined }), + findNearestRunBody3D(point, BODY_SNAP_RADIUS_M, { + kinds: ['duct-segment'], + levelId: activeLevelId ?? undefined, + }), surfaceClearance: (surface) => surface ? ductSurfaceClearanceM(profileRef.current, surface.kind === 'wall') : 0, minimumSegmentLength: 0.08, diff --git a/packages/nodes/src/duct-terminal/tool.tsx b/packages/nodes/src/duct-terminal/tool.tsx index 66f26240db..70ac58bf8b 100644 --- a/packages/nodes/src/duct-terminal/tool.tsx +++ b/packages/nodes/src/duct-terminal/tool.tsx @@ -29,7 +29,6 @@ import { alignDrawPoint, clearDrawAlignment, collectScenePorts, - DUCT_PORT_SYSTEMS, findNearestPort3D, } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' @@ -40,6 +39,7 @@ import { Euler, Matrix3, Matrix4, Plane, Quaternion, Raycaster, Vector2, Vector3 import { subscribeAccessorySnapping } from '../shared/accessory-snapping' import { ConnectionFeedback } from '../shared/connection-feedback' import { LevelOffsetGroup } from '../shared/level-offset-group' +import { DUCT_PORT_SYSTEMS } from '../shared/port-systems' import { ductTerminalDefinition } from './definition' import { buildDuctTerminalGeometry } from './geometry' import { COLLAR_LENGTH, getDuctTerminalPorts, mountQuaternion } from './ports' diff --git a/packages/nodes/src/lineset/tool.tsx b/packages/nodes/src/lineset/tool.tsx index 9bc0e84de0..7fd94555d4 100644 --- a/packages/nodes/src/lineset/tool.tsx +++ b/packages/nodes/src/lineset/tool.tsx @@ -19,13 +19,13 @@ import { clearDrawAlignment, collectScenePorts, findNearestPortXZ, - REFRIGERANT_PORT_SYSTEMS, } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { Html } from '@react-three/drei' import { useEffect, useRef, useState } from 'react' import { type Group, Vector3 } from 'three' import { LevelOffsetGroup } from '../shared/level-offset-group' +import { REFRIGERANT_PORT_SYSTEMS } from '../shared/port-systems' import { linesetDefinition } from './definition' /** diff --git a/packages/nodes/src/liquid-line/tool.tsx b/packages/nodes/src/liquid-line/tool.tsx index 4552c4e7b0..fd69e5704d 100644 --- a/packages/nodes/src/liquid-line/tool.tsx +++ b/packages/nodes/src/liquid-line/tool.tsx @@ -26,7 +26,6 @@ import { clearDrawAlignment, collectScenePorts, findNearestPortXZ, - REFRIGERANT_PORT_SYSTEMS, } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { Html } from '@react-three/drei' @@ -34,6 +33,7 @@ import { useEffect, useRef, useState } from 'react' import { type Group, Vector3 } from 'three' import { LevelOffsetGroup } from '../shared/level-offset-group' import { offsetPathHorizontal } from '../shared/path-offset' +import { REFRIGERANT_PORT_SYSTEMS } from '../shared/port-systems' import { liquidLineDefinition } from './definition' import { useLiquidLineToolOptions } from './options' diff --git a/packages/nodes/src/pipe-fitting/tool.tsx b/packages/nodes/src/pipe-fitting/tool.tsx index afc0ff8776..c09e184411 100644 --- a/packages/nodes/src/pipe-fitting/tool.tsx +++ b/packages/nodes/src/pipe-fitting/tool.tsx @@ -23,7 +23,6 @@ import { alignDrawPoint, clearDrawAlignment, collectScenePorts, - DWV_PORT_SYSTEMS, findNearestRunBody3D, findNearestRunBodyXZ, type ScenePort, @@ -47,6 +46,7 @@ import { } from '../shared/fitting-rotation' import { createFittingSurfaceSupport } from '../shared/fitting-surface-support' import { LevelOffsetGroup } from '../shared/level-offset-group' +import { DWV_PORT_SYSTEMS } from '../shared/port-systems' import { pipeFittingDefinition } from './definition' import { buildPipeFittingGeometry } from './geometry' import { diff --git a/packages/nodes/src/pipe-segment/selection.tsx b/packages/nodes/src/pipe-segment/selection.tsx index 6e5fb0e60b..abb7646e59 100644 --- a/packages/nodes/src/pipe-segment/selection.tsx +++ b/packages/nodes/src/pipe-segment/selection.tsx @@ -23,11 +23,7 @@ import { triggerSFX, useEditor, } from '@pascal-app/editor' -import { - collectScenePorts, - DWV_PORT_SYSTEMS, - findNearestPortXZ, -} from '@pascal-app/editor/distribution' +import { collectScenePorts, findNearestPortXZ } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { Html } from '@react-three/drei' import { createPortal, type ThreeEvent, useFrame, useThree } from '@react-three/fiber' @@ -42,6 +38,7 @@ import { import { PipeFittingGhost, PipeSegmentGhost } from '../shared/mep-ghost' import { planPipeRunTranslationOffsets } from '../shared/pipe-run-translation-offset' import { planVerticalOffsets, type VerticalOffsetResult } from '../shared/pipe-vertical-offset' +import { DWV_PORT_SYSTEMS } from '../shared/port-systems' import { ContinuePlusHandle, HandleCube, MoveChevron } from '../shared/selection-handles' import { refreshWallRunAttachment } from '../shared/wall-run-move' import { diff --git a/packages/nodes/src/pipe-segment/tool.tsx b/packages/nodes/src/pipe-segment/tool.tsx index 59dd094ba1..8063dd9f02 100644 --- a/packages/nodes/src/pipe-segment/tool.tsx +++ b/packages/nodes/src/pipe-segment/tool.tsx @@ -12,7 +12,6 @@ import { collectScenePorts, createRunWallAttachment, DistributionRunCursor, - DWV_PORT_SYSTEMS, findNearestRunBody3D, findRunBodyCrossingSurface, RUN_PREVIEW_OPACITY, @@ -20,7 +19,6 @@ import { type RunPoint, type RunSurfaceTarget, runDistanceSquared, - runSectionHalfSizeM, type ScenePort, stepNominalRunSize, useDistributionRunTool, @@ -41,6 +39,7 @@ import { ConnectionFeedback } from '../shared/connection-feedback' import { FITTING_CLEARANCE_MESSAGE, hasFittingClearance } from '../shared/fitting-clearance' import { LevelOffsetGroup } from '../shared/level-offset-group' import { PipeFittingGhost } from '../shared/mep-ghost' +import { DWV_PORT_SYSTEMS, runSectionHalfSizeM } from '../shared/port-systems' import { RunHangerPreview } from '../shared/run-hanger-controls' import { useRunHangerMode } from '../shared/run-hanger-mode' import { currentPipeContinuationSeed, pipeEndpointPort } from './continuation' diff --git a/packages/nodes/src/shared/port-systems.test.ts b/packages/nodes/src/shared/port-systems.test.ts new file mode 100644 index 0000000000..3728966f74 --- /dev/null +++ b/packages/nodes/src/shared/port-systems.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'bun:test' +import { runSectionHalfSizeM } from './port-systems' + +test('places a run centerline half its section above the support plane', () => { + expect(runSectionHalfSizeM(2)).toBeCloseTo(0.0254) + expect(runSectionHalfSizeM(8)).toBeCloseTo(0.1016) +}) diff --git a/packages/nodes/src/shared/port-systems.ts b/packages/nodes/src/shared/port-systems.ts new file mode 100644 index 0000000000..a2e3b184fd --- /dev/null +++ b/packages/nodes/src/shared/port-systems.ts @@ -0,0 +1,11 @@ +/** Air-loop port systems — what duct runs and fittings snap to. */ +export const DUCT_PORT_SYSTEMS = ['supply', 'return'] as const +/** DWV port systems — what drain / waste / vent pipe runs snap to. */ +export const DWV_PORT_SYSTEMS = ['waste', 'vent'] as const +/** Refrigerant-loop port system — what linesets snap to. */ +export const REFRIGERANT_PORT_SYSTEMS = ['refrigerant'] as const + +/** Half a run's section, in metres, from its nominal size in inches: how far its centerline sits off a support. */ +export function runSectionHalfSizeM(nominalInches: number): number { + return (nominalInches * 0.0254) / 2 +} diff --git a/packages/nodes/src/shared/refrigerant-line-selection.tsx b/packages/nodes/src/shared/refrigerant-line-selection.tsx index d15207e555..d3153db432 100644 --- a/packages/nodes/src/shared/refrigerant-line-selection.tsx +++ b/packages/nodes/src/shared/refrigerant-line-selection.tsx @@ -15,16 +15,13 @@ import { useScene, } from '@pascal-app/core' import { DimensionPill, swallowNextClick, triggerSFX, useEditor } from '@pascal-app/editor' -import { - collectScenePorts, - findNearestPortXZ, - REFRIGERANT_PORT_SYSTEMS, -} from '@pascal-app/editor/distribution' +import { collectScenePorts, findNearestPortXZ } from '@pascal-app/editor/distribution' import { useViewer } from '@pascal-app/viewer' import { Html } from '@react-three/drei' import { createPortal, type ThreeEvent, useFrame, useThree } from '@react-three/fiber' import { useEffect, useMemo, useRef, useState } from 'react' import { type Group, type Object3D, Plane, Raycaster, Vector2, Vector3 } from 'three' +import { REFRIGERANT_PORT_SYSTEMS } from './port-systems' import { HandleCube, MoveChevron } from './selection-handles' type RefrigerantLineKind = 'lineset' | 'liquid-line' diff --git a/packages/nodes/src/shared/run-crossing.test.ts b/packages/nodes/src/shared/run-crossing.test.ts index 0c4826cc32..2638052205 100644 --- a/packages/nodes/src/shared/run-crossing.test.ts +++ b/packages/nodes/src/shared/run-crossing.test.ts @@ -26,9 +26,14 @@ test('ceiling crossings ignore floor runs and connect only at matching 3D height } try { useScene.setState({ nodes: { [floor.id]: floor } }) - expect(findRunBodyCrossingSurface([-2, 3, 0], [2, 3, 0], 0.1, target)).toBeNull() + expect( + findRunBodyCrossingSurface([-2, 3, 0], [2, 3, 0], 0.1, target, { kinds: ['duct-segment'] }), + ).toBeNull() useScene.setState({ nodes: { [floor.id]: floor, [ceiling.id]: ceiling } }) - expect(findRunBodyCrossingSurface([-2, 3, 0], [2, 3, 0], 0.1, target)?.nodeId).toBe(ceiling.id) + expect( + findRunBodyCrossingSurface([-2, 3, 0], [2, 3, 0], 0.1, target, { kinds: ['duct-segment'] }) + ?.nodeId, + ).toBe(ceiling.id) } finally { useScene.setState({ nodes: previous }) } From 1db5c143c759ca756624e4af3eef2f6b1c80b28e Mon Sep 17 00:00:00 2001 From: Wassim SAMAD Date: Fri, 16 Oct 2026 08:33:15 -0400 Subject: [PATCH 2/2] Drop the Pool patch for a commit no longer pinned #1001 moved @pascal-app/plugin-pool from 483a080 to 1da7fb0, which carries the same @types/three 0.186 texture typing fix upstream, so the patch applied to nothing and only made installs rewrite the lockfile. Co-Authored-By: Claude Opus 5.5 --- bun.lock | 1 - package.json | 3 +-- patches/plugin-pool@483a080.patch | 26 -------------------------- 3 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 patches/plugin-pool@483a080.patch diff --git a/bun.lock b/bun.lock index 0ddbf50761..47055cd052 100644 --- a/bun.lock +++ b/bun.lock @@ -375,7 +375,6 @@ }, }, "patchedDependencies": { - "@pascal-app/plugin-pool@github:sudhir9297/pool-pascal-plugin#483a080": "patches/plugin-pool@483a080.patch", "three@0.186.0": "patches/three@0.186.0.patch", "iwer@2.3.0": "patches/iwer@2.3.0.patch", }, diff --git a/package.json b/package.json index b2fbd20fc3..07e23a167c 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,6 @@ ], "patchedDependencies": { "iwer@2.3.0": "patches/iwer@2.3.0.patch", - "three@0.186.0": "patches/three@0.186.0.patch", - "@pascal-app/plugin-pool@github:sudhir9297/pool-pascal-plugin#483a080": "patches/plugin-pool@483a080.patch" + "three@0.186.0": "patches/three@0.186.0.patch" } } diff --git a/patches/plugin-pool@483a080.patch b/patches/plugin-pool@483a080.patch deleted file mode 100644 index 435810b757..0000000000 --- a/patches/plugin-pool@483a080.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/src/shader/water-effect.ts b/src/shader/water-effect.ts -index 49b8849e46bd71ab7b92dc511865844afb598747..e9e626669e00fb096d77cdcea8d1bd4f1ba1cb1f 100644 ---- a/src/shader/water-effect.ts -+++ b/src/shader/water-effect.ts -@@ -5,6 +5,7 @@ import { - HalfFloatType, - LinearFilter, - MeshBasicNodeMaterial, -+ type Node, - NodeMaterial, - QuadMesh, - RenderTarget, -@@ -173,7 +174,12 @@ export function createImmersiveXRPoolWaterMaterial( - return material - } - --type TextureNodeLike = ReturnType & { value: Texture } -+// @types/three 0.186 types `sample()` as returning the texture node itself, which hides -+// the vec4 swizzles (.r, .rgb, ...) the shader reads from every sample. -+type TextureNodeLike = Omit, 'sample'> & { -+ value: Texture -+ sample(uvNode: Node): Node<'vec4'> -+} - - function makeTarget(resolution: number) { - const target = new RenderTarget(resolution, resolution, {