[Fix]: Corrected camera's projection when engine idle reconnects (#7173)

* fix: implemented a fix to read from settings before restoring camera view and log if it desyncs

* fix: reverting testing code

* fix: always enable ortho scale enabled mode

* fix: fixed the ortho_scale_enabled boolean, do not touch it. Set it to true and never touch it again
This commit is contained in:
Kevin Nadro
2025-05-23 16:30:05 -05:00
committed by GitHub
parent 08dfaba7f7
commit 30bd307931
3 changed files with 52 additions and 1 deletions

View File

@ -43,6 +43,7 @@ import {
uuidv4,
} from '@src/lib/utils'
import { deg2Rad } from '@src/lib/utils2d'
import type { SettingsType } from '@src/lib/settings/initialSettings'
const ORTHOGRAPHIC_CAMERA_SIZE = 20
const FRAMES_TO_ANIMATE_IN = 30
@ -124,6 +125,8 @@ export class CameraControls {
interactionGuards: MouseGuard = cameraMouseDragGuards.Zoo
isFovAnimationInProgress = false
perspectiveFovBeforeOrtho = 45
// TODO: proper dependency injection
getSettings: (() => SettingsType) | null = null
// NOTE: Duplicated state across Provider and singleton. Mapped from settingsMachine
_setting_allowOrbitInSketchMode = false
@ -964,8 +967,50 @@ export class CameraControls {
})
}
/**
* A helper function that will override this.oldCameraState
* with the current setting's camera projection. If these are desynced
* that is okay but when the camera restores we want the user to be in the correct
* camera projection which is the settings value. Not this old state.
*
* Gotcha: This is not to be confused with Named Views, those have correct state.
*/
overrideOldCameraStateToPreventDesync() {
if (!this.getSettings) {
return
}
// Engine idle disconnection happened, we saved off the camera state
// If the settings camera projection is different from the saved camera state we need to override it.
const settings = this.getSettings()
const cameraProjection = settings.modeling.cameraProjection.current
const isOrtho = cameraProjection === 'orthographic' ? true : false
if (this.oldCameraState) {
// Leave a log to know when this desyncs
console.log(`restoring camera projection setting:${cameraProjection}`)
console.log(
`oldCameraState projection:${isOrtho ? 'orthographic' : 'perspective'}, ortho_scaled_enabled:${this.oldCameraState.ortho_scale_enabled}`
)
if (this.oldCameraState.is_ortho !== isOrtho) {
console.log(
'oldCameraState is_ortho desynced',
this.oldCameraState.is_ortho,
isOrtho
)
}
this.oldCameraState.is_ortho = isOrtho
// Always keep this enabled!
this.oldCameraState.ortho_scale_enabled = true
}
}
async restoreRemoteCameraStateAndTriggerSync() {
if (this.oldCameraState) {
// Always write settings.modeling.cameraProjection to the restored camera view
this.overrideOldCameraStateToPreventDesync()
await this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd_id: uuidv4(),

View File

@ -206,6 +206,11 @@ export const getSettings = () => {
const { currentProject: _, ...settings } = settingsActor.getSnapshot().context
return settings
}
// These are all late binding because of their circular dependency.
// TODO: proper dependency injection.
sceneInfra.camControls.getSettings = getSettings
export const useSettings = () =>
useSelector(settingsActor, (state) => {
// We have to peel everything that isn't settings off

View File

@ -648,7 +648,8 @@ export async function engineViewIsometricWithoutGeometryPresent({
fov_y: 45,
ortho_scale_factor: 1.4063792,
is_ortho: cameraProjection !== 'perspective',
ortho_scale_enabled: cameraProjection !== 'perspective',
// always keep this enabled
ortho_scale_enabled: true,
world_coord_system: 'right_handed_up_z',
}
await engineCommandManager.sendSceneCommand({