色々怪しい所が見え始めてくるRealSenseのHandModuleですが、
新しい情報はあまり公開されてないようなので、一例と思い、タイトル通りの記事を投稿します。
意外とすんなり動いてくれた上に、結構まともに動いてます。まぁ、出来てる事がほぼLeapMotionなんですけどね。ただ、カメラ配置的に私の用途としてはRealSenseの思想が理想なのです。 pic.twitter.com/6H0SB5DIiO
— 琴葉 葵(偽) (@Hv2RMjHzDyqXVIr) 2017年6月4日
Version
Unity:5.6.1f1 Personal
RealSenseSDK:2016 R3
Device:SR300
動かし方
空のシーンを作ってカメラに下のコードをコピペして作ったスクリプトをアタッチするだけです。
using System;
using System.Collections.Generic;
using UnityEngine;
using Intel.RealSense;
using Intel.RealSense.Hand;
public class HandTest : MonoBehaviour
{
SenseManager SenseM;
HandModule HandM;
HandData HandD;
List<GameObject> PointsL = new List<GameObject>();
List<GameObject> PointsR = new List<GameObject>();
List<JointData> JointsL = new List<JointData>();
List<JointData> JointsR = new List<JointData>();
float SphereSize = 0.03f;
void Start()
{
int n = Enum.GetNames(typeof(JointType)).Length;
for (int i = 0; i < n; i++)
{
var goL = GameObject.CreatePrimitive(PrimitiveType.Sphere);
var goR = GameObject.CreatePrimitive(PrimitiveType.Sphere);
goL.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);
goR.transform.localScale = new Vector3(SphereSize, SphereSize, SphereSize);
PointsL.Add(goL);
PointsR.Add(goR);
JointsL.Add(new JointData());
JointsR.Add(new JointData());
}
SenseM = SenseManager.CreateInstance();
HandM = HandModule.Activate(SenseM);
HandM.FrameProcessed += Hand_FrameProcessed;
HandD = HandM.CreateOutput();
SenseM.Init();
SenseM.StreamFrames(false);
}
private void Hand_FrameProcessed(object sender, FrameProcessedEventArgs args)
{
HandD.Update();
IHand[] hand;
if (HandD.QueryHandData(AccessOrderType.ACCESS_ORDER_BY_ID, out hand) == Status.STATUS_NO_ERROR)
{
foreach (IHand h in hand)
{
int n = Enum.GetNames(typeof(JointType)).Length;
if (h.BodySide == BodySideType.BODY_SIDE_LEFT)
{
for (int i = 0; i < n; i++)
{
var jt = (JointType)Enum.ToObject(typeof(JointType), i);
JointsL[i] = h.TrackedJoints[jt];
}
}
if (h.BodySide == BodySideType.BODY_SIDE_RIGHT)
{
for (int i = 0; i < n; i++)
{
var jt = (JointType)Enum.ToObject(typeof(JointType), i);
JointsR[i] = h.TrackedJoints[jt];
}
}
}
}
}
void Update()
{
int n = Enum.GetNames(typeof(JointType)).Length;
for (int i = 0; i < n; i++)
{
PointsL[i].transform.position = JointsL[i].positionWorld;
PointsR[i].transform.position = JointsR[i].positionWorld;
}
}
void OnDestroy()
{
HandM.FrameProcessed -= Hand_FrameProcessed;
HandD.Dispose();
SenseM.Dispose();
}
}
※怪しいポイント※
・MIRROR_MODE_HORIZONTALを適用すると認識がおかしくなる。
・TRACKING_MODE_FULL_HANDを適用しなくても何故か動いてしまう。
・HandConfigurationの値をデバッガで見ても信用ならない。