UsdLayerManager/openspec/changes/viewport-custom-camera/tasks.md

3.3 KiB

1. Maya-style Viewport Controls

  • 1.1 Refactor ViewportPanel::HandleInput() to use Alt+LMB for orbit, Alt+MMB for pan, Alt+RMB for dolly
  • 1.2 Remove legacy input mappings (LMB orbit, MMB pan, Shift+LMB pan) from HandleInput()
  • 1.3 Keep mouse scroll zoom working without Alt modifier
  • 1.4 Add Alt key detection via io.KeyAlt in ImGui and ensure Alt is not consumed by ImGui menu navigation

2. ViewportCamera Dual-Mode Support

  • 2.1 Add enum class CameraMode { Free, UsdCamera } and a m_mode member to ViewportCamera
  • 2.2 Add m_usdCameraPath (SdfPath) and m_savedFreeCameraState struct to persist free camera state across mode switches
  • 2.3 Add SetUsdCamera(const UsdStageRefPtr& stage, const SdfPath& cameraPath) method that reads UsdCamera attributes (focalLength, horizontalAperture, verticalAperture, clippingRange, projection) and world transform
  • 2.4 Implement ComputeUsdCameraViewMatrix() deriving the view matrix from the UsdCamera prim's world-space transform
  • 2.5 Implement ComputeUsdCameraProjectionMatrix() deriving the projection matrix from UsdCamera focalLength, aperture, and clip attributes
  • 2.6 Modify GetViewMatrix() and GetProjectionMatrix() to dispatch based on m_mode (free vs USD camera)
  • 2.7 Add SwitchToFreeCamera() that restores the saved free camera state
  • 2.8 Disable orbit/pan/zoom/dolly calls when m_mode == UsdCamera (no-op in USD camera mode)

3. Camera Selector UI

  • 3.1 Add method FindCameraPrims(const UsdStageRefPtr& stage) to traverse the stage and return a vector of SdfPaths for all UsdCamera-typed prims
  • 3.2 Cache the camera list in ViewportPanel and invalidate on stage change
  • 3.3 Add an ImGui combo dropdown above the viewport canvas in ViewportPanel::Render() with "Free Camera" as the first entry followed by discovered camera prim paths
  • 3.4 Wire the dropdown selection to call ViewportCamera::SetUsdCamera() or SwitchToFreeCamera()
  • 3.5 Reset the camera selector to "Free Camera" when a new stage is loaded via ViewportPanel::SetStage()

4. Frame Selected Prim

  • 4.1 Add m_selectedPrimPath string member to ViewportPanel and a setter SetSelectedPrimPath(const std::string&)
  • 4.2 Wire Application to call ViewportPanel::SetSelectedPrimPath() from the SceneHierarchyPanel::SetOnPrimSelected() callback
  • 4.3 Add F key handler in ViewportPanel::HandleInput(): compute bounding box of the selected prim using UsdGeomBBoxCache and call FrameBoundingBox
  • 4.4 If viewport is in USD camera mode when F is pressed, switch to free camera mode first then frame
  • 4.5 Add A key handler in ViewportPanel::HandleInput(): call FrameScene() to frame all

5. Integration and Verification

  • 5.1 Verify Maya-style Alt+button navigation works for orbit, pan, and dolly in the viewport
  • 5.2 Verify camera selector dropdown lists free camera and all stage camera prims
  • 5.3 Verify switching to a USD camera renders from that camera's viewpoint
  • 5.4 Verify switching back to free camera restores the previous free camera position
  • 5.5 Verify F key frames the selected prim and A key frames the entire stage
  • 5.6 Build and run the application to confirm no regressions in existing viewport rendering