/* * Copyright (c) 2017 Yoshihisa Nitta * Released under the MIT license * http://opensource.org/licenses/mit-license.php */ /* * NtUnity.cs version 1.0.2 2017/08/25 * http://nw.tsuda.ac.jp/NtKinectDLL/ * * requires: * NtKinectDLL version 1.2.1 or later */ using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Runtime.InteropServices; namespace NtUnity { public class Kinect { public const int // Number bodyCount = 6, jointCount = 25, rgbCols = 1920, rgbRows = 1080, depthCols = 512, depthRows = 424, // JointType JointType_SpineBase= 0, JointType_SpineMid= 1, JointType_Neck= 2, JointType_Head= 3, JointType_ShoulderLeft= 4, JointType_ElbowLeft= 5, JointType_WristLeft= 6, JointType_HandLeft= 7, JointType_ShoulderRight= 8, JointType_ElbowRight= 9, JointType_WristRight= 10, JointType_HandRight= 11, JointType_HipLeft= 12, JointType_KneeLeft= 13, JointType_AnkleLeft= 14, JointType_FootLeft= 15, JointType_HipRight= 16, JointType_KneeRight= 17, JointType_AnkleRight= 18, JointType_FootRight= 19, JointType_SpineShoulder= 20, JointType_HandTipLeft= 21, JointType_ThumbLeft= 22, JointType_HandTipRight= 23, JointType_ThumbRight= 24, // TrackingState TrackingState_NotTracked= 0, TrackingState_Inferred= 1, TrackingState_Tracked= 2, // FacePoint FacePointType_None= -1, FacePointType_EyeLeft= 0, FacePointType_EyeRight= 1, FacePointType_Nose= 2, FacePointType_MouthCornerLeft= 3, FacePointType_MouthCornerRight= 4, FacePointType_Count= ( FacePointType_MouthCornerRight + 1 ) , // a_FaceProperty FaceProperty_Happy= 0, FaceProperty_Engaged= 1, FaceProperty_WearingGlasses= 2, FaceProperty_LeftEyeClosed= 3, FaceProperty_RightEyeClosed= 4, FaceProperty_MouthOpen= 5, FaceProperty_MouthMoved= 6, FaceProperty_LookingAway= 7, FaceProperty_Count= ( FaceProperty_LookingAway + 1 ) , // FaceDetectionResult DetectionResult_Unknown= 0, DetectionResult_No= 1, DetectionResult_Maybe= 2, DetectionResult_Yes= 3, // HDFace HDFaceVerticesSize = 1347, // dummy NtKinectdummy = 0; [DllImport ("NtKinectDLL")] private static extern IntPtr getKinect(); [DllImport ("NtKinectDLL")] private static extern void stopKinect(IntPtr ptr); // OpenCV [DllImport ("NtKinectDLL")] private static extern void imshow(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern void imshowBlack(IntPtr ptr); // CoordinateMapper [DllImport ("NtKinectDLL")] private static extern void mapCameraPointToColorSpace(IntPtr ptr,IntPtr sv,IntPtr cv,int n); [DllImport ("NtKinectDLL")] private static extern void mapCameraPointToDepthSpace(IntPtr ptr,IntPtr sv,IntPtr dv,int n); [DllImport ("NtKinectDLL")] private static extern void mapDepthPointToColorSpace(IntPtr ptr,IntPtr dv,IntPtr dth,IntPtr cv,int n); [DllImport ("NtKinectDLL")] private static extern void mapDepthPointToCameraSpace(IntPtr ptr,IntPtr dv,IntPtr dth,IntPtr sv,int n); // Multi Thread [DllImport ("NtKinectDLL")] private static extern void acquire(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern void release(IntPtr ptr); // Audio [DllImport ("NtKinectDLL")] private static extern void setAudio(IntPtr ptr, bool flag); [DllImport ("NtKinectDLL")] private static extern float getBeamAngle(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern float getBeamAngleConfidence(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern ulong getAudioTrackingId(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern void openAudio(IntPtr ptr, IntPtr filename); [DllImport ("NtKinectDLL")] private static extern void closeAudio(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern bool isOpenedAudio(IntPtr ptr); // RGB [DllImport ("NtKinectDLL")] private static extern void setRGB(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getRGB(IntPtr ptr, IntPtr data); // Depth [DllImport ("NtKinectDLL")] private static extern void setDepth(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getDepth(IntPtr ptr, IntPtr data); // Infrared [DllImport ("NtKinectDLL")] private static extern void setInfrared(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getInfrared(IntPtr ptr, IntPtr data); // BodyIndex [DllImport ("NtKinectDLL")] private static extern void setBodyIndex(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getBodyIndex(IntPtr ptr, IntPtr data); // Skeleton [DllImport ("NtKinectDLL")] private static extern void setSkeleton(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getSkeleton(IntPtr ptr, IntPtr skelton, IntPtr state, IntPtr id, IntPtr tid); [DllImport ("NtKinectDLL")] private static extern int handState(IntPtr ptr,int id,bool isLeft); // Face [DllImport ("NtKinectDLL")] private static extern void setFace(IntPtr ptr, bool isColorSpace); [DllImport ("NtKinectDLL")] private static extern int getFace(IntPtr ptr, IntPtr point,IntPtr rect,IntPtr direction,IntPtr property,IntPtr tid); // HDFace [DllImport ("NtKinectDLL")] private static extern void setHDFace(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getHDFace(IntPtr ptr, IntPtr point, IntPtr tid, IntPtr status); // Gesture [DllImport ("NtKinectDLL")] private static extern void setGestureFile(IntPtr ptr, IntPtr filename); [DllImport ("NtKinectDLL")] private static extern int setGestureId(IntPtr ptr, IntPtr name, int id); // id: non-zero [DllImport ("NtKinectDLL")] private static extern void setGesture(IntPtr ptr); [DllImport ("NtKinectDLL")] private static extern int getDiscreteGesture(IntPtr ptr, IntPtr gid, IntPtr confidence, IntPtr tid); [DllImport ("NtKinectDLL")] private static extern int getContinuousGesture(IntPtr ptr, IntPtr gid, IntPtr progress, IntPtr tid); [DllImport ("NtKinectDLL")] private static extern int getGidMapSize(); private IntPtr kinect; //public Vector3[] joint = new Vector3[jointCount]; //public int[] jointState = new int[jointCount]; // audio public float beamAngle; public float beamAngleConfidence; public ulong audioTrackingId; // images public Color32[] rgbImage; public ushort[] depthImage; public ushort[] infraredImage; public byte[] bodyIndexImage; // skeleton public List> skeleton; public List> skeletonState; public List skeletonId; public List skeletonTrackingId; // skeleton (internal) private float[] skel; private int[] skelState; private int[] skelId; private ulong[] skelTrackingId; // face public List> facePoint; public List faceRect; public List faceDirection; public List> faceProperty; public List faceTrackingId; // face (internal) private float[] fcPoint; private float[] fcRect; private float[] fcDirection; private int[] fcProperty; private ulong[] fcTrackingId; // hdface public List> hdfacePoint; public List hdfaceTrackingId; public List hdfaceStatus; // hdface (internal) private float[] hdfcPoint; private ulong[] hdfcTrackingId; private int[] hdfcStatus; // gesture public List discreteGesture; public List gestureConfidence; public List discreteGestureTrackingId; public List continuousGesture; public List gestureProgress; public List continuousGestureTrackingId; // gesture (internal) private int[] gstId; private float[] gstFloat; private ulong[] gstTrackingId; public Kinect() { kinect = getKinect(); //rgbImage = new byte[rgbRows * rgbCols * 4]; rgbImage = new Color32[rgbRows * rgbCols]; depthImage = new ushort[depthRows * depthCols]; infraredImage = new ushort[depthRows * depthCols]; bodyIndexImage = new byte[depthRows * depthCols]; skeleton = new List>(); skeletonState = new List>(); skeletonId = new List(); skeletonTrackingId = new List(); skel = new float[bodyCount * jointCount * 3]; skelState = new int[bodyCount * jointCount]; skelId = new int[bodyCount]; skelTrackingId = new ulong[bodyCount]; facePoint = new List>(); faceRect = new List(); faceDirection = new List(); faceProperty = new List>(); faceTrackingId = new List(); fcPoint = new float[bodyCount * FacePointType_Count * 3]; fcRect = new float[bodyCount * 4]; fcDirection = new float[bodyCount * 3]; fcProperty = new int[bodyCount * FaceProperty_Count * 2]; fcTrackingId = new ulong[bodyCount]; hdfacePoint = new List>(); hdfaceTrackingId = new List(); hdfaceStatus = new List(); hdfcPoint = new float[bodyCount * HDFaceVerticesSize * 3]; hdfcTrackingId = new ulong[bodyCount]; hdfcStatus = new int[bodyCount * 2]; discreteGesture = new List(); gestureConfidence = new List(); discreteGestureTrackingId = new List(); continuousGesture = new List(); gestureProgress = new List(); continuousGestureTrackingId = new List(); gstId = new int[bodyCount * 100]; gstFloat = new float[bodyCount * 100]; gstTrackingId = new ulong[bodyCount * 100]; } public void stopKinect() { stopKinect(kinect); } // OpenCV public void imshow() { imshow(kinect); } public void imshowBlack() { imshowBlack(kinect); } // coordinateMapper public void mapCameraPointToColorSpace(List skel,ref List color,int n) { float[] sv = new float[n * 3]; float[] cv = new float[n * 2]; for (int i=0; i skel, ref List depth, int n) { float[] sv = new float[n * 3]; float[] dv = new float[n * 2]; for (int i=0; i depth,ushort[] dth,ref List color,int n) { float[] dv = new float[n * 2]; float[] cv = new float[n * 2]; for (int i=0; i depth,ushort[] dth,ref List skel,int n) { float[] dv = new float[n * 2]; float[] sv = new float[n * 3]; for (int i=0; i()); skeletonState.Add(new List()); for (int j=0; j()); for (int j=0; j()); for (int j=0; j()); for (int j=0; j < HDFaceVerticesSize; j++) { hdfacePoint[i].Add(new Vector3(hdfcPoint[idx++],hdfcPoint[idx++],hdfcPoint[idx++])); } hdfaceTrackingId.Add(hdfcTrackingId[i]); hdfaceStatus.Add(hdfcStatus[i]); } return n; } // Gesture public void setGestureFile(string filename) { IntPtr gbd = Marshal.StringToHGlobalUni(filename); setGestureFile(kinect,gbd); Marshal.FreeHGlobal(gbd); } public int setGestureId(string name, int id) { System.IntPtr g = Marshal.StringToHGlobalUni(name); // discrete int n = setGestureId(kinect,g,id); Marshal.FreeHGlobal(g); return n; } public void setGesture() { setGesture(kinect); } public int getDiscreteGesture() { int size = bodyCount * getGidMapSize(); if (gstId.Length < size) { gstId = new int[size]; gstFloat = new float[size]; gstTrackingId = new ulong[size]; } GCHandle gch = GCHandle.Alloc(gstId,GCHandleType.Pinned); GCHandle gch2 = GCHandle.Alloc(gstFloat,GCHandleType.Pinned); GCHandle gch3 = GCHandle.Alloc(gstTrackingId,GCHandleType.Pinned); int n = getDiscreteGesture(kinect,gch.AddrOfPinnedObject(),gch2.AddrOfPinnedObject(),gch3.AddrOfPinnedObject()); gch.Free(); gch2.Free(); gch3.Free(); discreteGesture.Clear(); gestureConfidence.Clear(); discreteGestureTrackingId.Clear(); for (int i=0; i(); if (animator == null) { Debug.Log("no Animator Component"); return; } Avatar avatar = animator.avatar; if (avatar == null || !avatar.isHuman || !avatar.isValid) { Debug.Log("Avatar is not Humanoid or it is not valid"); return; } isValid = true; savedValue = animator.GetBoneTransform(bone).localRotation; } public void set(float a, float x, float y, float z) { set(Quaternion.AngleAxis(a, new Vector3(x,y,z))); } public void set(Quaternion q) { animator.GetBoneTransform(bone).localRotation = q; savedValue = q; } public void mul(float a, float x, float y, float z) { mul(Quaternion.AngleAxis(a, new Vector3(x,y,z))); } public void mul(Quaternion q) { Transform tr = animator.GetBoneTransform(bone); tr.localRotation = q * tr.localRotation; } public void offset(float a, float x, float y, float z) { offset(Quaternion.AngleAxis(a, new Vector3(x,y,z))); } public void offset(Quaternion q) { animator.GetBoneTransform(bone).localRotation = q * savedValue; } public void changeBone(HumanBodyBones b) { bone = b; savedValue = animator.GetBoneTransform(bone).localRotation; } } class HumanoidSkeleton { private static int[] jointSegment = new int[] { Kinect.JointType_SpineBase, Kinect.JointType_SpineMid, // Spine Kinect.JointType_Neck, Kinect.JointType_Head, // Neck // left Kinect.JointType_ShoulderLeft, Kinect.JointType_ElbowLeft, // LeftUpperArm Kinect.JointType_ElbowLeft, Kinect.JointType_WristLeft, // LeftLowerArm Kinect.JointType_WristLeft, Kinect.JointType_HandLeft, // LeftHand Kinect.JointType_HipLeft, Kinect.JointType_KneeLeft, // LeftUpperLeg Kinect.JointType_KneeLeft, Kinect.JointType_AnkleLeft, // LeftLowerLeg6 Kinect.JointType_AnkleLeft, Kinect.JointType_FootLeft, // LeftFoot // right Kinect.JointType_ShoulderRight, Kinect.JointType_ElbowRight, // RightUpperArm Kinect.JointType_ElbowRight, Kinect.JointType_WristRight, // RightLowerArm Kinect.JointType_WristRight, Kinect.JointType_HandRight, // RightHand Kinect.JointType_HipRight, Kinect.JointType_KneeRight, // RightUpperLeg Kinect.JointType_KneeRight, Kinect.JointType_AnkleRight, // RightLowerLeg Kinect.JointType_AnkleRight, Kinect.JointType_FootRight, // RightFoot }; public Vector3[] joint = new Vector3[Kinect.jointCount]; public int[] jointState = new int[Kinect.jointCount]; Dictionary trackingSegment = null; Dictionary trackingState = null; private static HumanBodyBones[] humanBone = new HumanBodyBones[] { HumanBodyBones.Hips, HumanBodyBones.Spine, HumanBodyBones.UpperChest, HumanBodyBones.Neck, HumanBodyBones.Head, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, }; private static HumanBodyBones[] targetBone = new HumanBodyBones[] { HumanBodyBones.Spine, HumanBodyBones.Neck, HumanBodyBones.LeftUpperArm, HumanBodyBones.LeftLowerArm, HumanBodyBones.LeftHand, HumanBodyBones.LeftUpperLeg, HumanBodyBones.LeftLowerLeg, HumanBodyBones.LeftFoot, HumanBodyBones.RightUpperArm, HumanBodyBones.RightLowerArm, HumanBodyBones.RightHand, HumanBodyBones.RightUpperLeg, HumanBodyBones.RightLowerLeg, HumanBodyBones.RightFoot, }; public GameObject humanoid; private Dictionary rigBone = null; private bool isSavedPosition = false; private Vector3 savedPosition; //private Quaternion savedHumanoidRotation; public HumanoidSkeleton(GameObject h) { humanoid = h; rigBone = new Dictionary(); foreach (HumanBodyBones bone in humanBone) { rigBone[bone] = new RigBone(humanoid,bone); } //savedHumanoidRotation = humanoid.transform.rotation; trackingSegment = new Dictionary(targetBone.Length); trackingState = new Dictionary(targetBone.Length); } private void swapJoint(int a, int b) { Vector3 tmp = joint[a]; joint[a] = joint[b]; joint[b] = tmp; int t = jointState[a]; jointState[a] = jointState[b]; jointState[b] = t; } public void set(Kinect kinect, int n, bool mirrored, bool move) { Vector3 faceDir = kinect.getFaceDirectionByTrackingId(kinect.skeletonTrackingId[n]); if (isSavedPosition == false && kinect.skeletonState[n][Kinect.JointType_SpineBase] != Kinect.TrackingState_NotTracked) { isSavedPosition = true; savedPosition = kinect.skeleton[n][Kinect.JointType_SpineBase]; } for (int i=0; i