fix slab detection for wall
This commit is contained in:
@@ -210,6 +210,7 @@ export class SpatialGridManager {
|
|||||||
// Called when nodes change
|
// Called when nodes change
|
||||||
handleNodeCreated(node: AnyNode, levelId: string) {
|
handleNodeCreated(node: AnyNode, levelId: string) {
|
||||||
if (node.type === 'slab') {
|
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)
|
this.getSlabMap(levelId).set(node.id, node as SlabNode)
|
||||||
} else if (node.type === 'ceiling') {
|
} else if (node.type === 'ceiling') {
|
||||||
this.ceilings.set(node.id, node as CeilingNode)
|
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.
|
* Returns the highest slab elevation found, or 0 if none.
|
||||||
*/
|
*/
|
||||||
getSlabElevationForWall(
|
getSlabElevationForWall(
|
||||||
@@ -457,25 +459,17 @@ export class SpatialGridManager {
|
|||||||
end: [number, number],
|
end: [number, number],
|
||||||
): number {
|
): number {
|
||||||
const slabMap = this.slabsByLevel.get(levelId)
|
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
|
if (!slabMap) return 0
|
||||||
|
|
||||||
const samples: [number, number][] = [
|
|
||||||
start,
|
|
||||||
[(start[0] + end[0]) / 2, (start[1] + end[1]) / 2],
|
|
||||||
end,
|
|
||||||
]
|
|
||||||
|
|
||||||
let maxElevation = 0
|
let maxElevation = 0
|
||||||
for (const slab of slabMap.values()) {
|
for (const slab of slabMap.values()) {
|
||||||
if (slab.polygon.length < 3) continue
|
if (slab.polygon.length < 3) continue
|
||||||
for (const [sx, sz] of samples) {
|
if (wallOverlapsPolygon(start, end, slab.polygon)) {
|
||||||
if (pointInPolygon(sx, sz, slab.polygon)) {
|
|
||||||
const elevation = slab.elevation ?? 0.05
|
const elevation = slab.elevation ?? 0.05
|
||||||
if (elevation > maxElevation) {
|
if (elevation > maxElevation) {
|
||||||
maxElevation = elevation
|
maxElevation = elevation
|
||||||
}
|
}
|
||||||
break // This slab matched, no need to check more sample points
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return maxElevation
|
return maxElevation
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ export const CeilingSystem = () => {
|
|||||||
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
updateCeilingGeometry(node as CeilingNode, mesh)
|
updateCeilingGeometry(node as CeilingNode, mesh)
|
||||||
}
|
|
||||||
clearDirty(id as AnyNodeId)
|
clearDirty(id as AnyNodeId)
|
||||||
|
}
|
||||||
|
// If mesh not found, keep it dirty for next frame
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ export const RoofSystem = () => {
|
|||||||
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
updateRoofGeometry(node as RoofNode, mesh)
|
updateRoofGeometry(node as RoofNode, mesh)
|
||||||
}
|
|
||||||
clearDirty(id as AnyNodeId)
|
clearDirty(id as AnyNodeId)
|
||||||
|
}
|
||||||
|
// If mesh not found, keep it dirty for next frame
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ export const SlabSystem = () => {
|
|||||||
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
const mesh = sceneRegistry.nodes.get(id) as THREE.Mesh
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
updateSlabGeometry(node as SlabNode, mesh)
|
updateSlabGeometry(node as SlabNode, mesh)
|
||||||
}
|
|
||||||
clearDirty(id as AnyNodeId)
|
clearDirty(id as AnyNodeId)
|
||||||
|
}
|
||||||
|
// If mesh not found, keep it dirty for next frame
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ export const WallSystem = () => {
|
|||||||
const mesh = sceneRegistry.nodes.get(wallId) as THREE.Mesh
|
const mesh = sceneRegistry.nodes.get(wallId) as THREE.Mesh
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
updateWallGeometry(wallId, miterData)
|
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
|
// Update adjacent walls that share junctions
|
||||||
const adjacentWallIds = getAdjacentWallIds(levelWalls, dirtyWallIds)
|
const adjacentWallIds = getAdjacentWallIds(levelWalls, dirtyWallIds)
|
||||||
@@ -106,6 +107,7 @@ function updateWallGeometry(wallId: string, miterData: WallMiterData) {
|
|||||||
|
|
||||||
const levelId = resolveLevelId(node, nodes)
|
const levelId = resolveLevelId(node, nodes)
|
||||||
const slabElevation = spatialGridManager.getSlabElevationForWall(levelId, node.start, node.end)
|
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 childrenIds = node.children || []
|
||||||
const childrenNodes = childrenIds
|
const childrenNodes = childrenIds
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const RoofRenderer = ({ node }: { node: RoofNode }) => {
|
|||||||
>
|
>
|
||||||
{/* RoofSystem will replace this geometry in the next frame */}
|
{/* RoofSystem will replace this geometry in the next frame */}
|
||||||
<boxGeometry args={[0, 0, 0]} />
|
<boxGeometry args={[0, 0, 0]} />
|
||||||
<meshStandardMaterial color="#8b4513" />
|
<meshStandardMaterial color="white" />
|
||||||
</mesh>
|
</mesh>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user