OculusGoで擬似的に6DoF(ポジショントラッキング)を実現する方法
OculusGoを擬似的に6DoF(ヘッドトラッキングに加えて、ポジショントラッキングも行う)対応する方法を説明します。
これは座っている状態専用の方法なので、立っている状態で足も動かすとポジショントラッキングは行えません。
OculusGoを購入する前から出来るんじゃないかと思っていた疑似6DoFができた!OculusGoのみで実現してます。 https://t.co/dYWRWz9ybd #OculusGo
— くらげ (@ku__ra__ge) 2018年6月28日
原理としては、座っている人間の視点の位置と向きは腰の関節+首の関節2つからほぼ決まるので、腰の動きをOculusコントローラーで、首の動きをヘッドトラッキングで取得すれば6DoFっぽい挙動が実現できるんじゃないかと考えて実装してみたのがこれになります。
環境: Unity 2018.1.5f1 (64-bit) / OculusUtilities(1.26.0 2018/06/20)
GameObjectのHierarchy構造
こんな感じで空のゲームオブジェクトCameraBase
の子にOVRCameraRig
(カメラ)を配置します。
CameraBase
が「腰の位置」
OVRCameraRig
が「目の位置」
なので、CameraBase
の上の位置にOVRCameraRig
に配置しましょう。
コード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fake6dof : MonoBehaviour {
[SerializeField]
private Transform _rightController = null;
[SerializeField]
private Transform _leftController = null;
private Transform _camera;
private float _cameraHeight;
private Vector3 _cameraOriginalPos;
// Use this for initialization
void Start () {
_camera = GameObject.Find("OVRCameraRig").transform;
_cameraHeight = _camera.localPosition.y;
_cameraOriginalPos = _camera.localPosition;
}
// 現在アクティブな左右のどちらかのコントロールを得る
private Transform GetController() {
var controller = OVRInput.GetActiveController();
return (controller == OVRInput.Controller.RTrackedRemote ? _rightController : _leftController);
}
// Update is called once per frame
void Update () {
// コントローラーを押している間は、カメラ位置を調整
if ((OVRInput.Get(OVRInput.Button.PrimaryIndexTrigger))) {
// コントローラーから前に伸ばしたRayを作成して、オフセットを得る
Transform controller = GetController();
var pointerRay = new Ray(controller.position, controller.transform.forward);
// カメラのローカル座標に変換
Vector3 rayPointFm = _camera.transform.InverseTransformPoint(pointerRay.GetPoint(0));
Vector3 rayPointTo = _camera.transform.InverseTransformPoint(pointerRay.GetPoint(_cameraHeight));
// 移動距離取得
Vector3 cameraOffset = rayPointTo - rayPointFm;
// カメラのローカル座標を設定
_camera.localPosition = cameraOffset;
}
}
}
説明
1.腰から頭の差を算出する
「OculusGoコントローラーを上に向けて胸の位置に固定している」という前提で腰から頭まで距離を取得します。
具体的には「OculusGoコントローラー座標と、OculusGoコントローラーから座高の長さのほどレーザーを伸ばした先の座標の差」が「腰から頭の差」として解釈することができます。
// 移動距離取得
Vector3 cameraOffset = rayPointTo - rayPointFm;
2.座標をカメラのローカル座標に変換
コードと説明の順が前後しますが、ワールド座標で腰から頭の差を取得してしまうとカメラの角度を変えた時に変になってしまうため座標はカメラのローカル座標に変換して取得します。
// カメラのローカル座標に変換
Vector3 rayPointFm = _camera.transform.InverseTransformPoint(pointerRay.GetPoint(0));
Vector3 rayPointTo = _camera.transform.InverseTransformPoint(pointerRay.GetPoint(_cameraHeight));
3.頭の位置を設定
OVRCameraRig
のローカル座標を設定します。
腰の位置になるCameraBase
に対しての設定になるため、これで腰を動かしたときの頭の位置が設定できます。
// カメラのローカル座標を設定
_camera.localPosition = cameraOffset;
Author And Source
この問題について(OculusGoで擬似的に6DoF(ポジショントラッキング)を実現する方法), 我々は、より多くの情報をここで見つけました https://qiita.com/culage/items/0ea9542c75ebe1c42505著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .