Commit Graph

11 Commits

Author SHA1 Message Date
indigo 9d8840ced6 Add per-viewport render settings persistence (delegate, grid, AA, bg, bbox, lighting)
ViewportTileSettings struct captures: render delegate, show grid, AA, background
color, bbox mode, ambient-light-only, dome-light flags.

ViewportPanel::SaveSettings() writes a simple INI file (layout + one [TileN]
section per tile) to %APPDATA%\UsdLayerManager\viewport_settings.ini on
Application::Shutdown().

ViewportPanel::LoadSettings() is called at the end of Application::Initialize()
— after the viewport panel is constructed but before the first frame — so the
saved render delegate is picked up by UsdSceneRenderer::InitRenderer() on the
first Render() call.  Layout (Single/HSplit/VSplit/Quad) and split ratios are
also restored, creating the correct number of tiles before settings are applied.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 09:34:00 +08:00
indigo 425d21db45 Add animation curve editor with Bezier F-curve round-trip
Maya-style Graph Editor panel (View > Curve Editor) that fits Catmull-Rom
Bezier curves through USD time samples, allows interactive editing with
tangent handles, and bakes the result back to dense linear samples on Apply.

Key behaviours:
- Left panel lists all animated attributes of the selected prim, decomposed
  into per-component channels (translate [X/Y/Z], etc.) with colour swatches
  and visibility toggles
- ImDrawList canvas: smooth Bezier polylines, always-visible tangent handle
  lines/circles, diamond keyframe markers
- Pan (MMB/Alt+drag), zoom (scroll / Shift+scroll), Frame All (F)
- LMB drag moves keyframes; tangent handle drag reshapes curve with mirrored
  or broken handles; box-select for multi-selection
- Double-click canvas adds a keyframe; Delete removes selected keyframes
- RMB context menu: Delete, Flatten, Break/Unify Tangents, Auto Tangents
- Simplify toggle (Ramer-Douglas-Peucker) reduces baked sample count
- Time cursor draggable to scrub the timeline
- UsdNotice::ObjectsChanged listener re-fits clean channels whenever the
  stage changes externally (Property Panel edits, Auto-Key, undo/redo),
  while preserving channels with unsaved Bezier edits
- Bake is a single undoable AttributeSetCommand (Ctrl+Z restores original
  sparse samples); Revert discards in-editor edits without touching USD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 08:25:25 +08:00
indigo 0538dd3243 Add playblast: viewport capture to H.264 MP4 via libavcodec
- TimelinePanel: Playblast button opens modal with output dir (native
  folder picker via IFileOpenDialog), custom resolution (HD/FHD/4K
  presets), frame range, and movie export toggle
- UsdSceneRenderer: CaptureFrame() reads pixels from resolved MSAA FBO;
  Render() stores last dimensions for off-screen re-render at capture res
- MovieEncoder: streams RGBA frames directly into MP4 using libavcodec/
  libswscale (H.264, tries libx264 → nvenc → qsv → amf → openh264)
- Application: CapturePlayblastFrame() re-renders at capture resolution
  each frame; opens/writes/closes MovieEncoder inline with the render loop
- FileDialog: BrowseFolder() using Vista-style IFileOpenDialog (COM)
- CMake: FindFFmpeg.cmake locates prebuilt BtbN GPL shared package in
  third_party/ffmpeg; links and copies DLLs for main and test targets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 09:36:30 +08:00
indigo a62764397c Scene Hierarchy ET switcher + Create Sublayer via Save dialog
- Add edit-target layer combo at top of Scene Hierarchy panel (always
  visible when stage loaded — session, root, sublayers); routes through
  LayerManager::SetEditTarget so StageEditor ET checkboxes stay in sync
- Replace custom Create Sublayer modal with native SaveFile dialog;
  LayerManager::CreateNewSublayer creates the file on disk, inserts it
  at the top of the sublayer stack, and activates it as edit target

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 03:49:35 +08:00
indigo e5d7967455 View menu — panel visibility toggles for all 5 panels
Each panel (Stage Editor, Scene Hierarchy, Viewport, Property Panel,
Timeline) now has a checkable menu item under View. Closing a panel via
its X button also unchecks the entry. Stage Info and Demo Window follow
below a separator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 22:39:50 +08:00
indigo 7f0fa6a944 Fix rotate manipulator axis and gizmo pivot placement
Rotate manipulator — correct axis bug:
- Object-space delta axis was set to initRot.GetRow3(axis) (a parent-space
  vector) then applied in the prim's local frame via deltaM * initRot.
  These frames are mismatched: the axis must be the canonical e_a so that
  Rot(e_a) fixes e_a and the prim rotates purely about its own axis.
  Fixed to use the canonical axis for both spaces; only composition order
  differs (deltaM * initRot for object, initRot * deltaM for world).

Gizmo pivot placement:
- ComputeGizmoPivot() used the bounding-box centre (geometry centroid),
  placing the gizmo at the wrong location for any non-centred prim.
  Replaced with parentToWorld.Transform(translate + pivot) from
  XformCommonAPI::GetXformVectors — the authored pivot point in world space.
  Fallback for incompatible op stacks uses worldMatrix.ExtractTranslation().

Property panel:
- Show pivot (X/Y/Z) as read-only row below Scale, populated from
  XformCommonAPI::GetXformVectors each frame.
- Removed active-rotate-axis display (was added and then removed per request).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 09:57:39 +08:00
indigo e0b0fd8204 Fix sublayers not persisted on save
- SaveStage: explicitly call rootLayer->Save() before m_stage->Save() to
  ensure root-layer metadata (subLayers field) is always written to disk
- SaveUsdFile: redirect to SaveAs when the root layer is anonymous so
  Ctrl+S on an in-memory stage no longer silently does nothing
- SaveUsdFileAs: call RefreshManagers() after SaveStageAs so LayerManager
  stays in sync with the newly opened file-backed stage; without this,
  sublayers added after a Save As went to the old stale stage and were lost
- LayerCreateCommand::Execute: use GetSublayers() (sublayer-local indices)
  instead of GetLayerStack() (full-stack indices) to record m_insertedIndex,
  fixing undo of add-sublayer removing the wrong layer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 07:49:34 +08:00
indigo 9816fb8759 Stage Editor Panel — sublayer editing with ET control, mute, reorder, dirty state
Replace LayerPanel with StageEditorPanel for full sublayer composition workflow:
- Edit target (ET) checkbox on root/session and each sublayer; pen icon header
- Dirty indicator (*) per layer; muted layers remain visible in list
- Drag-drop and Move Up/Down reordering with undo (LayerReorderCommand)
- Add existing sublayer via file dialog; create new sublayer modal
- Fixed LayerReorderCommand::ApplyOrder using full-stack indices on sublayer-local
  list (silent remove failure → duplicate insert → USD _ValidateEdit error)
- Fixed muted sublayer visibility: walk GetSubLayerPaths() + FindOrOpenRelativeToLayer
  + m_layerRefs to keep muted layers alive and visible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 16:37:30 +08:00
indigo c4bf9673a8 Timeline Prototype 2026-06-13 11:48:56 +08:00
indigo 43c70be574 PropertyPanel Update 2026-06-13 08:45:16 +08:00
indigo 9be48d8b9e Init Repo 2026-06-03 09:00:11 +08:00