Compare commits
	
		
			1 Commits
		
	
	
		
			jess/test-
			...
			franknoiro
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c03357d897 | 
| @ -34,7 +34,7 @@ const FRAMES_TO_ANIMATE_IN = 30 | ||||
|  | ||||
| const tempQuaternion = new Quaternion() // just used for maths | ||||
|  | ||||
| type interactionType = 'pan' | 'rotate' | 'zoom' | ||||
| export type CameraInteractionType = 'pan' | 'rotate' | 'zoom' | ||||
|  | ||||
| interface ThreeCamValues { | ||||
|   position: Vector3 | ||||
| @ -1219,8 +1219,8 @@ function _getInteractionType( | ||||
|   enablePan: boolean, | ||||
|   enableRotate: boolean, | ||||
|   enableZoom: boolean | ||||
| ): interactionType | 'none' { | ||||
|   let state: interactionType | 'none' = 'none' | ||||
| ): CameraInteractionType | 'none' { | ||||
|   let state: CameraInteractionType | 'none' = 'none' | ||||
|   if (enablePan && interactionGuards.pan.callback(event)) return 'pan' | ||||
|   if (enableRotate && interactionGuards.rotate.callback(event)) return 'rotate' | ||||
|   if (enableZoom && interactionGuards.zoom.dragCallback(event)) return 'zoom' | ||||
|  | ||||
| @ -105,7 +105,7 @@ export const ModelingMachineProvider = ({ | ||||
|     settings: { | ||||
|       context: { | ||||
|         app: { theme, enableSSAO }, | ||||
|         modeling: { defaultUnit, highlightEdges, showScaleGrid }, | ||||
|         modeling: { defaultUnit, highlightEdges, showScaleGrid, mouseControls }, | ||||
|       }, | ||||
|     }, | ||||
|   } = useSettingsAuthContext() | ||||
| @ -509,6 +509,7 @@ export const ModelingMachineProvider = ({ | ||||
|             settings: { | ||||
|               theme: theme.current, | ||||
|               highlightEdges: highlightEdges.current, | ||||
|               mouseControls: mouseControls.current, | ||||
|             }, | ||||
|           }).catch(reportRejection) | ||||
|         }, | ||||
|  | ||||
| @ -5,7 +5,7 @@ import { isDesktop } from 'lib/isDesktop' | ||||
| import { PATHS } from 'lib/paths' | ||||
| import toast from 'react-hot-toast' | ||||
| import { TextToCad_type } from '@kittycad/lib/dist/types/src/models' | ||||
| import { useCallback, useEffect, useRef, useState } from 'react' | ||||
| import { useCallback, useEffect, useMemo, useRef, useState } from 'react' | ||||
| import { | ||||
|   Box3, | ||||
|   Color, | ||||
| @ -15,6 +15,7 @@ import { | ||||
|   LineSegments, | ||||
|   Mesh, | ||||
|   MeshBasicMaterial, | ||||
|   MOUSE, | ||||
|   OrthographicCamera, | ||||
|   Scene, | ||||
|   Vector3, | ||||
| @ -29,6 +30,15 @@ import { commandBarMachine } from 'machines/commandBarMachine' | ||||
| import { EventFrom } from 'xstate' | ||||
| import { fileMachine } from 'machines/fileMachine' | ||||
| import { reportRejection } from 'lib/trap' | ||||
| import { | ||||
|   CameraControls, | ||||
|   CameraInteractionType, | ||||
| } from 'clientSideScene/CameraControls' | ||||
| import { | ||||
|   cameraMouseDragGuards, | ||||
|   CameraSystem, | ||||
|   MouseGuard, | ||||
| } from 'lib/cameraControls' | ||||
|  | ||||
| const CANVAS_SIZE = 128 | ||||
| const PROMPT_TRUNCATE_LENGTH = 128 | ||||
| @ -118,8 +128,14 @@ export function ToastTextToCadSuccess({ | ||||
|   settings: { | ||||
|     theme: Themes | ||||
|     highlightEdges: boolean | ||||
|     mouseControls: CameraSystem | ||||
|   } | ||||
| }) { | ||||
|   const interactionGuards = useMemo( | ||||
|     () => cameraMouseDragGuards[settings.mouseControls], | ||||
|     [settings.mouseControls] | ||||
|   ) | ||||
|   const controlsRef = useRef<OrbitControls | null>(null) | ||||
|   const wrapperRef = useRef<HTMLDivElement | null>(null) | ||||
|   const canvasRef = useRef<HTMLCanvasElement | null>(null) | ||||
|   const animationRequestRef = useRef<number>() | ||||
| @ -168,8 +184,59 @@ export function ToastTextToCadSuccess({ | ||||
|     const ambientLight = new DirectionalLight(new Color('white'), 8.0) | ||||
|     scene.add(ambientLight) | ||||
|     const camera = createCamera() | ||||
|     // Because this listener is registered before the OrbitControls are created, | ||||
|     // it runs first and can block the OrbitControls from working. | ||||
|     renderer.domElement.addEventListener('pointerdown', (e) => { | ||||
|       if (!controlsRef.current) return | ||||
|       const newInteractionType = getCameraInteractionType({ | ||||
|         interactionGuards, | ||||
|         event: e, | ||||
|       }) | ||||
|       console.log('newInteractionType', newInteractionType) | ||||
|  | ||||
|       if (newInteractionType === 'none') { | ||||
|         e.stopImmediatePropagation() | ||||
|       } | ||||
|  | ||||
|       /** | ||||
|        * Update the OrbitControls to enable only the current interaction type. | ||||
|        * This is a hack to override the interaction types of the OrbitControls | ||||
|        * to match ours. In the future, we should roll our own class based on OrbitControls, | ||||
|        * which can handle interaction guards that are more complex than just mouse buttons. | ||||
|        */ | ||||
|       if (newInteractionType === 'pan') { | ||||
|         controlsRef.current.enablePan = true | ||||
|         controlsRef.current.enableZoom = false | ||||
|         controlsRef.current.enableRotate = false | ||||
|         controlsRef.current.mouseButtons = { | ||||
|           LEFT: MOUSE.PAN, | ||||
|           MIDDLE: MOUSE.PAN, | ||||
|           RIGHT: MOUSE.PAN, | ||||
|         } | ||||
|       } else if (newInteractionType === 'zoom') { | ||||
|         controlsRef.current.enablePan = false | ||||
|         controlsRef.current.enableZoom = true | ||||
|         controlsRef.current.enableRotate = false | ||||
|         controlsRef.current.mouseButtons = { | ||||
|           LEFT: MOUSE.DOLLY, | ||||
|           MIDDLE: MOUSE.DOLLY, | ||||
|           RIGHT: MOUSE.DOLLY, | ||||
|         } | ||||
|       } else if (newInteractionType === 'rotate') { | ||||
|         controlsRef.current.enablePan = false | ||||
|         controlsRef.current.enableZoom = false | ||||
|         controlsRef.current.enableRotate = true | ||||
|         controlsRef.current.mouseButtons = { | ||||
|           LEFT: MOUSE.ROTATE, | ||||
|           MIDDLE: MOUSE.ROTATE, | ||||
|           RIGHT: MOUSE.ROTATE, | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       controls.update() | ||||
|     }) | ||||
|     const controls = new OrbitControls(camera, renderer.domElement) | ||||
|     controls.enableDamping = true | ||||
|     controlsRef.current = controls | ||||
|     const loader = new GLTFLoader() | ||||
|     const dracoLoader = new DRACOLoader() | ||||
|     dracoLoader.setDecoderPath('/examples/jsm/libs/draco/') | ||||
| @ -270,7 +337,7 @@ export function ToastTextToCadSuccess({ | ||||
|   }, []) | ||||
|  | ||||
|   return ( | ||||
|     <div className="flex gap-4 min-w-80" ref={wrapperRef}> | ||||
|     <div className="flex gap-4 min-w-80 user-select-none" ref={wrapperRef}> | ||||
|       <div | ||||
|         className="flex-none overflow-hidden" | ||||
|         style={{ width: CANVAS_SIZE + 'px', height: CANVAS_SIZE + 'px' }} | ||||
| @ -411,3 +478,22 @@ function traverseSceneToStyleObjects({ | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| function getCameraInteractionType({ | ||||
|   interactionGuards, | ||||
|   event, | ||||
| }: { | ||||
|   interactionGuards: MouseGuard | ||||
|   event: MouseEvent | ||||
| }): CameraInteractionType | 'none' { | ||||
|   if (interactionGuards.pan.callback(event)) { | ||||
|     return 'pan' | ||||
|   } | ||||
|   if (interactionGuards.zoom.dragCallback(event)) { | ||||
|     return 'zoom' | ||||
|   } | ||||
|   if (interactionGuards.rotate.callback(event)) { | ||||
|     return 'rotate' | ||||
|   } | ||||
|   return 'none' | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,7 @@ const META = | ||||
|   PLATFORM === 'macos' ? 'Cmd' : PLATFORM === 'windows' ? 'Win' : 'Super' | ||||
| const ALT = PLATFORM === 'macos' ? 'Option' : 'Alt' | ||||
|  | ||||
| const noModifiersPressed = (e: React.MouseEvent) => | ||||
| const noModifiersPressed = (e: React.MouseEvent | MouseEvent) => | ||||
|   !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey | ||||
|  | ||||
| export type CameraSystem = | ||||
| @ -53,14 +53,14 @@ export function mouseControlsToCameraSystem( | ||||
|  | ||||
| interface MouseGuardHandler { | ||||
|   description: string | ||||
|   callback: (e: React.MouseEvent) => boolean | ||||
|   callback: (e: React.MouseEvent | MouseEvent) => boolean | ||||
|   lenientDragStartButton?: number | ||||
| } | ||||
|  | ||||
| interface MouseGuardZoomHandler { | ||||
|   description: string | ||||
|   dragCallback: (e: React.MouseEvent) => boolean | ||||
|   scrollCallback: (e: React.MouseEvent) => boolean | ||||
|   dragCallback: (e: React.MouseEvent | MouseEvent) => boolean | ||||
|   scrollCallback: (e: React.MouseEvent | MouseEvent) => boolean | ||||
|   lenientDragStartButton?: number | ||||
| } | ||||
|  | ||||
| @ -70,7 +70,7 @@ export interface MouseGuard { | ||||
|   rotate: MouseGuardHandler | ||||
| } | ||||
|  | ||||
| export const btnName = (e: React.MouseEvent) => ({ | ||||
| export const btnName = (e: React.MouseEvent | MouseEvent) => ({ | ||||
|   middle: !!(e.buttons & 4) || e.button === 1, | ||||
|   right: !!(e.buttons & 2) || e.button === 2, | ||||
|   left: !!(e.buttons & 1) || e.button === 0, | ||||
|  | ||||
| @ -16,6 +16,7 @@ import { commandBarMachine } from 'machines/commandBarMachine' | ||||
| import { getNextFileName } from './desktopFS' | ||||
| import { reportRejection } from './trap' | ||||
| import { toSync } from './utils' | ||||
| import { CameraSystem } from './cameraControls' | ||||
|  | ||||
| export async function submitTextToCadPrompt( | ||||
|   prompt: string, | ||||
| @ -77,6 +78,7 @@ interface TextToKclProps { | ||||
|   settings: { | ||||
|     theme: Themes | ||||
|     highlightEdges: boolean | ||||
|     mouseControls: CameraSystem | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	