soundvision/UnityProject/Assets/Scripts/Kinect/KinectManagerBehaviour.cs

179 lines
6.3 KiB
C#
Raw Normal View History

using System;
using System.IO;
2019-11-03 12:29:35 +00:00
using System.Linq;
using Windows.Kinect;
using UnityEngine;
using UnityEngine.Events;
2019-07-07 07:39:46 +00:00
2019-10-31 09:43:47 +00:00
namespace cylvester
2019-07-07 07:39:46 +00:00
{
2019-11-13 20:15:25 +00:00
[Serializable] public class UnityDepthCameraEvent : UnityEvent<Texture2D>{ }
2019-11-03 12:29:35 +00:00
[Serializable] public class UnitySkeletonEvent : UnityEvent<Body, int>{ }
public class KinectManagerBehaviour : MonoBehaviour
2019-07-07 07:39:46 +00:00
{
2019-11-13 20:15:25 +00:00
[SerializeField] private bool depth;
[SerializeField] public UnityDepthCameraEvent depthFrameReceived;
[SerializeField] private bool skeleton;
2019-10-31 17:38:58 +00:00
[SerializeField] public UnitySkeletonEvent skeletonDataReceived;
2019-11-03 12:29:35 +00:00
[SerializeField, Range(1, 6)] private int numberOfBodiesTobeTracked = 2;
private KinectSensor sensor_;
2019-11-13 20:15:25 +00:00
private DepthFrameReader depthFrameReader_;
private BodyFrameReader bodyFrameReader_;
2019-11-03 12:29:35 +00:00
private BodyIndexFrameReader bodyIndexFrameReader_;
2019-11-13 20:15:25 +00:00
private ushort [] depthData_;
private Texture2D depthTexture_;
//QUICK CODE FROM FRIEDRICH - SORRY FOR EVERYTHING!!!
//private byte[] depthData8bit_;
//private Texture2D depthTexture8bit_;
//public ushort front;
//public ushort back;
//FK CODE ENDS
2019-10-31 17:38:58 +00:00
private Body[] bodies_;
2019-11-13 20:15:25 +00:00
private EventHandler<DepthFrameArrivedEventArgs> onDepthFrameArrived_;
2019-11-03 12:29:35 +00:00
private EventHandler<BodyFrameArrivedEventArgs> onBodyFrameArrived_;
private EventHandler<BodyIndexFrameArrivedEventArgs> onBodyIndexFrameArrived_;
2019-11-03 14:19:11 +00:00
private BodyHolder trackedBodies_;
private void Start()
{
sensor_ = KinectSensor.GetDefault();
if (sensor_ == null)
throw new IOException("cannot find Kinect Sensor ");
2019-11-13 20:15:25 +00:00
InitDepthCamera();
InitSkeletonTracking();
2019-11-03 12:29:35 +00:00
if (!sensor_.IsOpen)
2019-11-03 12:29:35 +00:00
{
sensor_.Open();
2019-11-03 12:29:35 +00:00
}
}
2019-11-13 20:15:25 +00:00
private void InitDepthCamera()
{
2019-11-13 20:15:25 +00:00
depthFrameReader_ = sensor_.DepthFrameSource.OpenReader();
var frameDesc = sensor_.DepthFrameSource.FrameDescription;
depthData_ = new ushort[frameDesc.LengthInPixels];
depthTexture_ = new Texture2D(frameDesc.Width, frameDesc.Height, TextureFormat.R16, false);
//FRIEDRICH QUICK CODE FROM HERE
//depthData8bit_ = new byte[frameDesc.LengthInPixels];
//depthTexture8bit_ = new Texture2D(frameDesc.Width, frameDesc.Height, TextureFormat.Alpha8, false);
//END FRIEDRICH
2019-11-13 20:15:25 +00:00
onDepthFrameArrived_ = (frameReader, eventArgs) =>
{
2019-11-13 20:15:25 +00:00
if(!depth)
return;
2019-11-13 20:15:25 +00:00
using (var depthFrame = eventArgs.FrameReference.AcquireFrame())
{
2019-11-13 20:15:25 +00:00
if (depthFrame == null)
2019-10-31 20:08:01 +00:00
return;
2019-11-13 20:15:25 +00:00
depthFrame.CopyFrameDataToArray(depthData_);
unsafe
{
2019-11-13 20:15:25 +00:00
fixed (ushort* irDataPtr = depthData_)
{
2019-11-13 20:15:25 +00:00
depthTexture_.LoadRawTextureData((IntPtr) irDataPtr, sizeof(ushort) * depthData_.Length);
}
}
//SUPER DUPER QUICK FRIEDRICH CODE
//float distanceFrontBack = back - front;
//calculation should be:
//result = incoming data - front
//result = result * 255/distanceFrontBack
//for (int i = 0; i < depthData_.Length; i++)
//{
// float value = (float)(depthData_[i] - front);
// value = value * 255.0f / distanceFrontBack;
// depthData8bit_[i] = Convert.ToByte(value);
//}
//depthTexture8bit_.Apply();
//END SUPER QUICK FRIEDRICH CODE
2019-11-13 20:15:25 +00:00
depthTexture_.Apply();
}
2019-11-13 20:15:25 +00:00
depthFrameReceived.Invoke(depthTexture_);
2019-10-31 17:38:58 +00:00
};
2019-11-13 20:15:25 +00:00
depthFrameReader_.FrameArrived += onDepthFrameArrived_;
}
private void InitSkeletonTracking()
2019-07-07 07:39:46 +00:00
{
2019-11-03 12:29:35 +00:00
bodies_ = new Body[6];
2019-11-03 14:19:11 +00:00
trackedBodies_ = new BodyHolder(numberOfBodiesTobeTracked);
2019-11-03 12:29:35 +00:00
InitBodyFrameReader();
}
2019-11-03 12:29:35 +00:00
private void InitBodyFrameReader()
{
bodyFrameReader_ = sensor_.BodyFrameSource.OpenReader();
2019-11-03 12:29:35 +00:00
onBodyFrameArrived_ = (frameReader, eventArgs) =>
{
if(!skeleton)
return;
2019-10-31 17:38:58 +00:00
using (var bodyFrame = eventArgs.FrameReference.AcquireFrame())
{
2019-10-31 20:08:01 +00:00
if (bodyFrame == null)
return;
2019-11-03 12:29:35 +00:00
2019-10-31 17:38:58 +00:00
bodyFrame.GetAndRefreshBodyData(bodies_);
2019-11-03 14:19:11 +00:00
foreach (var body in bodies_.Where(t => t.IsTracked))
2019-11-03 12:29:35 +00:00
{
2019-11-03 14:19:11 +00:00
if (body.IsTracked)
2019-11-03 12:29:35 +00:00
{
2019-11-03 14:19:11 +00:00
if (trackedBodies_.Exist(body))
2019-11-03 12:29:35 +00:00
{
2019-11-03 14:19:11 +00:00
var idNumber = trackedBodies_.IndexOf(body);
if (idNumber.HasValue)
2019-11-03 12:29:35 +00:00
skeletonDataReceived.Invoke(body, idNumber.Value);
}
2019-11-03 14:19:11 +00:00
else
{
if (trackedBodies_.Add(body))
{
var idNumber = trackedBodies_.IndexOf(body);
if (idNumber.HasValue)
skeletonDataReceived.Invoke(body, idNumber.Value);
}
}
2019-11-03 12:29:35 +00:00
}
}
2019-11-03 14:19:11 +00:00
foreach (var body in bodies_.Where(t => !t.IsTracked && trackedBodies_.Exist(t)))
{
trackedBodies_.Remove(body);
}
}
};
2019-11-03 12:29:35 +00:00
bodyFrameReader_.FrameArrived += onBodyFrameArrived_;
2019-07-07 07:39:46 +00:00
}
2019-11-03 12:29:35 +00:00
private void OnDestroy()
2019-07-07 07:39:46 +00:00
{
2019-11-13 20:15:25 +00:00
depthFrameReader_.FrameArrived -= onDepthFrameArrived_;
2019-11-03 12:29:35 +00:00
bodyFrameReader_.FrameArrived -= onBodyFrameArrived_;
2019-07-07 07:39:46 +00:00
}
}
}