Remove setInterval implementations from camera controls (#4255)

* remove setInterval implementations from camera controls

* fmt
This commit is contained in:
Mike Farrell
2024-10-21 16:46:47 -07:00
committed by GitHub
parent af74f3bb05
commit 26042790b6
2 changed files with 59 additions and 48 deletions

BIN
..env.development.local.swp Normal file

Binary file not shown.

View File

@ -64,6 +64,27 @@ export type ReactCameraProperties =
const lastCmdDelay = 50 const lastCmdDelay = 50
class CameraRateLimiter {
lastSend?: Date = undefined
rateLimitMs: number = 16 //60 FPS
send = (f: () => void) => {
let now = new Date()
if (
this.lastSend === undefined ||
now.getTime() - this.lastSend.getTime() > this.rateLimitMs
) {
f()
this.lastSend = now
}
}
reset = () => {
this.lastSend = undefined
}
}
export class CameraControls { export class CameraControls {
engineCommandManager: EngineCommandManager engineCommandManager: EngineCommandManager
syncDirection: 'clientToEngine' | 'engineToClient' = 'engineToClient' syncDirection: 'clientToEngine' | 'engineToClient' = 'engineToClient'
@ -77,9 +98,8 @@ export class CameraControls {
enableRotate = true enableRotate = true
enablePan = true enablePan = true
enableZoom = true enableZoom = true
zoomDataFromLastFrame?: number = undefined moveSender: CameraRateLimiter = new CameraRateLimiter()
// holds coordinates, and interaction zoomSender: CameraRateLimiter = new CameraRateLimiter()
moveDataFromLastFrame?: [number, number, string] = undefined
lastPerspectiveFov: number = 45 lastPerspectiveFov: number = 45
pendingZoom: number | null = null pendingZoom: number | null = null
pendingRotation: Vector2 | null = null pendingRotation: Vector2 | null = null
@ -171,6 +191,36 @@ export class CameraControls {
} }
} }
doMove = (interaction: any, coordinates: any) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd: {
type: 'camera_drag_move',
interaction: interaction,
window: {
x: coordinates[0],
y: coordinates[1],
},
},
cmd_id: uuidv4(),
})
}
doZoom = (zoom: number) => {
this.handleStart()
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd: {
type: 'default_camera_zoom',
magnitude: (-1 * zoom) / window.devicePixelRatio,
},
cmd_id: uuidv4(),
})
this.handleEnd()
}
constructor( constructor(
isOrtho = false, isOrtho = false,
domElement: HTMLCanvasElement, domElement: HTMLCanvasElement,
@ -258,49 +308,6 @@ export class CameraControls {
this.onCameraChange() this.onCameraChange()
} }
// Our stream is never more than 60fps.
// We can get away with capping our "virtual fps" to 60 then.
const FPS_VIRTUAL = 60
const doZoom = () => {
if (this.zoomDataFromLastFrame !== undefined) {
this.handleStart()
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd: {
type: 'default_camera_zoom',
magnitude:
(-1 * this.zoomDataFromLastFrame) / window.devicePixelRatio,
},
cmd_id: uuidv4(),
})
this.handleEnd()
}
this.zoomDataFromLastFrame = undefined
}
setInterval(doZoom, 1000 / FPS_VIRTUAL)
const doMove = () => {
if (this.moveDataFromLastFrame !== undefined) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.engineCommandManager.sendSceneCommand({
type: 'modeling_cmd_req',
cmd: {
type: 'camera_drag_move',
interaction: this.moveDataFromLastFrame[2] as any,
window: {
x: this.moveDataFromLastFrame[0],
y: this.moveDataFromLastFrame[1],
},
},
cmd_id: uuidv4(),
})
}
this.moveDataFromLastFrame = undefined
}
setInterval(doMove, 1000 / FPS_VIRTUAL)
setTimeout(() => { setTimeout(() => {
this.engineCommandManager.subscribeTo({ this.engineCommandManager.subscribeTo({
event: 'camera_drag_end', event: 'camera_drag_end',
@ -386,7 +393,9 @@ export class CameraControls {
if (interaction === 'none') return if (interaction === 'none') return
if (this.syncDirection === 'engineToClient') { if (this.syncDirection === 'engineToClient') {
this.moveDataFromLastFrame = [event.clientX, event.clientY, interaction] this.moveSender.send(() => {
this.doMove(interaction, [event.clientX, event.clientY])
})
return return
} }
@ -459,7 +468,9 @@ export class CameraControls {
if (this.syncDirection === 'engineToClient') { if (this.syncDirection === 'engineToClient') {
if (interaction === 'zoom') { if (interaction === 'zoom') {
this.zoomDataFromLastFrame = event.deltaY this.zoomSender.send(() => {
this.doZoom(event.deltaY)
})
} else { } else {
// This case will get handled when we add pan and rotate using Apple trackpad. // This case will get handled when we add pan and rotate using Apple trackpad.
console.error( console.error(