Share

Motion Capture Devices

This section provides information on how to use motion capture devices (mocap) and other input/output devices with the MotionBuilder SDK.

A device is a piece of hardware that communicates with MotionBuilder, typically motion capture (mocap) hardware transmitting positional data from opical sensors which are then used by MotionBuilder to animate a character. Hardware providing the data could also be a joystick, a mouse, or any other input device.

Devices are controlled by plugins written with this SDK.

Device plugins derive from FBDevice or a derived class of it (e.g. FBDeviceOptical, FBDeviceCamera).

Note: FBDevice() cannot be instantiated from Python.

An FBDevice is an abstraction layer representing flows of input or output. For example, when the input/output thread communicates with the device, it fills the data structure at a constant rate. The evaluation thread pulls the information from this data structure when it needs to, isolating communication with the hardware to one high-priority thread.

FBDevice inherits from FBBox, including the evaluation of input and output animation nodes.

Main types of devices:

  • Input devices: these receive data from hardware and use it to animate models in the scene.
  • Output devices.

Relationship of mocap data to characters:

  • Mocap sensor data can be associated directly in the mocap hardware with a character's skeleton nodes. This mechanism is demonstrated by the NO LABEL sample.
  • Mocap data can be mapped onto markers (FBModelMarker), which are contained on the actor FBActor using model templates FBModelTemplate. This can be gotten and set via the FBActor::OutputMarkerSet property. The actor drives the animation of the character FBCharacter, and is gotten or set via the FBCharacter:: InputActor property.

MotionBuilder runs two different threads

  • Real-time engine thread: tells your plugin to query the hardware for data. It calls FBDevice::DeviceTransportNotify(), FBDevice::DeviceIONotify(), and FBDevice::DeviceEvaluationNotify(). Note that any functions called by the real-time engine, must be optimized and cannot block (i.e. wait on a resource or another thread).
  • Animation thread: tells your plugin to deliver animation data. This calls FBDevice::AnimationNodeNotify().

Plugins can be built by overriding the following functions:

  • FBDevice::AnimationNodeNotify(): get data from the hardware abstraction. Write data to animation nodes. It is called asynchronously, when needed.
  • FBDevice::DeviceIONotify(): read and record each data packet. DeviceIONotify is called at the SamplingPeriod. The input data is read from the hardware into the abstraction layer. Be careful that calls to functions like AnimationNodeNotify, DeviceEvaluationNotify, and DeviceIONotify consume as little CPU time as possible and return as soon as possible because they have a high priority of execution. Blocking is generally an option in most protocols.
  • FBDevice::DeviceOperation(): operates the device.
  • FBDevice::FBCreate() and FBDevice::FBDestroy(): perform initialization such as creation of model templates and clean-up such as removing binding.
  • FBDevice::FbxStore() and FBDevice::FbxRetrieve() are used to access device configuration in the FBX file.
  • FBDevice::RecordingDoneAnimation(): called by motion builder when recording of an animation is completed.

OnStatusChange is an event associated with a change of status (live/online/record) of the device.

It is also possible to use the real-time synchronous calls to schedule functionality in the application (as the devicereclist sample).

Store data in the object, not in the layout, due to the volatile nature of a layout. A layout in MotionBuilder may be destroyed and re-created many times during the execution of the program, creating a problem for the persistence of the data required by the tool/manipulator/constraint. Store data in the object itself (FBDevice, FBManipulator, and so on) instead of in the layout (FBDeviceLayout, and so on).

Display current state: use the UI tools to display the current operation/status. There are various user interface tools available in the Open Reality SDK that can help you debug a plug-in, and they also provide useful information. Among these are the FBProgress classes and the text strings for the status of a device. These items can be useful when interacting with you, and inform both you and the user of the current status of the device and what is happening on the internal side of the software.

Acknowledge samples for statistics. Use the AckOneSample[Sent/Received]() functions so they display beside the sampling rate in the user interface. Use AckOneSampleReceived, AckOneSampleSent, and so on, to mark the receipt/transmission of a data packet. MotionBuilder is able to deal with the data that they generate. This can also be a good source of information to help with debugging a plug-in.

In the case of the output functionality for a device, DeviceEvaluationNotify reads data from the output nodes and copies it into the hardware abstraction to be transferred to the device in the IO thread. The difference between this thread and the AnimationNodeNotify thread is that it provokes an evaluation if necessary and is called at a fixed rate (the same rate as DeviceIONotify). To change the rate of DeviceIONotify: In the FBDevice class, there is a variable called SamplingPeriod. This variable determines the rate at which DeviceIONotify and DeviceEvaluationNotify are called.

DeviceIONotify is called twice each evaluation loop, once for reading the device’s information, and once for writing data back to the device.

DeviceEvaluationNotify is called at a given sampling rate (see Q1), between the two DeviceIONotify calls (see Q3).

Was this information helpful?