You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			154 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			154 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C#
		
	
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
 | 
						|
//
 | 
						|
// Purpose: Generates a mesh based on field of view.
 | 
						|
//
 | 
						|
//=============================================================================
 | 
						|
 | 
						|
using UnityEngine;
 | 
						|
using Valve.VR;
 | 
						|
 | 
						|
namespace Valve.VR
 | 
						|
{
 | 
						|
    [ExecuteInEditMode, RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
 | 
						|
    public class SteamVR_Frustum : MonoBehaviour
 | 
						|
    {
 | 
						|
        public SteamVR_TrackedObject.EIndex index;
 | 
						|
 | 
						|
        public float fovLeft = 45, fovRight = 45, fovTop = 45, fovBottom = 45, nearZ = 0.5f, farZ = 2.5f;
 | 
						|
 | 
						|
        public void UpdateModel()
 | 
						|
        {
 | 
						|
            fovLeft = Mathf.Clamp(fovLeft, 1, 89);
 | 
						|
            fovRight = Mathf.Clamp(fovRight, 1, 89);
 | 
						|
            fovTop = Mathf.Clamp(fovTop, 1, 89);
 | 
						|
            fovBottom = Mathf.Clamp(fovBottom, 1, 89);
 | 
						|
            farZ = Mathf.Max(farZ, nearZ + 0.01f);
 | 
						|
            nearZ = Mathf.Clamp(nearZ, 0.01f, farZ - 0.01f);
 | 
						|
 | 
						|
            var lsin = Mathf.Sin(-fovLeft * Mathf.Deg2Rad);
 | 
						|
            var rsin = Mathf.Sin(fovRight * Mathf.Deg2Rad);
 | 
						|
            var tsin = Mathf.Sin(fovTop * Mathf.Deg2Rad);
 | 
						|
            var bsin = Mathf.Sin(-fovBottom * Mathf.Deg2Rad);
 | 
						|
 | 
						|
            var lcos = Mathf.Cos(-fovLeft * Mathf.Deg2Rad);
 | 
						|
            var rcos = Mathf.Cos(fovRight * Mathf.Deg2Rad);
 | 
						|
            var tcos = Mathf.Cos(fovTop * Mathf.Deg2Rad);
 | 
						|
            var bcos = Mathf.Cos(-fovBottom * Mathf.Deg2Rad);
 | 
						|
 | 
						|
            var corners = new Vector3[] {
 | 
						|
            new Vector3(lsin * nearZ / lcos, tsin * nearZ / tcos, nearZ), //tln
 | 
						|
			new Vector3(rsin * nearZ / rcos, tsin * nearZ / tcos, nearZ), //trn
 | 
						|
			new Vector3(rsin * nearZ / rcos, bsin * nearZ / bcos, nearZ), //brn
 | 
						|
			new Vector3(lsin * nearZ / lcos, bsin * nearZ / bcos, nearZ), //bln
 | 
						|
			new Vector3(lsin * farZ  / lcos, tsin * farZ  / tcos, farZ ), //tlf
 | 
						|
			new Vector3(rsin * farZ  / rcos, tsin * farZ  / tcos, farZ ), //trf
 | 
						|
			new Vector3(rsin * farZ  / rcos, bsin * farZ  / bcos, farZ ), //brf
 | 
						|
			new Vector3(lsin * farZ  / lcos, bsin * farZ  / bcos, farZ ), //blf
 | 
						|
		};
 | 
						|
 | 
						|
            var triangles = new int[] {
 | 
						|
		//	0, 1, 2, 0, 2, 3, // near
 | 
						|
		//	0, 2, 1, 0, 3, 2, // near
 | 
						|
		//	4, 5, 6, 4, 6, 7, // far
 | 
						|
		//	4, 6, 5, 4, 7, 6, // far
 | 
						|
			0, 4, 7, 0, 7, 3, // left
 | 
						|
			0, 7, 4, 0, 3, 7, // left
 | 
						|
			1, 5, 6, 1, 6, 2, // right
 | 
						|
			1, 6, 5, 1, 2, 6, // right
 | 
						|
			0, 4, 5, 0, 5, 1, // top
 | 
						|
			0, 5, 4, 0, 1, 5, // top
 | 
						|
			2, 3, 7, 2, 7, 6, // bottom
 | 
						|
			2, 7, 3, 2, 6, 7, // bottom
 | 
						|
		};
 | 
						|
 | 
						|
            int j = 0;
 | 
						|
            var vertices = new Vector3[triangles.Length];
 | 
						|
            var normals = new Vector3[triangles.Length];
 | 
						|
            for (int i = 0; i < triangles.Length / 3; i++)
 | 
						|
            {
 | 
						|
                var a = corners[triangles[i * 3 + 0]];
 | 
						|
                var b = corners[triangles[i * 3 + 1]];
 | 
						|
                var c = corners[triangles[i * 3 + 2]];
 | 
						|
                var n = Vector3.Cross(b - a, c - a).normalized;
 | 
						|
                normals[i * 3 + 0] = n;
 | 
						|
                normals[i * 3 + 1] = n;
 | 
						|
                normals[i * 3 + 2] = n;
 | 
						|
                vertices[i * 3 + 0] = a;
 | 
						|
                vertices[i * 3 + 1] = b;
 | 
						|
                vertices[i * 3 + 2] = c;
 | 
						|
                triangles[i * 3 + 0] = j++;
 | 
						|
                triangles[i * 3 + 1] = j++;
 | 
						|
                triangles[i * 3 + 2] = j++;
 | 
						|
            }
 | 
						|
 | 
						|
            var mesh = new Mesh();
 | 
						|
            mesh.vertices = vertices;
 | 
						|
            mesh.normals = normals;
 | 
						|
            mesh.triangles = triangles;
 | 
						|
 | 
						|
            GetComponent<MeshFilter>().mesh = mesh;
 | 
						|
        }
 | 
						|
 | 
						|
        private void OnDeviceConnected(int i, bool connected)
 | 
						|
        {
 | 
						|
            if (i != (int)index)
 | 
						|
                return;
 | 
						|
 | 
						|
            GetComponent<MeshFilter>().mesh = null;
 | 
						|
 | 
						|
            if (connected)
 | 
						|
            {
 | 
						|
                var system = OpenVR.System;
 | 
						|
                if (system != null && system.GetTrackedDeviceClass((uint)i) == ETrackedDeviceClass.TrackingReference)
 | 
						|
                {
 | 
						|
                    var error = ETrackedPropertyError.TrackedProp_Success;
 | 
						|
                    var result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_FieldOfViewLeftDegrees_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        fovLeft = result;
 | 
						|
 | 
						|
                    result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_FieldOfViewRightDegrees_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        fovRight = result;
 | 
						|
 | 
						|
                    result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_FieldOfViewTopDegrees_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        fovTop = result;
 | 
						|
 | 
						|
                    result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_FieldOfViewBottomDegrees_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        fovBottom = result;
 | 
						|
 | 
						|
                    result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_TrackingRangeMinimumMeters_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        nearZ = result;
 | 
						|
 | 
						|
                    result = system.GetFloatTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_TrackingRangeMaximumMeters_Float, ref error);
 | 
						|
                    if (error == ETrackedPropertyError.TrackedProp_Success)
 | 
						|
                        farZ = result;
 | 
						|
 | 
						|
                    UpdateModel();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        void OnEnable()
 | 
						|
        {
 | 
						|
            GetComponent<MeshFilter>().mesh = null;
 | 
						|
            SteamVR_Events.DeviceConnected.Listen(OnDeviceConnected);
 | 
						|
        }
 | 
						|
 | 
						|
        void OnDisable()
 | 
						|
        {
 | 
						|
            SteamVR_Events.DeviceConnected.Remove(OnDeviceConnected);
 | 
						|
            GetComponent<MeshFilter>().mesh = null;
 | 
						|
        }
 | 
						|
 | 
						|
#if UNITY_EDITOR
 | 
						|
        void Update()
 | 
						|
        {
 | 
						|
            if (!Application.isPlaying)
 | 
						|
                UpdateModel();
 | 
						|
        }
 | 
						|
#endif
 | 
						|
    }
 | 
						|
} |