Refine timeline UX and fix production build for 1.4.3 - #81
Merged
Conversation
Track page visits via Cloudflare KV in middleware, expose /api/visits endpoint (protected by VISITOR_NOTIFY_SECRET), and add local polling script with audio notification on new visitors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 6 AI debug tools for diagnosing the Gaussian Splat integration: - getGaussianStatus: renderer singleton state snapshot - getGaussianClips: all gaussian-avatar clips on timeline - getGaussianLayers: active layers at current playhead - testGaussianModule: fetch → blob → import() pipeline test - testGaussianRenderer: full init → load → canvas → pixel check - testGaussianImportPipeline: import → media store → timeline flow Fix 'gaussian-avatar' missing from sourceType union in ClipboardClipData and SerializedClipState (caused build errors). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root causes found and fixed: 1. Renderer module can't fetch blob: URLs — its internal axios silently fails, getInstance returns null. Fix: add blob-store middleware to Vite dev server that proxies blob data as HTTP URLs with .zip extension (module requires .zip in URL path). 2. loadAvatar set _avatarLoaded=true even when getInstance returned null — caused copyExternalImageToTexture to crash every frame on a canvas without a WebGL context (massive error spam). Fix: validate renderer instance and canvas WebGL context after getInstance. 3. processGaussianLayers had no try/catch around copyExternalImageToTexture — one error per frame with no throttle. Fix: try/catch with single-error logging. 4. loadGaussianAvatarMedia had no error handling — if blobUrlManager threw, clip stuck at isLoading=true forever. Fix: try/catch + null file guard. 5. is3D not serialized in SnapshotManager/ClipboardClipData — lost on undo/redo and copy/paste. Fix: add is3D to both types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add gaussian-avatar case in deserialization (serializationUtils.ts) — creates blob URL and sets gaussianAvatarUrl + blendshapes on restore - Add gaussian-avatar case in updateTimelineClips (fileManageSlice.ts) — relink dialog now properly reconnects gaussian avatar files - Serialize gaussianBlendshapes in project save - Add gaussianBlendshapes to SerializableClip type Without this, gaussian clips showed as "needs reload" (dashed outline) after every page refresh with no way to reconnect. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same bug as gaussian-avatar — the relink handler fell through to the generic else branch which only set the file reference but didn't create a modelUrl blob URL. Three.js needs that URL to load the model. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e 1) Register 'gaussian-splat' as a valid source type across all type unions (LayerSource, TimelineClip.source, SerializableClip, MediaType, MediaFile, SerializedClipState, ClipboardClipData). Add GaussianSplatSettings types with render/temporal/particle sub-settings and defaults. Create clip creation module (addGaussianSplatClip.ts), wire into clipSlice addClip flow, serialization (save/load/relink), and media import pipeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PLY and .splat parsers, header-only parse, LRU cache, normalize utils. Cherry-picked from worktree-agent-ad13695f with index.ts fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GaussianSplatGpuRenderer, SplatRenderTargetPool, SplatCameraUtils, gaussianSplat.wgsl shader. Cherry-picked from worktree-agent-ada90413. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…Wave 2C) - FileTypeIcon: green/teal point cloud icon for gaussian-splat - PropertiesPanel: GaussianSplatTab with render settings (scale, planes, max splats) - MediaPanel: accept .ply/.splat file imports - useExternalDrop: recognize gaussian splat files for drag-drop - Fix: restore useGaussianSplat feature flag for old avatar path - Fix: add typeOverride to ImportParams for gaussian-splat/avatar imports Cherry-picked from worktree-agent-a995b351 with conflict resolution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restores stashed changes for gaussian-avatar support in LayerBuilder, LayerCollector, and ExportLayerBuilder that were in progress before the gaussian-splat orchestrator work. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- LayerBuilderService: add buildGaussianSplatLayer() with clip-local time - LayerCollector: add gaussian-splat stub handler (textureView filled by RenderDispatcher) - RenderDispatcher: add processGaussianSplatLayers() — per-layer WebGPU rendering, async scene loading, in-place LayerRenderData replacement preserving compositor properties - ExportLayerBuilder: add gaussian-splat branch for export path Each gaussian-splat clip renders into its own texture (no merging). Compositor receives per-layer opacity, blend mode, masks, and effects intact. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… (Wave 5) - Add TemporalSampler: deterministic, stateless frame selection for 4D gaussian splat sequences with loop/clamp/pingpong modes and configurable frame blending - Add FrameBufferSwapper: double-buffered GPU storage for smooth frame transitions without pipeline stalls, only re-uploads when frames change - Add ParticleCompute: GPU compute pass applying deterministic particle offsets (explode, drift, swirl, dissolve) to splat positions/scales/opacities - Add temporalBlend.wgsl: compute shader for frame interpolation with nlerp quaternion blending - Add particleCompute.wgsl: compute shader with deterministic hash-based particle effects (no Math.random, no accumulated state) - Integrate particle pipeline into GaussianSplatGpuRenderer.renderToTexture() with per-clip output buffer caching and bind group management - Wire clip-local time and particle/temporal settings from layer source through RenderDispatcher into the GPU renderer - All effects are fully deterministic: scrub to frame N == play-through to frame N Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s (Wave 4) Adds large-asset performance optimizations for scenes with 100K+ gaussians: - SplatVisibilityPass: GPU compute frustum culling that tests each splat against 6 camera frustum planes with bounding sphere margin. Outputs visible indices via atomic counter. Async readback updates draw count for next frame. - SplatSortPass: GPU bitonic merge sort that orders visible splats back-to-front by view-space depth. Uses float-to-sortable-u32 encoding for correct ordering. O(n log²n) parallel sort, works well up to ~1M elements. - gaussianSplat.wgsl: Added sortedIndices storage buffer (binding 1) for index indirection. Vertex shader now reads splat[sortedIndices[instance_index]]. - GaussianSplatGpuRenderer: Integrated cull→sort→render pipeline with thresholds (cull > 50K splats, sort > 1K splats), sort frequency throttling, maxSplats budget cap, and graceful fallback to unsorted path on failure. - Identity index buffers created per-scene for the unsorted default path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uncommitted changes Includes stashed workspace changes from staging (2026-04-04): interactive tutorial overlay stubs, gaussian splat export preloading, preview enhancements, and radix sort fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace cached useMemo selectedGaussianSplatTransform with getFreshGaussianTransform() that reads the interpolated transform directly from the store at each mousedown/wheel event. Fixes race condition where second camera drag at same playhead position would jump back to pre-edit values because the memoized transform wasn't invalidated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…panels Mesh, Move to Folder, and Show in Explorer submenus were clipped by dock panel overflow:hidden containers. Now uses position:fixed with dynamic viewport boundary detection to always stay visible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ectional media sync Right-click any clip in the timeline to set its label color via a color grid submenu. Colors are synced bidirectionally with the media panel — setting a color on a clip updates the media item, and vice versa. All clip types supported (video, audio, image, text, solid, mesh, camera, compositions) with fallback matching for legacy clips without mediaFileId. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…a panel They were incorrectly classified as media files requiring a File object. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
labelColor was never included in the project file format, so colors set on media files, folders and compositions were lost on reload. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # tools/visitor-tray/.env.example # tools/visitor-tray/Install-Startup.ps1 # tools/visitor-tray/README.md # tools/visitor-tray/VisitorTray.ps1 # tools/visitor-tray/start.cmd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification