using System; using System.Runtime.InteropServices; using Iisu; using MathNet.Numerics.LinearAlgebra.Single; namespace bbiwarg { class IIsuDataSource: IVideoDataSource { private IHandle handle; private IDevice device; private string moviePath; bool active; // parameters private IParameterHandle frameRate; // data private IDataHandle[] handOpen = new IDataHandle[2]; private IDataHandle[] palmPositions3D = new IDataHandle[2]; private IDataHandle[] tipPositions3D = new IDataHandle[2]; private IDataHandle[] forearmPositions3D = new IDataHandle[2]; private IDataHandle[] palmNormals3D = new IDataHandle[2]; private IDataHandle[] fingerStatus = new IDataHandle[2]; private IDataHandle[] fingerTipPositions3D = new IDataHandle[2]; private IDataHandle[] handSides = new IDataHandle[2]; private IDataHandle depthImage; /* * Creates an Iisu data source. * params: * moviePath: path to movie to be used as source * if empty the camera is used */ public IIsuDataSource(string moviePath = "") { this.moviePath = moviePath; active = false; } public void init() { handle = Iisu.Iisu.Context.CreateHandle(); IDeviceConfiguration conf = handle.CreateDeviceConfiguration(); if (moviePath.Length != 0) conf.MoviePath = moviePath; device = handle.InitializeDevice(conf); // parameters device.RegisterParameterHandle("SOURCE.MOVIE.PlayMode").Value = 0; // playMode = once frameRate = device.RegisterParameterHandle("SOURCE.FrameRate"); // events device.EventManager.RegisterEventListener("DEVICE.Status", new Iisu.EventDelegates.Device.Status(onDeviceStatusChanged)); // data depthImage = device.RegisterDataHandle("SOURCE.CAMERA.DEPTH.Image"); handOpen[0] = device.RegisterDataHandle("CI.HAND1.IsOpen"); handOpen[1] = device.RegisterDataHandle("CI.HAND2.IsOpen"); palmPositions3D[0] = device.RegisterDataHandle("CI.HAND1.PalmPosition3D"); palmPositions3D[1] = device.RegisterDataHandle("CI.HAND2.PalmPosition3D"); tipPositions3D[0] = device.RegisterDataHandle("CI.HAND1.TipPosition3D"); tipPositions3D[1] = device.RegisterDataHandle("CI.HAND2.TipPosition3D"); forearmPositions3D[0] = device.RegisterDataHandle("CI.HAND1.ForearmPosition3D"); forearmPositions3D[1] = device.RegisterDataHandle("CI.HAND2.ForearmPosition3D"); palmNormals3D[0] = device.RegisterDataHandle("CI.HAND1.PalmNormal3D"); palmNormals3D[1] = device.RegisterDataHandle("CI.HAND2.PalmNormal3D"); fingerStatus[0] = device.RegisterDataHandle("CI.HAND1.FingerStatus"); fingerStatus[1] = device.RegisterDataHandle("CI.HAND2.FingerStatus"); fingerTipPositions3D[0] = device.RegisterDataHandle("CI.HAND1.FingerTipPositions3D"); fingerTipPositions3D[1] = device.RegisterDataHandle("CI.HAND2.FingerTipPositions3D"); handSides[0] = device.RegisterDataHandle("CI.HAND1.Side"); handSides[1] = device.RegisterDataHandle("CI.HAND1.Side"); } private void onDeviceStatusChanged(string eventName, DeviceStatus status) { active = status.HasFlag(Iisu.DeviceStatus.Playing); } public void start() { device.Start(); } public void stop() { device.Stop(true); } public void updateFrame() { device.UpdateFrame(true); } public void releaseFrame() { device.ReleaseFrame(); } public bool isActive() { return active; } public int getFrameRate() { return (int) frameRate.Value; } public DepthImage getDepthImage() { Iisu.Data.IImageInfos imageInfos = depthImage.Value.ImageInfos; int width = (int) imageInfos.Width; int height = (int) imageInfos.Height; int numBytes = (int) imageInfos.BytesRaw; IntPtr imageData = depthImage.Value.Raw; short[] tmp = new short[width * height]; Marshal.Copy(imageData, tmp, 0, width * height); ushort[] data = new ushort[width * height]; Buffer.BlockCopy(tmp, 0, data, 0, numBytes); return new DepthImage(width, height, data); } private void checkHandIndex(uint handIndex) { if (handIndex < 1 || handIndex > 2) throw new ArgumentOutOfRangeException("handIndex is out of range [0,1]"); } public bool isHandOpen(uint handIndex) { checkHandIndex(handIndex); return handOpen[handIndex - 1].Value; } public Vector getPalmPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(palmPositions3D[handIndex - 1].Value.ToArray()); } public Vector getTipPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(tipPositions3D[handIndex - 1].Value.ToArray()); } public Vector getForearmPosition3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(forearmPositions3D[handIndex - 1].Value.ToArray()); } public Vector getPalmNormal3D(uint handIndex) { checkHandIndex(handIndex); return new DenseVector(palmNormals3D[handIndex - 1].Value.ToArray()); } public FingerStatus[] getFingerStatus(uint handIndex) { checkHandIndex(handIndex); int[] status = fingerStatus[handIndex - 1].Value; FingerStatus[] result = new FingerStatus[status.Length]; for (int i = 0; i < status.Length; ++i) { switch (status[i]) { case 0: result[i] = FingerStatus.Inactive; break; case 1: result[i] = FingerStatus.Detected; break; case 2: result[i] = FingerStatus.Tracked; break; } } return result; } public Vector[] getFingerTipPositions3D(uint handIndex) { checkHandIndex(handIndex); Iisu.Data.Vector3[] positions = fingerTipPositions3D[handIndex - 1].Value; Vector[] results = new DenseVector[positions.Length]; for (int i = 0; i < positions.Length; ++i) results[i] = new DenseVector(positions[i].ToArray()); return results; } public HandSide getHandSide(uint handIndex) { checkHandIndex(handIndex); int side = handSides[handIndex - 1].Value; switch (side) { case 1: return HandSide.Left; case 2: return HandSide.Right; default: return HandSide.Unknown; } } } }