From 9c185c4d33290c6afab8ca45e00c8931df8d1a08 Mon Sep 17 00:00:00 2001 From: wass08 Date: Thu, 29 Jan 2026 15:08:57 +0900 Subject: [PATCH] fix slab detection for wall --- .../spatial-grid/spatial-grid-manager.ts | 22 +++++++------------ .../src/systems/ceiling/ceiling-system.tsx | 3 ++- .../core/src/systems/roof/roof-system.tsx | 3 ++- .../core/src/systems/slab/slab-system.tsx | 3 ++- .../core/src/systems/wall/wall-system.tsx | 4 +++- .../renderers/roof/roof-renderer.tsx | 2 +- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/core/src/hooks/spatial-grid/spatial-grid-manager.ts b/packages/core/src/hooks/spatial-grid/spatial-grid-manager.ts index bc01f718..e266179b 100644 --- a/packages/core/src/hooks/spatial-grid/spatial-grid-manager.ts +++ b/packages/core/src/hooks/spatial-grid/spatial-grid-manager.ts @@ -210,6 +210,7 @@ export class SpatialGridManager { // Called when nodes change handleNodeCreated(node: AnyNode, levelId: string) { if (node.type === 'slab') { + console.log(`[SpatialGrid] Adding slab ${node.id} to level ${levelId}`, (node as SlabNode).polygon) this.getSlabMap(levelId).set(node.id, node as SlabNode) } else if (node.type === 'ceiling') { this.ceilings.set(node.id, node as CeilingNode) @@ -448,7 +449,8 @@ export class SpatialGridManager { } /** - * Get the slab elevation for a wall by sampling its start, mid, and end points. + * Get the slab elevation for a wall by checking if it overlaps with any slab polygon. + * Uses wallOverlapsPolygon which handles edge cases (points on boundary, collinear segments). * Returns the highest slab elevation found, or 0 if none. */ getSlabElevationForWall( @@ -457,24 +459,16 @@ export class SpatialGridManager { end: [number, number], ): number { const slabMap = this.slabsByLevel.get(levelId) + console.log(`[SpatialGrid] getSlabElevationForWall | levelId: ${levelId} | slabMap size: ${slabMap?.size ?? 0} | slabs:`, slabMap ? Array.from(slabMap.keys()) : []) if (!slabMap) return 0 - const samples: [number, number][] = [ - start, - [(start[0] + end[0]) / 2, (start[1] + end[1]) / 2], - end, - ] - let maxElevation = 0 for (const slab of slabMap.values()) { if (slab.polygon.length < 3) continue - for (const [sx, sz] of samples) { - if (pointInPolygon(sx, sz, slab.polygon)) { - const elevation = slab.elevation ?? 0.05 - if (elevation > maxElevation) { - maxElevation = elevation - } - break // This slab matched, no need to check more sample points + if (wallOverlapsPolygon(start, end, slab.polygon)) { + const elevation = slab.elevation ?? 0.05 + if (elevation > maxElevation) { + maxElevation = elevation } } } diff --git a/packages/core/src/systems/ceiling/ceiling-system.tsx b/packages/core/src/systems/ceiling/ceiling-system.tsx index 8de4a45d..19b5dd51 100644 --- a/packages/core/src/systems/ceiling/ceiling-system.tsx +++ b/packages/core/src/systems/ceiling/ceiling-system.tsx @@ -22,8 +22,9 @@ export const CeilingSystem = () => { const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh if (mesh) { updateCeilingGeometry(node as CeilingNode, mesh) + clearDirty(id as AnyNodeId) } - clearDirty(id as AnyNodeId) + // If mesh not found, keep it dirty for next frame }) }) diff --git a/packages/core/src/systems/roof/roof-system.tsx b/packages/core/src/systems/roof/roof-system.tsx index edac2763..ed0611f8 100644 --- a/packages/core/src/systems/roof/roof-system.tsx +++ b/packages/core/src/systems/roof/roof-system.tsx @@ -22,8 +22,9 @@ export const RoofSystem = () => { const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh if (mesh) { updateRoofGeometry(node as RoofNode, mesh) + clearDirty(id as AnyNodeId) } - clearDirty(id as AnyNodeId) + // If mesh not found, keep it dirty for next frame }) }) diff --git a/packages/core/src/systems/slab/slab-system.tsx b/packages/core/src/systems/slab/slab-system.tsx index e62dda56..99be6a90 100644 --- a/packages/core/src/systems/slab/slab-system.tsx +++ b/packages/core/src/systems/slab/slab-system.tsx @@ -22,8 +22,9 @@ export const SlabSystem = () => { const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh if (mesh) { updateSlabGeometry(node as SlabNode, mesh) + clearDirty(id as AnyNodeId) } - clearDirty(id as AnyNodeId) + // If mesh not found, keep it dirty for next frame }) }) diff --git a/packages/core/src/systems/wall/wall-system.tsx b/packages/core/src/systems/wall/wall-system.tsx index b5f753d4..c9d9b8e9 100644 --- a/packages/core/src/systems/wall/wall-system.tsx +++ b/packages/core/src/systems/wall/wall-system.tsx @@ -53,8 +53,9 @@ export const WallSystem = () => { const mesh = sceneRegistry.nodes.get(wallId) as THREE.Mesh if (mesh) { updateWallGeometry(wallId, miterData) + clearDirty(wallId as AnyNodeId) } - clearDirty(wallId as AnyNodeId) + // If mesh not found, keep it dirty for next frame } // Update adjacent walls that share junctions @@ -106,6 +107,7 @@ function updateWallGeometry(wallId: string, miterData: WallMiterData) { const levelId = resolveLevelId(node, nodes) const slabElevation = spatialGridManager.getSlabElevationForWall(levelId, node.start, node.end) + console.log(`[WallSystem] Wall ${node.name || node.id} | levelId: ${levelId} | start: [${node.start}] | end: [${node.end}] | slabElevation: ${slabElevation}`) const childrenIds = node.children || [] const childrenNodes = childrenIds diff --git a/packages/viewer/src/components/renderers/roof/roof-renderer.tsx b/packages/viewer/src/components/renderers/roof/roof-renderer.tsx index 8c985b1f..31156860 100644 --- a/packages/viewer/src/components/renderers/roof/roof-renderer.tsx +++ b/packages/viewer/src/components/renderers/roof/roof-renderer.tsx @@ -21,7 +21,7 @@ export const RoofRenderer = ({ node }: { node: RoofNode }) => { > {/* RoofSystem will replace this geometry in the next frame */} - + ) }