Operating System:
[✓] Windows
Linux
Kit Version:
[✓] 107 (Kit App Template)
106 (Kit App Template)
105 (Launcher)
Kit Template:
USD Composer
USD Explorer
[✓] USD Viewer
Custom
GPU Hardware:
A series (Blackwell)
[✓] A series (ADA)
A series
50 series
40 series
30 series
GPU Driver:
Latest
[✓] Recommended (573.xx)
Other
Work Flow:
React app > Omniverse > 3D Assets Animation
Main Issue:
User need to control the speed of animation playing like 1x, 1.5x, 2x, 2.5x from react web app to omniverse.
Requirement:
In application animation was created & running in 30 FPS as default. But end user feels like some slowness so they need to increase/decrease the animation speed based on their needs like normal video speed controls. How to control the speed of animation through script in omniverse like 1x, 1.5x, 2x, 2.5x?
Your approach is not very clear, so you could be referring to a keyframed animation or a baked animation, for example, but they have different concepts.
It’s also not clear if you just have an animation and no physics, because there’s problems that can arise from that as well. Nonetheless…
Note: Tested on USD Composer Application using Kit App Template, should still be valid
Example:
I added a Cube to a scene and keyframed its translation at 0 - 50 - 100th frames (this is not optimal keyframe strategy, but just for the sake of the example).
Running this script directly in the Script Editor for validation, I can change the set_playback_speed value, and since you reset the timeline, every time you run it with a different speed you can evaluate from start-end frame.
There’s still some aspects you might have to look into like interpolation for smoother animation, and your keyframe density, etc.
You can create your own UI and based on a callback function from changing the speed (e.g. clicking a button << >> or by setting a specific value). You should also clamp the possible values (e.g. -5.0 → 5.0).
from pxr import Usd, UsdGeom
import omni.usd
import omni.timeline
stage = omni.usd.get_context().get_stage()
timeline = omni.timeline.get_timeline_interface()
BASE_TCPS = 60.0 # use this to set your base tcps
TARGET_FPS = 60
def set_playback_speed(multiplier: float):
stage.SetTimeCodesPerSecond(BASE_TCPS / multiplier) # divide to get higher TCPS == faster
stage.SetFramesPerSecond(BASE_TCPS)
# TESTING: stop animation/reset to 0.0
timeline.stop()
timeline.set_current_time(0.0)
# Examples -> you can change this values for testing purposes
#set_playback_speed(1.0) # 1x
#set_playback_speed(1.5) # 1.5x
#set_playback_speed(2.0) # 2x
set_playback_speed(2.5) # 2.5x
timeline.set_target_framerate(TARGET_FPS) # set your target FPS
# TESTING: play animation
timeline.play()
You can control animation speed through both the Timeline Interface and USD Stage APIs in Omniverse Kit.
Method 1: Using the Timeline Interface (Recommended)
import omni.timeline
# Get the timeline interface
timeline = omni.timeline.get_timeline_interface()
# Set the time codes per second (FPS) - this controls playback speed
timeline.set_time_codes_per_second(30.0) # Set to 30 FPS
# or use
timeline.set_time_codes_per_second(60.0) # Set to 60 FPS for faster playback
# Get current time codes per second
current_fps = timeline.get_time_codes_per_seconds()
print(f"Current FPS: {current_fps}")
# You can also control playback
timeline.play() # Start playback
timeline.pause() # Pause playback
timeline.stop() # Stop playback
# Set current time
timeline.set_current_time(5.0) # Set to 5 seconds
Method 2: Using USD Stage API
from pxr import Usd
import omni.usd
# Get the current stage
context = omni.usd.get_context()
stage = context.get_stage()
# Set frames per second (affects animation playback speed)
stage.SetFramesPerSecond(30.0) # 30 FPS
# or
stage.SetTimeCodesPerSecond(24.0) # 24 time codes per second
# Get current settings
fps = stage.GetFramesPerSecond()
tcps = stage.GetTimeCodesPerSecond()
print(f"FPS: {fps}, Time Codes Per Second: {tcps}")
Method 3: Control Individual Animation Speed
For individual USD animations (like UsdSkel animations), you can control speed through time scaling:
from pxr import UsdSkel
# For skeletal animations
animation = UsdSkel.Animation.Get(stage, '/path/to/animation')
# You can also use time scale on sound or other animated elements
# This is done through the playRate attribute on individual clips
Key Concepts
- TimeCodesPerSecond: Controls how many time units equal one second of playback
- FramesPerSecond: The frame rate for the stage
- Both settings affect how fast animations play back
Example: Complete Animation Speed Controller
import omni.timeline
import omni.usd
class AnimationSpeedController:
def __init__(self):
self.timeline = omni.timeline.get_timeline_interface()
def set_speed(self, speed_multiplier: float):
"""Set animation speed as a multiplier of normal speed"""
# Get current FPS
current_fps = self.timeline.get_time_codes_per_seconds()
# Set new FPS based on multiplier
new_fps = current_fps * speed_multiplier
self.timeline.set_time_codes_per_second(new_fps)
def reset_to_normal_speed(self):
"""Reset to 24 FPS (standard)"""
self.timeline.set_time_codes_per_second(24.0)
# Usage
controller = AnimationSpeedController()
controller.set_speed(2.0) # 2x speed
controller.set_speed(0.5) # Half speed
controller.reset_to_normal_speed() # Back to normal
Related Extensions
omni.timeline- Provides the timeline interfaceomni.anim.timeline- Animation timeline functionality
Additional Resources
- Timeline API documentation in Kit SDK
- USD Time Sampling documentation
- Animation workflow guides in Omniverse documentation
Thank you @Richard3D & @ForgedByRichard for the help! we have a bottleneck here due to scene complexity and FPS limitations. currently the animation stutters at 20-30 fps. if we increase fps its creating more lag, often crashes in complex animations. Unfortunately all our animations are done in Pushgraph with Curve editor. we tried baking and altering the playback through sequencer but its not working. Is there any alternate way available to resize existing keyframes in the timeline or trick time interpolation without altering the fps?
One really efficient way to change animation playback speed, is just save the asset out, with its animation, and then load it back in a payload or reference on its own dedicated layer. Then you can simply edit the layer properties and pick any playback framerate you want and it will interpolate it. Try that.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.