Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 9 additions & 20 deletions packages/nodes/src/wall/tool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import {
import { getSceneTheme, useViewer } from '@pascal-app/viewer'
import { useThree } from '@react-three/fiber'
import { useEffect, useRef, useState } from 'react'
import { BoxGeometry, DoubleSide, type Group, type Mesh, Vector3 } from 'three'
import { DoubleSide, type Group, type Mesh, Vector3 } from 'three'
import {
DraftAngleArc,
type DraftAngleLabel,
Expand Down Expand Up @@ -388,16 +388,11 @@ function updateWallPreview(
mesh.visible = true
direction.normalize()

const geometry = new BoxGeometry(length, previewHeight, previewThickness)
const angle = Math.atan2(direction.z, direction.x)

mesh.position.set((start.x + end.x) / 2, start.y + previewHeight / 2, (start.z + end.z) / 2)
mesh.rotation.y = -angle

if (mesh.geometry) {
mesh.geometry.dispose()
}
mesh.geometry = geometry
mesh.scale.set(length, previewHeight, previewThickness)
}

function getLevelWalls(levelId: string | null, nodes: Record<string, AnyNode>): WallNode[] {
Expand Down Expand Up @@ -687,13 +682,9 @@ export const WallTool: React.FC = () => {
angleLabel: null,
})
triggerSFX('sfx:structure-build-start')
// Visibility is owned by `updateWallPreview` — it flips
// `mesh.visible` based on segment length. Setting it here
// (before any geometry data has been written) draws the
// mesh's empty `<shapeGeometry/>` placeholder, which WebGPU
// flags as "Vertex buffer slot 0 ... was not set" on the
// first frame after click. Leaving it false until the next
// `onGridMove` writes a real BoxGeometry skips that frame.
// Visibility is owned by `updateWallPreview`. Leave the
// unit box hidden until the first pointer move scales and
// positions it for the active segment.
setDraftMeasurement(null)
} else if (buildingState.current === 1) {
const angleLocked = isAngleSnapActive()
Expand Down Expand Up @@ -772,11 +763,9 @@ export const WallTool: React.FC = () => {
y: event.localPosition[1],
angleLabel: null,
})
// Hide the preview until the next `onGridMove` writes the
// new segment's geometry. Without this the prior segment's
// BoxGeometry stays visible for a frame on top of the
// freshly-committed real wall, producing a brief
// double-paint at the new wall's position.
// Hide the preview until the next `onGridMove` scales and
// repositions it. Otherwise the prior segment stays visible
// for a frame on top of the freshly committed wall.
if (wallPreviewRef.current) {
wallPreviewRef.current.visible = false
}
Expand Down Expand Up @@ -818,7 +807,7 @@ export const WallTool: React.FC = () => {
/>
<CursorSphere height={previewHeight} ref={cursorRef} />
<mesh layers={EDITOR_LAYER} ref={wallPreviewRef} renderOrder={1} visible={false}>
<shapeGeometry />
<boxGeometry />
<meshBasicMaterial
color="#818cf8"
depthTest={false}
Expand Down