fix: guard null selected item during item tool placement (#229)
This commit is contained in:
@@ -8,11 +8,11 @@ export const ItemTool: React.FC = () => {
|
|||||||
const draftNode = useDraftNode()
|
const draftNode = useDraftNode()
|
||||||
|
|
||||||
const cursor = usePlacementCoordinator({
|
const cursor = usePlacementCoordinator({
|
||||||
asset: selectedItem!,
|
asset: selectedItem,
|
||||||
draftNode,
|
draftNode,
|
||||||
initDraft: (gridPosition) => {
|
initDraft: (gridPosition) => {
|
||||||
if (!selectedItem?.attachTo) {
|
if (selectedItem && !selectedItem.attachTo) {
|
||||||
draftNode.create(gridPosition, selectedItem!)
|
draftNode.create(gridPosition, selectedItem)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onCommitted: () => {
|
onCommitted: () => {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { distance, smoothstep, uv, vec2 } from 'three/tsl'
|
|||||||
import { LineBasicNodeMaterial, MeshBasicNodeMaterial } from 'three/webgpu'
|
import { LineBasicNodeMaterial, MeshBasicNodeMaterial } from 'three/webgpu'
|
||||||
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 { snapToGrid } from './placement-math'
|
||||||
import {
|
import {
|
||||||
ceilingStrategy,
|
ceilingStrategy,
|
||||||
checkCanPlace,
|
checkCanPlace,
|
||||||
@@ -41,7 +42,6 @@ import {
|
|||||||
wallStrategy,
|
wallStrategy,
|
||||||
} from './placement-strategies'
|
} from './placement-strategies'
|
||||||
import type { PlacementState, TransitionResult } from './placement-types'
|
import type { PlacementState, TransitionResult } from './placement-types'
|
||||||
import { snapToGrid } from './placement-math'
|
|
||||||
import type { DraftNodeHandle } from './use-draft-node'
|
import type { DraftNodeHandle } from './use-draft-node'
|
||||||
|
|
||||||
const DEFAULT_DIMENSIONS: [number, number, number] = [1, 1, 1]
|
const DEFAULT_DIMENSIONS: [number, number, number] = [1, 1, 1]
|
||||||
@@ -69,7 +69,7 @@ const radialOpacity = smoothstep(0, 0.7, dist).mul(0.6)
|
|||||||
basePlaneMaterial.opacityNode = radialOpacity
|
basePlaneMaterial.opacityNode = radialOpacity
|
||||||
|
|
||||||
export interface PlacementCoordinatorConfig {
|
export interface PlacementCoordinatorConfig {
|
||||||
asset: AssetInput
|
asset: AssetInput | null
|
||||||
draftNode: DraftNodeHandle
|
draftNode: DraftNodeHandle
|
||||||
initDraft: (gridPosition: Vector3) => void
|
initDraft: (gridPosition: Vector3) => void
|
||||||
onCommitted: () => boolean
|
onCommitted: () => boolean
|
||||||
@@ -98,6 +98,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
|
|||||||
const { asset, draftNode } = config
|
const { asset, draftNode } = config
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!asset) return
|
||||||
useScene.temporal.getState().pause()
|
useScene.temporal.getState().pause()
|
||||||
|
|
||||||
const validators = { canPlaceOnFloor, canPlaceOnWall, canPlaceOnCeiling }
|
const validators = { canPlaceOnFloor, canPlaceOnWall, canPlaceOnCeiling }
|
||||||
@@ -873,6 +874,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
|
|||||||
// Wall/ceiling items are managed by their own surface entry events (ensureDraft / reparent).
|
// Wall/ceiling items are managed by their own surface entry events (ensureDraft / reparent).
|
||||||
const viewerLevelId = useViewer((s) => s.selection.levelId)
|
const viewerLevelId = useViewer((s) => s.selection.levelId)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!asset) return
|
||||||
const draft = draftNode.current
|
const draft = draftNode.current
|
||||||
if (!(draft && viewerLevelId) || asset.attachTo) return
|
if (!(draft && viewerLevelId) || asset.attachTo) return
|
||||||
if (draft.parentId === viewerLevelId) return
|
if (draft.parentId === viewerLevelId) return
|
||||||
@@ -881,6 +883,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
|
|||||||
}, [viewerLevelId, draftNode, asset])
|
}, [viewerLevelId, draftNode, asset])
|
||||||
|
|
||||||
useFrame((_, delta) => {
|
useFrame((_, delta) => {
|
||||||
|
if (!asset) return
|
||||||
if (!draftNode.current) return
|
if (!draftNode.current) return
|
||||||
const mesh = sceneRegistry.nodes.get(draftNode.current.id)
|
const mesh = sceneRegistry.nodes.get(draftNode.current.id)
|
||||||
if (!mesh) return
|
if (!mesh) return
|
||||||
|
|||||||
Reference in New Issue
Block a user