Client Library and Live Overview
Introduced in 200.0
The Connect Samples version 200.0 includes a large update to the Omniverse Client Library version 2. This change impacts Connectors in these ways:
Omniverse dependencies are retrieved differently
The USD Resolver may need to be initialized separately
API changes
Live sync changes
USD version changes
The biggest changes are centered around live sync and USD versions. First, live sync no longer works on .usd files, but is now restricted only to .live files, which we’ll refer to as .live layers. This change to using .live layers allows Omniverse to start live sessions without changing the underlying data. Clients will typically use USD layer composition with the edit target set to the .live layer to enable live synchronization in a USD stage. Note: .live layers are presented to clients as USD layers.
More USD library versions are now supported due to changes in the Client Library and USD Resolver plugin because they can now compile against stock USD.
See the Omniverse Live Workflow Documentation for more information on the UI/UX for implementing and using Live Sessions in USD Composer and other clients.
See the Omniverse Live Workflow Developer FAQ for more information on the immediate changes (also described in some detail below).
Build Changes from Client Library 1.x
The Omniverse USD Resolver plugin is now separated from the Client Library, so it adds build dependencies to Connectors.
There is a very simple checkpoint API in the resolver plugin that Connectors will probably want to include, so adding the resolver as a build dependency is a new step.
The Client Library no longer depends on USD (this enables us to provide more USD versions in the future)
The Connect Sample has a build script that “double fetches” using the Packman dependency system.
First it grabs the correct Omniverse USD Resolver plugin which contains the USD library dependency and the Client Library dependency locations
These are then fetched and land here:
_build/target-deps/omni_usd_resolver
_build/target-deps/usd
_build/target-deps/omni_client_library
Initialization Changes
Because the USD Resolver plugin is no longer bundled with the Client Library it needs to be either copied to the correct folder for your application or initialized wherever you decide to use it.
The Connect Samples copy the USD Resolver files into the correct place so it is automatically initialized, but we made an example for initializing the resolver plugin anyway in
liveSession.cpp
. For more information on explicitly initializing the plugin, see the resolver docs in the “Initializing” section.
API Changes
All of the different
OmniClient*.h
files with interfaces required by a client are now combined into a singleOmniClient.h
file.The application no longer has a “live mode” controllable by the client library API. If a developer is editing a layer with a
.live
file extension and usesomniClientLiveProcess()
then all changes are automatically sent and received.The resolver can now be used to set a checkpoint message because every file save generates checkpoints (labeled or not):
omniUsdResolverSetCheckpointMessage()
Live Changes
Client and Resolver Changes
The live transfer of data between clients and Omniverse servers has been revamped with these goals in mind:
Support the full USD feature set. Anything that can be done in USD is supported with live layers.
Multiple simultaneous editors. This includes being able to edit the same prims, and even the same attributes, at the exact same time.
High performance. The power of live layers comes from their interactive speeds. However, performance must not come at the cost of correctness.
Read more about the intricacies in the USD Resolver technical overview documentation
Only .live files/layers resident on an Omniverse server will replicate data
omniClientLiveProcess()
is used to both send and receive changes to and from the Omniverse server. It is no longer required to save the .live layer using the USD Save API.
Live Session implications - Non-Destructive Live Session Workflow
To go along with only replicating data through .live layers the Omniverse team is formalizing a scheme for Omniverse applications and Connectors to have robust live editing sessions.
The idea is that when a Connector or content creation tool generates USD data (stages, props, etc), we want creators to be able to live-collaborate without unintentionally destroying or modifying that data.
Live stage composition
The .live layer is inserted, by each participating client, into the Session Layer. This is done for two reasons:
This avoids altering the original USD stage
All changes made in the .live layer will take authority over data in the base, or root USD stage.
Example:
Live_Stage.usd -------------- Session Layer |_ root.live (layer) |_ (overs replicated by Omniverse) Root Layer |_ /World |_ (Prims with overs in root.live)
Live stage file and folder structure
The .live layer files need to live somewhere on the Omniverse server so we established a common location for them.
.live folder - All live session files are stored in a folder called “.live”
usd_root_stage.live
folder - a folder is created for each root USD file since a live session can only apply to one particular USD filesession_name.live
- each session gets its own folder to store the session files
Session files - there are three files that exist for each session
root.live
- the .live layer where overs and new defs are stored for the session__session__.channel
- the channel file used by clients to send and receive Omniverse channel messages with other clients (peer presence, merge intentions, etc.)__session__.toml
- a configuration file for the live session
Inside the same folder where the USD root file
usd_root_stage.usd
being live-edited in a session calledsession_name
, a folder structure like this would exist:./.live/usd_root_stage.live/session_name.live/...
Live session configuration file:
__session__.toml
It contains these key/value pairs:
* version = "1.0" * user_name = "owner_user_name" * mode = "default" ("auto_authoring", "root_authoring", "project_authoring") * stage_url = "omniverse://server/path/root_stage.usd" * (optional) description = "A description of the session purpose"
When a client creates a new session, this file should be created with the above key/value pairs defined. The
user_name
value should be the owner’s username for the URL defined instage_url
.
Live session channel communication
An Omniverse Channel is used to communicate peer presence and merge status in the live session between clients. Clients broadcast JSON messages in this format:
Key |
Value |
Type |
Comments |
---|---|---|---|
version |
3.0 |
String |
Message version. 3.0 is the version defined by Kit in this release. The version is composed as pattern [major].[minor]. If the major version is upgraded it is no longer backwards compatible. An increase of minor versions will still be backwards compatible and possibly add new keys. Clients with older major versions should not join sessions with a newer major version. |
from_user_name |
Any String |
String |
User name. Since the Omniverse channel message only includes the user ID this field helps to provide a user-friendly login name. |
app |
Any String |
String |
The application name of the connected client (USD Composer, C++ Connect Sample, Maya, etc.). |
message_type |
|
String |
The message type. It supports these messages types:
|
content |
Any dict |
Dict |
A dictionary that includes all customized protocols based on the application |
Here are examples in JSON format based on the message specification:
{"version": "3.0", "from_user_name": "omniverse", "message_type": "JOIN", "content": {}} {"version": "3.0", "from_user_name": "omniverse", "message_type": "LEFT", "content": {}} {"version": "3.0", "from_user_name": "omniverse", "message_type": "HELLO", "content": {}}
Customized Messages for Managing the Session Merge Process
At the end of a live session the session owner may merge live changes into the root or new layers. To notify other users of this event customized messages are broadcast with
message_type = MESSAGE
. The contents of the message are contained in the payload of thecontent
field as a dictionary. For session management, thecontent
key is__SESSION_MANAGEMENT__
with the value being another dictionary to describe the details. This table describes the session management messages:
Key |
Value |
Type |
Comments |
---|---|---|---|
version |
1.0 |
String |
Message version. 1.0 is the version defined the current live session protocol. |
message |
|
String |
|
An example of a
MERGE_STARTED
message sent in JSON:{ "version": "3.0", "from_user_name": "omniverse", "message_type": "MESSAGE", "content": { "__SESSION_MANAGEMENT__": { "version": "1.0", "message": "MERGE_STARTED" } } }
Disabling and Deleting Prims
USD prims that are defined in the root layer cannot be deleted with an “over”, it’s not possible. If the client intends to delete a prim from the root layer it must use UsdPrim::SetActive(false) to deactivate the prim. This will effectively remove the prim from the viewport by setting its “active” metadata to false. This doesn’t remove the prim or any of its children from the stage file, but default stage traversals will no longer see it. This USD glossary entry for Active/Inactive discusses “non destructive and reversible prim deletion”.
Merging live session changes
When a session is complete and the owner wants to keep the changes from the session, they can choose to merge them into the root stage.
default
, orroot_authoring
mode: in this case, the .live and root layers are flattened in a temporary stage, then copied into the stage’s root layer.auto_authoring
mode: each live layer is merged into its respective root sublayer (currently this is experimental and only USD Composer can support such a session)See the Live Workflow FAQ for more information about these modes.
The specific “merge and end session” process works like this:
Verify that the current connected user is actually the “owner” of the session
Send a
MERGE_STARTED
channel messageAt this point other clients will disconnect from the live session to prevent any unwanted changes
Create a non-forced checkpoint on the live layer
Create a non-forced checkpoint on the root layer
Merge the live changes to the root layer
Create a checkpoint on the root layer while saving it
Clear the live layer changes
Remove the .live layer from the session layer (so that the open stage is still valid for editing in the client)
Send a
MERGE_FINISHED
channel message
.live Layers Without Sessions
Some clients may choose to forgo the Live Session workflow and simply use .live sublayers in their layer composition. A .live layer acts just like USD to the client, so when the client sets the edit target to Original_Stage_Edits.live
all changes will be replicated through Nucleus. This is assuming that omniClientLiveProcess()
is being called on all clients (USD Composer automatically does this). This doesn’t require a “live session” to be active. Note, the HelloWorld sample still allows you to open a .live file and edit it, demonstrating this point.
Example:
Original_Stage.usd
--------------
|_ Original_Stage_Edits.live (layer)
|_ (overs replicated by Omniverse)
|_ Original_Stage_Base.usd (layer)
|_ /World
|_ (Prims with overs in Original_Stage_Edits.live)