Camera Manipulator

Mouse interaction with the Viewport is handled with classes from omni.kit.manipulator.camera, which is built on top of the omni.ui.scene framework. We’ve created an omni.ui.scene.SceneView to host the manipulator, and by simply assigning the camera manipulators model into the SceneView’s model, all of the edits to the Camera’s transform will be pushed through to the SceneView.

# And finally add the camera-manipulator into that view
with self.__scene_view.scene:
    self.__camera_manip = ViewportCameraManipulator(self.viewport_api)

    # Push the camera manipulator's model into the SceneView so it'lll auto-update
    self.__scene_view.model = self.__camera_manip.model

The omni.ui.scene.SceneView only understands two values: ‘view’ and ‘projection’. Our CameraManipulator’s model will push out those values as edits are made; however, it supports a larger set of values to control the manipulator itself.

Operations and Values

The CameraManipulator model store’s the amount of movement according to three modes, applied in this order:

  1. Tumble

  2. Look

  3. Move (Pan)

  4. Fly (FlightMode / WASD navigation)

tumble

Tumble values are specified in degrees as the amount to rotate around the current up-axis. These values should be pre-scaled with any speed before setting into the model. This allows for different manipulators/gestures to interpret speed differently, rather than lock to a constant speed.

# Tumble by 180 degrees around Y (as a movement across ui X would cause)
model.set_floats('tumble', [0, 180, 0])

look

Look values are specified in degrees as the amount to rotate around the current up-axis. These values should be pre-scaled with any speed before setting into the model. This allows for different manipulators/gestures to interpret speed differently, rather than lock to a constant speed.

# Look by 90 degrees around X (as a movement across ui Y would cause)
# i.e Look straight up
model.set_floats('look', [90, 0, 0])

move

Move values are specified in world units and the amount to move the camera by. Move is applied after rotation, so the X, Y, Z are essentially left, right, back. These values should be pre-scaled with any speed before setting into the model. This allows for different manipulators/gestures to interpret speed differently, rather than lock to a constant speed.

# Move left by 30 units, up by 60 and back by 90
model.set_floats('move', [30, 60, 90])

fly

Fly values are the direction of flight in X, Y, Z. Fly is applied after rotation, so the X, Y, Z are essentially left, right, back. These values will be scaled with fly_speed before aplication. Because fly is a direction with fly_speed automatically applied, if a gesture/manipulator wants to fly slower without changing fly_speed globally, it must apply whatever factor is required before setting.

# Move left
model.set_floats('fly', [1, 0, 0])
# Move up
model.set_floats('fly', [0, 1, 0])

Speed

By default the Camera manipulator will map a full mouse move across the viewport as follows:

  • Pan: A full translation of the center-of-interest across the Viewport.

  • Tumble: A 180 degree rotation across X or Y.

  • Look: A 180 degree rotation across X and a 90 degree rotation across Y.

These speed can be adjusted by setting float values into the model.

world_speed

The Pan and Zoom speed can be adjusted with three floats set into the model as ‘world_speed’.

# Half the movement speed for both Pan and Zoom
pan_speed_x = 0.5, pan_speed_y = 0.5, zoom_speed_z = 0.5
model.set_floats('world_speed', [pan_speed_x, pan_speed_y, zoom_speed_z])

rotation_speed

The Tumble and Look speed can be adjusted with either a scalar value for all rotation axes or per component.

# Half the rotation speed for both Tumble and Look
rot_speed_both = 0.5
model.set_floats('rotation_speed', [rot_speed_both])
# Half the rotation speed for both Tumble and Look in X and quarter if for Y
rot_speed_x = 0.5, rot_speed_y = 0.25
model.set_floats('rotation_speed', [rot_speed_x, rot_speed_y])

tumble_speed

Tumble can be adjusted separately with either a scalar value for all rotation axes or per component. The final speed of Tumble operation is rotation_speed * tumble_speed

# Half the rotation speed for Tumble
rot_speed_both = 0.5
model.set_floats('tumble_speed', [rot_speed_both])
# Half the rotation speed for Tumble in X and quarter if for Y
rot_speed_x = 0.5, rot_speed_y = 0.25
model.set_floats('tumble_speed', [rot_speed_x, rot_speed_y])

look_speed

Look can be adjusted separately with either a scalar value for all rotation axes or per component. The final speed of a Look operation is rotation_speed * tumble_speed

# Half the rotation speed for Look
rot_speed_both = 0.5
model.set_floats('look_speed', [rot_speed_both])
# Half the rotation speed for Tumble in X and quarter if for Y
rot_speed_x = 0.5, rot_speed_y = 0.25
model.set_floats('look_speed', [rot_speed_x, rot_speed_y])

fly_speed

The speed at which FlightMode (WASD navigation) will fly through the scene. FlightMode speed can be adjusted separately with either a scalar value for all axes or per component.

# Half the speed in all directions
fly_speed = 0.5
model.set_floats('fly_speed', [fly_speed])
# Half the speed when moving in X or Y, but double it moving in Z
fly_speed_x_y = 0.5, fly_speed_z = 2
model.set_floats('fly_speed', [fly_speed_x_y, fly_speed_x_y, fly_speed_z])

Undo

Because we’re operating on a unique omni.usd.UsdContext we don’t want movement in the preview-window to affect the undo-stack. To accomplish that, we’ll set the ‘disable_undo’ value to an array of 1 int; essentially saying disable_undo=True.

# Let's disable any undo for these movements as we're a preview-window
model.set_ints('disable_undo', [1])

Disabling operations

By default the manipulator will allow Pan, Zoom, Tumble, and Look operations on a perspective camera, but only allow Pan and Zoom on an orthographic one. If we want to explicitly disable any operations again we set int values as booleans into the model.

disable_tumble

# Disable the Tumble manipulation
model.set_ints('disable_tumble', [1])

disable_look

# Disable the Look manipulation
model.set_ints('disable_look', [1])

disable_pan

# Disable the Pan manipulation.
model.set_ints('disable_pan', [1])

disable_zoom

# Disable the Zoom manipulation.
model.set_ints('disable_zoom', [1])