Devices > 
Optical devices
 
 
 

Optical devices are input devices that include optical data (such as occlusion), with specific tools to deal with this type of data. Tracking data from a device is mapped onto a MotionBuilder character.

The first step is to derive the FBDeviceOptical class, and then build the marker set, based on the configuration of the device.

FBDeviceOptical manages an optical marker set represented as a list of optical markers stored in FBDeviceOptical::Markers. These markers have position (X,Y,Z) and occlusion (0) data associated with them. They represent the physical sensors of your optical device.

You should set up your marker set in the functions that get called the initialization commands:

The marker set construction calls must happen between calls to DeviceOpticalBeginSetup() and DeviceOpticalEndSetup().

Markers must have a unique name.

Each marker has a dirty flag called IsUsed. When set to true, it confirms that the marker is active. When false, MotionBuilder ignores this marker when setting up the device (on a DeviceOpticalEndSetup() call). This flag is useful in the optical device and user interface support dynamic during the addition or removal of markers to/from an existing marker set.

DeviceOpticalBeginSetup() sets all IsUsed flags to false. When DeviceOpticalEndSetup() is called, the base class deletes the connectors and unbinds the markers that have an IsUsed flag set to false.

If you execute Markers.Add(“name”) with the name of a marker already in the list, the marker will not be added twice. If the dirty flag IsUsed is set to false, Markers.Add() is reset to true. You can therefore use the Markers.Add() function to reconfirm the activeness of a marker.

To add Rigid bodies to the input from an optical device, it is possible to use the class FBModelOptical, which contains a list of rigid bodies to add to the optical model when the sets are configured.

To create a rigid body:

  1. Get a handle on the optical model for the device.
  2. Declare an object of FBModelList.
FBModelOptical* lOptical = (HFBModelOptical)        (HFBModel) ModelOptical;
FBModelList lList;
for( i = 0; i < lMarkerCount; i++ )
{
 HFBModel lModel = 
 FBFindModelByName( lName[i] );
 lModel->SetVector( lSnapPos[i], 
 kModelTranslation, true );  
 lList.Add( lModel );
}
lOptical->RigidBodies.Add( lList,                                                   “MyRigidBody” );

All data streaming and recording functionality is contained in a single function in the case of an optical device, removing the need to manage DeviceIONotify and AnimationNodeNotify.

FBDeviceOptical::DeviceOpticalEvalAll
 Markers()

Support for the FBDevice::DeviceIONotify() and FBDevice::AnimationNodeNotify() calls are implemented by the FBDeviceOptical base class using the data supplied by DeviceOpticalEvalAllMarkers(). The base class calls this function at 30 Hz for NTSC or at 25 Hz for PAL.

DeviceOpticalRecordFrame sets a given maker’s position to [x,y,z] and its occlusion to 0. Once all markers have been updated with their current position and occlusion values, a single call to DeviceOpticalRecordFrame() enters the data in MotionBuilder for a given local time.

Markers[i]->SetData( x,y,z,o );

FBModelOptical provides the interface for configuring an optical device. This model is created when a model binding is instanced from the device driver of an optical device.

You can use FBRigidBody to access rigid body functionality. Attributes of FBRigidBody list associated marker names and initial positions. The initial positions are used to calculate the relative positions that the markers in the rigid body should have in respect to each other. For an example of how to use rigid bodies with optical models, see [MotionBuilder program directory]\OpenRealitySDK\Samples\devices\deviceoptical.

The following code shows how to set a key inside a gap on an optical marker model and then position the value (once InsertControlKey keys a default value).

void ORTool_Template::EventExecute_C_ButtonClick( HISender pSender, HKEvent pEvent )
// Callback for Button "Execute C"
{ __FUNCOUT
 ExportModel( FBSystem().SceneRootModel ); 
}
void ORTool_Template::ExportModel( HFBModel pModel)
{
 FBTrace ("in the function exportModel\n");
 FBTime lTime = FBTime(0,0,0,11);
 FBTrace(pModel->Name); //grabs the Scene Component
 for(int i=0;i< pModel->Children.GetCount();i++) //getting the children of the Scene
 {
 FBTrace(pModel->Children[i]->Name); //graps the optical component
 if (pModel->Children[i]->Is(FBModelOptical::TypeInfo)) //the optical component is of type FBModelOptical
 {
 FBTrace("1.-->Model is an FBModelOptical \n");
 //cast the FBModel as an FBModelOptical, the reason I need this is later I need to SetModelOptical, so I need the parent of lHMarkerOptical which is this lHOptical. 
 HFBModelOptical lHOptical = (HFBModelOptical)pModel->Children[i]; 
 //gets the selected marker, in this case it's M_RightShin
 FBModelList lModelList;
 FBGetSelectedModels( lModelList );
 int count = lModelList.GetCount();
 for( int j = 0; j < count; j++ )
 { 
 HFBModel lModel = lModelList[j];
 char* name = lModel->Name;
 FBTrace( "Model is : %s\n", name );
 if( lModel->Is(FBModelMarkerOptical::TypeInfo) )//the M_RightShin component is of type FBModelMarkerOptical
 {
 HFBModelMarkerOptical lHMarkerOptical = (HFBModelMarkerOptical)lModel;      //cast the model to type FBModelMarkerOptical
 //Getting the Segments, because you have to get the segments to get the gaps count to renew, (BUG 256123)
 lHMarkerOptical->SetModelOptical(lHOptical); 
 FBTrace("Marker Segment Count is %d\n", lHMarkerOptical->Segments.GetCount());
 FBTrace("Marker Gap Count is %d\n", lHMarkerOptical->Gaps.GetCount()); //now the gap count doesn't return 0 but the actual value...
 FBPlayerControl().Goto(FBTime(0, 0, 0, 11));
 //Add Evaluate Scene here for MB 7.5 Ext 2
FBSystem().Scene->Evaluate();
 //inserts gap key at a default location....
 lHMarkerOptical->Gaps[1].InsertControlKey(lTime);
 FBVector3d pos(-100.0, 0.0, 0.0);
 lHMarkerOptical->Translation = pos;
 //Add Evaluate Scene here for MB 7.5 Ext 2
 FBSystem().Scene->Evaluate();
 FBPlayerControl().Key();
 }
 }
 }
 }
}