Game-like update loop with transform operations

Hello, I am trying to create an omniverse extension that behaves like a game engine. What I mean by this is to have a callback to a function for every update in the main omniverse application, I have achieved that callback with this code:

        update_stream = omni.kit.app.get_app().get_update_event_stream()
        def on_update(e: carb.events.IEvent):
            #print(f"Update: {e.payload['dt']}")
            run_coroutine(self._scene_handler.update_scene(e.payload['dt']))

        self._updater = update_stream.create_subscription_to_pop(on_update, name="Scene handler")

the scene handler has an async enhanced dictionary which contains a small data structure representing the target transform. To optimize the calls to update position code, the transform of this data structure is None if it did not received an update.

here is the code of such update

def update_stage_objects(self, objects:list[FsObject], dt):
        #None
        for obj in objects:
            if(self._stage_objects.isdisjoint({obj.obj_id})):
                continue
            raw = obj.get_transform()
            if raw is not None:
                #print(f"updating stage object {obj.obj_id} with {raw}")
                transform = [float(value) for value in raw]
                matrix = Gf.Matrix4d(
                    transform[0:4],
                    transform[4:8],
                    transform[8:12],
                    transform[12:16]
                )
                prim = self._stage.GetPrimAtPath(self._world.GetPath().AppendPath(f"fsobject_{obj.obj_id}"))
                xformable = UsdGeom.Xformable(prim)
                #xformable.ClearXformOpOrder()
                #xformable.AddXformOp(UsdGeom.XformOp.TypeTransform, UsdGeom.XformOp.PrecisionDouble).Set(matrix)
                #xformable.MakeMatrixXform().Set(matrix, Usd.TimeCode(0))

With the xform operations commented, in a laptop 3080 FPS values oscilate between 110 and 120, there are ~400 objects that have a transform ( raw is not None ).

However, by adding the xform operations, updating 20 objects the FPS drop continously to 45-50 FPS.

Is there a way to speedup setting the transform of the object?

the data is obtained asynchronously in other python class, obtaining the data and store it is not an apparent bottle neck

perhaps i’m missing a function or call back with which I can create a batch operation for more than one element

Thanks in advance for your insight

You need to use usdrt instead of USD for those real-time updates or Sdf.ChangeBlock.

https://docs.omniverse.nvidia.com/kit/docs/usdrt/latest/index.html

Hello Richard

Thank you very much for your reply, I have indeed updated the code to use a Sdf.ChangeBlock

However, it is proving slightly more complicated to use usdrt.

Is usdrt orders of magnitude better than Sdf.ChangeBlock or the performance is expected to be the same?

In the specified scenario with Sdf.ChangeBlock I am able to consume changes for up to 300 objects in the same 3080 laptop GPU.

Best regards

Yes. It will be much better. Much more efficient. That is why we wrote it.

Thank you very much for your insight! I will invest more time in implementing the usdrt then

Best regards
Francisco

OK great. Good luck.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.