Skip to content

fix(scenes): el gizmo de world SFX anclado usa la pose viva - #315

Merged
IAnMove merged 1 commit into
developmentfrom
cursor/bc-c8496db7-898d-4b1d-8fb1-74464d9e0033-1e40
Sep 10, 2026
Merged

fix(scenes): el gizmo de world SFX anclado usa la pose viva#315
IAnMove merged 1 commit into
developmentfrom
cursor/bc-c8496db7-898d-4b1d-8fb1-74464d9e0033-1e40

Conversation

@cursor

@cursor cursor Bot commented Sep 10, 2026

Copy link
Copy Markdown

Resumen ejecutivo

Esta primera sección está pensada para project managers y revisores no
técnicos. Mantén el detalle técnico completo más abajo.

Qué cambia

El gizmo de un world SFX anclado a un actor ya no escribe anchor.offset con la pose de reposo del slot. Usa la pose viva del fotograma (y el root GPU si existe).

Para qué sirve

En el demo de duelo, pausar a mitad de viaje y arrastrar el círculo mágico dejaba el efecto a ~2 m del actor. Ese offset se persistía en la escena. #311 arregló lo mismo, pero se mergeó en feat/world-sfx-3d-20260910 después de integrar esa rama en development; el bug seguía en HEAD.

Impacto para el usuario

Arrastrar un portal, círculo, aura u orbe anclado a un personaje en movimiento deja el efecto pegado al actor. Guardar o exportar ya no corrompe el offset.

Riesgo

  • Bajo
  • Medio
  • Alto

Estado

  • Listo para revisión
  • En desarrollo
  • Bloqueado por CI o revisión
  • Requiere migración o acción manual

Summary

onTransform for anchored world SFX called worldAnchorOffsetFromWorldPoint(slot, worldPoint) with the document rest pose. Playback/seek uses slotPoseAtTime. A mid-travel duel-demo drag (pause at t=5, nudge the circle) inverted ~2 m of travel into local Z. The circle jumped and the bad offset persisted.

Fix: applyWorldSfxTranslate writes the offset from the live pose, or from worldAnchorOffsetFromSlotRoot when the GPU root is attached (handles scale). Same change as #311, retargeted to development.

Overview

  1. User opens Scene Animator → world SFX duel demo.
  2. Seeks/pauses around t=5 s (subject_1 has traveled from x=-2.2 toward x=2.1).
  3. Selects the anchored magic circle and translates it slightly.
  4. Before: offset is computed against rest [-2.2, 0, 0.2], so the circle teleports.
  5. After: offset is computed against slotPoseAtTime / GPU worldToLocal, so the circle stays on the actor.

Detailed changes

Backend

No backend changes.

UI and Wizard

  • applyWorldSfxTranslate in world.ts persists live-pose or GPU-local offset.
  • worldAnchorOffsetFromSlotRoot inverts a scaled/rotated slot root.
  • Gizmo attach stores attachedAnchorSlotId and fills patch.anchorOffset.
  • Workspace uses slotPoseAtTime(slot, seconds, duration) instead of the rest slot.

Data, provenance and compatibility

Existing cues keep their stored offsets. Only new gizmo writes change. Unanchored cues still write position.

Files and ownership

  • ui/src/features/sceneFx/world.ts — live-pose persist helper
  • ui/src/features/sceneFx/worldRuntime.ts — GPU local inverse
  • ui/src/features/scene3d/transformGizmo.ts — attach + anchorOffset patch
  • ui/src/features/scene3d/Scene3DWorkspace.tsx — use live pose on translate
  • ui/tests/worldSfxRuntime.test.ts — duel mid-travel + scaled-root inverse

Deliberately untouched: playback posing, MCP apply, showcase/replace (already fixed in #307/#309).

Validation

  • Date (UTC): 2026-09-10

  • Base SHA: cde67d3983a7e1f2e79433be2ff90385e0576285 (origin/development)

  • Head SHA: 4492d7a1f7a229dc31ef367699d71103ceaa008e

  • Validation scope: focused

  • python scripts/verify_clean_repo.py

  • python -m compileall -q app/services app/launch.py scripts

  • Focused Python tests: N/A (UI-only)

  • cd ui && npm run i18n:check

  • UI tests: npx tsx --tsconfig tsconfig.app.json --import ./tests/setupI18n.ts --test tests/worldSfxRuntime.test.ts — 7 passed

  • cd ui && npm run lint -- --max-warnings=0

  • cd ui && npm run build

  • git diff --check (clean on commit)

  • E2E/smoke checks: N/A — unit tests lock the duel mid-travel trigger and GPU worldToLocal inverse; full WebGL drag needs a GPU workstation

Code quality

  • Score: pending CI
  • Complexity trend: pending CI
  • Production LOC trend: pending CI
  • Regression versus main: pending CI
  • Ratchet: pending CI

CI and review

  • CI of this HEAD: pending

  • Independent agent review of this HEAD: pending

  • Human merge click (operational, not code review): pending

  • Reviewed at current HEAD

  • Earlier review; HEAD has changed since (stale)

  • Pending

  • Unavailable

Coste de la tarea

  • Tests simulados: 0 tokens externos
  • Tests reales: N/A
  • Llamadas LLM externas: 0
  • Tokens de prompt: N/A
  • Tokens de respuesta: N/A
  • Tokens totales: N/A
  • Generaciones de imágenes/audio/vídeo: 0
  • Tiempo transcurrido: N/A
  • Proveedores/modelos: N/A

Notes and limitations

#311 is merged into the already-integrated feature branch, not development. Do not retarget this PR to that branch.

Editing is disabled while playing; the trigger is seek/pause then drag.

Follow-up work

Checklist

  • The executive summary is understandable without reading the code.
  • The detailed Summary/Overview has not been removed or shortened.
  • Tests and their actual results are recorded.
  • Generated assets, secrets and local-only files are not committed.
  • Required CI and Cursor/Bugbot review are complete, or the PR is clearly marked as waiting for them.
Open in Web View Automation 

Note

Low Risk
UI-only change to how gizmo drags persist anchor offsets; existing stored offsets are untouched and behavior is covered by focused unit tests.

Overview
Fixes anchored world SFX so moving them with the 3D gizmo no longer bakes in the slot’s rest pose when the actor is mid-animation (e.g. pause at t≈5 in the duel demo and nudge the magic circle).

applyWorldSfxTranslate centralizes translate persistence: anchored cues get anchor.offset from slotPoseAtTime at the current timeline, or from an optional anchorOffset computed in the gizmo via worldAnchorOffsetFromSlotRoot (worldToLocal on the live GPU slot root, so scale/rotation match what’s on screen). Unanchored cues still update position.

The transform gizmo tracks the anchor slot id and attaches anchorOffset on translate drags; Scene3DWorkspace wires that into world SFX updates instead of inlining rest-slot math. Tests cover mid-travel duel offsets and round-trip through a scaled slot root.

Reviewed by Cursor Bugbot for commit 4492d7a. Configure here.

Un arrastre a mitad del demo de duelo invertía el offset con la pose de
reposo del slot, así que el círculo quedaba a metros del actor. #311 se
mergeó en feat/world-sfx-3d-20260910 después de integrar esa rama; este
cambio aplica el mismo arreglo sobre development.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
@github-actions

Copy link
Copy Markdown

PR Review — Loreframe Studio

Risk: low
Scope: 5 file(s); +81/-11; React UI

Automated review from scripts/analyze_pr.py. This is a heuristic pass (no LLM) so humans still own the merge decision.

Findings

  • low — UI changed — rebuild before merge
    Run cd ui && npm run build (CI already does this). Pinokio Update rebuilds for end users; keep ui/dist untracked.

Changed files

  • modified: ui/src/features/scene3d/Scene3DWorkspace.tsx, ui/src/features/scene3d/transformGizmo.ts, ui/src/features/sceneFx/world.ts, ui/src/features/sceneFx/worldRuntime.ts, ui/tests/worldSfxRuntime.test.ts

CONTRIBUTING checklist

  • python scripts/verify_clean_repo.py
  • python -m compileall -q app/services app/launch.py scripts
  • cd ui && npm run build if the UI changed
  • No weights, CivitAI sidecars, or generated guides
  • Stays local-first (no required accounts / telemetry)

Posted by the repo PR review workflow. Re-runs on each push to the PR.

@github-actions

Copy link
Copy Markdown

Code health

Quality score: 59.4/100

Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.

Component Weight Current Change
Cyclomatic health 45% 56.6 +0.0
File concentration 25% 67.3 +0.0
Oversized-file debt 20% 43.3 +0.0
Modularity 10% 84.9 +0.0

Change vs PR base: +0.0 points.

Metric Value
Production LOC 286,288
Production files 898
Test LOC 113,878
Functions measured 19,061
Functions complexity ≥ 15 874
Maximum complexity 674
Policy code-health-policy-v1
HEAD 719e44861a2386ff5d7a16a13cf50f750a92ee48
Base cde67d3983a7e1f2e79433be2ff90385e0576285
UI measurement complete

Markdown, JSON catalogs and tests are out of this table. Only app/ runtime + ui/src TS/JS count.

Most complex functions

Complexity Where
674 app/wgp.py:7221 generate_video
381 ui/src/stores/useStore.ts:4122 Async method 'startGeneration'
355 app/_launch_runtime.py:23653 _run_generation
308 app/wgp.py:12363 generate_video_tab
266 ui/src/components/Sidebar/SceneAnimatorPanel.tsx:505 Function 'SceneAnimatorPanel'
264 ui/src/stores/useStore.ts:8670 Async method 'loadSettingsFromOutput'
258 app/services/director/planners/short_film.py:3433 ShortFilmPlanner._plan_story_driven
248 app/services/director_pipeline.py:13607 _run_video_generation
245 app/services/director_pipeline.py:7712 _run_pipeline
233 ui/src/features/agent/agentActions.ts:1152 Function 'parseAction'
226 app/services/director_pipeline.py:6541 update_comic_preview
225 ui/src/features/agent/agentActions.ts:2998 Async function 'executeAgentActions'

Trend vs baseline

Metric Δ
Production LOC +35
Test LOC +35
Functions ≥ 15 +0
Maximum complexity +0

Warnings

  • production LOC increased by +35
  • complexity hotspot ui/src/features/scene3d/transformGizmo.ts rose 18 -> 20

Ratchet passed.

@IAnMove
IAnMove marked this pull request as ready for review September 10, 2026 15:38
@IAnMove IAnMove mentioned this pull request Sep 10, 2026
22 tasks
@cursor

cursor Bot commented Sep 10, 2026

Copy link
Copy Markdown
Author

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f10ec871-4102-4637-ae03-c4d234b007da)

@IAnMove
IAnMove merged commit 32c058f into development Sep 10, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants