Skip to content

ProjectionManager: switching to ortho hard-sets controls.distance = 200 (framing loss) — and moves the camera even when the switch aborts #781

Description

@stokuewe

Versions

@thatopen/components 3.4.8 (verified against the published dist/index.mjs; source: packages/core/src/core/OrthoPerspectiveCamera/src/projections.ts).

What happens

ProjectionManager.setOrthoCamera() begins:

this._previousDistance = this._component.controls.distance;
this._component.controls.distance = 200;
const dims = this.getPerspectiveDims();
if (!dims) return;

Two defects in one method:

  1. Framing loss by design. The hard distance = 200 discards the user's current camera distance before the ortho frustum is derived from it (getPerspectiveDims measures the just-set distance). Every perspective→ortho toggle re-frames a zoomed-in or zoomed-out view to the fixed 200. Note the distance setter also bypasses camera-controls' minDistance/maxDistance clamps (it writes _spherical.radius directly), so the library can place the camera outside its own configured bounds.
  2. State corruption on the early exit. getPerspectiveDims() returns null when the camera has no world/renderer yet. In that case the method returns — but controls.distance has already been moved to 200, current still reads "Perspective", and ProjectionManager.set triggers onChanged anyway, upon which OrthoPerspectiveCamera re-assigns this.three with the old perspective camera. Net effect: a projection switch that did not switch, but did move the view, with no error and a misleading onChanged event.

Suggested fix

Derive the ortho frustum from the current distance (no hard write), and perform all state writes only after the dims guard passes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions