LookingGlass欲しいけど高い!!
openCVとかで頭の位置を取得して、自分の立ち位置でカメラを動かせたら
擬似的なLookingGlassできないかなーと思っていた。
https://t.co/vK2b9y6xYq
こんな感じですね!
この映像、割と最近発表されてた気がするのに、もう12年も前なのか・・・— yusukeyusuke (@yusukeyusuke) March 13, 2019
10年以上前に既にあった。
で、最近かなりお世話になっているよしなが先生のサイトからリンク先を漁りました。
https://speakerdeck.com/takashiyoshinaga/kinectwoyong-itahetudotoratukingu
基本的にはUnityのKinectSDKを入れて
Cameraに「KinectManager」スクリプトをアタッチ。
Kinectの取得した頭情報=カメラの動きにするスクリプトをひとつ作るだけで出来る。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HeadGetScript : MonoBehaviour{ void Update() { KinectManager kinect = KinectManager.Instance; if(kinect != null){ uint playerID = kinect.GetPlayer1ID(); if(playerID > 0){//人が認識されていれば Vector3 head = kinect.GetJointPosition(playerID,3);//3は頭 head.Set(head.x, head.y , -head.z);//Z位置だけ反転させる Camera.main.transform.position=head; } } } }
このスクリプトをカメラにアタッチすればOK
ただし、綺麗に見せるためにはカメラや描画を座標変換する必要がある
https://docs.unity3d.com/ja/current/ScriptReference/Matrix4x4.html
サイン・・コサイン・・変換行列・・・(´A`)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HeadGetScript : MonoBehaviour{ public float halfWidth = 0.3f * 0.5f;//モニターの物理的な幅 public float halfHeight = 0.32f * 0.5f;//モニターの物理的な高さ [Range(0, 1)] public float KinectPosition_Y;//キネクトの置いている高さ public Camera targetcamera; void Update(){ KinectManager kinect = KinectManager.Instance; if(kinect != null){ uint playerID = kinect.GetPlayer1ID(); if(playerID > 0){//人が認識されていれば Debug.Log("認識"); Vector3 head = kinect.GetJointPosition(playerID,3);//3は頭 head.Set(head.x, head.y - KinectPosition_Y, -head.z);//Yはキネクトの高さ分位置を減らす、Z位置だけ反転させる targetcamera.transform.position=head; Matrix4x4 m = PerspectiveOffCenter( -halfWidth - head.x, halfWidth - head.x,//left,right -halfHeight - head.y, halfHeight - head.y,//bottom,top -head.z, -head.z + 1//near, far(スクリーンはz=0にあるため頭との距離がnear) ); targetcamera.projectionMatrix = m;//結果をカメラに反映 } } } //CG座標を描画座標に変換 Matrix4x4 PerspectiveOffCenter(float left, float right, float bottom, float top, float near , float far){ float x = 2 * near / (right -left); float y = 2 * near / (top - bottom); float a = (right + left) / (right - left); float b = (top + bottom) / (top - bottom); float c = -(far + near)/(far - near); float d = -(2 * far * near) / (far - near); float e = -1; Matrix4x4 m = new Matrix4x4(); m[0,0] = x; m[0,1] = 0; m[0,2] = a; m[0,3] = 0; m[1,0] = 0; m[1,1] = y; m[1,2] = b; m[1,3] = 0; m[2,0] = 0; m[2,1] = 0; m[2,2] = c; m[2,3] = d; m[3,0] = 0; m[3,1] = 0; m[3,2] = e; m[3,3] = 0; return m; } }
プロパティ側で色々いじれるように修正して
前回つくったleapmotionに組み込みます。
kinect使っての位置情報トラッキングできた! pic.twitter.com/g9s64QiLM0
— シロフード@るきはく参加 (@sirohood_exp) March 23, 2019
ついでにカメラ(自分)を見るようにするために
「Head Look Controller」という便利なアセットを入れました。
https://assetstore.unity.com/packages/tools/animation/head-look-controller-4
参考:http://gryith.com/oculus_unity_hlc/
参考:上半身だけうごかす
Head Look Controllerスクリプトはターゲットの座標を追うようになっているため
ターゲットを指定できるように修正してキャラクターにアタッチするだけ。
モデルによってどこのボーンを割り当てるかが違うのでちょっと迷った。
完成したものがこちら
部屋が汚くてモニターアップぎみ。
大きなモニターだったらハエるかもしれない。
サイズ的にazure Kinectとかrealsenceで位置情報取って
ミニプロジェクターで両面投影して
leapmotionで触れるならGateBox超えるな。— シロフード@るきはく参加 (@sirohood_exp) March 23, 2019
realsenceの あの小型感好きだからkinectから乗り換えたい欲。
※コメントは承認後に表示されます。
コメントを公開されたくない場合、名前の後に「:非公開」とつけてください。