Changing frameRate attribute of MPxThreadedDeviceNode

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I've created a plugin where serial data is read, parsed and a cube's rotation is updated based on that data. The serial data comes in at 120hz and includes comma spliced rotation values. Those values are changed via a joystick on the serial device.
To do this I use MPxThreadedDeviceNodeto attach a cubes rotation attributes to an attribute on my threaded node. This threaded node also starts a separate thread which opens a Serial port, parse the data, and stores it in a static class. In the threadHandler of the threaded node, it gets the rotation values from the static class and updates the attributes.
What I'm noticing is there is about a second delay from when I push the joystick, to when its actually updated in Maya. I believe this has to do with the way the threaded node is updating the cube, as watching the raw serial data, it doesn't look like theirs that big of a delay.
I see that there's an attribute on MPxThreadedDeviceNode thats "static MObject frameRate". This attribute has the description:
- The live and frameRate attributes are included in this class. Changes to these attributes will cause the thread to be shutdown and restarted so that the new settings can be in effect.
I'm thinking I need to increase the frameRate, so that the changes happen more instantaneously. I'm just not sure how to set that attribute. It says its a double, but the type is actually MObject. How can I set the frameRate to something like 120. Maybe I'm going at this wrong and its a setting I change directly in maya?
Here is my MPxThreadedNode class. I've omitted standard functions like the constructor and deconstructor. I've also not shown my Serial class (RiverSerialCommunication) as it basically is just a class with some static variables.
void RiverControllerNode::postConstructor() { MObjectArray attrArray; attrArray.append(RiverControllerNode::outputRotate); setRefreshOutputAttributes(attrArray); // Create 3 axis rotational data createMemoryPools(24, 3, sizeof(double)); MThreadAsync::createTask(RiverSerialCommunication::Start, this, NULL, NULL); } void RiverControllerNode::threadHandler() { MStatus status; setDone(false); // Loop until thread is killed while (!isDone()) { // Live allows for thread pausing if (!isLive()) continue; // Get buffer to write to MCharBuffer buffer; status = acquireDataStorage(buffer); if (!status) continue; // Data Operations beginThreadLoop(); { // Convert buffer to x,y,z rotation data double* doubleData = reinterpret_cast<double*>(buffer.ptr()); // Get serial data doubleData[0] = RiverSerialCommunication::GetPan(); doubleData[1] = RiverSerialCommunication::GetTilt(); // Push the data for the main thread to compute pushThreadData(buffer); } // Perform the throttling based on the frame rate attribute and additionally cause the output attribute to be marked dirty causing compute() to run endThreadLoop(); } } void RiverControllerNode::threadShutdownHandler() { // Break the loop in threadHandler setDone(true); } /* * @brief Runs on the main thread after the thread loop has run and marked the data dirty */ MStatus RiverControllerNode::compute(const MPlug& plug, MDataBlock& data) { MStatus status; // Access the data and update the output attribute MCharBuffer buffer; if (popThreadData(buffer)) { // Relative data coming in double* doubleData = reinterpret_cast<double*>(buffer.ptr()); MDataHandle outputTranslateHandle = data.outputValue(outputRotate, &status); double3& outputRotate = outputTranslateHandle.asDouble3(); outputRotate[0] = doubleData[0]; outputRotate[1] = doubleData[1]; outputRotate[2] = 0; data.setClean(plug); releaseDataStorage(buffer); return (MS::kSuccess); } else { return MS::kFailure; } } MStatus RiverControllerNode::initialize() { MStatus status; MFnNumericAttribute numAttr; outputRotateX = numAttr.create("outputRotateX", "orx", MFnNumericData::kDouble, 0.0, &status); outputRotateY = numAttr.create("outputRotateY", "ory", MFnNumericData::kDouble, 0.0, &status); outputRotateZ = numAttr.create("outputRotateZ", "orz", MFnNumericData::kDouble, 0.0, &status); outputRotate = numAttr.create("outputRotate", "or", outputRotateX, outputRotateY, outputRotateZ, &status); numAttr.setKeyable(true); numAttr.setStorable(true); numAttr.setHidden(false); numAttr.setDefault(true); addAttribute(outputRotate); attributeAffects(live, outputRotate); attributeAffects(frameRate, outputRotate); return MS::kSuccess; }
TL;DR: How can I change the frameRate attribute of MPxThreadedDeviceNode.