Using the Nimble GUI

Nimble has a powerful and simple web GUI built in. At its heart, it is a simple hash table that maps keys to 3D objects. Whenever you change the hash table, any connected web browsers will update in real time.

The boilerplate to use the GUI is the following:

import nimblephysics as nimble

# Create a GUI
gui = nimble.NimbleGUI()

# Serve the GUI on port 8080
gui.serve(8080)

############################
# Do something useful here!
############################

# Do not immediately exit
gui.blockWhileServing()

To access the hash table directly, you can use the gui.nativeAPI() command. Methods like gui.nativeAPI().createBox(...) will create a box in the hash table at the key argument. If the key already exists, it will be overwritten. Higher level methods like gui.nativeAPI().renderSkeleton(...) will create a bunch of objects in the hash table, for each mesh in the skeleton. If the keys already exist (if you have rendered the skeleton before), they will be overwritten.

You can delete objects by key, with gui.nativeAPI().deleteObject(key), or delete groups of objects with gui.nativeAPI().deleteObjectsByPrefix(prefix), or delete everything with gui.nativeAPI().clear(). You can also update individual attributes of objects by key (without entirely recreating them), with for example gui.nativeAPI().setObjectPosition(key, position).

class nimblephysics.server.GUIStateMachine
clear(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine) None
clearBodyWrench(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, body: nimblephysics_libs._nimblephysics.dynamics.BodyNode, prefix: str = 'wrench') None
createBox(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, size: numpy.ndarray[numpy.float64[3, 1]] = array([1., 1., 1.]), pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createButton(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, label: str, fromTopLeft: numpy.ndarray[numpy.int32[2, 1]], size: numpy.ndarray[numpy.int32[2, 1]], onClick: Callable[[], None], layer: str = '') None
createCapsule(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, radius: float, height: float, pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createCone(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, radius: float, height: float, pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createCylinder(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, radius: float, height: float, pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createLayer(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), defaultShow: bool = True) None
createLine(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, points: List[numpy.ndarray[numpy.float64[3, 1]]], color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', width: List[float] = []) None
createMeshFromShape(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, mesh: nimblephysics_libs._nimblephysics.dynamics.MeshShape, pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), scale: numpy.ndarray[numpy.float64[3, 1]] = array([1., 1., 1.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createPlot(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, fromTopLeft: numpy.ndarray[numpy.int32[2, 1]], size: numpy.ndarray[numpy.int32[2, 1]], xs: List[float], minX: float, maxX: float, ys: List[float], minY: float, maxY: float, plotType: str, layer: str = '') None
createRichPlot(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, fromTopLeft: numpy.ndarray[numpy.int32[2, 1]], size: numpy.ndarray[numpy.int32[2, 1]], minX: float, maxX: float, minY: float, maxY: float, title: str, xAxisLabel: str, yAxisLabel: str, layer: str = '') None
createSlider(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, fromTopLeft: numpy.ndarray[numpy.int32[2, 1]], size: numpy.ndarray[numpy.int32[2, 1]], min: float, max: float, value: float, onlyInts: bool, horizontal: bool, onChange: Callable[[float], None], layer: str = '') None
createSphere(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, radii: numpy.ndarray[numpy.float64[3, 1]] = array([0.5, 0.5, 0.5]), pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), color: numpy.ndarray[numpy.float64[4, 1]] = array([0.5, 0.5, 0.5, 1.]), layer: str = '', castShadows: bool = True, receiveShadows: bool = False) None
createText(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, contents: str, fromTopLeft: numpy.ndarray[numpy.int32[2, 1]], size: numpy.ndarray[numpy.int32[2, 1]], layer: str = '') None
deleteObject(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str) None
deleteObjectWarning(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, warningKey: str) None
deleteObjectsByPrefix(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, prefix: str) None
deleteUIElement(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str) None
getObjectColor(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str) numpy.ndarray[numpy.float64[4, 1]]
getObjectPosition(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str) numpy.ndarray[numpy.float64[3, 1]]
getObjectRotation(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str) numpy.ndarray[numpy.float64[3, 1]]
renderArrow(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, start: numpy.ndarray[numpy.float64[3, 1]], end: numpy.ndarray[numpy.float64[3, 1]], bodyRadius: float, tipRadius: float, color: numpy.ndarray[numpy.float64[4, 1]] = array([1., 0., 0., 0.5]), prefix: str = 'arrow', layer: str = '') None
renderBasis(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, scale: float = 10.0, prefix: str = 'basis', pos: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), euler: numpy.ndarray[numpy.float64[3, 1]] = array([0., 0., 0.]), layer: str = '') None
renderBodyWrench(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, body: nimblephysics_libs._nimblephysics.dynamics.BodyNode, wrench: numpy.ndarray[numpy.float64[6, 1]], scaleFactor: float = 0.1, prefix: str = 'wrench', layer: str = '') None
renderMovingBodyNodeVertices(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, body: nimblephysics_libs._nimblephysics.dynamics.BodyNode, scaleFactor: float = 0.1, prefix: str = 'vert-vel', layer: str = '') None
renderSkeleton(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, skeleton: nimblephysics_libs._nimblephysics.dynamics.Skeleton, prefix: str = 'world', overrideColor: numpy.ndarray[numpy.float64[4, 1]] = array([-1., -1., -1., -1.]), layer: str = '') None
renderTrajectoryLines(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, world: nimblephysics_libs._nimblephysics.simulation.World, positions: numpy.ndarray[numpy.float64[m, n]], prefix: str = 'trajectory', layer: str = '') None
renderWorld(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, world: nimblephysics_libs._nimblephysics.simulation.World, prefix: str = 'world', renderForces: bool = True, renderForceMagnitudes: bool = True, layer: str = '') None
setButtonLabel(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, label: str) None
setFramesPerSecond(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, framesPerSecond: int) None
setObjectColor(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, color: numpy.ndarray[numpy.float64[4, 1]]) None
setObjectPosition(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, position: numpy.ndarray[numpy.float64[3, 1]]) None
setObjectRotation(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, euler: numpy.ndarray[numpy.float64[3, 1]]) None
setObjectScale(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, scale: numpy.ndarray[numpy.float64[3, 1]]) None
setObjectTooltip(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, tooltip: str) None
setObjectWarning(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, warningKey: str, warning: str, layer: str) None
setPlotData(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, xs: List[float], minX: float, maxX: float, ys: List[float], minY: float, maxY: float) None
setRichPlotBounds(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, minX: float, maxX: float, minY: float, maxY: float) None
setRichPlotData(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, name: str, color: str, plotType: str, xs: List[float], ys: List[float]) None
setSliderMax(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, value: float) None
setSliderMin(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, value: float) None
setSliderValue(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, value: float) None
setSpanWarning(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, startTimestep: int, endTimestep: int, warningKey: str, warning: str, layer: str) None
setTextContents(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, contents: str) None
setUIElementPosition(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, position: numpy.ndarray[numpy.int32[2, 1]]) None
setUIElementSize(self: nimblephysics_libs._nimblephysics.server.GUIStateMachine, key: str, size: numpy.ndarray[numpy.int32[2, 1]]) None