Skip to content

[FEATURE] Add caller-specified cameras and camera state recovery to draw and animate #263

Description

@camUrban

Problem Statement

draw and animate offer no way to set the camera. The body-fixed rendering uses a fixed default view, the free flight path frames the trajectory automatically, and the only way to get any other view is to orient the window by hand with show set to True, which cannot be scripted and cannot be repeated exactly. The hero graphic pipeline is the motivating case: scripts/hero_generation/load_and_visualize_hero.py depends on a hand-oriented view, and because its oversized re-render loop renders through a fresh Plotter, every attempt needs the view oriented again and no two attempts frame it identically.

Location(s): pterasoftware/output.py, pterasoftware/_output_rendering.py, pterasoftware/_parameter_validation.py, scripts/hero_generation/load_and_visualize_hero.py

Proposed Solution

Add optional camera parameters to draw and animate, defaulting to None, which leaves all three camera regimes (plain, image surface, and free flight) untouched, so the feature is default preserving and needs no expected-output regeneration on its own. The rendering mechanics already exist in the free flight path, which sets the camera explicitly, passes show a cpos of None so the camera survives, fits the parallel scale, and sizes the clipping range afterward, and _output_rendering.get_free_flight_fit_parallel_scale already fits the projected extent for an arbitrary view direction and up vector, so auto-framing from a caller's direction is a reuse rather than new math.

Three design decisions do the real work:

  1. Both functions render under parallel projection, so a position, a focal point, and an up vector alone do not determine the framing: the parallel scale does, and the camera's distance means nearly nothing. Today the scale is always auto-fitted so the whole scene fills the window, and interactive zooming happens through the scroll wheel, which adjusts the parallel scale while the window is open. A scripted caller has neither lever, so the camera parameters should include an optional parallel scale, with None meaning fit it from the caller's view direction, and the recovered parallel scale from the other half of this issue round-trips through the same parameter.
  2. The coordinates' axes and reference point depend on the solver: the body-fixed rendering works in the first Airplane's geometry axes relative to its CG, while free flight works in Earth axes relative to the Earth origin. The parameter names and docstrings need the care docs/AXES_POINTS_AND_FRAMES.md and docs/ANGLE_VECTORS_AND_TRANSFORMATIONS.md prescribe.
  3. _parameter_validation has no vector helper, so the shape validation, including rejecting an up vector parallel to the view direction and a position equal to the focal point, is new, with its own unit tests.

The recovery half: give a caller a way to capture a camera that was oriented by hand, as the position, focal point, up vector, and parallel scale, so one interactive session can be fed back through the new parameters for every later scripted run. Two designs are on the table, and this issue should settle the choice. Logging the state through _logger when the window closes matches how the output functions already report and leaves the signatures alone. A flag that makes the function return the camera state is the cleaner path but has the downside of adding another parameter.

Additional Context

With both halves in place, the hero graphic becomes fully scripted and reproducible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or requestquestionFurther information is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions