init
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import type { Cognite3DViewer } from '@cognite/reveal';
|
||||
import { QUALITY_PRESETS, type QualitySettings } from './QualityPresets';
|
||||
|
||||
const CAMERA_IDLE_DEBOUNCE_MS = 200;
|
||||
|
||||
/**
|
||||
* Centralized quality settings controller for the Reveal viewer.
|
||||
*
|
||||
* Manages CAD/point-cloud budgets, resolution caps, and dynamic resolution
|
||||
* scaling during camera movement. All API calls are wrapped in try/catch
|
||||
* so the controller never crashes viewer initialization if a method is
|
||||
* unavailable on a particular Reveal version.
|
||||
*/
|
||||
export class RevealSettingsController {
|
||||
private settings: QualitySettings;
|
||||
private viewer: Cognite3DViewer | null = null;
|
||||
private moveTimeout: ReturnType<typeof setTimeout> | null = null;
|
||||
private cameraChangeHandler: (() => void) | null = null;
|
||||
|
||||
constructor(quality: 'low' | 'medium' | 'high' = 'medium') {
|
||||
this.settings = QUALITY_PRESETS[quality];
|
||||
}
|
||||
|
||||
applyToViewer(viewer: Cognite3DViewer): void {
|
||||
this.removeEventListeners();
|
||||
this.viewer = viewer;
|
||||
|
||||
try {
|
||||
if ('cadBudget' in viewer) {
|
||||
viewer.cadBudget = this.settings.cadBudget;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[RevealSettingsController] Failed to set cadBudget:', e);
|
||||
}
|
||||
|
||||
try {
|
||||
if ('pointCloudBudget' in viewer) {
|
||||
viewer.pointCloudBudget = this.settings.pointCloudBudget;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[RevealSettingsController] Failed to set pointCloudBudget:', e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof viewer.setResolutionOptions === 'function') {
|
||||
viewer.setResolutionOptions({
|
||||
maxRenderResolution: this.settings.resolutionOptions.maxRenderResolution,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[RevealSettingsController] Failed to set resolution:', e);
|
||||
}
|
||||
|
||||
this.setupDynamicResolution(viewer);
|
||||
}
|
||||
|
||||
setQuality(quality: 'low' | 'medium' | 'high'): void {
|
||||
this.settings = QUALITY_PRESETS[quality];
|
||||
if (this.viewer) {
|
||||
this.applyToViewer(this.viewer);
|
||||
}
|
||||
}
|
||||
|
||||
getSettings(): QualitySettings {
|
||||
return { ...this.settings };
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
if (this.moveTimeout) {
|
||||
clearTimeout(this.moveTimeout);
|
||||
this.moveTimeout = null;
|
||||
}
|
||||
this.removeEventListeners();
|
||||
}
|
||||
|
||||
private removeEventListeners(): void {
|
||||
if (this.viewer && this.cameraChangeHandler) {
|
||||
try {
|
||||
this.viewer.off('cameraChange', this.cameraChangeHandler);
|
||||
} catch {
|
||||
// Ignore if viewer is already disposed
|
||||
}
|
||||
this.cameraChangeHandler = null;
|
||||
}
|
||||
}
|
||||
|
||||
private setupDynamicResolution(viewer: Cognite3DViewer): void {
|
||||
if (typeof viewer.setResolutionOptions !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cameraChangeHandler = () => {
|
||||
try {
|
||||
viewer.setResolutionOptions({
|
||||
maxRenderResolution:
|
||||
this.settings.resolutionOptions.maxRenderResolution *
|
||||
this.settings.resolutionOptions.movingCameraResolutionFactor,
|
||||
});
|
||||
|
||||
if (this.moveTimeout) {
|
||||
clearTimeout(this.moveTimeout);
|
||||
}
|
||||
|
||||
this.moveTimeout = setTimeout(() => {
|
||||
try {
|
||||
viewer.setResolutionOptions({
|
||||
maxRenderResolution: this.settings.resolutionOptions.maxRenderResolution,
|
||||
});
|
||||
} catch {
|
||||
// Viewer may have been disposed
|
||||
}
|
||||
}, CAMERA_IDLE_DEBOUNCE_MS);
|
||||
} catch {
|
||||
// Viewer may have been disposed
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
viewer.on('cameraChange', this.cameraChangeHandler);
|
||||
} catch (e) {
|
||||
console.warn('[RevealSettingsController] Failed to add cameraChange listener:', e);
|
||||
this.cameraChangeHandler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user