質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.98%

foveのサンプルをいじって片目だけ視線追跡させたい。

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 736

ehuronkon35

score 31

foveのサンプルをいじって片目だけ視線追跡させたい。

FOVEが提供しているサンプルコードは現段階では両目が視線追跡されている状況です。

それを片目だけ視線を追跡するようにするにはコードをどう変えればいいですか。
右目、左目、どちらでも構いません。

コード
using UnityEngine;
using System.Collections;

public class FOVE3DCursor : MonoBehaviour
{
    public enum LeftOrRight
    {
        Left,
        Right
    }

    [SerializeField]
    public LeftOrRight whichEye;
    public FoveInterfaceBase foveInterface;

    // Use this for initialization
    void Start () {
    }

    // Latepdate ensures that the object doesn't lag behind the user's head motion
    void Update() {
        FoveInterfaceBase.EyeRays rays = foveInterface.GetGazeRays();

        Ray r = whichEye == LeftOrRight.Left ? rays.left : rays.right;

        RaycastHit hit;
        Physics.Raycast(r, out hit, Mathf.Infinity);
        if (hit.point != Vector3.zero) // Vector3 is non-nullable; comparing to null is always false
        {
            transform.position = hit.point;
        }
        else
        {
            transform.position = r.GetPoint(3.0f);
        }
    }
}
コード
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Runtime.Remoting.Messaging;
using Fove.Managed;

[RequireComponent(typeof(Camera))]
[AddComponentMenu("")]  // hide FoveEyeCamera from mono behaviour menus to discourage people adding it by hand
public class FoveEyeCamera : MonoBehaviour {

    [SerializeField]
    public EFVR_Eye whichEye = EFVR_Eye.Left;

    [SerializeField]
    public bool suppressProjectionUpdates = true;

    [SerializeField]
    [Range(0.1f, 4f)]
    public float resolutionScale = 1.4f;
    public int antiAliasing = 1;

    private float _lastScale;
    private int _lastAA;

    private FVRHeadset _headset = null;
    private Camera _cam = null;
    private FVRCompositor _compositor;
    public FoveInterfaceBase foveInterfaceBase;

    private SFVR_CompositorLayerSubmitInfo _layerSubmitInfo;

    private static bool couldUseNewMatrices;
    private static Matrix4x4 leftProjectionMatrix;
    private static Matrix4x4 rightProjectionMatrix;

    private class FoveCameraPair
    {
        public SFVR_CompositorLayer layer;

        public FoveEyeCamera left;
        public FoveEyeCamera right;

        // Private so nobody can make one this way
        private FoveCameraPair() {}

        public FoveCameraPair(FVRCompositor compositor, FoveInterfaceBase xface)
        {
            left = null;
            right = null;

            var createInfo = new SFVR_CompositorLayerCreateInfo
            {
                alphaMode = EFVR_AlphaMode.Auto,
                disableDistortion = xface.DistortionDisabled,
                disableTimewarp = xface.TimewarpDisabled,
                disableFading = xface.FadingDisabled,
                type = xface.LayerType
            };

            var err = compositor.CreateLayer(createInfo, out layer);
            if (err != EFVR_ErrorCode.None)
            {
                Debug.LogError("[FOVE] Error getting layer: " + err);
            }

            Debug.Log("[FOVE] Layer requested no distortion? " + createInfo.disableDistortion);
        }

        public void SetCamera(EFVR_Eye whichEye, FoveEyeCamera cam)
        {
            switch (whichEye)
            {
                case EFVR_Eye.Left:
                    left = cam;
                    break;
                case EFVR_Eye.Right:
                    right = cam;
                    break;
            }
        }

        public bool CanUseCamera(EFVR_Eye whichEye, FoveEyeCamera cam)
        {
            switch (whichEye)
            {
                case EFVR_Eye.Left:
                    return left == null || left == cam;
                case EFVR_Eye.Right:
                    return right == null || right == cam;
            }

            return false;
        }
    }

    private static List<FoveCameraPair> _layerCameraPairs = new List<FoveCameraPair>();

    private static FoveCameraPair GetNextLayerPair(EFVR_Eye whichEye, FoveEyeCamera cam)
    {
        if (whichEye != EFVR_Eye.Left && whichEye != EFVR_Eye.Right)
            return null;

        foreach (var pair in _layerCameraPairs)
        {
            if (pair.CanUseCamera(whichEye, cam))
                return pair;
        }

        var p = new FoveCameraPair(cam._compositor, cam.foveInterfaceBase);
        _layerCameraPairs.Add(p);

        return p;
    }

    public FVRCompositor Compositor
    {
        set
        {
            _compositor = value;
        }
    }

    private static bool _isProjectionErrorFree;

    private void UpdateProjectionMatrix()
    {
        // Get the projection matrix from the FOVE SDK and apply it to the camera
        if (!_isProjectionErrorFree || couldUseNewMatrices)
        {
            SFVR_Matrix44 fove_mx_left, fove_mx_right;
            var err = _headset.GetProjectionMatricesRH(_cam.nearClipPlane, _cam.farClipPlane, out fove_mx_left,
                out fove_mx_right);
            if (err != EFVR_ErrorCode.None)
            {
                _isProjectionErrorFree = false;
            }
            else
            {
                _isProjectionErrorFree = true;
                leftProjectionMatrix = FoveUnityUtils.GetUnityMx(fove_mx_left);
                rightProjectionMatrix = FoveUnityUtils.GetUnityMx(fove_mx_right);

                couldUseNewMatrices = false;
            }
        }

        switch (whichEye)
        {
            case EFVR_Eye.Left:
                _cam.projectionMatrix = leftProjectionMatrix;
                break;
            case EFVR_Eye.Right:
                _cam.projectionMatrix = rightProjectionMatrix;
                break;
            default:
                Debug.Log("Fove eye camera not set to left or right");
                break;
        }

    }

    private void SetSubmitBounds(ref SFVR_CompositorLayerEyeSubmitInfo info)
    {
        info.bounds.left = 0.0f;
        info.bounds.bottom = 0.0f;
        info.bounds.right = 1.0f;
        info.bounds.top = 1.0f;
    }

    void Start() {
        _headset = FoveInterfaceBase.GetFVRHeadset();

        _lastScale = resolutionScale;
        _lastAA = antiAliasing;

        FoveCameraPair myPair = GetNextLayerPair(whichEye, this);
        myPair.SetCamera(whichEye, this);
        SFVR_CompositorLayer layer = myPair.layer;
        SFVR_Vec2i res = layer.idealResolutionPerEye;

        var rt = new RenderTexture((int)(res.x * resolutionScale), (int)(res.y * resolutionScale), 24);
        rt.antiAliasing = antiAliasing;

        _cam = gameObject.GetComponent<Camera>();
        _cam.targetTexture = rt;
        _cam.enabled = false;

        switch (whichEye)
        {
            case EFVR_Eye.Left:
                SetSubmitBounds(ref _layerSubmitInfo.left);
                _layerSubmitInfo.left.texInfo.colorSpace = EFVR_ColorSpace.Linear;
                break;
            case EFVR_Eye.Right:
                SetSubmitBounds(ref _layerSubmitInfo.right);
                _layerSubmitInfo.left.texInfo.colorSpace = EFVR_ColorSpace.Linear;
                break;
        }

        _layerSubmitInfo.layerId = myPair.layer.layerId;
    }

    void Update()
    {
        // For live updating of resolution scale and antialiasing settings
        const float tolerance = 0.0001f;
        if (Math.Abs(resolutionScale - _lastScale) > tolerance || antiAliasing != _lastAA)
        {
            var rt = new RenderTexture((int)(1280 * resolutionScale), (int)(1440 * resolutionScale), 24);
            rt.antiAliasing = antiAliasing;

            _cam.targetTexture.Release();
            _cam.targetTexture = rt;

            _lastScale = resolutionScale;
            _lastAA = antiAliasing;
        }
    }

    void OnPreCull() {
        UpdateProjectionMatrix();
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit(source, destination);

        if (_compositor == null)
            return;

        IntPtr texPtr = source.GetNativeTexturePtr();
        if (texPtr != IntPtr.Zero)
        {
            _layerSubmitInfo.pose = FoveInterface.GetLastPose();
            switch (whichEye)
            {
                case EFVR_Eye.Left:
                    _layerSubmitInfo.left.texInfo.pTexture = texPtr;
                    _layerSubmitInfo.right.texInfo.pTexture = IntPtr.Zero;
                    break;
                case EFVR_Eye.Right:
                    _layerSubmitInfo.left.texInfo.pTexture = IntPtr.Zero;
                    _layerSubmitInfo.right.texInfo.pTexture = texPtr;
                    break;
                default:
                    Debug.LogError("[FOVE] Camera set to " + whichEye + " which isn't supported.");
                    return;
            }

            var result = _compositor.Submit(ref _layerSubmitInfo);
            if (result != EFVR_ErrorCode.None)
            {
                Debug.LogWarning("[FOVE] Submit returned unexpected " + result);
            }

            GL.Flush();
        }
        else
        {
            Debug.LogWarning("RenderTexture native pointer is null; cannot submit null texture pointers.");
        }

        if (!suppressProjectionUpdates)
        {
            couldUseNewMatrices = true;
        }
    }
}


よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2018/10/04 16:53

    回答いらい依頼いただきましたが、全く専門外なので期待には応えられません(私の登録タグ参照)。他に専門知識をお持ちのかたはたくさんいるかと思いますのでそちらに回していただけたらと。

    キャンセル

回答 1

0

片目のカーソルオブジェクトのチェックを外すのはどうでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる