Skip to content

Commit

Permalink
Add time pivot example
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaScheller committed Sep 27, 2023
1 parent e1fe27b commit 9047702
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
17 changes: 14 additions & 3 deletions code/core/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -1772,6 +1772,8 @@ def Xform "explosion" (
layer_identifier = "ref_layer.usd"
stage_fps = 24
stage_identifier = "root_layer.usd"
frame_start = 1001
frame_end = 1025

# Create layer
reference_layer = Sdf.Layer.CreateAnonymous()
Expand All @@ -1780,9 +1782,14 @@ def Xform "explosion" (
prim_spec.specifier = Sdf.SpecifierDef
prim_spec.typeName = "Cube"
attr_spec = Sdf.AttributeSpec(prim_spec, "size", Sdf.ValueTypeNames.Double)
for frame in range(1001, 1005):
value = float(frame - 1000)
for frame in range(frame_start, frame_end + 1):
value = float(frame - frame_start) + 1
# If we work correctly in seconds everything works as expected.
reference_layer.SetTimeSample(attr_spec.path, frame * (layer_fps/stage_fps), value)
# In VFX we often work frame based starting of at 1001 regardless of the FPS.
# If we then load the 25 FPS in 24 FPS, USD applies the correct scaling, but we have
# to apply the correct offset to our "custom" start frame.
# reference_layer.SetTimeSample(attr_spec.path, frame, value)
# FPS Metadata
time_samples = Sdf.Layer.ListAllTimeSamples(reference_layer)
reference_layer.timeCodesPerSecond = layer_fps
Expand All @@ -1793,8 +1800,12 @@ def Xform "explosion" (

# Create stage
stage = Usd.Stage.CreateInMemory()
# Without scale
# If we work correctly in seconds everything works as expected.
reference_layer_offset = Sdf.LayerOffset(0, 1)
# In VFX we often work frame based starting of at 1001.
# If we then load the 25 FPS in 24 FPS, USD applies the correct scaling, but we have
# to apply the correct offset to our "custom" start frame.
# reference_layer_offset = Sdf.LayerOffset(frame_start * (stage_fps/layer_fps) - frame_start, 1)
reference = Sdf.Reference(reference_layer.identifier, "/bicycle", reference_layer_offset)
bicycle_prim_path = Sdf.Path("/bicycle")
bicycle_prim = stage.DefinePrim(bicycle_prim_path)
Expand Down
6 changes: 6 additions & 0 deletions docs/src/core/elements/animation.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ Therefore when writing layers, we should always write these layer metrics, so th
the original intended FPS were and our caches work FPS independently.
~~~

~~~admonish warning
In VFX we often work starting from 1001 regardless of the FPS as it is easier for certain departments like FX to have pre-cache frames to init their sims as well as it also makes it easier to write frame based expressions. That means that when working with both 25 and 24 FPS caches, we have to adjust the offset of the incoming cache.
Let's say we have an anim in 25 FPS starting off at 1001 that we want to bring into a 24 FPS scene. USD as mentioned above handles the scaling for us based on the metadata, but since we still want to start at 1001, we have to offset based on "frame_start * (stage_fps/layer_fps) - frame_start". See the below commented out code for a live example. That way we now have the same 25 FPS cache running in 24 FPS from the same "starting pivot" frame. If we work fully time based, we don't have this problem, as animation in the 25 FPS cache would have its time samples written at larger frames than the 24 FPS cache and USD's scaling would auto correct it.
~~~

```python
(
timeCodesPerSecond = 24
Expand Down

0 comments on commit 9047702

Please sign in to comment.