From 2c50d4c707fa9c46025fb46c68641c579f601273 Mon Sep 17 00:00:00 2001 From: Steve Le Roy Harris Date: Fri, 1 Jul 2016 16:57:23 +0100 Subject: [PATCH] Initial commit --- CMakeLists.txt | 30 ++++ KinectDevice.cpp | 292 +++++++++++++++++++++++++++++++++++++ KinectDevice.h | 47 ++++++ LICENSE | 16 ++ README.md | 10 ++ cmake/FindEigen3.cmake | 81 ++++++++++ cmake/FindKinectSDK2.cmake | 183 +++++++++++++++++++++++ je_nourish_kinectv2.cpp | 42 ++++++ je_nourish_kinectv2.json | 168 +++++++++++++++++++++ 9 files changed, 869 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 KinectDevice.cpp create mode 100644 KinectDevice.h create mode 100644 LICENSE create mode 100644 README.md create mode 100644 cmake/FindEigen3.cmake create mode 100644 cmake/FindKinectSDK2.cmake create mode 100644 je_nourish_kinectv2.cpp create mode 100644 je_nourish_kinectv2.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..46989ba --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 2.8.12) +project(KinectV2Plugin) # Change this line. + +set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} ) +find_package(osvr REQUIRED) +find_package( KinectSDK2 REQUIRED ) +find_package( Eigen3 REQUIRED ) + +include_directories( ${KinectSDK2_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} ) +link_directories( ${KinectSDK2_LIBRARY_DIRS} ) + +osvr_convert_json(je_nourish_kinectv2_json + je_nourish_kinectv2.json + "${CMAKE_CURRENT_BINARY_DIR}/je_nourish_kinectv2_json.h") + + + + + +include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") + +osvr_add_plugin(NAME je_nourish_kinectv2 + CPP + SOURCES + je_nourish_kinectv2.cpp + KinectDevice.cpp + KinectDevice.h + "${CMAKE_CURRENT_BINARY_DIR}/je_nourish_kinectv2_json.h") + +target_link_libraries( je_nourish_kinectv2 ${KinectSDK2_LIBRARIES} ) \ No newline at end of file diff --git a/KinectDevice.cpp b/KinectDevice.cpp new file mode 100644 index 0000000..2f9e4a1 --- /dev/null +++ b/KinectDevice.cpp @@ -0,0 +1,292 @@ +#include +#include +#include +#include +#include + +#include "KinectDevice.h" + +// Generated JSON header file +#include "je_nourish_kinectv2_json.h" + +#include + +#include +#define _USE_MATH_DEFINES +#include + +namespace KinectOsvr { + + KinectDevice::KinectDevice(OSVR_PluginRegContext ctx, IKinectSensor* pKinectSensor) : m_pKinectSensor(pKinectSensor) { + + for (int i = 0; i < BODY_COUNT; i++) { + m_channels[i] = 0; + } + + HRESULT hr; + + // Initialize the Kinect and get coordinate mapper and the body reader + IBodyFrameSource* pBodyFrameSource = NULL; + + hr = m_pKinectSensor->Open(); + + if (SUCCEEDED(hr)) + { + hr = m_pKinectSensor->get_CoordinateMapper(&m_pCoordinateMapper); + } + if (SUCCEEDED(hr)) + { + hr = m_pKinectSensor->get_BodyFrameSource(&pBodyFrameSource); + } + if (SUCCEEDED(hr)) + { + hr = pBodyFrameSource->OpenReader(&m_pBodyFrameReader); + } + SafeRelease(pBodyFrameSource); + + /// Create the initialization options + OSVR_DeviceInitOptions opts = osvrDeviceCreateInitOptions(ctx); + + osvrDeviceTrackerConfigure(opts, &m_tracker); + osvrDeviceAnalogConfigure(opts, &m_analog, 25); + osvrDeviceButtonConfigure(opts, &m_button, 6); + + /// Create the device token with the options + m_dev.initAsync(ctx, "KinectV2", opts); + + /// Send JSON descriptor + m_dev.sendJsonDescriptor(je_nourish_kinectv2_json); + + /// Register update callback + m_dev.registerUpdateCallback(this); + }; + + OSVR_ReturnCode KinectDevice::update() { + + if (!m_pBodyFrameReader) + { + return OSVR_RETURN_SUCCESS; + } + + IBodyFrame* pBodyFrame = NULL; + + HRESULT hr = m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame); + + + if (SUCCEEDED(hr)) + { + INT64 nTime = 0; + + hr = pBodyFrame->get_RelativeTime(&nTime); + + IBody* ppBodies[BODY_COUNT] = { 0 }; + + if (SUCCEEDED(hr)) + { + hr = pBodyFrame->GetAndRefreshBodyData(_countof(ppBodies), ppBodies); + } + + if (SUCCEEDED(hr)) + { + ProcessBody(ppBodies); + } + + for (int i = 0; i < _countof(ppBodies); ++i) + { + SafeRelease(ppBodies[i]); + } + } + + SafeRelease(pBodyFrame); + + return OSVR_RETURN_SUCCESS; + }; + + void boneSpaceToWorldSpace(OSVR_Quaternion* q) { + Eigen::Quaterniond quaternion = osvr::util::fromQuat(*q); + + // Rotate bone quaternion around its own x axis + Eigen::AngleAxisd rotationAxis (M_PI/2, quaternion._transformVector(Eigen::Vector3d::UnitX())); + Eigen::Quaterniond worldSpace = rotationAxis * quaternion; + + osvr::util::toQuat(worldSpace, (*q)); + } + + void offsetTranslation(OSVR_Vec3* translation_offset, OSVR_Vec3* translation) { + osvrVec3SetX(translation, osvrVec3GetX(translation) - osvrVec3GetX(translation_offset)); + osvrVec3SetY(translation, osvrVec3GetY(translation) - osvrVec3GetY(translation_offset)); + osvrVec3SetZ(translation, osvrVec3GetZ(translation) - osvrVec3GetZ(translation_offset)); + } + + void setupOffset(OSVR_PoseState* offset, Joint* joint, JointOrientation* jointOrientation) { + osvrVec3SetX(&(offset->translation), joint->Position.X); + osvrVec3SetY(&(offset->translation), joint->Position.Y); + osvrVec3SetZ(&(offset->translation), joint->Position.Z); + + osvrQuatSetX(&(offset->rotation), jointOrientation->Orientation.x); + osvrQuatSetY(&(offset->rotation), jointOrientation->Orientation.y); + osvrQuatSetZ(&(offset->rotation), jointOrientation->Orientation.z); + osvrQuatSetW(&(offset->rotation), jointOrientation->Orientation.w); + + Eigen::Quaterniond q = osvr::util::fromQuat(offset->rotation); + osvr::util::toQuat(q.inverse(), offset->rotation); + } + + void applyOffset(OSVR_PoseState* offset, OSVR_PoseState* poseState) { + offsetTranslation(&(offset->translation), &(poseState->translation)); + } + + void KinectDevice::ProcessBody(IBody** ppBodies) { + + if (m_pCoordinateMapper) + { + for (int i = 0; i < BODY_COUNT; i++) { + IBody* pBody = ppBodies[i]; + if (pBody) + { + + BOOLEAN bTracked = false; + HRESULT hr = pBody->get_IsTracked(&bTracked); + + if (!bTracked) { + removeBody(i); + } + + // Tracked body is the one who's been visible longest + if (SUCCEEDED(hr) && bTracked && firstBody(addBody(i))) + { + + Joint joints[JointType_Count]; + JointOrientation jointOrientations[JointType_Count]; + HandState rightHandState = HandState_Unknown; + HandState leftHandState = HandState_Unknown; + + pBody->get_HandRightState(&rightHandState); + pBody->get_HandLeftState(&leftHandState); + + OSVR_ButtonState buttons[6]; + buttons[0] = rightHandState == HandState_Open; + buttons[1] = rightHandState == HandState_Closed; + buttons[2] = rightHandState == HandState_Lasso; + buttons[3] = leftHandState == HandState_Open; + buttons[4] = leftHandState == HandState_Closed; + buttons[5] = leftHandState == HandState_Lasso; + + // Send hand gestures as button presses + osvrDeviceButtonSetValues(m_dev, m_button, buttons, 6); + + hr = pBody->GetJoints(_countof(joints), joints); + HRESULT hr2 = pBody->GetJointOrientations(_countof(jointOrientations), jointOrientations); + + if (SUCCEEDED(hr) && SUCCEEDED(hr2)) + { + OSVR_PoseState poseState; + OSVR_Vec3 translation; + OSVR_Quaternion rotation; + + osvrVec3Zero(&translation); + osvrQuatSetIdentity(&rotation); + + if (m_firstUpdate) { + m_firstUpdate = false; + + setupOffset(&m_offset, &joints[JointType_Head], &jointOrientations[JointType_Neck]); + } + + for (int j = 0; j < _countof(joints); ++j) + { + osvrVec3SetX(&translation, joints[j].Position.X); + osvrVec3SetY(&translation, joints[j].Position.Y); + osvrVec3SetZ(&translation, joints[j].Position.Z); + + osvrQuatSetX(&rotation, jointOrientations[j].Orientation.x); + osvrQuatSetY(&rotation, jointOrientations[j].Orientation.y); + osvrQuatSetZ(&rotation, jointOrientations[j].Orientation.z); + osvrQuatSetW(&rotation, jointOrientations[j].Orientation.w); + + // Rotate hand orientation to something more useful for OSVR + if (j == JointType_HandLeft || j == JointType_HandRight) { + boneSpaceToWorldSpace(&rotation); + } + + poseState.translation = translation; + poseState.rotation = rotation; + applyOffset(&m_offset, &poseState); + // Send pose + osvrDeviceTrackerSendPose(m_dev, m_tracker, &poseState, j); + + OSVR_AnalogState confidence = 0; + switch (joints[j].TrackingState) { + case TrackingState_Tracked: + confidence = 1; + break; + case TrackingState_Inferred: + confidence = 0.5; + break; + default: + case TrackingState_NotTracked: + confidence = 0; + break; + } + // Tracking confidence for use in smoothing plugins + osvrDeviceAnalogSetValue(m_dev, m_analog, confidence, j); + } + } + } + } + } + } + }; + + bool KinectDevice::firstBody(int channel) { + for (int i = 0; i < channel; i++) { + if (m_channels[i] != 0) { + return false; + } + } + return true; + } + + int KinectDevice::addBody(int idx) { + for (int i = 0; i < BODY_COUNT; i++) { + if (m_channels[i] == idx) { + return i; + } + } + for (int i = 0; i < BODY_COUNT; i++) { + if (!m_channels[i]) { + m_channels[i] = idx; + return i; + } + } + return -1; + } + + void KinectDevice::removeBody(int idx) { + for (int i = 0; i < BODY_COUNT; i++) { + if (m_channels[i] == idx) { + m_channels[i] = 0; + } + } + } + + bool KinectDevice::Detect(IKinectSensor** ppKinectSensor) { + + HRESULT hr = GetDefaultKinectSensor(ppKinectSensor); + + return SUCCEEDED(hr); + + }; + + KinectDevice::~KinectDevice() { + SafeRelease(m_pBodyFrameReader); + SafeRelease(m_pCoordinateMapper); + + if (m_pKinectSensor) + { + m_pKinectSensor->Close(); + } + SafeRelease(m_pKinectSensor); + }; + +}; diff --git a/KinectDevice.h b/KinectDevice.h new file mode 100644 index 0000000..b844bc3 --- /dev/null +++ b/KinectDevice.h @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +#include + +namespace KinectOsvr { + class KinectDevice { + public: + KinectDevice(OSVR_PluginRegContext ctx, IKinectSensor* pKinectSensor); + ~KinectDevice(); + + OSVR_ReturnCode update(); + static bool Detect(IKinectSensor** ppKinectSensor); + private: + void ProcessBody(IBody** ppBodies); + int addBody(int idx); + void removeBody(int idx); + bool firstBody(int channel); + + osvr::pluginkit::DeviceToken m_dev; + OSVR_TrackerDeviceInterface m_tracker; + OSVR_AnalogDeviceInterface m_analog; + OSVR_ButtonDeviceInterface m_button; + + IKinectSensor* m_pKinectSensor; + ICoordinateMapper* m_pCoordinateMapper; + IBodyFrameReader* m_pBodyFrameReader; + + int m_channels[BODY_COUNT]; + + bool m_firstUpdate = true; + OSVR_PoseState m_offset; + }; +} + +// Safe release for interfaces +template +inline void SafeRelease(Interface *& pInterfaceToRelease) +{ + if (pInterfaceToRelease != NULL) + { + pInterfaceToRelease->Release(); + pInterfaceToRelease = NULL; + } +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f2ae2bf --- /dev/null +++ b/LICENSE @@ -0,0 +1,16 @@ +The MIT License (MIT) +Copyright (c) 2016 Steve Le Roy Harris + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1593e2 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# OSVR-KinectV2 + +An OSVR plugin providing Kinect SDK v2 position and orientation joint tracking, for use with a Kinect for Xbox One. + +git clone https://github.com/simlrh/OSVR-KinectV2 +cd OSVR-KinectV2 +git submodule init +git submodule update + +Then follow the standard OSVR plugin build instructions. \ No newline at end of file diff --git a/cmake/FindEigen3.cmake b/cmake/FindEigen3.cmake new file mode 100644 index 0000000..9c546a0 --- /dev/null +++ b/cmake/FindEigen3.cmake @@ -0,0 +1,81 @@ +# - Try to find Eigen3 lib +# +# This module supports requiring a minimum version, e.g. you can do +# find_package(Eigen3 3.1.2) +# to require version 3.1.2 or newer of Eigen3. +# +# Once done this will define +# +# EIGEN3_FOUND - system has eigen lib with correct version +# EIGEN3_INCLUDE_DIR - the eigen include directory +# EIGEN3_VERSION - eigen version + +# Copyright (c) 2006, 2007 Montel Laurent, +# Copyright (c) 2008, 2009 Gael Guennebaud, +# Copyright (c) 2009 Benoit Jacob +# Redistribution and use is allowed according to the terms of the 2-clause BSD license. + +if(NOT Eigen3_FIND_VERSION) + if(NOT Eigen3_FIND_VERSION_MAJOR) + set(Eigen3_FIND_VERSION_MAJOR 2) + endif(NOT Eigen3_FIND_VERSION_MAJOR) + if(NOT Eigen3_FIND_VERSION_MINOR) + set(Eigen3_FIND_VERSION_MINOR 91) + endif(NOT Eigen3_FIND_VERSION_MINOR) + if(NOT Eigen3_FIND_VERSION_PATCH) + set(Eigen3_FIND_VERSION_PATCH 0) + endif(NOT Eigen3_FIND_VERSION_PATCH) + + set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}") +endif(NOT Eigen3_FIND_VERSION) + +macro(_eigen3_check_version) + file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) + + string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") + set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}") + set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}") + string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}") + set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}") + + set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION}) + if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK FALSE) + else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + set(EIGEN3_VERSION_OK TRUE) + endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION}) + + if(NOT EIGEN3_VERSION_OK) + + message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, " + "but at least version ${Eigen3_FIND_VERSION} is required") + endif(NOT EIGEN3_VERSION_OK) +endmacro(_eigen3_check_version) + +if (EIGEN3_INCLUDE_DIR) + + # in cache already + _eigen3_check_version() + set(EIGEN3_FOUND ${EIGEN3_VERSION_OK}) + +else (EIGEN3_INCLUDE_DIR) + + find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library + PATHS + ${CMAKE_INSTALL_PREFIX}/include + ${KDE4_INCLUDE_DIR} + PATH_SUFFIXES eigen3 eigen + ) + + if(EIGEN3_INCLUDE_DIR) + _eigen3_check_version() + endif(EIGEN3_INCLUDE_DIR) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK) + + mark_as_advanced(EIGEN3_INCLUDE_DIR) + +endif(EIGEN3_INCLUDE_DIR) + diff --git a/cmake/FindKinectSDK2.cmake b/cmake/FindKinectSDK2.cmake new file mode 100644 index 0000000..dae32bc --- /dev/null +++ b/cmake/FindKinectSDK2.cmake @@ -0,0 +1,183 @@ +#.rst: +# FindKinectSDK2 +# -------------- +# +# Find Kinect for Windows SDK v2 (Kinect SDK v2) include dirs, library dirs, libraries and post-build commands +# +# Use this module by invoking find_package with the form:: +# +# find_package( KinectSDK2 [REQUIRED] ) +# +# Results for users are reported in following variables:: +# +# KinectSDK2_FOUND - Return "TRUE" when Kinect SDK v2 found. Otherwise, Return "FALSE". +# KinectSDK2_INCLUDE_DIRS - Kinect SDK v2 include directories. (${KinectSDK2_DIR}/inc) +# KinectSDK2_LIBRARY_DIRS - Kinect SDK v2 library directories. (${KinectSDK2_DIR}/Lib/x86 or ${KinectSDK2_DIR}/Lib/x64) +# KinectSDK2_LIBRARIES - Kinect SDK v2 library files. (${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib (If check the box of any application festures, corresponding library will be added.)) +# KinectSDK2_COMMANDS - Copy commands of redist files for application functions of Kinect SDK v2. (If uncheck the box of all application features, this variable has defined empty command.) +# +# This module reads hints about search locations from following environment variables:: +# +# KINECTSDK20_DIR - Kinect SDK v2 root directory. (This environment variable has been set by installer of Kinect SDK v2.) +# +# CMake entries:: +# +# KinectSDK2_DIR - Kinect SDK v2 root directory. (Default $ENV{KINECTSDK20_DIR}) +# KinectSDK2_FACE - Check the box when using Face or HDFace features. (Default uncheck) +# KinectSDK2_FUSION - Check the box when using Fusion features. (Default uncheck) +# KinectSDK2_VGB - Check the box when using Visual Gesture Builder features. (Default uncheck) +# +# Example to find Kinect SDK v2:: +# +# cmake_minimum_required( VERSION 2.8 ) +# +# project( project ) +# add_executable( project main.cpp ) +# set_property( DIRECTORY PROPERTY VS_STARTUP_PROJECT "project" ) +# +# # Find package using this module. +# find_package( KinectSDK2 REQUIRED ) +# +# if(KinectSDK2_FOUND) +# # [C/C++]>[General]>[Additional Include Directories] +# include_directories( ${KinectSDK2_INCLUDE_DIRS} ) +# +# # [Linker]>[General]>[Additional Library Directories] +# link_directories( ${KinectSDK2_LIBRARY_DIRS} ) +# +# # [Linker]>[Input]>[Additional Dependencies] +# target_link_libraries( project ${KinectSDK2_LIBRARIES} ) +# +# # [Build Events]>[Post-Build Event]>[Command Line] +# add_custom_command( TARGET project POST_BUILD ${KinectSDK2_COMMANDS} ) +# endif() +# +# ============================================================================= +# +# Copyright (c) 2016 Tsukasa SUGIURA +# Distributed under the MIT License. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# ============================================================================= + +##### Utility ##### + +# Check Directory Macro +macro(CHECK_DIR _DIR) + if(NOT EXISTS "${${_DIR}}") + message(WARNING "Directory \"${${_DIR}}\" not found.") + set(KinectSDK2_FOUND FALSE) + unset(_DIR) + endif() +endmacro() + +# Check Files Macro +macro(CHECK_FILES _FILES _DIR) + set(_MISSING_FILES) + foreach(_FILE ${${_FILES}}) + if(NOT EXISTS "${_FILE}") + get_filename_component(_FILE ${_FILE} NAME) + set(_MISSING_FILES "${_MISSING_FILES}${_FILE}, ") + endif() + endforeach() + if(_MISSING_FILES) + message(WARNING "In directory \"${${_DIR}}\" not found files: ${_MISSING_FILES}") + set(KinectSDK2_FOUND FALSE) + unset(_FILES) + endif() +endmacro() + +# Target Platform +set(TARGET_PLATFORM) +if(NOT CMAKE_CL_64) + set(TARGET_PLATFORM x86) +else() + set(TARGET_PLATFORM x64) +endif() + +##### Find Kinect SDK v2 ##### + +# Found +set(KinectSDK2_FOUND TRUE) +if(MSVC_VERSION LESS 1700) + message(WARNING "Kinect for Windows SDK v2 supported Visual Studio 2012 or later.") + set(KinectSDK2_FOUND FALSE) +endif() + +# Options +option(KinectSDK2_FACE "Face and HDFace features" FALSE) +option(KinectSDK2_FUSION "Fusion features" FALSE) +option(KinectSDK2_VGB "Visual Gesture Builder features" FALSE) + +# Root Directoty +set(KinectSDK2_DIR) +if(KinectSDK2_FOUND) + set(KinectSDK2_DIR $ENV{KINECTSDK20_DIR} CACHE PATH "Kinect for Windows SDK v2 Install Path." FORCE) + check_dir(KinectSDK2_DIR) +endif() + +# Include Directories +set(KinectSDK2_INCLUDE_DIRS) +if(KinectSDK2_FOUND) + set(KinectSDK2_INCLUDE_DIRS ${KinectSDK2_DIR}/inc) + check_dir(KinectSDK2_INCLUDE_DIRS) +endif() + +# Library Directories +set(KinectSDK2_LIBRARY_DIRS) +if(KinectSDK2_FOUND) + set(KinectSDK2_LIBRARY_DIRS ${KinectSDK2_DIR}/Lib/${TARGET_PLATFORM}) + check_dir(KinectSDK2_LIBRARY_DIRS) +endif() + +# Dependencies +set(KinectSDK2_LIBRARIES) +if(KinectSDK2_FOUND) + set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARY_DIRS}/Kinect20.lib) + + if(KinectSDK2_FACE) + set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Face.lib) + endif() + + if(KinectSDK2_FUSION) + set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.Fusion.lib) + endif() + + if(KinectSDK2_VGB) + set(KinectSDK2_LIBRARIES ${KinectSDK2_LIBRARIES};${KinectSDK2_LIBRARY_DIRS}/Kinect20.VisualGestureBuilder.lib) + endif() + + check_files(KinectSDK2_LIBRARIES KinectSDK2_LIBRARY_DIRS) +endif() + +# Custom Commands +set(KinectSDK2_COMMANDS) +if(KinectSDK2_FOUND) + if(KinectSDK2_FACE) + set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Face/${TARGET_PLATFORM}) + check_dir(KinectSDK2_REDIST_DIR) + list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL) + endif() + + if(KinectSDK2_FUSION) + set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/Fusion/${TARGET_PLATFORM}) + check_dir(KinectSDK2_REDIST_DIR) + list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL) + endif() + + if(KinectSDK2_VGB) + set(KinectSDK2_REDIST_DIR ${KinectSDK2_DIR}/Redist/VGB/${TARGET_PLATFORM}) + check_dir(KinectSDK2_REDIST_DIR) + list(APPEND KinectSDK2_COMMANDS COMMAND xcopy "${KinectSDK2_REDIST_DIR}" "$(OutDir)" /e /y /i /r > NUL) + endif() + + # Empty Commands + if(NOT KinectSDK2_COMMANDS) + set(KinectSDK2_COMMANDS COMMAND) + endif() +endif() + +message(STATUS "KinectSDK2_FOUND : ${KinectSDK2_FOUND}") \ No newline at end of file diff --git a/je_nourish_kinectv2.cpp b/je_nourish_kinectv2.cpp new file mode 100644 index 0000000..d4d7503 --- /dev/null +++ b/je_nourish_kinectv2.cpp @@ -0,0 +1,42 @@ +// Internal Includes +#include +#include +#include + +// Library/third-party includes +// - none + +// Standard includes +#include + +namespace KinectOsvr { + class HardwareDetection { + public: + HardwareDetection() : m_found(false) {} + OSVR_ReturnCode operator()(OSVR_PluginRegContext ctx) { + + if (!m_found) { + IKinectSensor* pKinectSensor; + + if (KinectDevice::Detect(&pKinectSensor)) { + m_found = true; + osvr::pluginkit::registerObjectForDeletion( + ctx, new KinectDevice(ctx, pKinectSensor)); + } + } + return OSVR_RETURN_SUCCESS; + } + + private: + bool m_found; + }; +} + +OSVR_PLUGIN(je_nourish_kinectv2) { + + osvr::pluginkit::PluginContext context(ctx); + + context.registerHardwareDetectCallback(new KinectOsvr::HardwareDetection()); + + return OSVR_RETURN_SUCCESS; +} diff --git a/je_nourish_kinectv2.json b/je_nourish_kinectv2.json new file mode 100644 index 0000000..83b0fbd --- /dev/null +++ b/je_nourish_kinectv2.json @@ -0,0 +1,168 @@ +{ + "deviceVendor": "Microsoft", + "deviceName": "Kinect for Xbox ONE", + "author": "Steve Le Roy Harris ", + "version": 1, + "lastModified": "2016-06023T21:13:07.585Z", + "interfaces": { + "tracker": { + "count": 25, + "position": true, + "orientation": true + }, + "analog": { + "count": 25, + "traits": [ + { + "min": 0, + "max": 1, + "rest": 0 + } + ] + }, + "button": { + "count": 6 + } + }, + "semantic": { + "body1": { + "torso": { + "hips": { + "$target": "tracker/0", // SpineBase + "confidence": "analog/0" + }, + "spine": { + "$target": "tracker/1", // SpineMid + "confidence": "analog/1" + }, + "chest": { + "$target": "tracker/20", // SpineShoulder + "confidence": "analog/20" + } + }, + "head": { + "neck": { + "$target": "tracker/2", // Neck + "confidence": "analog/2" + }, + "$target": "tracker/3", // Head + "confidence": "analog/3" + }, + "arms": { + "right": { + "shoulder": { + "$target": "tracker/8", // ShoulderRight + "confidence": "analog/8" + }, + "elbow": { + "$target": "tracker/9", // ElbowRight + "confidence": "analog/9" + }, + "wrist": { + "$target": "tracker/10", // WristRight + "confidence": "analog/10" + }, + "hand": { + "$target": "tracker/11", // HandRight + "confidence": "analog/11", + "tip": { + "$target": "tracker/23", // HandTipRight + "confidence": "analog/23" + }, + "thumb": { + "$target": "tracker/24", // ThumbRight + "confidence": "analog/24" + }, + "open": "button/0", + "closed": "button/1", + "lassoo": "button/2" + } + }, + "left": { + "shoulder": { + "$target": "tracker/4", // ShoulderLeft + "confidence": "analog/4" + }, + "elbow": { + "$target": "tracker/5", // ElbowLeft + "confidence": "analog/5" + }, + "wrist": { + "$target": "tracker/6", // WristLeft + "confidence": "analog/6" + }, + "hand": { + "$target": "tracker/7", // HandLeft + "confidence": "analog/7", + "tip": { + "$target": "tracker/21", // HandTipLeft + "confidence": "analog/21" + }, + "thumb": { + "$target": "tracker/22", // ThumbLeft + "confidence": "analog/22" + }, + "open": "button/3", + "closed": "button/4", + "lassoo": "button/5" + } + } + }, + "legs": { + "left": { + "hip": { + "$target": "tracker/12", // HipLeft + "confidence": "analog/12" + }, + "knee": { + "$target": "tracker/13", // KneeLeft + "confidence": "analog/13" + }, + "ankle": { + "$target": "tracker/14", // AnkleLeft + "confidence": "analog/14" + }, + "foot": { + "$target": "tracker/15", // FootLeft + "confidence": "analog/15" + } + }, + "right": { + "hip": { + "$target": "tracker/16", // HipRight + "confidence": "analog/16" + }, + "knee": { + "$target": "tracker/17", // KneeRight + "confidence": "analog/17" + }, + "ankle": { + "$target": "tracker/18", // AnkleRight + "confidence": "analog/18" + }, + "foot": { + "$target": "tracker/19", // FootRight + "confidence": "analog/19" + } + } + } + } + }, + "automaticAliases": { + "/me/head": "semantic/body1/head", + "/me/hands/left": "semantic/body1/arms/left/hand", + "/me/hands/right": "semantic/body1/arms/right/hand", + + "/controller/right/1": "semantic/body1/arms/right/hand/open", + "/controller/right/2": "semantic/body1/arms/right/hand/closed", + "/controller/right/3": "semantic/body1/arms/right/hand/lasso", + "/controller/left/1": "semantic/body1/arms/left/hand/open", + "/controller/left/2": "semantic/body1/arms/left/hand/closed", + "/controller/left/3": "semantic/body1/arms/left/hand/lasso", + + "/me/torso": "semantic/body1/torso/*", + "/me/arms": "semantic/body1/arms/*", + "/me/legs": "semantic/body1/legs/*", + "/me/neck": "semantic/body1/head/neck" + } +}