feat: implement editable wall length slider (#195)
feat: implement editable wall length slider #191
This commit is contained in:
@@ -6,7 +6,7 @@ import { markToolCancelConsumed } from '../../../hooks/use-keyboard'
|
|||||||
import { EDITOR_LAYER } from '../../../lib/constants'
|
import { EDITOR_LAYER } from '../../../lib/constants'
|
||||||
import { sfxEmitter } from '../../../lib/sfx-bus'
|
import { sfxEmitter } from '../../../lib/sfx-bus'
|
||||||
import { CursorSphere } from '../shared/cursor-sphere'
|
import { CursorSphere } from '../shared/cursor-sphere'
|
||||||
import { createWallOnCurrentLevel, snapWallDraftPoint, type WallPlanPoint } from './wall-drafting'
|
import { createWallOnCurrentLevel, snapWallDraftPoint, WALL_MIN_LENGTH, type WallPlanPoint } from './wall-drafting'
|
||||||
|
|
||||||
const WALL_HEIGHT = 2.5
|
const WALL_HEIGHT = 2.5
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ const updateWallPreview = (mesh: Mesh, start: Vector3, end: Vector3) => {
|
|||||||
const direction = new Vector3(end.x - start.x, 0, end.z - start.z)
|
const direction = new Vector3(end.x - start.x, 0, end.z - start.z)
|
||||||
const length = direction.length()
|
const length = direction.length()
|
||||||
|
|
||||||
if (length < 0.01) {
|
if (length < WALL_MIN_LENGTH) {
|
||||||
mesh.visible = false
|
mesh.visible = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ export const WallTool: React.FC = () => {
|
|||||||
endingPoint.current.set(snappedEnd[0], event.position[1], snappedEnd[1])
|
endingPoint.current.set(snappedEnd[0], event.position[1], snappedEnd[1])
|
||||||
const dx = endingPoint.current.x - startingPoint.current.x
|
const dx = endingPoint.current.x - startingPoint.current.x
|
||||||
const dz = endingPoint.current.z - startingPoint.current.z
|
const dz = endingPoint.current.z - startingPoint.current.z
|
||||||
if (dx * dx + dz * dz < 0.01 * 0.01) return
|
if (dx * dx + dz * dz < WALL_MIN_LENGTH * WALL_MIN_LENGTH) return
|
||||||
createWallOnCurrentLevel(
|
createWallOnCurrentLevel(
|
||||||
[startingPoint.current.x, startingPoint.current.z],
|
[startingPoint.current.x, startingPoint.current.z],
|
||||||
[endingPoint.current.x, endingPoint.current.z],
|
[endingPoint.current.x, endingPoint.current.z],
|
||||||
|
|||||||
@@ -25,6 +25,29 @@ export function WallPanel() {
|
|||||||
[selectedId, updateNode],
|
[selectedId, updateNode],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Função mágica para a Issue #191: Atualiza o comprimento via cálculo vetorial
|
||||||
|
const handleUpdateLength = useCallback((newLength: number) => {
|
||||||
|
if (!node || newLength <= 0) return
|
||||||
|
|
||||||
|
const dx = node.end[0] - node.start[0]
|
||||||
|
const dz = node.end[1] - node.start[1]
|
||||||
|
const currentLength = Math.sqrt(dx * dx + dz * dz)
|
||||||
|
|
||||||
|
if (currentLength === 0) return
|
||||||
|
|
||||||
|
// Calcula a direção (vetor unitário)
|
||||||
|
const dirX = dx / currentLength
|
||||||
|
const dirZ = dz / currentLength
|
||||||
|
|
||||||
|
// Define o novo ponto final baseado no novo comprimento
|
||||||
|
const newEnd: [number, number] = [
|
||||||
|
node.start[0] + dirX * newLength,
|
||||||
|
node.start[1] + dirZ * newLength
|
||||||
|
]
|
||||||
|
|
||||||
|
handleUpdate({ end: newEnd })
|
||||||
|
}, [node, handleUpdate])
|
||||||
|
|
||||||
const handleClose = useCallback(() => {
|
const handleClose = useCallback(() => {
|
||||||
setSelection({ selectedIds: [] })
|
setSelection({ selectedIds: [] })
|
||||||
}, [setSelection])
|
}, [setSelection])
|
||||||
@@ -46,6 +69,17 @@ export function WallPanel() {
|
|||||||
width={280}
|
width={280}
|
||||||
>
|
>
|
||||||
<PanelSection title="Dimensions">
|
<PanelSection title="Dimensions">
|
||||||
|
{/* Adicionando o controle de Length solicitado na Issue #191 */}
|
||||||
|
<SliderControl
|
||||||
|
label="Length"
|
||||||
|
max={20}
|
||||||
|
min={0.1}
|
||||||
|
onChange={handleUpdateLength}
|
||||||
|
precision={2}
|
||||||
|
step={0.01}
|
||||||
|
unit="m"
|
||||||
|
value={length}
|
||||||
|
/>
|
||||||
<SliderControl
|
<SliderControl
|
||||||
label="Height"
|
label="Height"
|
||||||
max={6}
|
max={6}
|
||||||
@@ -67,13 +101,6 @@ export function WallPanel() {
|
|||||||
value={Math.round(thickness * 1000) / 1000}
|
value={Math.round(thickness * 1000) / 1000}
|
||||||
/>
|
/>
|
||||||
</PanelSection>
|
</PanelSection>
|
||||||
|
|
||||||
<PanelSection title="Info">
|
|
||||||
<div className="flex items-center justify-between px-2 py-1 text-muted-foreground text-sm">
|
|
||||||
<span>Length</span>
|
|
||||||
<span className="font-mono text-white">{length.toFixed(2)} m</span>
|
|
||||||
</div>
|
|
||||||
</PanelSection>
|
|
||||||
</PanelWrapper>
|
</PanelWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user