@@ -8,6 +8,8 @@ import ScreenInteractionHandler, {
88 PRIMARY_MOUSE_INTERACTION ,
99 SECONDARY_MOUSE_INTERACTION ,
1010} from "./ScreenInteractionHandler"
11+ import { MiraType } from "@/mirabuf/MirabufLoader"
12+ import World from "../World"
1113
1214export type CameraControlsType = "Orbit"
1315
@@ -143,6 +145,43 @@ export class CustomOrbitControls extends CameraControls {
143145 this . _interactionHandler . interactionMove = e => this . interactionMove ( e )
144146 }
145147
148+ /**
149+ * Finds a suitable fallback focus target when the current focus is no longer available.
150+ * Prioritizes robots first, then fields, then any other MirabufSceneObject.
151+ */
152+ private findFallbackFocus ( mirabufObjects ?: MirabufSceneObject [ ] ) : MirabufSceneObject | undefined {
153+ if ( ! mirabufObjects ) {
154+ const sceneObjects = Array . from ( World . sceneRenderer . sceneObjects . values ( ) )
155+ mirabufObjects = sceneObjects . filter ( obj => obj instanceof MirabufSceneObject ) as MirabufSceneObject [ ]
156+ }
157+
158+ const robots = mirabufObjects . filter ( obj => obj . miraType === MiraType . ROBOT )
159+ const fields = mirabufObjects . filter ( obj => obj . miraType === MiraType . FIELD )
160+
161+ return robots [ 0 ] || fields [ 0 ] || mirabufObjects [ 0 ]
162+ }
163+
164+ /**
165+ * Validates that the current focus provider still exists in the scene.
166+ * If not, automatically finds a suitable replacement.
167+ */
168+ private validateFocusProvider ( ) : void {
169+ if ( ! World . sceneRenderer ?. sceneObjects ) {
170+ return
171+ }
172+
173+ const allSceneObjects = Array . from ( World . sceneRenderer . sceneObjects . values ( ) )
174+ const mirabufObjects = allSceneObjects . filter ( obj => obj instanceof MirabufSceneObject ) as MirabufSceneObject [ ]
175+
176+ if ( this . _focusProvider ) {
177+ if ( ! mirabufObjects . includes ( this . _focusProvider ) ) {
178+ this . _focusProvider = this . findFallbackFocus ( mirabufObjects )
179+ }
180+ } else {
181+ this . _focusProvider = this . findFallbackFocus ( mirabufObjects )
182+ }
183+ }
184+
146185 public interactionEnd ( end : InteractionEnd ) {
147186 /**
148187 * If Pointer is already down, and the button that is being
@@ -246,6 +285,8 @@ export class CustomOrbitControls extends CameraControls {
246285 public update ( deltaT : number ) : void {
247286 deltaT = Math . max ( 1.0 / 60.0 , Math . min ( 1 / 144.0 , deltaT ) )
248287
288+ this . validateFocusProvider ( )
289+
249290 if ( this . enabled ) this . _focusProvider ?. loadFocusTransform ( this . _focus )
250291
251292 // Generate delta of spherical coordinates
0 commit comments