├── BSD.txt ├── KUInterface.cs ├── KUInterface.dll ├── KUInterface.zip └── README.txt /BSD.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011, Andrew DeVine, University of Central 2 | Florida ISUE lab 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, 6 | with or without modification, are permitted provided 7 | that the following conditions are met: 8 | 9 | 1) Redistributions of source code must retain the above 10 | copyright notice, this list of conditions and the following 11 | disclaimer. 12 | 13 | 2) Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following 15 | disclaimer in the documentation and/or other materials 16 | provided with the distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 19 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /KUInterface.cs: -------------------------------------------------------------------------------- 1 | /************************************************************************ 2 | * * 3 | * KinectSDK-Unity3D C# Wrapper: * 4 | * Attach to a GameObject * 5 | * * 6 | * Author: Andrew DeVine * 7 | * University of Central Florida ISUE Lab * 8 | * 2012 * 9 | * (see included BSD license for licensing information) * 10 | ************************************************************************/ 11 | 12 | using UnityEngine; 13 | using System; 14 | using System.Text; 15 | using System.Runtime.InteropServices; 16 | using System.Collections; 17 | 18 | /// 19 | /// Kinect method access 20 | /// 21 | public class KUInterface : MonoBehaviour { 22 | 23 | //public variables 24 | /// 25 | /// scales all joint positions by given amount. Do not set to zero. 26 | /// 27 | public int scaleFactor = 1000; 28 | /// 29 | /// set to true to track two skeletons 30 | /// 31 | public bool twoPlayer = false; 32 | /// 33 | /// set to false to optimize performance if RGB camera is not being used 34 | /// 35 | public bool useRGB = true; 36 | /// 37 | /// set to false to optimize performance if depth camera is not being used 38 | /// 39 | public bool useDepth = true; 40 | /// 41 | /// displays joint position data on screen 42 | /// 43 | public bool displayJointInformation = false; 44 | /// 45 | /// displays RGB texture image on screen 46 | /// 47 | public bool displayTextureImage = false; 48 | /// 49 | /// displays depth image on screen 50 | /// 51 | public bool displayDepthImage = false; 52 | 53 | //constants 54 | private const int IM_W = 640; 55 | private const int IM_H = 480; 56 | 57 | //private variables 58 | private bool NUIisReady = false; 59 | private float lastCameraAngleChange = -30.0f; 60 | private byte[] seqTex; 61 | private Color32[] cols; 62 | private Texture2D texture; 63 | private byte[] seqDepth; 64 | private Color32[] dcols; 65 | private Texture2D depthImg; 66 | private short[][] depth; 67 | 68 | 69 | /******************************************************************************** 70 | * USER METHODS -> Call these methods from your scripts 71 | * ******************************************************************************/ 72 | 73 | /// 74 | /// main joint position get function 75 | /// 76 | /// player number (1,2) 77 | /// KinectWrapper.Joints enum 78 | /// position of given joint for given player 79 | public Vector3 GetJointPos(int player, KinectWrapper.Joints joint) { 80 | 81 | KinectWrapper.SkeletonTransform trans = new KinectWrapper.SkeletonTransform(); 82 | if (NUIisReady && (player == 1 || player == 2)) 83 | { 84 | KinectWrapper.GetSkeletonTransform(player, (int)joint, ref trans); 85 | return new Vector3(trans.x * scaleFactor, trans.y * scaleFactor, trans.z * scaleFactor); 86 | } 87 | else 88 | { 89 | return Vector3.zero; 90 | } 91 | } 92 | 93 | 94 | /// 95 | /// one-player overload of joint position get function 96 | /// 97 | /// KinectWrapper.Joints enum 98 | /// position of given joint 99 | public Vector3 GetJointPos(KinectWrapper.Joints joint) { 100 | 101 | return GetJointPos(1, joint); 102 | } 103 | 104 | 105 | /// 106 | /// gets color texture image from Kinect RGB camera 107 | /// 108 | /// RGB image 109 | public Texture2D GetTextureImage() { 110 | 111 | return this.texture; 112 | } 113 | 114 | 115 | /// 116 | /// gets depth data from Kinect depth camera 117 | /// 118 | /// 2D array of pixel depths as bytes 119 | /// depth[x=0][y=0] corresponds to top-left corner of image 120 | public short[][] GetDepthData() { 121 | 122 | return this.depth; 123 | } 124 | 125 | 126 | /// 127 | /// returns current Kinect camera angle from horizontal 128 | /// 129 | /// camera angle from horizontal 130 | public float GetCameraAngle() { 131 | 132 | float cameraAngle = 0; 133 | 134 | KinectWrapper.GetCameraAngle(ref cameraAngle); 135 | return cameraAngle; 136 | } 137 | 138 | 139 | /// 140 | /// sets Kinect camera angle 141 | /// 142 | /// range: -27 -> 27 143 | /// returns true if successful 144 | /// do not change angle more than once every 30 sec 145 | public bool SetCameraAngle(int angle) { 146 | 147 | /* DO NOT CHANGE CAMERA ANGLE MORE OFTEN THAN ONCE 148 | * EVERY 30 SECONDS, IT COULD DAMAGE THE KINECT 149 | * SENSOR (SEE KINECT SDK DOCUMENTATION). 150 | */ 151 | 152 | if (Time.time - lastCameraAngleChange > 30 && NUIisReady) { 153 | lastCameraAngleChange = Time.time; 154 | return KinectWrapper.SetCameraAngle(angle); 155 | } else { 156 | return false; 157 | } 158 | } 159 | 160 | 161 | /******************************************************************************** 162 | * DEVICE MANAGEMENT -> initialize, uninitialize, and update sensor 163 | * ******************************************************************************/ 164 | 165 | //called on application start 166 | private void Start() { 167 | 168 | NUIisReady = false; 169 | 170 | //initialize Kinect sensor 171 | NUIisReady = KinectWrapper.NuiContextInit(twoPlayer); 172 | 173 | //display messages 174 | if (NUIisReady) 175 | Debug.Log("Sensor Initialized."); 176 | else 177 | Debug.Log("Could Not Initialize Sensor."); 178 | 179 | if (scaleFactor == 0) 180 | Debug.Log("WARNING: KUInterface.scaleFactor is set to zero. All joint positions will be the zero vector."); 181 | 182 | //set up image memory 183 | seqTex = new byte[IM_W * IM_H * 4]; 184 | cols = new Color32[IM_W * IM_H]; 185 | texture = new Texture2D(IM_W, IM_H); 186 | 187 | seqDepth = new byte[IM_W * IM_H * 2]; 188 | dcols = new Color32[IM_W * IM_H]; 189 | depthImg = new Texture2D(IM_W, IM_H); 190 | depth = new short[IM_W][]; 191 | for (int i = 0; i < depth.Length; i++) { 192 | depth[i] = new short[IM_H]; 193 | } 194 | } 195 | 196 | 197 | //called on application stop 198 | private void OnApplicationQuit() { 199 | 200 | NUIisReady = false; 201 | KinectWrapper.NuiContextUnInit(); 202 | Debug.Log("Sensor Off."); 203 | } 204 | 205 | 206 | //called every Unity frame (frame-rate dependent) 207 | private void Update() { 208 | 209 | if (NUIisReady) 210 | { 211 | //update Kinect 212 | KinectWrapper.NuiUpdate(); 213 | 214 | //update RGB texture 215 | if (useRGB) 216 | UpdateTextureImage(); 217 | 218 | //update Depth data 219 | if (useDepth) 220 | UpdateDepth(); 221 | } 222 | } 223 | 224 | 225 | //update RGB texture 226 | private void UpdateTextureImage() { 227 | 228 | int size = 0; 229 | 230 | //copy pixel data from unmanaged memory 231 | IntPtr ptr = KinectWrapper.GetTextureImage(ref size); 232 | 233 | if (ptr != IntPtr.Zero) 234 | { 235 | Marshal.Copy(ptr, seqTex, 0, size); 236 | Debug.Log(size.ToString()); 237 | 238 | //create color matrix 239 | for (int i = 0; i < (IM_W * IM_H * 4); i += 4) 240 | { 241 | cols[(IM_W * IM_H) - (i / 4) - 1] = new Color32(seqTex[i + 2], seqTex[i + 1], seqTex[i], 255); 242 | } 243 | 244 | //set texture 245 | texture.SetPixels32(cols); 246 | texture.Apply(); 247 | } 248 | } 249 | 250 | 251 | //update Depth array and texture 252 | private void UpdateDepth() { 253 | 254 | int size = 0; 255 | 256 | //copy pixel data from unmanaged memory 257 | IntPtr ptr = KinectWrapper.GetDepthImage(ref size); 258 | 259 | if (ptr != IntPtr.Zero) 260 | { 261 | Marshal.Copy(ptr, seqDepth, 0, size); 262 | 263 | //create depth array 264 | for (int x = 0; x < IM_W; x++) 265 | { 266 | for (int y = 0; y < IM_H; y++) 267 | { 268 | depth[IM_W - x - 1][IM_H - y - 1] = BitConverter.ToInt16(seqDepth, (x*2)+(y*IM_W*2)); 269 | } 270 | } 271 | 272 | if (displayDepthImage) 273 | { 274 | //create color matrix as bytes (loops resolution) 275 | for (int x = 0; x < IM_W; x++) 276 | { 277 | for (int y = 0; y < IM_H; y++) 278 | { 279 | dcols[x + (y * IM_W)] = new Color32((byte)depth[x][y], (byte)depth[x][y], (byte)depth[x][y], 255); 280 | } 281 | } 282 | 283 | //set texture 284 | depthImg.SetPixels32(dcols); 285 | depthImg.Apply(); 286 | } 287 | } 288 | } 289 | 290 | 291 | //update function for GUI (if enabled) 292 | private void OnGUI() { 293 | 294 | if (displayJointInformation && NUIisReady) { 295 | //display joint info in upper-left corner 296 | if (twoPlayer) { 297 | for (int i = 0; i < (int)KinectWrapper.Joints.COUNT; i++) { 298 | DisplayPlayerData(1, i); 299 | DisplayPlayerData(2, i); 300 | } 301 | } else { 302 | for (int i = 0; i < (int)KinectWrapper.Joints.COUNT; i++) { 303 | DisplayPlayerData(1, i); 304 | } 305 | } 306 | } 307 | 308 | if (displayTextureImage && useRGB && NUIisReady) { 309 | //scaled to half-res 310 | GUI.DrawTexture(new Rect(600, 50, IM_W / 2, IM_H / 2), texture, ScaleMode.ScaleToFit, false); 311 | } 312 | 313 | if (displayDepthImage && useDepth && NUIisReady) { 314 | //scaled to half-res 315 | GUI.DrawTexture(new Rect(600, 300, IM_W / 2, IM_H / 2), depthImg, ScaleMode.ScaleToFit, false); 316 | } 317 | } 318 | 319 | 320 | //displays joint position data in GUI (if enabled) 321 | private void DisplayPlayerData(int player, int place) { 322 | 323 | Vector3 joint = GetJointPos(player, (KinectWrapper.Joints)place); 324 | 325 | GUI.Label(new Rect((player - 1) * 300, place * 30, 200, 30), joint.ToString()); 326 | } 327 | } 328 | 329 | 330 | //------------------------------------------------------------------------------------------------ 331 | //------------------------------------------------------------------------------------------------ 332 | 333 | /// 334 | /// KUInterface.dll wrapper 335 | /// 336 | public class KinectWrapper { 337 | 338 | /// 339 | /// defines Kinect skeleton 340 | /// 341 | public enum Joints { 342 | HIP_CENTER = 0, 343 | SPINE, 344 | SHOULDER_CENTER, 345 | HEAD, 346 | SHOULDER_LEFT, 347 | ELBOW_LEFT, 348 | WRIST_LEFT, 349 | HAND_LEFT, 350 | SHOULDER_RIGHT, 351 | ELBOW_RIGHT, 352 | WRIST_RIGHT, 353 | HAND_RIGHT, 354 | HIP_LEFT, 355 | KNEE_LEFT, 356 | ANKLE_LEFT, 357 | FOOT_LEFT, 358 | HIP_RIGHT, 359 | KNEE_RIGHT, 360 | ANKLE_RIGHT, 361 | FOOT_RIGHT, 362 | COUNT 363 | }; 364 | 365 | 366 | [StructLayout(LayoutKind.Sequential)] 367 | public struct SkeletonTransform { 368 | 369 | public float x, y, z, w; 370 | } 371 | 372 | 373 | //NUI Context Management 374 | [DllImport("/Assets/Plugins/KUInterface.dll")] 375 | public static extern bool NuiContextInit(bool twoPlayer); 376 | [DllImport("/Assets/Plugins/KUInterface.dll")] 377 | public static extern void NuiUpdate(); 378 | [DllImport("/Assets/Plugins/KUInterface.dll")] 379 | public static extern void NuiContextUnInit(); 380 | //Get Methods 381 | [DllImport("/Assets/Plugins/KUInterface.dll")] 382 | public static extern void GetSkeletonTransform(int player, int joint, ref SkeletonTransform trans); 383 | [DllImport("/Assets/Plugins/KUInterface.dll")] 384 | public static extern IntPtr GetTextureImage(ref int size); 385 | [DllImport("/Assets/Plugins/KUInterface.dll")] 386 | public static extern IntPtr GetDepthImage(ref int size); 387 | [DllImport("/Assets/Plugins/KUInterface.dll")] 388 | public static extern void GetCameraAngle(ref float angle); 389 | //Set Methods 390 | [DllImport("/Assets/Plugins/KUInterface.dll")] 391 | public static extern bool SetCameraAngle(int angle); 392 | } -------------------------------------------------------------------------------- /KUInterface.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adevine1618/KinectSDK-Unity3D_Interface_Plugin/160ceb6a494dbcc0853c32894967d388379de33d/KUInterface.dll -------------------------------------------------------------------------------- /KUInterface.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adevine1618/KinectSDK-Unity3D_Interface_Plugin/160ceb6a494dbcc0853c32894967d388379de33d/KUInterface.zip -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | *********************************README********************************* 2 | 3 | KinectSDK / Unity3D Interface 4 | 5 | 6 | Andrew DeVine 7 | 8 | ************************************************************************ 9 | 10 | Thanks for downloading! 11 | 12 | The Microsoft Kinect SDK v.1.7 is required for this dll: 13 | 14 | http://www.microsoft.com/en-us/kinectforwindows/develop/developer-downloads.aspx 15 | 16 | Changes (08/16/13): 17 | - DLL LOCATION HAS CHANGED TO ASSETS/PLUGINS 18 | - Initialization routine now starts first connected sensor found. 19 | - Depth Stream is now correct. The depth stream is actually of type 'short'. 20 | However, Color32 object requires bytes. Therefore, the displayed depth 21 | image is 'looped' over intensities, in order to not lose resolution. 22 | - There still seems to be a problem with editing scripts, then returning 23 | to the Unity window and having it crash on play. I'm investigating this. 24 | 25 | Since there still seems to be a demand for this, I've revisited it. 26 | If you're still getting a 'DLL not found' error after following the setup 27 | instructions, make sure the Environment Variable 'KINECTSDK10_DIR' is set 28 | to...you guessed it...the Kinect SDK dir. 29 | 30 | This hasn't been rigorously tested, so the source is also on Github. 31 | You'll probably have to change the build directory. 32 | 33 | 34 | ************************************************************************ 35 | SETUP 36 | ************************************************************************ 37 | 38 | copy KUInterface.dll to Assets/Plugins 39 | 40 | import the C# file into your game, and attach it to a game object. 41 | 42 | use the C# functions as you would any other script in Unity. 43 | 44 | 45 | ************************************************************************ 46 | USE 47 | ************************************************************************ 48 | 49 | PUBLIC SETTINGS: 50 | 51 | scaleFactor: scales all joint positions by this number. Do not set to zero. 52 | 53 | twoPlayer: set to true to track the maximum of two skeletons. Do not change 54 | value while in play. 55 | 56 | useRGB: update RGB feed every frame. Set to false if not being used to 57 | optimize performance. Do not change value while in play. 58 | 59 | useDepth: update depth feed every frame. Set to false if not being used to 60 | optimize performance. Do not change value while in play. 61 | 62 | displayJointInformation: for visualization of data. 63 | 64 | diplayTextureImage: renders RGB feed on-screen. 65 | 66 | displayDepthImage: renders depth feed on-screen as reverse-intensity image. 67 | 68 | 69 | NUI: 70 | 71 | - Call GetJointPos(KinectWrapper.Joints joint) to retrieve the given 72 | joint's current position as a Vector3 object. 73 | 74 | - Call the override GetJointPos(int player, KinectWrapper.Joints joint) 75 | for player = 1,2 to use two-player mode. The Microsoft Kinect SDK supports 76 | a maximum of two players with fully recognized skeletons. To use this, 77 | field 'twoPlayer' must be set to 'True'. 78 | 79 | 80 | IMAGE STREAMS: 81 | 82 | - Call GetTextureImage() to get the RGB camera's current output as a 83 | Texture2D object. 84 | 85 | - Call GetDepthData() to return the pixel depths as a short[][] array. The 86 | coordinate depth[x=0][y=0] corresponds to the top-left corner of the depth 87 | camera's viewport. 88 | 89 | 90 | CAMERA: 91 | 92 | - Call GetCameraAngle() to get the Kinect Camera's current angle from the 93 | horizontal as a float. 94 | 95 | - Call SetCameraAngle(int angle) to set the Kinect Camera's angle from the 96 | horizontal. Do not change the camera angle more than once every 30 seconds, 97 | as this may damage the motor (A provision to prevent this already exists, 98 | do not remove this code). The camera is capable of -27 deg. to 27 deg. 99 | 100 | 101 | ************************************************************************ 102 | Aug 2013 103 | 104 | Questions? email: andrew@ardevine.com 105 | ************************************************************************ --------------------------------------------------------------------------------