8 #include "PlusConfigure.h" 13 #include <vtkImageImport.h> 14 #include <vtkMatrix4x4.h> 15 #include <vtkObjectFactory.h> 17 #include <vtkQuaternion.h> 18 #include <vtkTransform.h> 19 #include <vtkXMLDataElement.h> 20 #include <vtksys/SystemTools.hxx> 36 static void* allocate(uint32_t size, eLeapAllocatorType typeHint,
void*
state)
38 void* ptr = malloc(size);
42 static void deallocate(
void* ptr,
void*
state)
55 , Mutex(vtkIGSIORecursiveCriticalSection::New())
56 , LeapHMDPolicy(false)
57 , RefusePauseResumePolicy(false)
59 , ImageInitialized(false)
60 , LeftCameraSource(nullptr)
61 , RightCameraSource(nullptr)
72 this->
Mutex->Delete();
84 os <<
"Poll timeout (ms)" << this->
PollTimeoutMs << std::endl;
85 os <<
"Leap HMD policy" << (this->
LeapHMDPolicy ?
"TRUE" :
"FALSE") << std::endl;
87 os <<
"Invert image:" << (this->
InvertImage ?
"TRUE" :
"FALSE") << std::endl;
95 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
LeapHMDPolicy, deviceConfig);
97 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(
InvertImage, deviceConfig);
109 XML_WRITE_BOOL_ATTRIBUTE(
InvertImage, deviceConfig);
117 LOG_TRACE(
"vtkPlusLeapMotion::Connect");
124 if ((result = LeapCreateConnection(NULL, &this->
Connection)) != eLeapRS_Success)
126 LOG_ERROR(
"Unable to create the connection to the LeapMotion device:" << this->
ResultToString(result));
129 if ((result = LeapOpenConnection(this->
Connection)) != eLeapRS_Success)
131 LOG_ERROR(
"Unable to open the connection to the LeapMotion device:" << this->
ResultToString(result));
135 LEAP_ALLOCATOR allocator = { allocate, deallocate, NULL };
136 if ((result = LeapSetAllocator(this->
Connection, &allocator)) != eLeapRS_Success)
138 LOG_WARNING(
"Unable to set allocator. Some functionality may be missing.");
147 LOG_TRACE(
"vtkPlusLeapMotion::Disconnect");
158 LOG_TRACE(
"vtkPlusLeapMotion::InternalUpdate");
161 if (result == eLeapRS_Timeout)
167 if (result != eLeapRS_Success)
169 LOG_ERROR(
"LeapC PollConnection call error: " << this->
ResultToString(result));
176 uint64_t
set = eLeapPolicyFlag_Images;
180 clear |= eLeapPolicyFlag_AllowPauseResume;
184 set |= eLeapPolicyFlag_AllowPauseResume;
189 set |= eLeapPolicyFlag_OptimizeHMD;
193 clear |= eLeapPolicyFlag_OptimizeHMD;
196 if ((result = LeapSetPolicyFlags(this->
Connection, set, clear)) != eLeapRS_Success)
198 LOG_WARNING(
"Unable to set HMD policy flag, tracking will be greatly degraded if attached to an HMD: " << this->
ResultToString(result));
205 case eLeapEventType_Connection:
207 case eLeapEventType_ConnectionLost:
209 case eLeapEventType_Device:
211 case eLeapEventType_DeviceLost:
213 case eLeapEventType_DeviceFailure:
215 case eLeapEventType_Tracking:
217 case eLeapEventType_LogEvent:
219 case eLeapEventType_Policy:
221 case eLeapEventType_ConfigChange:
223 case eLeapEventType_ConfigResponse:
225 case eLeapEventType_Image:
227 case eLeapEventType_PointMappingChange:
229 case eLeapEventType_LogEvents:
231 case eLeapEventType_HeadPose:
233 case eLeapEventType_ImageComplete:
234 case eLeapEventType_ImageRequestError:
246 LOG_TRACE(
"vtkPlusLeapMotion::Probe");
258 LOG_TRACE(
"vtkPlusLeapMotion::InternalStartRecording");
260 eLeapRS result = LeapOpenConnection(this->
Connection);
261 if (result == eLeapRS_Success)
271 LOG_TRACE(
"vtkPlusLeapMotion::InternalStopRecording");
278 #define CHECK_DATA_SOURCE(name) if(this->GetDataSource(std::string(#name) + "To" + this->ToolReferenceFrameName, aSource) != PLUS_SUCCESS){ LOG_WARNING("Data source with ID \"" << #name << "\" doesn't exist. Joint will not be tracked.");} 338 LOG_ERROR(
"Must record at least one joint/palm. Please add a data source.");
344 LOG_ERROR(
"Device must have at least one output channel.");
361 vtkNew<vtkMatrix4x4> mat;
367 #undef CHECK_DATA_SOURCE 375 vtkNew<vtkTransform> pose;
380 if (hand.type != handIndex)
384 LEAP_BONE& bone = hand.digits[fingerIndex].bones[boneIndex];
386 vtkQuaternion<float> orientation;
387 orientation.Set(bone.rotation.w, bone.rotation.x, bone.rotation.y, bone.rotation.z);
389 float angle = orientation.GetRotationAngleAndAxis(axis);
390 pose->Translate(bone.next_joint.x, bone.next_joint.y, bone.next_joint.z);
391 pose->RotateWXYZ(vtkMath::DegreesFromRadians(angle), axis);
392 float x = bone.next_joint.x - bone.prev_joint.x;
393 float y = bone.next_joint.y - bone.prev_joint.y;
394 float z = bone.next_joint.z - bone.prev_joint.z;
395 float mag = std::sqrtf(
x *
x +
y *
y + z * z);
396 igsioFieldMapType fields;
398 std::stringstream ss;
405 std::stringstream ss;
413 LOG_ERROR(
"Unable to record " << boneName <<
" transform.");
422 vtkNew<vtkMatrix4x4> mat;
438 vtkNew<vtkTransform> pose;
443 if (hand.type != handType)
447 LEAP_PALM& palm = hand.palm;
448 vtkQuaternion<float> orientation;
449 orientation.Set(palm.orientation.w, palm.orientation.x, palm.orientation.y, palm.orientation.z);
450 pose->Translate(palm.position.x, palm.position.y, palm.position.z);
452 float angle = orientation.GetRotationAngleAndAxis(axis);
453 pose->RotateWXYZ(angle, axis);
456 LOG_ERROR(
"Unable to record " << name <<
" transform.");
464 vtkNew<vtkMatrix4x4> mat;
479 this->
Mutex->Unlock();
493 this->
Mutex->Unlock();
535 if ((policyEvent->current_policy & eLeapPolicyFlag_OptimizeHMD) == (this->LeapHMDPolicy ? eLeapPolicyFlag_OptimizeHMD : 0) &&
536 (policyEvent->current_policy & eLeapPolicyFlag_AllowPauseResume) == (this->RefusePauseResumePolicy ? 0 : eLeapPolicyFlag_AllowPauseResume) &&
537 (policyEvent->current_policy & eLeapPolicyFlag_Images) == eLeapPolicyFlag_Images)
539 LOG_INFO(
"Successfully changed policy.");
544 LOG_ERROR(
"Unable to change policy.");
615 switch (logEvent->severity)
617 case eLeapLogSeverity_Unknown:
618 case eLeapLogSeverity_Information:
619 LOG_INFO(logEvent->message);
621 case eLeapLogSeverity_Warning:
622 LOG_WARNING(logEvent->message);
624 case eLeapLogSeverity_Critical:
625 LOG_ERROR(logEvent->message);
635 for (uint32_t
i = 0;
i < logEvents->nEvents; ++
i)
637 LEAP_LOG_EVENT&
event = logEvents->events[
i];
638 switch (event.severity)
640 case eLeapLogSeverity_Unknown:
641 case eLeapLogSeverity_Information:
642 LOG_INFO(event.message);
644 case eLeapLogSeverity_Warning:
645 LOG_WARNING(event.message);
647 case eLeapLogSeverity_Critical:
648 LOG_ERROR(event.message);
672 FrameSizeType leftFrameSize{ imageEvent->image[0].properties.width, imageEvent->image[0].properties.height, 1 };
673 FrameSizeType rightFrameSize{ imageEvent->image[1].properties.width, imageEvent->image[1].properties.height, 1 };
683 if (imageEvent->image[0].properties.format == eLeapImageFormat_RGBIr_Bayer)
692 if (imageEvent->image[1].properties.format == eLeapImageFormat_RGBIr_Bayer)
710 uint32_t byteCount = ((imageEvent->image[0].properties.format == eLeapImageFormat_RGBIr_Bayer)) ? 3 : 1 * leftFrameSize[0] * leftFrameSize[1] * leftFrameSize[2];
711 for (uint32_t
i = 0;
i < byteCount;)
713 ((
unsigned char*)(imageEvent->image[0].data))[
i] = 255 - ((
unsigned char*)(imageEvent->image[0].data))[
i];
714 if (imageEvent->image[1].properties.format == eLeapImageFormat_RGBIr_Bayer)
716 ((
unsigned char*)(imageEvent->image[0].data))[
i + 1] = 255 - ((
unsigned char*)(imageEvent->image[0].data))[
i + 1];
717 ((
unsigned char*)(imageEvent->image[0].data))[
i + 2] = 255 - ((
unsigned char*)(imageEvent->image[0].data))[
i + 2];
727 byteCount = ((imageEvent->image[1].properties.format == eLeapImageFormat_RGBIr_Bayer)) ? 3 : 1 * rightFrameSize[0] * rightFrameSize[1] * rightFrameSize[2];
728 for (uint32_t
i = 0;
i < rightFrameSize[0];)
730 ((
unsigned char*)(imageEvent->image[1].data))[
i] = 255 - ((
unsigned char*)(imageEvent->image[1].data))[
i];
731 if (imageEvent->image[1].properties.format == eLeapImageFormat_RGBIr_Bayer)
733 ((
unsigned char*)(imageEvent->image[1].data))[
i + 1] = 255 - ((
unsigned char*)(imageEvent->image[1].data))[
i + 1];
734 ((
unsigned char*)(imageEvent->image[1].data))[
i + 2] = 255 - ((
unsigned char*)(imageEvent->image[1].data))[
i + 2];
745 this->LeftCameraSource->GetInputImageOrientation(),
748 imageEvent->image[0].properties.bpp,
749 (imageEvent->image[0].properties.format == eLeapImageFormat_RGBIr_Bayer) ? US_IMG_RGB_COLOR : US_IMG_BRIGHTNESS,
753 this->RightCameraSource->GetInputImageOrientation(),
756 imageEvent->image[1].properties.bpp,
757 (imageEvent->image[1].properties.format == eLeapImageFormat_RGBIr_Bayer) ? US_IMG_RGB_COLOR : US_IMG_BRIGHTNESS,
765 LOG_DEBUG(
"Image event received but no video data sources are available.");
791 case eLeapRS_Success:
792 return "eLeapRS_Success";
793 case eLeapRS_UnknownError:
794 return "eLeapRS_UnknownError";
795 case eLeapRS_InvalidArgument:
796 return "eLeapRS_InvalidArgument";
797 case eLeapRS_InsufficientResources:
798 return "eLeapRS_InsufficientResources";
799 case eLeapRS_InsufficientBuffer:
800 return "eLeapRS_InsufficientBuffer";
801 case eLeapRS_Timeout:
802 return "eLeapRS_Timeout";
803 case eLeapRS_NotConnected:
804 return "eLeapRS_NotConnected";
805 case eLeapRS_HandshakeIncomplete:
806 return "eLeapRS_HandshakeIncomplete";
807 case eLeapRS_BufferSizeOverflow:
808 return "eLeapRS_BufferSizeOverflow";
809 case eLeapRS_ProtocolError:
810 return "eLeapRS_ProtocolError";
811 case eLeapRS_InvalidClientID:
812 return "eLeapRS_InvalidClientID";
813 case eLeapRS_UnexpectedClosed:
814 return "eLeapRS_UnexpectedClosed";
815 case eLeapRS_UnknownImageFrameRequest:
816 return "eLeapRS_UnknownImageFrameRequest";
817 case eLeapRS_UnknownTrackingFrameID:
818 return "eLeapRS_UnknownTrackingFrameID";
819 case eLeapRS_RoutineIsNotSeer:
820 return "eLeapRS_RoutineIsNotSeer";
821 case eLeapRS_TimestampTooEarly:
822 return "eLeapRS_TimestampTooEarly";
823 case eLeapRS_ConcurrentPoll:
824 return "eLeapRS_ConcurrentPoll";
825 case eLeapRS_NotAvailable:
826 return "eLeapRS_NotAvailable";
827 case eLeapRS_NotStreaming:
828 return "eLeapRS_NotStreaming";
829 case eLeapRS_CannotOpenDevice:
830 return "eLeapRS_CannotOpenDevice";
832 return "Unknown result type.";
841 case eLeapEventType_None:
842 return "eLeapEventType_None";
843 case eLeapEventType_Connection:
844 return "eLeapEventType_Connection";
845 case eLeapEventType_ConnectionLost:
846 return "eLeapEventType_ConnectionLost";
847 case eLeapEventType_Device:
848 return "eLeapEventType_Device";
849 case eLeapEventType_DeviceFailure:
850 return "eLeapEventType_DeviceFailure";
851 case eLeapEventType_Policy:
852 return "eLeapEventType_Policy";
853 case eLeapEventType_Tracking:
854 return "eLeapEventType_Tracking";
855 case eLeapEventType_ImageRequestError:
856 return "eLeapEventType_ImageRequestError";
857 case eLeapEventType_ImageComplete:
858 return "eLeapEventType_ImageComplete";
859 case eLeapEventType_LogEvent:
860 return "eLeapEventType_LogEvent";
861 case eLeapEventType_DeviceLost:
862 return "eLeapEventType_DeviceLost";
863 case eLeapEventType_ConfigResponse:
864 return "eLeapEventType_ConfigResponse";
865 case eLeapEventType_ConfigChange:
866 return "eLeapEventType_ConfigChange";
867 case eLeapEventType_DeviceStatusChange:
868 return "eLeapEventType_DeviceStatusChange";
869 case eLeapEventType_DroppedFrame:
870 return "eLeapEventType_DroppedFrame";
871 case eLeapEventType_Image:
872 return "eLeapEventType_Image";
873 case eLeapEventType_PointMappingChange:
874 return "eLeapEventType_PointMappingChange";
875 case eLeapEventType_LogEvents:
876 return "eLeapEventType_LogEvents";
877 case eLeapEventType_HeadPose:
878 return "eLeapEventType_HeadPose";
880 return "Unknown event type.";
unsigned int PollTimeoutMs
PlusStatus GetDataSource(const char *aSourceId, vtkPlusDataSource *&aSource)
PlusStatus OnPolicyEvent(const LEAP_POLICY_EVENT *policyEvent)
std::string ToolReferenceFrameName
PlusStatus OnConfigChangeEvent(const LEAP_CONFIG_CHANGE_EVENT *configChangeEvent)
Interface for the LeapMotion hand tracker.
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
LEAP_CONNECTION Connection
virtual int GetNumberOfVideoSources() const
PlusStatus OnLogEvent(const LEAP_LOG_EVENT *logEvent)
LEAP_HEAD_POSE_EVENT LastHeadPoseEvent
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
LEAP_CONNECTION_MESSAGE LastMessage
PlusStatus OnDeviceLostEvent(const LEAP_DEVICE_EVENT *deviceEvent)
PlusStatus OnPointMappingChangeEvent(const LEAP_POINT_MAPPING_CHANGE_EVENT *pointMappingChangeEvent)
PlusStatus ToolTimeStampedUpdatePalm(const std::string &name, eLeapHandType hand)
PlusStatus OnConnectionLostEvent(const LEAP_CONNECTION_LOST_EVENT *connectionLostEvent)
PlusStatus OnDeviceEvent(const LEAP_DEVICE_EVENT *deviceEvent)
LEAP_TRACKING_EVENT * GetFrame()
PlusStatus GetVideoSourceByIndex(const unsigned int index, vtkPlusDataSource *&aVideoSource)
PlusStatus SetInputFrameSize(unsigned int x, unsigned int y, unsigned int z)
vtkPlusDataSource * RightCameraSource
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
PlusStatus ToolTimeStampedUpdateBone(std::string boneName, eLeapHandType handIndex, Finger fingerIndex, Bone boneIndex)
bool RefusePauseResumePolicy
virtual PlusStatus AddItem(vtkImageData *frame, US_IMAGE_ORIENTATION usImageOrientation, US_IMAGE_TYPE imageType, long frameNumber, double unfilteredTimestamp=UNDEFINED_TIMESTAMP, double filteredTimestamp=UNDEFINED_TIMESTAMP, const igsioFieldMapType *customFields=NULL)
bool RequirePortNameInDeviceSetConfiguration
PlusStatus OnLogEvents(const LEAP_LOG_EVENTS *logEvents)
PlusStatus SetImageType(US_IMAGE_TYPE imageType)
LEAP_TRACKING_EVENT LastTrackingEvent
vtkPlusDataSource * LeftCameraSource
DataSourceContainer Tools
void PrintSelf(ostream &os, vtkIndent indent)
LEAP_HEAD_POSE_EVENT * GetHeadPose()
virtual int GetNumberOfTools() const
virtual PlusStatus InternalStopRecording()
PlusStatus SetPixelType(igsioCommon::VTKScalarPixelType pixelType)
virtual PlusStatus InternalConnect()
virtual PlusStatus NotifyConfigured()
unsigned long FrameNumber
PlusStatus OnConnectionEvent(const LEAP_CONNECTION_EVENT *connectionEvent)
std::string ResultToString(eLeapRS)
PlusStatus OnDeviceFailureEvent(const LEAP_DEVICE_FAILURE_EVENT *deviceFailureEvent)
virtual PlusStatus StopRecording()
virtual PlusStatus InternalUpdate()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
PlusStatus OnImageEvent(const LEAP_IMAGE_EVENT *imageEvent)
std::string EventToString(_eLeapEventType)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
bool StartThreadForInternalUpdates
virtual PlusStatus InternalDisconnect()
vtkIGSIORecursiveCriticalSection * Mutex
set(gca, 'XTick', axisXRange(1):1:axisXRange(2))
PlusStatus SetNumberOfScalarComponents(unsigned int numberOfScalarComponents)
PlusStatus OnTrackingEvent(const LEAP_TRACKING_EVENT *trackingEvent)
Direction vectors of rods y
void SetHeadPose(const LEAP_HEAD_POSE_EVENT *headPose)
#define CHECK_DATA_SOURCE(name)
vtkStandardNewMacro(vtkPlusLeapMotion)
virtual int OutputChannelCount() const
PlusStatus OnHeadPoseEvent(const LEAP_HEAD_POSE_EVENT *headPoseEvent)
void SetFrame(const LEAP_TRACKING_EVENT *trackingEvent)
PlusStatus OnConfigResponseEvent(const LEAP_CONFIG_RESPONSE_EVENT *configResponseEvent)
virtual PlusStatus InternalStartRecording()
Interface to a 3D positioning tool, video source, or generalized data stream.