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

139 lines
4.9 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
{
[Serializable] public class UnityInfraredCameraEvent : 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
{
[SerializeField] private bool infrared;
[SerializeField] public UnityInfraredCameraEvent infraredFrameReceived;
[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_;
private InfraredFrameReader infraredFrameReader_;
private BodyFrameReader bodyFrameReader_;
2019-11-03 12:29:35 +00:00
private BodyIndexFrameReader bodyIndexFrameReader_;
2019-10-31 17:38:58 +00:00
private ushort [] irData_;
private Texture2D infraredTexture_;
private Body[] bodies_;
private EventHandler<InfraredFrameArrivedEventArgs> onInfraredFrameArrived_;
2019-11-03 12:29:35 +00:00
private EventHandler<BodyFrameArrivedEventArgs> onBodyFrameArrived_;
private EventHandler<BodyIndexFrameArrivedEventArgs> onBodyIndexFrameArrived_;
private Holder<ulong> trackedIds_;
private void Start()
{
sensor_ = KinectSensor.GetDefault();
if (sensor_ == null)
throw new IOException("cannot find Kinect Sensor ");
InitInfraredCamera();
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
}
}
private void InitInfraredCamera()
{
infraredFrameReader_ = sensor_.InfraredFrameSource.OpenReader();
var frameDesc = sensor_.InfraredFrameSource.FrameDescription;
irData_ = new ushort[frameDesc.LengthInPixels];
2019-10-31 17:38:58 +00:00
infraredTexture_ = new Texture2D(frameDesc.Width, frameDesc.Height, TextureFormat.R16, false);
onInfraredFrameArrived_ = (frameReader, eventArgs) =>
{
if(!infrared)
return;
2019-10-31 17:38:58 +00:00
using (var infraredFrame = eventArgs.FrameReference.AcquireFrame())
{
2019-10-31 20:08:01 +00:00
if (infraredFrame == null)
return;
infraredFrame.CopyFrameDataToArray(irData_);
unsafe
{
fixed (ushort* irDataPtr = irData_)
{
2019-10-31 17:38:58 +00:00
infraredTexture_.LoadRawTextureData((IntPtr) irDataPtr, sizeof(ushort) * irData_.Length);
}
}
2019-10-31 17:38:58 +00:00
infraredTexture_.Apply();
}
2019-10-31 17:38:58 +00:00
infraredFrameReceived.Invoke(infraredTexture_);
};
infraredFrameReader_.FrameArrived += onInfraredFrameArrived_;
}
private void InitSkeletonTracking()
2019-07-07 07:39:46 +00:00
{
2019-11-03 12:29:35 +00:00
bodies_ = new Body[6];
trackedIds_ = new Holder<ulong>(numberOfBodiesTobeTracked);
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 12:29:35 +00:00
foreach (var body in bodies_.Where(body => body.IsTracked))
{
if (trackedIds_.Exist(body.TrackingId))
{
var idNumber = trackedIds_.IndexOf(body.TrackingId);
if(idNumber.HasValue)
skeletonDataReceived.Invoke(body, idNumber.Value);
}
else
{
if (trackedIds_.Add(body.TrackingId))
{
var idNumber = trackedIds_.IndexOf(body.TrackingId);
if (idNumber.HasValue)
skeletonDataReceived.Invoke(body, idNumber.Value);
}
}
}
}
};
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
{
infraredFrameReader_.FrameArrived -= onInfraredFrameArrived_;
2019-11-03 12:29:35 +00:00
bodyFrameReader_.FrameArrived -= onBodyFrameArrived_;
2019-07-07 07:39:46 +00:00
}
}
}