fix item scale surface
This commit is contained in:
@@ -34,13 +34,15 @@ function MoveItemContent({ movingNode }: { movingNode: ItemNode }) {
|
|||||||
draftNode,
|
draftNode,
|
||||||
// Duplicates start fresh in floor mode; wall/ceiling draft is created lazily by ensureDraft
|
// Duplicates start fresh in floor mode; wall/ceiling draft is created lazily by ensureDraft
|
||||||
initialState: isNew ? { surface: 'floor', wallId: null, ceilingId: null, surfaceItemId: null } : getInitialState(movingNode),
|
initialState: isNew ? { surface: 'floor', wallId: null, ceilingId: null, surfaceItemId: null } : getInitialState(movingNode),
|
||||||
|
// Preserve the original item's scale so Y-position calculations use the correct height
|
||||||
|
defaultScale: isNew ? movingNode.scale : undefined,
|
||||||
initDraft: (gridPosition) => {
|
initDraft: (gridPosition) => {
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
// Duplicate: use the same create() path as ItemTool so ghost rendering works correctly.
|
// Duplicate: use the same create() path as ItemTool so ghost rendering works correctly.
|
||||||
// Floor items get a draft immediately; wall/ceiling items are created lazily on surface entry.
|
// Floor items get a draft immediately; wall/ceiling items are created lazily on surface entry.
|
||||||
gridPosition.copy(new Vector3(...movingNode.position))
|
gridPosition.copy(new Vector3(...movingNode.position))
|
||||||
if (!movingNode.asset.attachTo) {
|
if (!movingNode.asset.attachTo) {
|
||||||
draftNode.create(gridPosition, movingNode.asset, movingNode.rotation)
|
draftNode.create(gridPosition, movingNode.asset, movingNode.rotation, movingNode.scale)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
draftNode.adopt(movingNode)
|
draftNode.adopt(movingNode)
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ export const itemSurfaceStrategy = {
|
|||||||
|
|
||||||
const x = snapToGrid(localPos.x, ourDims[0])
|
const x = snapToGrid(localPos.x, ourDims[0])
|
||||||
const z = snapToGrid(localPos.z, ourDims[2])
|
const z = snapToGrid(localPos.z, ourDims[2])
|
||||||
const y = surfaceItem.asset.surface.height
|
const y = surfaceItem.asset.surface.height * surfaceItem.scale[1]
|
||||||
|
|
||||||
const worldSnapped = surfaceMesh.localToWorld(new Vector3(x, y, z))
|
const worldSnapped = surfaceMesh.localToWorld(new Vector3(x, y, z))
|
||||||
|
|
||||||
@@ -445,7 +445,7 @@ export const itemSurfaceStrategy = {
|
|||||||
|
|
||||||
const x = snapToGrid(localPos.x, ourDims[0])
|
const x = snapToGrid(localPos.x, ourDims[0])
|
||||||
const z = snapToGrid(localPos.z, ourDims[2])
|
const z = snapToGrid(localPos.z, ourDims[2])
|
||||||
const y = surfaceItem.asset.surface.height
|
const y = surfaceItem.asset.surface.height * surfaceItem.scale[1]
|
||||||
|
|
||||||
const worldSnapped = surfaceMesh.localToWorld(new Vector3(x, y, z))
|
const worldSnapped = surfaceMesh.localToWorld(new Vector3(x, y, z))
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export interface DraftNodeHandle {
|
|||||||
/** Whether the current draft was adopted (move mode) vs created (create mode) */
|
/** Whether the current draft was adopted (move mode) vs created (create mode) */
|
||||||
readonly isAdopted: boolean
|
readonly isAdopted: boolean
|
||||||
/** Create a new draft item at the given position. Returns the created node or null. */
|
/** Create a new draft item at the given position. Returns the created node or null. */
|
||||||
create: (gridPosition: Vector3, asset: AssetInput, rotation?: [number, number, number]) => ItemNode | null
|
create: (gridPosition: Vector3, asset: AssetInput, rotation?: [number, number, number], scale?: [number, number, number]) => ItemNode | null
|
||||||
/** Take ownership of an existing scene node as the draft (for move mode). */
|
/** Take ownership of an existing scene node as the draft (for move mode). */
|
||||||
adopt: (node: ItemNode) => void
|
adopt: (node: ItemNode) => void
|
||||||
/** Commit the current draft. Create mode: delete+recreate. Move mode: update in place. */
|
/** Commit the current draft. Create mode: delete+recreate. Move mode: update in place. */
|
||||||
@@ -40,13 +40,14 @@ export function useDraftNode(): DraftNodeHandle {
|
|||||||
const adoptedRef = useRef(false)
|
const adoptedRef = useRef(false)
|
||||||
const originalStateRef = useRef<OriginalState | null>(null)
|
const originalStateRef = useRef<OriginalState | null>(null)
|
||||||
|
|
||||||
const create = useCallback((gridPosition: Vector3, asset: AssetInput, rotation?: [number, number, number]): ItemNode | null => {
|
const create = useCallback((gridPosition: Vector3, asset: AssetInput, rotation?: [number, number, number], scale?: [number, number, number]): ItemNode | null => {
|
||||||
const currentLevelId = useViewer.getState().selection.levelId
|
const currentLevelId = useViewer.getState().selection.levelId
|
||||||
if (!currentLevelId) return null
|
if (!currentLevelId) return null
|
||||||
|
|
||||||
const node = ItemNode.parse({
|
const node = ItemNode.parse({
|
||||||
position: [gridPosition.x, gridPosition.y, gridPosition.z],
|
position: [gridPosition.x, gridPosition.y, gridPosition.z],
|
||||||
rotation: rotation ?? [0, 0, 0],
|
rotation: rotation ?? [0, 0, 0],
|
||||||
|
scale: scale ?? [1, 1, 1],
|
||||||
name: asset.name,
|
name: asset.name,
|
||||||
asset,
|
asset,
|
||||||
parentId: currentLevelId,
|
parentId: currentLevelId,
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ export interface PlacementCoordinatorConfig {
|
|||||||
onCommitted: () => boolean
|
onCommitted: () => boolean
|
||||||
onCancel?: () => void
|
onCancel?: () => void
|
||||||
initialState?: PlacementState
|
initialState?: PlacementState
|
||||||
|
/** Scale to use when lazily creating a draft (e.g. for wall/ceiling duplicates). Defaults to [1,1,1]. */
|
||||||
|
defaultScale?: [number, number, number]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePlacementCoordinator(config: PlacementCoordinatorConfig): React.ReactNode {
|
export function usePlacementCoordinator(config: PlacementCoordinatorConfig): React.ReactNode {
|
||||||
@@ -140,7 +142,7 @@ export function usePlacementCoordinator(config: PlacementCoordinatorConfig): Rea
|
|||||||
cursorGroupRef.current.position.set(...result.cursorPosition)
|
cursorGroupRef.current.position.set(...result.cursorPosition)
|
||||||
cursorGroupRef.current.rotation.y = result.cursorRotationY
|
cursorGroupRef.current.rotation.y = result.cursorRotationY
|
||||||
|
|
||||||
draftNode.create(gridPosition.current, asset, [0, result.cursorRotationY, 0])
|
draftNode.create(gridPosition.current, asset, [0, result.cursorRotationY, 0], configRef.current.defaultScale)
|
||||||
|
|
||||||
const draft = draftNode.current
|
const draft = draftNode.current
|
||||||
if (draft) {
|
if (draft) {
|
||||||
|
|||||||
Reference in New Issue
Block a user