Documentation: Scripting

Scripting and Customization

MARUI offers a set of Maya commands that you can use to build you own VR utilities or customize the MARUI user interface to meet your needs.

Reading VR Device Data

You can read the current position and rotation of VR devices (the headset or a controller) with the following commands:

MARUI_UI -dt <device>; // Get device location in Maya coordinates as a float[3] vector
MARUI_UI -dr <device> <rotationOrder>; // Get device rotation angles as a float[3] vector
MARUI_UI -dq <device>; // Get device rotation in quaternions as a float[4] vector
MARUI_UI -dm <device>; // Get device transformation matrix as a float[16] vector

<device> can be either “hmd” (the headset), “leftEye”, “rightEye”, “dominantEye”, “rightController”, “leftController”, or “aux” (the third controller or HTC Vive tracker if available),
and <rotationOrder> can be either “xyz”, “xzy”, “yxz”, “yzx”, “zxy”, or “zyx”.

Here is an example of how to use the commands in MEL: Creating a polygon cube at the position and rotation of the right controller.

// Create a polygon cube of size 1:
string $cube[] = `polyCube -w 1 -h 1 -d 1`;
// Get the right controller position
float $t[] = `MARUI_UI -dt "rightController"`;
// Move the cube to the controller position:
move -a $t[0] $t[1] $t[2] $cube[0];
// Get controller rotation:
float $r[] = `MARUI_UI -dr "rightController" "xyz"`;
// Rotate the cube to match the controller:
rotate -a $r[0] $r[1] $r[2] $cube[0];

Widgets

User Interface elements in MARUI are called “Widget”.
There are several types of widgets available.
The are all created and edited with the MARUI_Widget command.

MEL:
MARUI_Widget -create <widgetType> <additionalParameters> "myWidgetName";
Python:
MARUI_Widget("myWidgetName", create=<widgetType>, <additionalParameters>)

The following Widgets are available:

Timer Widget

The timer widget is similar to an alarm clock or a recurring callback.
It will call a predefined MEL or Python command after a set interval.
You can use it to get regular updates for your script or to wait a certain amount of time.

The following parameters are available

command <string>

The command to be called when the time is up. You can define your own MEL or Python function or insert any Maya command here. Please note that MARUI cannot continue operation until the operation finishes, so slow commands may make the VR experience unusable.

python <boolean>

Whether the command is a Python (true) or MEL (false) command. If you do not set this parameter, MARUI will expect a MEL command.

time <integer>

The time until the Timer should trigger the command in milliseconds. If this parameter is omitted, a default value of 1000ms (one second) is assumed. If you set the time to 0, the command will be executed on every frame (up to 60 times per second).

number <integer>

The number of times the Timer should repeat itself. The default is 1. After the number of repetitions is completed, the Timer Widget will be destroyed, and you will no longer be able to change the value. You can however create a new Timer with the same name. If you set the number to 0 the Timer will continue indefinitely until you edit it or exit MARUI.

Usage example:

Python:

import maya.cmds as cmds
# Set up a timer named "myTimer", called 10 times, once every 200ms+-
cmds.MARUI_Widget("myTimer", create="timer", command="print(\"timer\")", python=True, number=10, time=200)
# Change the timer to continue indefinitely at a frequency of 1/second
cmds.MARUI_Widget("myTimer", number=0)
cmds.MARUI_Widget("myTimer", time=1000)
# Unsetting (deleting) the timer:
cmds.MARUI_Widget("myTimer", command="")

MEL:

// Set up a timer named "myTimer", called 10 times, once every 200ms
MARUI_Widget -create "timer" -command "print(\"timer\");" -python false -number 10 -time 200 "myTimer";
// Change the timer to continue indefinitely at a frequency of 1/second
MARUI_Widget -number 0 "myTimer";
MARUI_Widget -time 1000 "myTimer";
// Unsetting (deleting) the timer:
MARUI_Widget -command "" "myTimer";

Command Widget

The command widget is used to bind MEL or Python command to buttons on the HTC Vive or Oculus Touch controllers. The command will be called when you click or drag the button, depending on how you use the command.
Use the MARUI_UI -map command to bind the Command Widget to a button.

The following parameters are available:

icon <string>

An icon image file on the disc to symbolize the command. This icon will show up on the botton of the controller that you bind it to. Supported image types are jpg, png, bmp, and tga. If you do not specify an icon, the name of the command will be shown instead.

command <string>

Which MEL or Python command to execute upon the <event>. This can be your own self defined function or a Maya function.

event <string>

The event upon which to call the command. Available events are “click”, “dragStart”, “dragContd”, and “dragStop”.

python <boolean>

Whether the command to call is in Python (true) or MEL (false). If this parameter is omitted, MEL is assumed.

Example:

MEL:

// Create a new Command Widget called myCommand
MARUI_Widget -create "command" -icon "C:/Temp/icon_command.bmp" "myCommand";
// Set different commands for all available events
MARUI_Widget -event "click"     -command "print(\"click\");"      -python true "myCommand";
MARUI_Widget -event "dragStart" -command "print(\"drag start\");" -python true "myCommand";
MARUI_Widget -event "dragContd" -command "print(\"drag contd\");" -python true "myCommand";
MARUI_Widget -event "dragStop"  -command "print(\"drag stop\");"  -python true "myCommand";
// Map the Command Widget to the "A" or "X" button on the left (Oculus Touch) controller.
MARUI_UI -map "oculus" "left" "AX" "myCommand";
// Query what command was set on the click-event
MARUI_Widget -q -event "click" -command "myCommand";
// Query whether the command is treated as a Python command
MARUI_Widget -q -event "click" -python "myCommand";

Python:

import maya.cmds as cmds
# Create a new Command Widget called "myCommand"
cmds.MARUI_Widget("myCommand", create="command" , icon="C:/Temp/icon_command.bmp")
# Set commands for all available commands
cmds.MARUI_Widget("myCommand", event="click"    , command="print(\"click\")"     , python=True) 
cmds.MARUI_Widget("myCommand", event="dragStart", command="print(\"drag start\")", python=True) 
cmds.MARUI_Widget("myCommand", event="dragContd", command="print(\"drag contd\");", python=False) 
cmds.MARUI_Widget("myCommand", event="dragStop" , command="print(\"drag stop\")" , python=True) 
# Connect this Command Widget to the left controllers "A" (or "X") button of the Oculus touch controller.
cmds.MARUI_UI(map=["oculus", "left", "AX", "myCommand"])

Marking Menu Widget

Marking Menus are the circular Menus that MARUI uses to offer access to Maya tools and functions.
With the Marking Menu Widget, you can build your own Marking Menus and map them to any button on your controllers.
Use the MARUI_UI -map command to bind the Command Widget to a button.

MEL:

MARUI_Widget -create "markingmenu" <additionalParameters> <menuName>;
MARUI_Widget -addElement <additionalParameters> <menuName>;
MARUI_UI -map <ui> <side> <button> <menuName>;

Python:

MARUI_Widget(<menuName>, create="markingmenu", icon="<pathToIconFile")
MARUI_Widget(<menuName>, addElement=True, <additionalParameters>)
MARUI_UI(map=[<ui>, <side>, <button>, <menuName>])

The following parameters are available:

icon <string>

An icon image file on the disc to symbolize the command. This icon will show up on the botton of the controller that you bind it to. Supported image types are jpg, png, bmp, and tga. If you do not specify an icon, the name of the command (or title of the element) will be shown instead.

title <string>

Name or description of the element. This will be shown when hovering over the element.

command <string>

Which MEL or Python command to execute upon the <event>. This can be your own self defined function or a Maya function.

python <boolean>

Whether the command to call is in Python (true) or MEL (false). If this parameter is omitted, MEL is assumed.

Example:

MEL:

// Create a Marking Menu Widget called "myMenu"
MARUI_Widget -create "markingmenu" -icon "C:/Temp/icon_menu.bmp" "myMenu";
// Add a couple of elements to it
MARUI_Widget -addElement -title "command one" -icon "C:/Temp/icon1.jpg" -command "print(\"one\");" -python true "myMenu";
MARUI_Widget -addElement -title "command two" -icon "C:/Temp/icon2.png" -command "print(\"two\");" -python true "myMenu";
MARUI_Widget -addElement -title "command three" -icon "C:/Temp/icon3.tga" -command "print(\"three\");" -python true "myMenu";
// Bind the menu to the left controllers "push the thumb-stick left" button of the Oculus Touch controller.
MARUI_UI -map "oculus" "left" "StickLeft" "myMenu";

Python:

import maya.cmds as cmds
# Create a custom marking menu called "myMenu":
cmds.MARUI_Widget("myMenu", create="markingmenu", icon="C:/Temp/icon_menu.bmp")
# Add some menu entries
cmds.MARUI_Widget("myMenu", addElement=True, title="command one",   icon="C:/Temp/icon1.jpg", command="print(\"one\");",   python=True)
cmds.MARUI_Widget("myMenu", addElement=True, title="command two",   icon="C:/Temp/icon2.png", command="print(\"two\");",   python=True)
cmds.MARUI_Widget("myMenu", addElement=True, title="command three", icon="C:/Temp/icon3.tga", command="print(\"three\");", python=True)
# Bind the menu to the left controllers "push the thumb-stick left" button of the oculus touch controller.
cmds.MARUI_UI(map=["oculus", "left", "StickLeft", "myMenu"])

Mapping Widgets to Buttons

The setmapping or map parameter on the MARUI_UI command can be used to bind widgets to buttons on the controllers.

MEL:

MARUI_UI -setmapping <device> <side> <button> <widget>;

Python:

MARUI_UI(map=[<device>, <side>, <button>, <widget>])

Will bind the <function> to the <button> on the <side> controller, which is of the type <device> (either HTC Vive, Oculus Rift, or LeapMotion).

For example: in order to bind the left controller trigger button to the MARUI Omni-Tool, you can use the following command:
MARUI_UI -setmapping “vive” “left” “Trigger” “Omni”;

The <device can be “oculus”, “vive”, or “leapmotion”.
The <side> can be either “left” or “right”.

The following buttons are available, based on the VR device that you are using

HTC Vive

The following buttons are available for the HTC Vive controllers:

  • SystemButton : The system button (above the touch pad).
  • MenuButton : The menu button (below the touch pad).
  • Grip : The grip or shoulder button (squeezing the handle).
  • DPadLeft : Left side area of the touch pad.
  • DPadUp : Upper area of the touch pad.
  • DPadRight : Right side area of the touch pad.
  • DPadDown” : Lower area of the touch pad.
  • Trigger : The trigger button.

Oculus Rift

The following buttons are available for the Oculus Touch controllers:

  • StickRight : Pushing the thumb stick to the right.
  • StickLeft : Pushing the thumb stick to the left.
  • StickUp : Pushing the thumb stick upwards.
  • StickDown : Pulling the thumb stick downwards.
  • AX : The A (on the right controller) or X (on the left controller) button.
  • BY : The B (on the right controller) or Y (on the left controller) button.
  • Thumb : Pressing the thumb-stick.
  • Shoulder : The grip or shoulder button (squeezing the handle).
  • Grip : The grip or shoulder button (squeezing the handle).
  • Trigger : The trigger button.

LeapMotion

The following buttons are available for the LeapMotion device:

  • Pinch : Pinching with the thumb and index finger.
  • Grab : Making the hand into a fist.

Build-in MARUI Widgets

Apart from your own Widgets, you can use the MARUI_UI -map Command to bind the build-in MARUI functions to any button.
The following Widgets are available:

  • Trigger : The default trigger action for whatever tool is selected.
  • Select : Selection (either by ray-casting or proximity, depending on the current setting).
  • Select_Cursor : Selection (by ray casting or “pointing at”).
  • Select_Proximity : Selecting by proximity to the controller or volumetric selection.
  • Move : The 3D move tool (translation).
  • Rotate : The 3D rotation tool.
  • Scale : The 3D scale tool.
  • EditPivot : The tool to change the location of the rotation/scale pivot of an object.
  • Omni : The 6DOF “Omni” tool.
  • EPCurve : The EP Curve Tool from the Modeling Menu
  • PencilCurve : The Pencil Curve Tool from the Modeling Menu
  • QuadDraw : The Quad Draw Tool from the Modeling Menu
  • PolyCut : The Polygon Cut (or Split) Tool from the Modeling Menu
  • InsertEdgeLoop : The Insert Edge Loop Tool from the Modeling Menu
  • Extrude : The Extrude Tool from the Modeling Menu
  • POVCamera : The ((POVCameraTool|POV Camera Tool) from the Lighting / Rendering Menu
  • RecorderInit : A tool to initialize the position of the camera for MR capturing
  • Snapping_ToUnits : Activate snapping to Maya units, as in the Modeling Menu
  • Snapping_ToPoints : Activate snapping to points, as in the Modeling Menu
  • Snapping_ToCurves : Activate snapping to curves, as in the Modeling Menu
  • Menu_Tool : The tool menu to choose the current tool.
  • Menu_Mode : The mode menu to chose the component mode (Vertex, Edge, Object, …).
  • Menu_Action : The action menu (for “delete”, “undo”, “redo” etc).
  • Menu_Anim : The animation menu (for setting keyframes etc).
  • Menu_UILayouts : The UI layouts menu that allows switching between “modeling”, “animation”, “lighting/rendering” and custom UI layouts.
  • Menu_MARUI : The MARUI menu (for “look-through-selected”, “shading” etc).
  • Menu_LightingRendering : The Lighting / Rendering menu.
  • Menu_PolyTools : The Modeling Menu.
  • Shelf : The Maya Shelf.
  • HotBox : The Maya HotBox (aka spacebar menu).
  • Navi : Navigation, whichever was selected in the settings.
  • Navi_GrabAir : Grabbing-the-air navigation.
  • Navi_Tumble : Maya-mouse-style tumbling navigation.
  • Navi_Joystick : Joystick-style navigation.
  • TimeSlider : The MARUI Time Slider.
  • ViewCube : The MARUI ViewCube widget.
  • Shift : The Shift button.
  • Alt : The “Alt” button that switches the UI layout to it’s alternative button mapping (see User Interface Customization )