dynamic cursor depending on mouse scene state (#1995)
* dynamic cursor depending on mouse scene state * hover stuff * bump min length * clean up * sketch on face failing randomly * more time out for extrude snapshots * Update src/clientSideScene/sceneEntities.ts Co-authored-by: Frank Noirot <frank@zoo.dev> * move for profileStart handle, and select when no tool equiped --------- Co-authored-by: Frank Noirot <frank@zoo.dev>
This commit is contained in:
@ -1533,6 +1533,7 @@ test('Sketch on face', async ({ page, context }) => {
|
|||||||
await page.getByRole('button', { name: 'Extrude' }).click()
|
await page.getByRole('button', { name: 'Extrude' }).click()
|
||||||
|
|
||||||
await expect(page.getByTestId('command-bar')).toBeVisible()
|
await expect(page.getByTestId('command-bar')).toBeVisible()
|
||||||
|
await page.waitForTimeout(100)
|
||||||
|
|
||||||
await page.keyboard.press('Enter')
|
await page.keyboard.press('Enter')
|
||||||
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
await expect(page.getByText('Confirm Extrude')).toBeVisible()
|
||||||
|
@ -363,14 +363,14 @@ test('extrude on each default plane should be stable', async ({
|
|||||||
// clear code
|
// clear code
|
||||||
await u.removeCurrentCode()
|
await u.removeCurrentCode()
|
||||||
// add makeCode('XZ')
|
// add makeCode('XZ')
|
||||||
|
await u.openAndClearDebugPanel()
|
||||||
await page.locator('.cm-content').fill(makeCode(plane))
|
await page.locator('.cm-content').fill(makeCode(plane))
|
||||||
// wait for execution done
|
// wait for execution done
|
||||||
await u.openDebugPanel()
|
|
||||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||||
await u.clearAndCloseDebugPanel()
|
await u.clearAndCloseDebugPanel()
|
||||||
|
|
||||||
await page.getByText('Code').click()
|
await page.getByText('Code').click()
|
||||||
await page.waitForTimeout(80)
|
await page.waitForTimeout(150)
|
||||||
await expect(page).toHaveScreenshot({
|
await expect(page).toHaveScreenshot({
|
||||||
maxDiffPixels: 100,
|
maxDiffPixels: 100,
|
||||||
})
|
})
|
||||||
|
@ -4,10 +4,15 @@ import { useModelingContext } from 'hooks/useModelingContext'
|
|||||||
import { cameraMouseDragGuards } from 'lib/cameraControls'
|
import { cameraMouseDragGuards } from 'lib/cameraControls'
|
||||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||||
import { useStore } from 'useStore'
|
import { useStore } from 'useStore'
|
||||||
import { DEBUG_SHOW_BOTH_SCENES } from './sceneInfra'
|
import { ARROWHEAD, DEBUG_SHOW_BOTH_SCENES } from './sceneInfra'
|
||||||
import { ReactCameraProperties } from './CameraControls'
|
import { ReactCameraProperties } from './CameraControls'
|
||||||
import { throttle } from 'lib/utils'
|
import { throttle } from 'lib/utils'
|
||||||
import { sceneInfra } from 'lib/singletons'
|
import { sceneInfra } from 'lib/singletons'
|
||||||
|
import {
|
||||||
|
EXTRA_SEGMENT_HANDLE,
|
||||||
|
PROFILE_START,
|
||||||
|
getParentGroup,
|
||||||
|
} from './sceneEntities'
|
||||||
|
|
||||||
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
|
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
|
||||||
const [isCamMoving, setIsCamMoving] = useState(false)
|
const [isCamMoving, setIsCamMoving] = useState(false)
|
||||||
@ -40,7 +45,7 @@ export const ClientSideScene = ({
|
|||||||
>['settings']['context']['modeling']['mouseControls']['current']
|
>['settings']['context']['modeling']['mouseControls']['current']
|
||||||
}) => {
|
}) => {
|
||||||
const canvasRef = useRef<HTMLDivElement>(null)
|
const canvasRef = useRef<HTMLDivElement>(null)
|
||||||
const { state, send } = useModelingContext()
|
const { state, send, context } = useModelingContext()
|
||||||
const { hideClient, hideServer } = useShouldHideScene()
|
const { hideClient, hideServer } = useShouldHideScene()
|
||||||
const { setHighlightRange } = useStore((s) => ({
|
const { setHighlightRange } = useStore((s) => ({
|
||||||
setHighlightRange: s.setHighlightRange,
|
setHighlightRange: s.setHighlightRange,
|
||||||
@ -76,9 +81,33 @@ export const ClientSideScene = ({
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
let cursor = 'default'
|
||||||
|
if (state.matches('Sketch')) {
|
||||||
|
if (
|
||||||
|
context.mouseState.type === 'isHovering' &&
|
||||||
|
getParentGroup(context.mouseState.on, [
|
||||||
|
ARROWHEAD,
|
||||||
|
EXTRA_SEGMENT_HANDLE,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
|
) {
|
||||||
|
cursor = 'move'
|
||||||
|
} else if (context.mouseState.type === 'isDragging') {
|
||||||
|
cursor = 'grabbing'
|
||||||
|
} else if (
|
||||||
|
state.matches('Sketch.Line tool') ||
|
||||||
|
state.matches('Sketch.Tangential arc to')
|
||||||
|
) {
|
||||||
|
cursor = 'crosshair'
|
||||||
|
} else {
|
||||||
|
cursor = 'default'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={canvasRef}
|
ref={canvasRef}
|
||||||
|
style={{ cursor: cursor }}
|
||||||
className={`absolute inset-0 h-full w-full transition-all duration-300 ${
|
className={`absolute inset-0 h-full w-full transition-all duration-300 ${
|
||||||
hideClient ? 'opacity-0' : 'opacity-100'
|
hideClient ? 'opacity-0' : 'opacity-100'
|
||||||
} ${hideServer ? 'bg-black' : ''} ${
|
} ${hideServer ? 'bg-black' : ''} ${
|
||||||
|
@ -98,8 +98,9 @@ export const TANGENTIAL_ARC_TO__SEGMENT_DASH =
|
|||||||
'tangential-arc-to-segment-body-dashed'
|
'tangential-arc-to-segment-body-dashed'
|
||||||
export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
export const TANGENTIAL_ARC_TO_SEGMENT = 'tangential-arc-to-segment'
|
||||||
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
export const TANGENTIAL_ARC_TO_SEGMENT_BODY = 'tangential-arc-to-segment-body'
|
||||||
export const MIN_SEGMENT_LENGTH = 60 // in pixels
|
|
||||||
export const SEGMENT_WIDTH_PX = 1.6
|
export const SEGMENT_WIDTH_PX = 1.6
|
||||||
|
export const HIDE_SEGMENT_LENGTH = 75 // in pixels
|
||||||
|
export const HIDE_HOVER_SEGMENT_LENGTH = 60 // in pixels
|
||||||
|
|
||||||
// This singleton Class is responsible for all of the things the user sees and interacts with.
|
// This singleton Class is responsible for all of the things the user sees and interacts with.
|
||||||
// That mostly mean sketch elements.
|
// That mostly mean sketch elements.
|
||||||
@ -563,7 +564,7 @@ export class SceneEntities {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
...mouseEnterLeaveCallbacks(),
|
...this.mouseEnterLeaveCallbacks(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setupSketchIdleCallbacks = ({
|
setupSketchIdleCallbacks = ({
|
||||||
@ -685,7 +686,7 @@ export class SceneEntities {
|
|||||||
if (!event) return
|
if (!event) return
|
||||||
sceneInfra.modelingSend(event)
|
sceneInfra.modelingSend(event)
|
||||||
},
|
},
|
||||||
...mouseEnterLeaveCallbacks(),
|
...this.mouseEnterLeaveCallbacks(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
prepareTruncatedMemoryAndAst = (
|
prepareTruncatedMemoryAndAst = (
|
||||||
@ -882,7 +883,16 @@ export class SceneEntities {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const pxLength = arcInfo.arcLength / scale
|
const pxLength = arcInfo.arcLength / scale
|
||||||
const shouldHide = pxLength < MIN_SEGMENT_LENGTH
|
const shouldHideIdle = pxLength < HIDE_SEGMENT_LENGTH
|
||||||
|
const shouldHideHover = pxLength < HIDE_HOVER_SEGMENT_LENGTH
|
||||||
|
|
||||||
|
const hoveredParent =
|
||||||
|
sceneInfra.hoveredObject &&
|
||||||
|
getParentGroup(sceneInfra.hoveredObject, [TANGENTIAL_ARC_TO_SEGMENT])
|
||||||
|
let isHandlesVisible = !shouldHideIdle
|
||||||
|
if (hoveredParent && hoveredParent?.uuid === group?.uuid) {
|
||||||
|
isHandlesVisible = !shouldHideHover
|
||||||
|
}
|
||||||
|
|
||||||
if (arrowGroup) {
|
if (arrowGroup) {
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
@ -894,7 +904,7 @@ export class SceneEntities {
|
|||||||
new Vector3(Math.cos(arrowheadAngle), Math.sin(arrowheadAngle), 0)
|
new Vector3(Math.cos(arrowheadAngle), Math.sin(arrowheadAngle), 0)
|
||||||
)
|
)
|
||||||
arrowGroup.scale.set(scale, scale, scale)
|
arrowGroup.scale.set(scale, scale, scale)
|
||||||
arrowGroup.visible = !shouldHide
|
arrowGroup.visible = isHandlesVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extraSegmentGroup) {
|
if (extraSegmentGroup) {
|
||||||
@ -913,7 +923,7 @@ export class SceneEntities {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
extraSegmentGroup.scale.set(scale, scale, scale)
|
extraSegmentGroup.scale.set(scale, scale, scale)
|
||||||
extraSegmentGroup.visible = !shouldHide
|
extraSegmentGroup.visible = isHandlesVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
const tangentialArcToSegmentBody = group.children.find(
|
const tangentialArcToSegmentBody = group.children.find(
|
||||||
@ -970,7 +980,16 @@ export class SceneEntities {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const pxLength = length / scale
|
const pxLength = length / scale
|
||||||
const shouldHide = pxLength < MIN_SEGMENT_LENGTH
|
const shouldHideIdle = pxLength < HIDE_SEGMENT_LENGTH
|
||||||
|
const shouldHideHover = pxLength < HIDE_HOVER_SEGMENT_LENGTH
|
||||||
|
|
||||||
|
const hoveredParent =
|
||||||
|
sceneInfra.hoveredObject &&
|
||||||
|
getParentGroup(sceneInfra.hoveredObject, [STRAIGHT_SEGMENT])
|
||||||
|
let isHandlesVisible = !shouldHideIdle
|
||||||
|
if (hoveredParent && hoveredParent?.uuid === group?.uuid) {
|
||||||
|
isHandlesVisible = !shouldHideHover
|
||||||
|
}
|
||||||
|
|
||||||
if (arrowGroup) {
|
if (arrowGroup) {
|
||||||
arrowGroup.position.set(to[0], to[1], 0)
|
arrowGroup.position.set(to[0], to[1], 0)
|
||||||
@ -983,7 +1002,7 @@ export class SceneEntities {
|
|||||||
.normalize()
|
.normalize()
|
||||||
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
||||||
arrowGroup.scale.set(scale, scale, scale)
|
arrowGroup.scale.set(scale, scale, scale)
|
||||||
arrowGroup.visible = !shouldHide
|
arrowGroup.visible = isHandlesVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
const extraSegmentGroup = group.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
const extraSegmentGroup = group.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||||
@ -997,7 +1016,7 @@ export class SceneEntities {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
extraSegmentGroup.scale.set(scale, scale, scale)
|
extraSegmentGroup.scale.set(scale, scale, scale)
|
||||||
extraSegmentGroup.visible = !shouldHide
|
extraSegmentGroup.visible = isHandlesVisible
|
||||||
}
|
}
|
||||||
|
|
||||||
const straightSegmentBody = group.children.find(
|
const straightSegmentBody = group.children.find(
|
||||||
@ -1175,6 +1194,119 @@ export class SceneEntities {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
mouseEnterLeaveCallbacks() {
|
||||||
|
return {
|
||||||
|
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
||||||
|
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||||
|
const obj = selected as Mesh
|
||||||
|
const mat = obj.material as MeshBasicMaterial
|
||||||
|
mat.color.set(obj.userData.baseColor)
|
||||||
|
mat.color.offsetHSL(0, 0, 0.5)
|
||||||
|
}
|
||||||
|
const parent = getParentGroup(selected, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
|
if (parent?.userData?.pathToNode) {
|
||||||
|
const updatedAst = parse(recast(kclManager.ast))
|
||||||
|
const node = getNodeFromPath<CallExpression>(
|
||||||
|
updatedAst,
|
||||||
|
parent.userData.pathToNode,
|
||||||
|
'CallExpression'
|
||||||
|
).node
|
||||||
|
sceneInfra.highlightCallback([node.start, node.end])
|
||||||
|
const yellow = 0xffff00
|
||||||
|
colorSegment(selected, yellow)
|
||||||
|
const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||||
|
if (extraSegmentGroup) {
|
||||||
|
extraSegmentGroup.traverse((child) => {
|
||||||
|
if (child instanceof Points || child instanceof Mesh) {
|
||||||
|
child.material.opacity = dragSelected ? 0 : 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
|
const factor =
|
||||||
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
|
? orthoFactor
|
||||||
|
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||||
|
sceneInfra._baseUnitMultiplier
|
||||||
|
if (parent.name === STRAIGHT_SEGMENT) {
|
||||||
|
this.updateStraightSegment({
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
|
this.updateTangentialArcToSegment({
|
||||||
|
prevSegment: parent.userData.prevSegment,
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sceneInfra.highlightCallback([0, 0])
|
||||||
|
},
|
||||||
|
onMouseLeave: ({ selected, ...rest }: OnMouseEnterLeaveArgs) => {
|
||||||
|
sceneInfra.highlightCallback([0, 0])
|
||||||
|
const parent = getParentGroup(selected, [
|
||||||
|
STRAIGHT_SEGMENT,
|
||||||
|
TANGENTIAL_ARC_TO_SEGMENT,
|
||||||
|
PROFILE_START,
|
||||||
|
])
|
||||||
|
if (parent) {
|
||||||
|
const orthoFactor = orthoScale(sceneInfra.camControls.camera)
|
||||||
|
|
||||||
|
const factor =
|
||||||
|
(sceneInfra.camControls.camera instanceof OrthographicCamera
|
||||||
|
? orthoFactor
|
||||||
|
: perspScale(sceneInfra.camControls.camera, parent)) /
|
||||||
|
sceneInfra._baseUnitMultiplier
|
||||||
|
if (parent.name === STRAIGHT_SEGMENT) {
|
||||||
|
this.updateStraightSegment({
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
} else if (parent.name === TANGENTIAL_ARC_TO_SEGMENT) {
|
||||||
|
this.updateTangentialArcToSegment({
|
||||||
|
prevSegment: parent.userData.prevSegment,
|
||||||
|
from: parent.userData.from,
|
||||||
|
to: parent.userData.to,
|
||||||
|
group: parent,
|
||||||
|
scale: factor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const isSelected = parent?.userData?.isSelected
|
||||||
|
colorSegment(
|
||||||
|
selected,
|
||||||
|
isSelected ? 0x0000ff : parent?.userData?.baseColor || 0xffffff
|
||||||
|
)
|
||||||
|
const extraSegmentGroup = parent?.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
||||||
|
if (extraSegmentGroup) {
|
||||||
|
extraSegmentGroup.traverse((child) => {
|
||||||
|
if (child instanceof Points || child instanceof Mesh) {
|
||||||
|
child.material.opacity = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
||||||
|
const obj = selected as Mesh
|
||||||
|
const mat = obj.material as MeshBasicMaterial
|
||||||
|
mat.color.set(obj.userData.baseColor)
|
||||||
|
if (obj.userData.isSelected) mat.color.offsetHSL(0, 0, 0.2)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DefaultPlaneStr = 'XY' | 'XZ' | 'YZ' | '-XY' | '-XZ' | '-YZ'
|
export type DefaultPlaneStr = 'XY' | 'XZ' | 'YZ' | '-XY' | '-XZ' | '-YZ'
|
||||||
@ -1417,69 +1549,3 @@ function massageFormats(a: any): Vector3 {
|
|||||||
? new Vector3(a[0], a[1], a[2])
|
? new Vector3(a[0], a[1], a[2])
|
||||||
: new Vector3(a.x, a.y, a.z)
|
: new Vector3(a.x, a.y, a.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
function mouseEnterLeaveCallbacks() {
|
|
||||||
return {
|
|
||||||
onMouseEnter: ({ selected, dragSelected }: OnMouseEnterLeaveArgs) => {
|
|
||||||
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
|
||||||
const obj = selected as Mesh
|
|
||||||
const mat = obj.material as MeshBasicMaterial
|
|
||||||
mat.color.set(obj.userData.baseColor)
|
|
||||||
mat.color.offsetHSL(0, 0, 0.5)
|
|
||||||
}
|
|
||||||
const parent = getParentGroup(selected, [
|
|
||||||
STRAIGHT_SEGMENT,
|
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
PROFILE_START,
|
|
||||||
])
|
|
||||||
if (parent?.userData?.pathToNode) {
|
|
||||||
const updatedAst = parse(recast(kclManager.ast))
|
|
||||||
const node = getNodeFromPath<CallExpression>(
|
|
||||||
updatedAst,
|
|
||||||
parent.userData.pathToNode,
|
|
||||||
'CallExpression'
|
|
||||||
).node
|
|
||||||
sceneInfra.highlightCallback([node.start, node.end])
|
|
||||||
const yellow = 0xffff00
|
|
||||||
colorSegment(selected, yellow)
|
|
||||||
const extraSegmentGroup = parent.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
|
||||||
if (extraSegmentGroup) {
|
|
||||||
extraSegmentGroup.traverse((child) => {
|
|
||||||
if (child instanceof Points || child instanceof Mesh) {
|
|
||||||
child.material.opacity = dragSelected ? 0 : 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sceneInfra.highlightCallback([0, 0])
|
|
||||||
},
|
|
||||||
onMouseLeave: ({ selected }: OnMouseEnterLeaveArgs) => {
|
|
||||||
sceneInfra.highlightCallback([0, 0])
|
|
||||||
const parent = getParentGroup(selected, [
|
|
||||||
STRAIGHT_SEGMENT,
|
|
||||||
TANGENTIAL_ARC_TO_SEGMENT,
|
|
||||||
PROFILE_START,
|
|
||||||
])
|
|
||||||
const isSelected = parent?.userData?.isSelected
|
|
||||||
colorSegment(
|
|
||||||
selected,
|
|
||||||
isSelected ? 0x0000ff : parent?.userData?.baseColor || 0xffffff
|
|
||||||
)
|
|
||||||
const extraSegmentGroup = parent?.getObjectByName(EXTRA_SEGMENT_HANDLE)
|
|
||||||
if (extraSegmentGroup) {
|
|
||||||
extraSegmentGroup.traverse((child) => {
|
|
||||||
if (child instanceof Points || child instanceof Mesh) {
|
|
||||||
child.material.opacity = 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if ([X_AXIS, Y_AXIS].includes(selected?.userData?.type)) {
|
|
||||||
const obj = selected as Mesh
|
|
||||||
const mat = obj.material as MeshBasicMaterial
|
|
||||||
mat.color.set(obj.userData.baseColor)
|
|
||||||
if (obj.userData.isSelected) mat.color.offsetHSL(0, 0, 0.2)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -30,6 +30,7 @@ import { type BaseUnit } from 'lib/settings/settingsTypes'
|
|||||||
import { CameraControls } from './CameraControls'
|
import { CameraControls } from './CameraControls'
|
||||||
import { EngineCommandManager } from 'lang/std/engineConnection'
|
import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||||
import { settings } from 'lib/settings/initialSettings'
|
import { settings } from 'lib/settings/initialSettings'
|
||||||
|
import { MouseState } from 'machines/modelingMachine'
|
||||||
|
|
||||||
type SendType = ReturnType<typeof useModelingContext>['send']
|
type SendType = ReturnType<typeof useModelingContext>['send']
|
||||||
|
|
||||||
@ -102,6 +103,7 @@ export class SceneInfra {
|
|||||||
_baseUnit: BaseUnit = 'mm'
|
_baseUnit: BaseUnit = 'mm'
|
||||||
_baseUnitMultiplier = 1
|
_baseUnitMultiplier = 1
|
||||||
extraSegmentTexture: Texture
|
extraSegmentTexture: Texture
|
||||||
|
lastMouseState: MouseState = { type: 'idle' }
|
||||||
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragStartCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
onDragEndCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragEndCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
onDragCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
onDragCallback: (arg: OnDragCallbackArgs) => void = () => {}
|
||||||
@ -338,8 +340,6 @@ export class SceneInfra {
|
|||||||
planeIntersectPoint.twoD &&
|
planeIntersectPoint.twoD &&
|
||||||
planeIntersectPoint.threeD
|
planeIntersectPoint.threeD
|
||||||
) {
|
) {
|
||||||
// // console.log('onDrag', this.selected)
|
|
||||||
|
|
||||||
this.onDragCallback({
|
this.onDragCallback({
|
||||||
mouseEvent,
|
mouseEvent,
|
||||||
intersectionPoint: {
|
intersectionPoint: {
|
||||||
@ -349,6 +349,10 @@ export class SceneInfra {
|
|||||||
intersects,
|
intersects,
|
||||||
selected: this.selected.object,
|
selected: this.selected.object,
|
||||||
})
|
})
|
||||||
|
this.updateMouseState({
|
||||||
|
type: 'isDragging',
|
||||||
|
on: this.selected.object,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
planeIntersectPoint &&
|
planeIntersectPoint &&
|
||||||
@ -368,27 +372,34 @@ export class SceneInfra {
|
|||||||
if (intersects[0]) {
|
if (intersects[0]) {
|
||||||
const firstIntersectObject = intersects[0].object
|
const firstIntersectObject = intersects[0].object
|
||||||
if (this.hoveredObject !== firstIntersectObject) {
|
if (this.hoveredObject !== firstIntersectObject) {
|
||||||
if (this.hoveredObject) {
|
const hoveredObj = this.hoveredObject
|
||||||
this.onMouseLeave({
|
this.hoveredObject = null
|
||||||
selected: this.hoveredObject,
|
this.onMouseLeave({
|
||||||
mouseEvent: mouseEvent,
|
selected: hoveredObj,
|
||||||
})
|
mouseEvent: mouseEvent,
|
||||||
}
|
})
|
||||||
this.hoveredObject = firstIntersectObject
|
this.hoveredObject = firstIntersectObject
|
||||||
this.onMouseEnter({
|
this.onMouseEnter({
|
||||||
selected: this.hoveredObject,
|
selected: this.hoveredObject,
|
||||||
dragSelected: this.selected?.object,
|
dragSelected: this.selected?.object,
|
||||||
mouseEvent: mouseEvent,
|
mouseEvent: mouseEvent,
|
||||||
})
|
})
|
||||||
|
if (!this.selected)
|
||||||
|
this.updateMouseState({
|
||||||
|
type: 'isHovering',
|
||||||
|
on: this.hoveredObject,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.hoveredObject) {
|
if (this.hoveredObject) {
|
||||||
|
const hoveredObj = this.hoveredObject
|
||||||
|
this.hoveredObject = null
|
||||||
this.onMouseLeave({
|
this.onMouseLeave({
|
||||||
selected: this.hoveredObject,
|
selected: hoveredObj,
|
||||||
dragSelected: this.selected?.object,
|
dragSelected: this.selected?.object,
|
||||||
mouseEvent: mouseEvent,
|
mouseEvent: mouseEvent,
|
||||||
})
|
})
|
||||||
this.hoveredObject = null
|
if (!this.selected) this.updateMouseState({ type: 'idle' })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -445,6 +456,11 @@ export class SceneInfra {
|
|||||||
(a, b) => a.distance - b.distance
|
(a, b) => a.distance - b.distance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
updateMouseState(mouseState: MouseState) {
|
||||||
|
if (this.lastMouseState.type === mouseState.type) return
|
||||||
|
this.lastMouseState = mouseState
|
||||||
|
this.modelingSend({ type: 'Set mouse state', data: mouseState })
|
||||||
|
}
|
||||||
|
|
||||||
onMouseDown = (event: MouseEvent) => {
|
onMouseDown = (event: MouseEvent) => {
|
||||||
this.currentMouseVector.x = (event.clientX / window.innerWidth) * 2 - 1
|
this.currentMouseVector.x = (event.clientX / window.innerWidth) * 2 - 1
|
||||||
@ -484,6 +500,16 @@ export class SceneInfra {
|
|||||||
mouseEvent,
|
mouseEvent,
|
||||||
selected: this.selected as any,
|
selected: this.selected as any,
|
||||||
})
|
})
|
||||||
|
if (intersects.length) {
|
||||||
|
this.updateMouseState({
|
||||||
|
type: 'isHovering',
|
||||||
|
on: intersects[0].object,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.updateMouseState({
|
||||||
|
type: 'idle',
|
||||||
|
})
|
||||||
|
}
|
||||||
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
} else if (planeIntersectPoint?.twoD && planeIntersectPoint?.threeD) {
|
||||||
// fire onClick event as there was no drags
|
// fire onClick event as there was no drags
|
||||||
this.onClickCallback({
|
this.onClickCallback({
|
||||||
|
@ -25,7 +25,7 @@ import { PathToNode, SketchGroup, getTangentialArcToInfo } from 'lang/wasm'
|
|||||||
import {
|
import {
|
||||||
EXTRA_SEGMENT_HANDLE,
|
EXTRA_SEGMENT_HANDLE,
|
||||||
EXTRA_SEGMENT_OFFSET_PX,
|
EXTRA_SEGMENT_OFFSET_PX,
|
||||||
MIN_SEGMENT_LENGTH,
|
HIDE_SEGMENT_LENGTH,
|
||||||
PROFILE_START,
|
PROFILE_START,
|
||||||
SEGMENT_WIDTH_PX,
|
SEGMENT_WIDTH_PX,
|
||||||
STRAIGHT_SEGMENT,
|
STRAIGHT_SEGMENT,
|
||||||
@ -141,7 +141,7 @@ export function straightSegment({
|
|||||||
.normalize()
|
.normalize()
|
||||||
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
arrowGroup.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), dir)
|
||||||
const pxLength = length / scale
|
const pxLength = length / scale
|
||||||
const shouldHide = pxLength < MIN_SEGMENT_LENGTH
|
const shouldHide = pxLength < HIDE_SEGMENT_LENGTH
|
||||||
arrowGroup.visible = !shouldHide
|
arrowGroup.visible = !shouldHide
|
||||||
|
|
||||||
group.add(mesh)
|
group.add(mesh)
|
||||||
@ -282,7 +282,7 @@ export function tangentialArcToSegment({
|
|||||||
new Vector3(Math.cos(arrowheadAngle), Math.sin(arrowheadAngle), 0)
|
new Vector3(Math.cos(arrowheadAngle), Math.sin(arrowheadAngle), 0)
|
||||||
)
|
)
|
||||||
const pxLength = arcLength / scale
|
const pxLength = arcLength / scale
|
||||||
const shouldHide = pxLength < MIN_SEGMENT_LENGTH
|
const shouldHide = pxLength < HIDE_SEGMENT_LENGTH
|
||||||
arrowGroup.visible = !shouldHide
|
arrowGroup.visible = !shouldHide
|
||||||
|
|
||||||
const extraSegmentGroup = createExtraSegmentHandle(scale, texture)
|
const extraSegmentGroup = createExtraSegmentHandle(scale, texture)
|
||||||
|
@ -112,6 +112,9 @@ export const ModelingMachineProvider = ({
|
|||||||
kclManager.executeAst()
|
kclManager.executeAst()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'Set mouse state': assign({
|
||||||
|
mouseState: (_, event) => event.data,
|
||||||
|
}),
|
||||||
'Set selection': assign(({ selectionRanges }, event) => {
|
'Set selection': assign(({ selectionRanges }, event) => {
|
||||||
if (event.type !== 'Set selection') return {} // this was needed for ts after adding 'Set selection' action to on done modal events
|
if (event.type !== 'Set selection') return {} // this was needed for ts after adding 'Set selection' action to on done modal events
|
||||||
const setSelections = event.data
|
const setSelections = event.data
|
||||||
|
@ -64,6 +64,19 @@ export type SetSelections =
|
|||||||
selection: Selections
|
selection: Selections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MouseState =
|
||||||
|
| {
|
||||||
|
type: 'idle'
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'isHovering'
|
||||||
|
on: any
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'isDragging'
|
||||||
|
on: any
|
||||||
|
}
|
||||||
|
|
||||||
export interface SketchDetails {
|
export interface SketchDetails {
|
||||||
sketchPathToNode: PathToNode
|
sketchPathToNode: PathToNode
|
||||||
zAxis: [number, number, number]
|
zAxis: [number, number, number]
|
||||||
@ -128,12 +141,13 @@ export type ModelingMachineEvent =
|
|||||||
type: 'done.invoke.animate-to-face' | 'done.invoke.animate-to-sketch'
|
type: 'done.invoke.animate-to-face' | 'done.invoke.animate-to-sketch'
|
||||||
data: SketchDetails
|
data: SketchDetails
|
||||||
}
|
}
|
||||||
|
| { type: 'Set mouse state'; data: MouseState }
|
||||||
|
|
||||||
export type MoveDesc = { line: number; snippet: string }
|
export type MoveDesc = { line: number; snippet: string }
|
||||||
|
|
||||||
export const modelingMachine = createMachine(
|
export const modelingMachine = createMachine(
|
||||||
{
|
{
|
||||||
/** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0ANgCcARgB0NcQHYAHKIBMw8QGY1ogKxKANCACeiWUvmT5SraNE15a4QBZxW2QF9X+tBhz4CAZTB2AAJYLDByTm5aBiQQFjZInliBBEFtWUlxGlEnWWVZNQc1fSMEDSl1NXlVewcirWE1d090LDwoSWwITDACAFFcdjAAJxCAa0DyAAto3niOLiTQFMEVDPEVUUd5DfFxYVkHEsQlHMkioqUnNWzq0WaQLzb8Tu7egaHR2An2aapxGLMVgLbi8FZXGjnfYyLS2G7yGiyY4IBw0JSSfLCLQbYQ7Kr7B5PHwdLo9fp8djDACuGFmsXmiTBQi0LkkpxoDW0Di0O2Re1hbOqim0NAcOSchNaxNeZL6fBYw3YdKBCUWTNSpjMpghSiU4jF3PkyNksikBy0hSxCKUhy0ku87Ukfh+02IZEomGdkxm9DmwMZyUQe1EZgcKgOGxoaj1uL5ShkkgtciFzgOOXtzw6Xt+UydLqmAEk3gRkCQJiEwFAALZgQZBABuI045BImGVcX9asDCHUUcTaMRthouNhWj5RTUklNNxkouEwlF9w8jyljuz0zz3qLZNL5dC1drwSmqGG2AAXtx2K32wyu8sg6ZhBibRYLGoWTYjYYg+UMTyDqadTyLIBwZtK665hB269EQ3CwJSJB4EEx6nhegytkEEDYPB7pgDenagt2OJPvYzjRukhxXMiVz7OcuIOLIVgmKIhQOGBa75puObQcQcEIUhjaKtgLaYJh2FXhQeG+vSBFLPwD47GyJiIgxjQ2Ao1GnJOLGmgupxZMB7EvBBXHTDxsG4PBwyIbgQQAIIAEJ+EEAAa+GqoR949qcGSMQcVQck4ziiNRoiMZI9hhSyFphdoRlZpxUHFhZVk2fZTlBAAmu5IJySkGxhYmNTyA0VQMSGyJqFkoiZFUOimrqDRaGxy5Ehx3qmYWyV8dZSFkFAPQ5QGXnqCyU5RhycizmiwjUfVkgRiy0ayMOerxZ1nXmT1aU9Pg7A+oCHYeXlP5igt8gOHYjXYlUs3fggKiaJkb4sYaVrrSZSVkil-G2UwIz-bgWHkFSmAkKMWE4ZJQ13vJ3mouY4gle+OgOPRej3aY761aYBRKFUmwfYl+ZbZZv3ISe56Xq2mAGEErbYFAuAw55cMbOFcgmrYaMWKcIX3WRT4rfIb40WV8hEx1X0wdtAlNsJNN0wzTMsyd3kSFOOhZI9yhI0iAuOE+NBoiaThbAiIuSzmm3dWTvW2bAuAkEwQTsKgrmq+q6iWImdhRnqs7CCo1GrQtt1hsGYgtS0DrGcTW626lSGO87rvu9l0kqrlXvRloEXaM1thWPk+ulDGGRbFN+pVaYLhWxu0u8XbaVgAAjlSGG7VA+2e0RNx53YqJoq+iImHyjGQhdy0sitmgcvXkEk4n5NMODNPUJnR3Z33T2FEjzW6TRfLpOcaPqBP3JNK1q5x1LS-fbLtnDGAVaoI2QTkI-7CwL3I0qJCLF9h5FRGIHY-NSj7ykGGEM2gchiFHgvG2ZIABKYBBBgD4OEKkQxf5s3sHnbkOh3wHBKnkO6pQQwZFnKab2-klCIMbn0du2AXYABk8BgDTqgNsm9bys3yp+cwOhgI3BAlVOQyISp52UGiTm9ETDCAYffd4zCXYSRgIMbAGFwbkDTrglIeoETjUugfBEWJwFBg2OiJGzgdg+RUBLa+scEodTsgAd0QkeSmaEryiUhhJSgQQ8AADNUAEAgNwMAnRcD1lQBMSQMB2CCBQlTdCmBBAhNQPok4VUhZYkaI+UwMhqJ1EhCoFwIZcSiMcTHTMG13GeIpqhamfjxK4SCbgUJBARjDBPJIJgYN2ChOGFWBJgRkneJaRkzpWTeGyXVPjOQ5wNCNDqLiPYGgSlonOBaFw-4rSWEQQ0jgDZ5YiTElDQJmTwmROibE+JiTBCCWbK2aZoTskPWjA4HZs9Cg2BkI0aiNxvmal1CBNG1h7BHI8Sc55CtWmXM4dcnpfSBkkCGSeUZjy4UiTebMw6fC1b4x9hsMUvNKmOE0kHRMCgXB5FkeIaFjTHLORch0rpETcBRLwPcqJjySAACNYCCD4Hij5xKaq2CsRacFUYjiYxDOiJamhxBwKAjUlczj6kwuCCy1y7KwkouGP0wZwysXjMFcK0VmTxXkU1lVYc041CAVCvYKch9qj7xWnaJxdSTLHN1RlTKBqblcruXEvlFqhWCAMGKuZx0FnRjMAcMU9KtYVXuvCCuwZ-7m0Yj62p4FOIBvSs5YNyLhi9ONWijFIyxlJMtTGuNBL5ndglRFHmC4qgSCxJVJG3zLqPRNFiVVhQmUnP6j0ENnLuUxIjfWwQk60E2vjdvLy7ag5Rh5ATU25CTh0o7YUEC85zZLkLe1a2Jal0hqNSa9FZqF1LubX6BNbbfxog0NiK4zqyJzWdYmcp3JwWFA1W1W+l6dVBC7vtadtyeXzsedBqYz6ZKvvXctTW+w5A+RmsUTG3rzggVOLjZVBbNV+uLZBpDN7K2otNZihdSGUNZ2GnDYloZVU8gKgVPdD15yTkRM1RwMCmLjuCP9YYgNgag3BhcgJSKZmhtnbyhdEmpPCRk8MQQ-jcLMa3qxgxNo842kYgxW0sJeOmG5FOC6dQ9SVAYmJoIanazSbBhDNpkkaNVrvbW81SSXNAw0+57TnnKB6cJQsozSlTOmxZMOaieRfK2Yjg5twvqi0dXYVyrhmB+iqNdv1Q8WjRI6L0augzJwFBPgYjXVE7NVXyooYVC6BwCn4wjmRsDLjrbZc4W7bhkgCy4A4AQcVVwarOFNrsYWNpjQJhHRIQhWGqiIL67lobI32BjYBC+tdbGrPmF1FGbQIHlC8byDVYCI6zOIl1GtjhG2ABy7sAAKqA8DfwIHZCAEAQhXkVM5j7gxxUATZFcEWlhYQixNMiXEV36omCsOU9MGWL0bnWwNzAkgXtBHe592AbpJI8JbWhtmnqIrYgXFrECFgmvGD1BibI+xIfzguul894GNzDdGx87WZgERijWEUzZAtLCThFsOGEhwi6KLR1z3MPPtv-FJ-t-Kw4QVZHZqZiwY4BY10yCGaM+xURVS6zfHrG4AAqRXNHaOGLot2+WqQsKCJj1A3DQcNE1sbbIiJWKFGRFsdYJV7N6jWRYRBVIgbuxwoqCCAB5XASnw3xLsn4K3gho8RMEHH9gifmYVdhvlDQZh6oqv1PUWwyIeQANUJ+WrdhnULyCLgd2wSSCUH8GECImEwAd9BuJsGXKPmrD2M9HIzrDjVEONoOHKhEYdeddYcFZ7yPSjINgKs6L2hp2c8P3oM7U9RM39voYgg3aCA75QD5LIKgIgUKKY2x3S6ICDmYGuGhh5hUuqBi3khT8d98A98MFxJd9vhvQU94N4lADz9L8ICcwPkg484ZobQQxnAigx5M0kYFp-JFBcRFAGJHFlw28MB4BYhus9tKtUgChJVkxztKhtAMYIERZzBZ8NBTRB4EF5cSQ3gqDi8hBtgioksyoeQGJJFFILQpUkx8YZA19utOp+D+FEAQxJ5FxhcERRcy4QIIpZ8kYDgjMZUlEE4eglC1Z9RnAFogE0RUQZdA8xd9RExmp4xVAGJUY-8tV-VIMUkfEMIdMvNMkzCvZJcpw9IZA7APwqgSkNhNYLAQIkYbh8gnMcU-CwsFNQkgiiJCDCNlB7BzE9g0ZNIVpllTRORNCkcnM9U2VAjUM1cgwbACEP13Chc6hQpsRzAxB4idBKEwpKig0DVMiRobBvl2csQhcVp8Y9dSh4Q85GhkZxFykownNr0aiWMBCex1IMQhd5wtZ3w8My5ui2R7A7A9hw9uQnNqNVj9N1jVVtkTAXxCC9QbBmCTgsQMh4wxRGhR0TMPCKNXFINAs3NZN-CrkZlBjycxBMgpszcfjX8HprQcZB4T1VACgHscssdwSDF+R85-5qgYwe04dtl3wbQGIgIqpUdOdLdcx3dBsldMSTh9hJxNBcSg59gCT7oGoaUWJ4xnBHwLo0T+sPdsc28RlWx6SHpYQaoyEWRjsqpuR6cEATApAbAe1Wd5EBTns3tgdv5xSrgsQFoP0Gp-4LsLAFochbBgIZAIU5dKSNo6TajqCshTQMRDYGIsM9QpiHwEwkxqsdgGhgFEEbd8Bit7dHdUBdSmJpAJASpzS8SqIBY7tzoTdUQp4x0eCNps9Y8Ad898wk9xSq4hEGJbBGJqgGgFSGgnxgIxRfcVoFwOd190cphW929O8wBxTVgEYrpzRDhhZuRkR5T+wrBjYnS8hUZ1pYDd83Z98yA2yHSbjGgMQQJhj0hIxeMg4jYqhrtmo-ZDJ0yJzgCpzQD4JwD8x8zCo-I3jZEihVUXj4TIR5xbBniUz393B3AgA */
|
/** @xstate-layout N4IgpgJg5mDOIC5QFkD2EwBsCWA7KAxAMICGuAxlgNoAMAuoqAA6qzYAu2qujIAHogC0ANgCcARgB0NcQHYAHKIBMw8QGY1ogKxKANCACeiWUvmT5SraNE15a4QBZxW2QF9X+tBhz4CAZTB2AAJYLDByTm5aBiQQFjZInliBBEFtWUlxGlEnWWVZNQc1fSMEDSl1NXlVewcirWE1d090LDxCAODYdgAnMBIAWyDyAFce2FQe6N54ji4k0BSaEsQaZpAvNvxJbAhMMAIAUVx2MB6QgGtA8gALadjZxN4UwRUM8RVRR3kP8XFhWQOFYIJQ5SRFIpKJxqbLVUTrTY+KA7PYHY6nc6wK7sW5UcQxZisObcZ5CKE0cH-GRaWww+Q0WTAhw0JSSfLCLQfYQ-Kr-BGtJEo-ZHPi9EYYe6EhLzUmpLQuSSgmgNbQOLQ-YF-GmK6qKbQ0Bw5Jz87ztIVovgsHrsSVxIlPZJk+RmUzkpRKcSGtXyYGyWRSAFaQoc+lKQFaE1bZF+bG3YhkSiYGPXO70Gb2mWOhB-DTg5TCDm-bnqTXiGySTkOeQKDSKaoOSOC5M4m6SZu3ACSqIIyBIVxCYCgAzAJyCADczpxyCRMLbHpnFogPlUK9yaI4TEHnJqHO7JGJhNlLGIJOJ5I2ze3W1eu8Le-3QkOR8EbpNsAAvbjsGdzjMkrMfB6bKiFU7rOMy8pAoYS5qEoFI5HI3IFj8djCBe2xXm2sY3LeBxENw3Q9CQeBBK+PQfl+M5BBA2DdAmYC-tK-6LtmcFSLusg6NysjCHBjLQSCEHgpyDSAl8ULqOh0bYVhKa4cQBG9MRuDjpO2DTpg1G0d+FAMWmDx-gs-BLh6wiSLW666koagmMUAnuhYbJwZYZ6epoDYeBsAqXjJN7dvhuCEcpQQAIIAEJ+EEAAajHEkZKTLqyFhhmoZabvSUGlKCjjmTo8gOLI66pTI56eYiPkprJLbyQFQUkeFkUAJqxQ6LGJfuKV5PKYh1HZpQwqIZhFmejjqrZUlVbck04f5ilESRZBQPsLULsZrHljxNhqqoOQAsCLlmRyDiOAVIHKKVLSmhhvnYTVc3Bfs+DsKmBJ2kx8UmflkicbYKhyPYNCwftvFDUd+WDWWHITZhfnCrVSkkUwZxI7gNGjJgJDnDRdG6StzFrX8nHmPlOhGqlVb8VlFgOJkzhfAVqguGhZXeddlWw3h90kWRFEnDOmAGEEM7YFAuB4x9rFZIqRSFdZ1Q9ZlS46Fo+4SBIDPHRIF1eVd0ns7ds2BQjKkTta6n84Lwui+LsqAWZKHZByTN2HoAn-IUbLyOqHImDIzhuCzuvTdNd1G-NKmwLgJBMEE7CoNFNsASoFKODYydljo-r7cqAYegUtQwjI0M3XJht1RHUcx3HQTNfpUpxbbyfgozhR+nYyiu1lzhmUaeSgloar5MX+ul3DXMqWAACOIxUY9UDPYnbXkuY1jWACx0D2emoFKI5gqPYhUgWIJjDy2Idl8bQRMJj-PUHXb0N0ngLggy+XVK3ypaJqu3gqC7ppzWbkp8pocwUmHYKfQBioAnMMce7BYCLwJhnYCPF86WDqI4TU+UKROFBNWAqLJPQeUulGYOoCABKYBBBgD4OEEYpxEEJULhWD0-8rCFSKKIYEogibWCqCyL2NBAbVmAdeA2wpDjT2wDHAAMngMAsdUCoFnPfec+MEr5TUGyM88trAFR4sCfKNMbAaCPBIP0ORRHnwkVIqui1nzYCopjcgijGGIA9M4b6hU34nkSqWP4mRHAAldMqQEAcSFNhkiFAA7sRF8b5Px800tjHSlAgh4AAGaoAIBAbgYAdi4DHKgK4kgYDsEEDzRJ35MCCEyagNxIIXLmFSrxAEPwVBf3sruXeUJnRpyKl7KxMS4mkQSZRZJ2l6LpNwFkggZweiTEkEwDG7Ask9AGKUwIFSxlJNqTM+pqjDKyndDoPM4k7DVBcAY+ymh2L2ALAUOsihiE61IZhYZHBVJmw0lpHGaS6k5LyQUopJSymCFNlOGceyskNJObvHQMIwzMjfuufaoItFhnUGWOQgMhHMwiRVM+HzggQvNhMv5CiAXzMWcskgqzJgbLBaSjS0KDmvTURLd0h5Mg2B4bxOQHwfT2SaQ0f4PV0H-G1uVNmRLYmfIatFaZszcm4HyXgEF+SwUkAAEawEEHwVlsKVA009CYMsoIqwAkpu4nhUggzfGDDw+U4TXmRMqsS0KEVFVUp6AsnoSyVlrMZVsnVeqDV1KNTlH4Eg8WpTsC4faygVacQKmxJw1ZARDLlcEBVjUlXZJVWqwpxTNUht1YIAwhrDnvWOfvb6zIeGgkKgWKEwIYQ8RXjSRCbFqZZpGbm-NczfU0sDQyzZ5TQ0Vqreyo5WYuU01wV7IoDJeLaDbf9ZuLg-7OhpAaPtnzFr7EHYW4FJbx2CEPVQiN1bH4sXnfud+CKZDWS4fZBoZlYIcmLMoNe+7giXsHdS-1tL6XrPPZe6d6Ya1zpUGZWwIE1T-Dzl8faXEKyOxsqYHi8o-1BDns9Y9QL1VnrBfhm4kGDLQbvSoJKiE-gegHjYYQwMwSDyqJw50EFcNkcA8O4Do6wOkZHPPcj16Z1UbWlyrRVZnU6GyNcrKHJWTKi9g0TkSoXnSr1rKkZSMegozRiMDGWNJm6UI6q09oKtl6YM+pIzmNBApPohR+urVJMegpIUNQm8CyaA4ftOwNNUFBnsPcoMUrWbaamh6mzI5DPGd+akyl+yh1+oDXSoN57Yuozs8ZxzpnKAuYfm5lIYFPP1CcL5nhBp9oKDMsFjQjQCzhasXI1VijlFHFsbHexJxHGaWca4m9JX3FmorLcuQIE-h2GtQgQa9s8ED0BMEiwrX5EdcwJIDsuAOAEFhWeGm7obLefUJBWbYgU7ebxQyQ0cEIyBzeTJNrCi47KK2zt9ge38RQdve5ssxN6QaDVBoBNAkFBmC9l8dcFqBEuq08HZ7G3JAADl44AAVUB4HgQQEKEAIAhG-NaK+mOTiwtUKyJU1YgkgR0MCNpzTvZODpi2tb7XXubdR0EDHWPYDxl0io8Tv2Ep5DMrkKwEh7Cmt9FLRQXLAaGmsJ6Kx23dsNK+Fo6sR51zHUNICTUUIkpNZAvJzQKhlcfa+4Lkbc3rCKh4kWAopgciahhBUH40J3a8SUFYgAKr1zgTieguLjl1kY0igiI-Z7CqwUgfiHhZIrmwQrSjaDMpKxFBQ-RiSsSMVG8c6LWivAAeVwICizxGSkhT8D7wQufcmCAL+wYvYthurSYSuTOE3eo0mT4gdU8Edq2AKlUDQcPIvTSCLgeOGSSCUH8GECI1EwAz6M8EWlqqGmvACWeHINlATVDEp00orTzDLhltYHihoJpkGwAMOl7RFFXwxqqsvRaNWSBv3f04gg46CBn5QBpeUN3V+A0IRd0BkOnUwcyZcRFRQffCLIOT-e-fAR-GhbSB-LEFMV-SzfJJA7-X-TAlsBpXiFWFkXiPIH4AeTDddMwB5KoL4PpAqUqTyKfDAeAWILTH7a3QQHeaQOQWXGoTQWnN2TkcwfvHFKEKwGQTTcfXYfYLgtvIQb4VcPIR5b0AqQxH4cbWwZwVKayGQeEB7N1FsBQ9RRACQFWTXZQbXVOPXG5XebzekSbdUduTiKxDmUwiWU7FOCwA8WCb2XvViQGcbEwPlbxONXDSpcZRLKZOpTw22SgveHaFwAeFTPqdxZkKQQEdQK1IqX9IwwlaLbNL5SFclJLfNeIgCCweFNUfQq5FwV9LKSwXeXcFkGTQGAESxAomVIo-tL1KKCoyjIXJcbBZuQLRwQGegxNZkMQ0wIMZUONAEXDAdOIoY63M8TQbRWoTjAeZ0NtG7DqJDY6bzdIb3boqLVsD1ADVY1zRQ7MTRPgriA0TQH4OwrKTkF0MsDuE6TiM4glHoy44onjG44rO4jYjIcHBQUwQ8I6WbY1NPZ0ZUAqf4dUAqXDbLeLTGGIszEEjlBIg0TIV49BY6FyRWEEPICoOmP6H9A3VnF7JRTASou9ZUHBb2FkVI7uYEGPcyRwxoGQGyOkpHFXdgJkyTWEYSaodkzIhoX0GQVcCSf4e3TicQQU9nSQKfdZGcUU0rOoGmaodBcnKkHhaXCkWXZOQoVeJXc4hHdbNUznbnE4dg24swwSIRfcbkewSsWo46X0f0fcP0M8FkKEP0Roc3DgbUpcIRDIXFRwLIEXPIMkv4csSsasOweg+sX3f3frIWIPRRCMkEIMVkf2L2DQMMWwPaN2dcAMDcbzQ8S-FU60zCOvfPQnJvbCEvfMz3JyBkMggMviLk+UMQvICws6dQBAx7FMSfafWfMAfM14GYl2QMMJIfI-RANUGmGkKQmQBkLqKEa-HbL-B-audfWctYsExoNkTaA0dID4VFASE-YRKnXYukMfRAg85AqAVAvgdAlAwg24Tsnhb6d9FwQhIoc1ALFOQ8RQNo8s0wdwdwIAA */
|
||||||
id: 'Modeling',
|
id: 'Modeling',
|
||||||
|
|
||||||
tsTypes: {} as import('./modelingMachine.typegen').Typegen0,
|
tsTypes: {} as import('./modelingMachine.typegen').Typegen0,
|
||||||
@ -157,6 +171,7 @@ export const modelingMachine = createMachine(
|
|||||||
sketchPlaneId: '' as string,
|
sketchPlaneId: '' as string,
|
||||||
sketchEnginePathId: '' as string,
|
sketchEnginePathId: '' as string,
|
||||||
moveDescs: [] as MoveDesc[],
|
moveDescs: [] as MoveDesc[],
|
||||||
|
mouseState: { type: 'idle' } as MouseState,
|
||||||
},
|
},
|
||||||
|
|
||||||
schema: {
|
schema: {
|
||||||
@ -535,6 +550,10 @@ export const modelingMachine = createMachine(
|
|||||||
internal: true,
|
internal: true,
|
||||||
actions: 'Set selection',
|
actions: 'Set selection',
|
||||||
},
|
},
|
||||||
|
'Set mouse state': {
|
||||||
|
internal: true,
|
||||||
|
actions: 'Set mouse state',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user