This commit is contained in:
49lf
2024-10-17 16:28:52 -04:00
parent 89309b6ccd
commit 721b3e8cbd
16 changed files with 104 additions and 86 deletions

View File

@ -273,7 +273,6 @@ test.describe('Sketch tests', () => {
await page.waitForTimeout(1000) await page.waitForTimeout(1000)
await u.closeDebugPanel() await u.closeDebugPanel()
const step5 = { steps: 5 } const step5 = { steps: 5 }
await expect(page.getByTestId('segment-overlay')).toHaveCount(2) await expect(page.getByTestId('segment-overlay')).toHaveCount(2)
@ -289,7 +288,6 @@ test.describe('Sketch tests', () => {
} }
}) })
await page.waitForTimeout(100) await page.waitForTimeout(100)
test.step('drag line handle', async () => { test.step('drag line handle', async () => {
@ -309,7 +307,11 @@ test.describe('Sketch tests', () => {
const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]') const tangentEnd = await u.getBoundingBox('[data-overlay-index="1"]')
await page.mouse.move(tangentEnd.x, tangentEnd.y - 5) await page.mouse.move(tangentEnd.x, tangentEnd.y - 5)
await page.mouse.down() await page.mouse.down()
await page.mouse.move(tangentEnd.x + dragPX, tangentEnd.y - dragPX, step5) await page.mouse.move(
tangentEnd.x + dragPX,
tangentEnd.y - dragPX,
step5
)
await page.mouse.up() await page.mouse.up()
await page.waitForTimeout(100) await page.waitForTimeout(100)
if (openPanes.includes('code')) { if (openPanes.includes('code')) {
@ -654,11 +656,9 @@ test.describe('Sketch tests', () => {
const viewportSize = { width: 1200, height: 500 } const viewportSize = { width: 1200, height: 500 }
await page.setViewportSize(viewportSize) await page.setViewportSize(viewportSize)
await u.waitForAuthSkipAppStart() await u.waitForAuthSkipAppStart()
await u.openDebugPanel() await u.openDebugPanel()
await expect( await expect(
page.getByRole('button', { name: 'Start Sketch' }) page.getByRole('button', { name: 'Start Sketch' })
).not.toBeDisabled() ).not.toBeDisabled()

View File

@ -19,7 +19,10 @@ import {
Vector2, Vector2,
Vector3, Vector3,
} from 'three' } from 'three'
import { RAYCASTABLE_PLANE, INTERSECTION_PLANE_LAYER } from 'clientSideScene/constants' import {
RAYCASTABLE_PLANE,
INTERSECTION_PLANE_LAYER,
} from 'clientSideScene/constants'
import { EngineCommand } from 'lang/std/artifactGraph' import { EngineCommand } from 'lang/std/artifactGraph'
import fsp from 'fs/promises' import fsp from 'fs/promises'
import fsSync from 'fs' import fsSync from 'fs'
@ -261,17 +264,16 @@ export function rollingRound(n: number, digitsAfterDecimal: number) {
const fractStr = nineIndex > 0 ? s[1].slice(0, nineIndex + 1) : s[1] const fractStr = nineIndex > 0 ? s[1].slice(0, nineIndex + 1) : s[1]
let fract = Number(fractStr) / (10 ** fractStr.length) let fract = Number(fractStr) / 10 ** fractStr.length
for (let i = fractStr.length - 1; i >= 0; i -= 1) { for (let i = fractStr.length - 1; i >= 0; i -= 1) {
if (i === digitsAfterDecimal) break if (i === digitsAfterDecimal) break
fract = Math.round(fract*(10**i)) / (10 **i) fract = Math.round(fract * 10 ** i) / 10 ** i
} }
return (Number(s[0]) + fract).toFixed(digitsAfterDecimal) return (Number(s[0]) + fract).toFixed(digitsAfterDecimal)
} }
export const getMovementUtils = async (opts: any) => { export const getMovementUtils = async (opts: any) => {
const sceneInfra = await opts.page.evaluate(() => window.sceneInfra) const sceneInfra = await opts.page.evaluate(() => window.sceneInfra)
@ -330,13 +332,16 @@ export const getMovementUtils = async (opts: any) => {
return window.sceneInfra.camControls.camera return window.sceneInfra.camControls.camera
}) })
const windowWH = await opts.page.evaluate(() => ({ w: window.innerWidth, h: window.innerHeight })) const windowWH = await opts.page.evaluate(() => ({
w: window.innerWidth,
h: window.innerHeight,
}))
// I didn't write this math, it's copied from sceneInfra.ts, and I understand // I didn't write this math, it's copied from sceneInfra.ts, and I understand
// it's just normalizing the point, but why *-2 ± 1 I have no idea. // it's just normalizing the point, but why *-2 ± 1 I have no idea.
const mouseVector = new Vector2( const mouseVector = new Vector2(
(targetX / windowWH.w) * 2 - 1, (targetX / windowWH.w) * 2 - 1,
-(targetY / windowWH.h) * 2 + 1, -(targetY / windowWH.h) * 2 + 1
) )
planeRaycaster.setFromCamera(mouseVector, camera) planeRaycaster.setFromCamera(mouseVector, camera)
const intersections = planeRaycaster.intersectObjects(scene.children, true) const intersections = planeRaycaster.intersectObjects(scene.children, true)
@ -359,13 +364,7 @@ export const getMovementUtils = async (opts: any) => {
).applyQuaternion(inversePlaneQuaternion) ).applyQuaternion(inversePlaneQuaternion)
twoD.sub(new Vector2(...planePositionCorrected)) twoD.sub(new Vector2(...planePositionCorrected))
await circleMove( await circleMove(opts.page, targetX, targetY, 10, 10)
opts.page,
targetX,
targetY,
10,
10
)
await click00(targetX, targetY) await click00(targetX, targetY)
last.x += x last.x += x
@ -379,13 +378,13 @@ export const getMovementUtils = async (opts: any) => {
lastScreenSpace.x = kcRound(twoD.x) lastScreenSpace.x = kcRound(twoD.x)
lastScreenSpace.y = kcRound(twoD.y) lastScreenSpace.y = kcRound(twoD.y)
// Returns the new absolute coordinate and the screen space coordinate if you need it. // Returns the new absolute coordinate and the screen space coordinate if you need it.
return { return {
nextXY: [last.x, last.y], nextXY: [last.x, last.y],
kcl: `[${kcRound(relativeScreenSpace.x)}, ${-kcRound(relativeScreenSpace.y)}]`, kcl: `[${kcRound(relativeScreenSpace.x)}, ${-kcRound(
relativeScreenSpace.y
)}]`,
} }
} }
return { click00r } return { click00r }
@ -447,7 +446,7 @@ export async function getUtils(page: Page, test_?: typeof test) {
const bb = await sidebar.boundingBox() const bb = await sidebar.boundingBox()
return { return {
w: windowInnerWidth - (bb?.width ?? 0), w: windowInnerWidth - (bb?.width ?? 0),
h: windowInnerHeight - (bb?.height ?? 0) h: windowInnerHeight - (bb?.height ?? 0),
} }
}, },
async getCenterOfModelViewArea() { async getCenterOfModelViewArea() {
@ -456,7 +455,7 @@ export async function getUtils(page: Page, test_?: typeof test) {
const sidebar = page.getByTestId('modeling-sidebar') const sidebar = page.getByTestId('modeling-sidebar')
const bb = await sidebar.boundingBox() const bb = await sidebar.boundingBox()
const goRightPx = (bb?.width ?? 0 ) / 2 const goRightPx = (bb?.width ?? 0) / 2
const borderWidthsCombined = 2 const borderWidthsCombined = 2
return { return {
x: Math.round(windowInnerWidth / 2 + goRightPx) - borderWidthsCombined, x: Math.round(windowInnerWidth / 2 + goRightPx) - borderWidthsCombined,

View File

@ -749,9 +749,7 @@ extrude001 = extrude(5, sketch001)
await test.step(`Check the sketch line color before`, async () => { await test.step(`Check the sketch line color before`, async () => {
await expect await expect
.poll(() => .poll(() => u.getGreatestPixDiff(line1, darkThemeSegmentColor))
u.getGreatestPixDiff(line1, darkThemeSegmentColor)
)
.toBeLessThanOrEqual(34) .toBeLessThanOrEqual(34)
}) })
@ -767,9 +765,7 @@ extrude001 = extrude(5, sketch001)
await test.step(`Check the sketch line color after`, async () => { await test.step(`Check the sketch line color after`, async () => {
await expect await expect
.poll(() => .poll(() => u.getGreatestPixDiff(line1, lightThemeSegmentColor))
u.getGreatestPixDiff(line1, lightThemeSegmentColor)
)
.toBeLessThanOrEqual(34) .toBeLessThanOrEqual(34)
}) })
}) })

View File

@ -502,7 +502,7 @@ test('Sketch on face', async ({ page }) => {
// This basically waits for sketch mode to be ready. // This basically waits for sketch mode to be ready.
await u.doAndWaitForCmd( await u.doAndWaitForCmd(
async () => page.mouse.click(center.x, 180), async () => page.mouse.click(center.x, 180),
'default_camera_get_settings', 'default_camera_get_settings',
true true
) )

View File

@ -85,34 +85,33 @@ export function App() {
useEngineConnectionSubscriptions() useEngineConnectionSubscriptions()
return ( return (
<div <div className="relative h-full flex flex-col" ref={ref}>
className="relative h-full flex flex-col" <AppHeader
ref={ref} className={'transition-opacity transition-duration-75 ' + paneOpacity}
> project={{ project, file }}
<AppHeader enableMenu={true}
className={'transition-opacity transition-duration-75 ' + paneOpacity} />
project={{ project, file }} <ModalContainer />
enableMenu={true} <ModelingSidebar paneOpacity={paneOpacity} ref={modelingSidebarRef} />
/> <EngineStreamContext.Provider
<ModalContainer /> options={{
<ModelingSidebar paneOpacity={paneOpacity} ref={modelingSidebarRef} />
<EngineStreamContext.Provider options={{
input: { input: {
videoRef, videoRef,
canvasRef, canvasRef,
mediaStream: null, mediaStream: null,
authToken: auth?.context?.token ?? null, authToken: auth?.context?.token ?? null,
pool pool,
} },
}}> }}
<EngineStream /> >
{/* <CamToggle /> */} <EngineStream />
<LowerRightControls coreDumpManager={coreDumpManager}> {/* <CamToggle /> */}
<UnitsMenu /> <LowerRightControls coreDumpManager={coreDumpManager}>
<Gizmo /> <UnitsMenu />
<CameraProjectionToggle /> <Gizmo />
</LowerRightControls> <CameraProjectionToggle />
</EngineStreamContext.Provider> </LowerRightControls>
</EngineStreamContext.Provider>
</div> </div>
) )
} }

View File

@ -923,7 +923,10 @@ export class CameraControls {
}, },
}) })
await this.centerModelRelativeToPanes({ zoomToFit: true, resetLastPaneWidth: true }) await this.centerModelRelativeToPanes({
zoomToFit: true,
resetLastPaneWidth: true,
})
this.cameraDragStartXY = new Vector2() this.cameraDragStartXY = new Vector2()
this.cameraDragStartXY.x = 0 this.cameraDragStartXY.x = 0
@ -954,7 +957,11 @@ export class CameraControls {
private lastFramePaneWidth: number = 0 private lastFramePaneWidth: number = 0
async centerModelRelativeToPanes(args?: { zoomObjectId?: string, zoomToFit?: boolean, resetLastPaneWidth?: boolean }): Promise<void> { async centerModelRelativeToPanes(args?: {
zoomObjectId?: string
zoomToFit?: boolean
resetLastPaneWidth?: boolean
}): Promise<void> {
const panes = this.modelingSidebarRef?.current const panes = this.modelingSidebarRef?.current
if (!panes) return if (!panes) return
@ -964,7 +971,8 @@ export class CameraControls {
this.lastFramePaneWidth = 0 this.lastFramePaneWidth = 0
} }
const goPx = ((panesWidth - this.lastFramePaneWidth) / 2) / window.devicePixelRatio const goPx =
(panesWidth - this.lastFramePaneWidth) / 2 / window.devicePixelRatio
this.lastFramePaneWidth = panesWidth this.lastFramePaneWidth = panesWidth
// Originally I had tried to use the default_camera_look_at endpoint and // Originally I had tried to use the default_camera_look_at endpoint and

View File

@ -1,4 +1,11 @@
import { CSSProperties, useRef, useEffect, useState, useMemo, Fragment } from 'react' import {
CSSProperties,
useRef,
useEffect,
useState,
useMemo,
Fragment,
} from 'react'
import { useModelingContext } from 'hooks/useModelingContext' import { useModelingContext } from 'hooks/useModelingContext'
import { cameraMouseDragGuards } from 'lib/cameraControls' import { cameraMouseDragGuards } from 'lib/cameraControls'

View File

@ -26,11 +26,9 @@ export function createGridHelper({
return gridHelper return gridHelper
} }
// Re-export scale.ts // Re-export scale.ts
export * from './scale' export * from './scale'
export function isQuaternionVertical(q: Quaternion) { export function isQuaternionVertical(q: Quaternion) {
const v = new Vector3(0, 0, 1).applyQuaternion(q) const v = new Vector3(0, 0, 1).applyQuaternion(q)
// no x or y components means it's vertical // no x or y components means it's vertical

View File

@ -1,16 +1,17 @@
import { import { OrthographicCamera, PerspectiveCamera, Group, Mesh } from 'three'
OrthographicCamera,
PerspectiveCamera,
Group,
Mesh,
} from 'three'
export const fudgeFactor = 72.66985970437086 export const fudgeFactor = 72.66985970437086
export const orthoScale = (cam: OrthographicCamera | PerspectiveCamera, innerHeight?: number) => export const orthoScale = (
(0.55 * fudgeFactor) / cam.zoom / (innerHeight ?? window.innerHeight) cam: OrthographicCamera | PerspectiveCamera,
innerHeight?: number
) => (0.55 * fudgeFactor) / cam.zoom / (innerHeight ?? window.innerHeight)
export const perspScale = (cam: PerspectiveCamera, group: Group | Mesh, innerHeight?: number) => export const perspScale = (
cam: PerspectiveCamera,
group: Group | Mesh,
innerHeight?: number
) =>
(group.position.distanceTo(cam.position) * cam.fov * fudgeFactor) / (group.position.distanceTo(cam.position) * cam.fov * fudgeFactor) /
4000 / 4000 /
(innerHeight ?? window.innerHeight) (innerHeight ?? window.innerHeight)

View File

@ -19,7 +19,6 @@ import useEngineStreamContext, {
} from 'hooks/useEngineStreamContext' } from 'hooks/useEngineStreamContext'
import { REASONABLE_TIME_TO_REFRESH_STREAM_SIZE } from 'lib/timings' import { REASONABLE_TIME_TO_REFRESH_STREAM_SIZE } from 'lib/timings'
export const EngineStream = () => { export const EngineStream = () => {
const { setAppState } = useAppState() const { setAppState } = useAppState()
@ -33,6 +32,7 @@ export const EngineStream = () => {
enableSSAO: settings.context.app.enableSSAO.current, enableSSAO: settings.context.app.enableSSAO.current,
highlightEdges: settings.context.modeling.highlightEdges.current, highlightEdges: settings.context.modeling.highlightEdges.current,
showScaleGrid: settings.context.modeling.showScaleGrid.current, showScaleGrid: settings.context.modeling.showScaleGrid.current,
cameraProjection: settings.context.modeling.cameraProjection.current,
} }
const { state: modelingMachineState, send: modelingMachineActorSend } = const { state: modelingMachineState, send: modelingMachineActorSend } =
@ -86,7 +86,8 @@ export const EngineStream = () => {
if (!canvas) return if (!canvas) return
new ResizeObserver(() => { new ResizeObserver(() => {
if (Date.now() - last.current < REASONABLE_TIME_TO_REFRESH_STREAM_SIZE) return if (Date.now() - last.current < REASONABLE_TIME_TO_REFRESH_STREAM_SIZE)
return
last.current = Date.now() last.current = Date.now()
if ( if (
@ -97,7 +98,6 @@ export const EngineStream = () => {
configure() configure()
} }
}).observe(document.body) }).observe(document.body)
}, [engineStreamState.value]) }, [engineStreamState.value])
// When the video and canvas element references are set, start the engine. // When the video and canvas element references are set, start the engine.

View File

@ -644,7 +644,9 @@ export const ModelingMachineProvider = ({
engineCommandManager, engineCommandManager,
input.faceId input.faceId
) )
await sceneInfra.camControls.centerModelRelativeToPanes({ resetLastPaneWidth: true }) await sceneInfra.camControls.centerModelRelativeToPanes({
resetLastPaneWidth: true,
})
sceneInfra.camControls.syncDirection = 'clientToEngine' sceneInfra.camControls.syncDirection = 'clientToEngine'
return { return {
sketchPathToNode: pathToNewSketchNode, sketchPathToNode: pathToNewSketchNode,
@ -665,7 +667,9 @@ export const ModelingMachineProvider = ({
engineCommandManager, engineCommandManager,
input.planeId input.planeId
) )
await sceneInfra.camControls.centerModelRelativeToPanes({ resetLastPaneWidth: true }) await sceneInfra.camControls.centerModelRelativeToPanes({
resetLastPaneWidth: true,
})
return { return {
sketchPathToNode: pathToNode, sketchPathToNode: pathToNode,
@ -688,7 +692,9 @@ export const ModelingMachineProvider = ({
engineCommandManager, engineCommandManager,
info?.sketchDetails?.faceId || '' info?.sketchDetails?.faceId || ''
) )
await sceneInfra.camControls.centerModelRelativeToPanes({ resetLastPaneWidth: true }) await sceneInfra.camControls.centerModelRelativeToPanes({
resetLastPaneWidth: true,
})
return { return {
sketchPathToNode: sketchPathToNode || [], sketchPathToNode: sketchPathToNode || [],
zAxis: info.sketchDetails.zAxis || null, zAxis: info.sketchDetails.zAxis || null,

View File

@ -65,7 +65,7 @@ export const ModelingSidebar = forwardRef<
useEffect(() => { useEffect(() => {
if (typeof outerRef === 'function') { if (typeof outerRef === 'function') {
outerRef(innerRef.current) outerRef(innerRef.current)
} else { } else {
if (outerRef) { if (outerRef) {
outerRef.current = innerRef.current outerRef.current = innerRef.current
} }
@ -190,7 +190,6 @@ export const ModelingSidebar = forwardRef<
void sceneInfra.camControls.centerModelRelativeToPanes() void sceneInfra.camControls.centerModelRelativeToPanes()
}, [context.store?.openPanes]) }, [context.store?.openPanes])
// If the panes are resized then center the model also // If the panes are resized then center the model also
useEffect(() => { useEffect(() => {
if (!innerRef.current) return if (!innerRef.current) return

View File

@ -285,7 +285,10 @@ export class KclManager {
) )
} }
await sceneInfra.camControls.centerModelRelativeToPanes({ zoomToFit: true, zoomObjectId }) await sceneInfra.camControls.centerModelRelativeToPanes({
zoomToFit: true,
zoomObjectId,
})
} }
} }

View File

@ -11,10 +11,10 @@ export const codeManager = new CodeManager()
export const engineCommandManager = new EngineCommandManager() export const engineCommandManager = new EngineCommandManager()
declare global { declare global {
interface Window { interface Window {
tearDown: typeof engineCommandManager.tearDown, tearDown: typeof engineCommandManager.tearDown
sceneInfra: typeof sceneInfra, sceneInfra: typeof sceneInfra
} }
} }
// Accessible for tests // Accessible for tests

View File

@ -1,3 +1,3 @@
// 0.25s is the average visual reaction time for humans so we'll go a bit less // 0.25s is the average visual reaction time for humans so we'll go a bit less
// so those exception people don't see. // so those exception people don't see.
export const REASONABLE_TIME_TO_REFRESH_STREAM_SIZE = 100 export const REASONABLE_TIME_TO_REFRESH_STREAM_SIZE = 100

View File

@ -550,7 +550,9 @@ export const modelingMachine = setup({
up: { x: 0, y: 0, z: 1 }, up: { x: 0, y: 0, z: 1 },
}, },
}) })
await sceneInfra.camControls.centerModelRelativeToPanes({ resetLastPaneWidth: true }) await sceneInfra.camControls.centerModelRelativeToPanes({
resetLastPaneWidth: true,
})
})().catch(reportRejection) })().catch(reportRejection)
}, },
'set new sketch metadata': assign(({ event }) => { 'set new sketch metadata': assign(({ event }) => {