forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			366 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			366 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
/************************************************************************************
 | 
						|
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
 | 
						|
 | 
						|
Licensed under the Oculus Master SDK License Version 1.0 (the "License"); you may not use
 | 
						|
the Utilities SDK except in compliance with the License, which is provided at the time of installation
 | 
						|
or download, or which otherwise accompanies this software in either electronic or hard copy form.
 | 
						|
 | 
						|
You may obtain a copy of the License at
 | 
						|
https://developer.oculus.com/licenses/oculusmastersdk-1.0/
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
 | 
						|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 | 
						|
ANY KIND, either express or implied. See the License for the specific language governing
 | 
						|
permissions and limitations under the License.
 | 
						|
************************************************************************************/
 | 
						|
 | 
						|
using System.Collections;
 | 
						|
using System.Collections.Generic;
 | 
						|
using UnityEngine;
 | 
						|
 | 
						|
[DefaultExecutionOrder(-70)]
 | 
						|
public class OVRSkeletonRenderer : MonoBehaviour
 | 
						|
{
 | 
						|
	public interface IOVRSkeletonRendererDataProvider
 | 
						|
	{
 | 
						|
		SkeletonRendererData GetSkeletonRendererData();
 | 
						|
	}
 | 
						|
 | 
						|
	public struct SkeletonRendererData
 | 
						|
	{
 | 
						|
		public float RootScale { get; set; }
 | 
						|
		public bool IsDataValid { get; set; }
 | 
						|
		public bool IsDataHighConfidence { get; set; }
 | 
						|
		public bool ShouldUseSystemGestureMaterial { get; set; }
 | 
						|
	}
 | 
						|
 | 
						|
	public enum ConfidenceBehavior
 | 
						|
	{
 | 
						|
		None,
 | 
						|
		ToggleRenderer,
 | 
						|
	}
 | 
						|
 | 
						|
	public enum SystemGestureBehavior
 | 
						|
	{
 | 
						|
		None,
 | 
						|
		SwapMaterial,
 | 
						|
	}
 | 
						|
 | 
						|
	[SerializeField]
 | 
						|
	private IOVRSkeletonRendererDataProvider _dataProvider;
 | 
						|
	[SerializeField]
 | 
						|
	private ConfidenceBehavior _confidenceBehavior = ConfidenceBehavior.ToggleRenderer;
 | 
						|
	[SerializeField]
 | 
						|
	private SystemGestureBehavior _systemGestureBehavior = SystemGestureBehavior.SwapMaterial;
 | 
						|
	[SerializeField]
 | 
						|
	private bool _renderPhysicsCapsules = false;
 | 
						|
	[SerializeField]
 | 
						|
	private Material _skeletonMaterial;
 | 
						|
	private Material _skeletonDefaultMaterial;
 | 
						|
	[SerializeField]
 | 
						|
	private Material _capsuleMaterial;
 | 
						|
	private Material _capsuleDefaultMaterial;
 | 
						|
	[SerializeField]
 | 
						|
	private Material _systemGestureMaterial = null;
 | 
						|
	private Material _systemGestureDefaultMaterial;
 | 
						|
 | 
						|
	private const float LINE_RENDERER_WIDTH = 0.005f;
 | 
						|
	private List<BoneVisualization> _boneVisualizations;
 | 
						|
	private List<CapsuleVisualization> _capsuleVisualizations;
 | 
						|
	private OVRSkeleton _ovrSkeleton;
 | 
						|
	private GameObject _skeletonGO;
 | 
						|
	private float _scale;
 | 
						|
	private static readonly Quaternion _capsuleRotationOffset = Quaternion.Euler(0, 0, 90);
 | 
						|
 | 
						|
	public bool IsInitialized { get; private set; }
 | 
						|
	public bool IsDataValid { get; private set; }
 | 
						|
	public bool IsDataHighConfidence { get; private set; }
 | 
						|
	public bool ShouldUseSystemGestureMaterial { get; private set; }
 | 
						|
 | 
						|
	private class BoneVisualization
 | 
						|
	{
 | 
						|
		private GameObject BoneGO;
 | 
						|
		private Transform BoneBegin;
 | 
						|
		private Transform BoneEnd;
 | 
						|
		private LineRenderer Line;
 | 
						|
		private Material RenderMaterial;
 | 
						|
		private Material SystemGestureMaterial;
 | 
						|
 | 
						|
		public BoneVisualization(GameObject rootGO,
 | 
						|
				Material renderMat,
 | 
						|
				Material systemGestureMat,
 | 
						|
				float scale,
 | 
						|
				Transform begin,
 | 
						|
				Transform end)
 | 
						|
		{
 | 
						|
			RenderMaterial = renderMat;
 | 
						|
			SystemGestureMaterial = systemGestureMat;
 | 
						|
 | 
						|
			BoneBegin = begin;
 | 
						|
			BoneEnd = end;
 | 
						|
 | 
						|
			BoneGO = new GameObject(begin.name);
 | 
						|
			BoneGO.transform.SetParent(rootGO.transform, false);
 | 
						|
 | 
						|
			Line = BoneGO.AddComponent<LineRenderer>();
 | 
						|
			Line.sharedMaterial = RenderMaterial;
 | 
						|
			Line.useWorldSpace = true;
 | 
						|
			Line.positionCount = 2;
 | 
						|
 | 
						|
			Line.SetPosition(0, BoneBegin.position);
 | 
						|
			Line.SetPosition(1, BoneEnd.position);
 | 
						|
 | 
						|
			Line.startWidth = LINE_RENDERER_WIDTH * scale;
 | 
						|
			Line.endWidth = LINE_RENDERER_WIDTH * scale;
 | 
						|
		}
 | 
						|
 | 
						|
		public void Update(float scale,
 | 
						|
				bool shouldRender,
 | 
						|
				bool shouldUseSystemGestureMaterial,
 | 
						|
				ConfidenceBehavior confidenceBehavior,
 | 
						|
				SystemGestureBehavior systemGestureBehavior)
 | 
						|
		{
 | 
						|
			Line.SetPosition(0, BoneBegin.position);
 | 
						|
			Line.SetPosition(1, BoneEnd.position);
 | 
						|
 | 
						|
			Line.startWidth = LINE_RENDERER_WIDTH * scale;
 | 
						|
			Line.endWidth = LINE_RENDERER_WIDTH * scale;
 | 
						|
 | 
						|
			if (confidenceBehavior == ConfidenceBehavior.ToggleRenderer)
 | 
						|
			{
 | 
						|
				Line.enabled = shouldRender;
 | 
						|
			}
 | 
						|
 | 
						|
			if (systemGestureBehavior == SystemGestureBehavior.SwapMaterial)
 | 
						|
			{
 | 
						|
				if (shouldUseSystemGestureMaterial && Line.sharedMaterial != SystemGestureMaterial)
 | 
						|
				{
 | 
						|
					Line.sharedMaterial = SystemGestureMaterial;
 | 
						|
				}
 | 
						|
				else if (!shouldUseSystemGestureMaterial && Line.sharedMaterial != RenderMaterial)
 | 
						|
				{
 | 
						|
					Line.sharedMaterial = RenderMaterial;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	private class CapsuleVisualization
 | 
						|
	{
 | 
						|
		private GameObject CapsuleGO;
 | 
						|
		private OVRBoneCapsule BoneCapsule;
 | 
						|
		private Vector3 capsuleScale;
 | 
						|
		private MeshRenderer Renderer;
 | 
						|
		private Material RenderMaterial;
 | 
						|
		private Material SystemGestureMaterial;
 | 
						|
 | 
						|
		public CapsuleVisualization(GameObject rootGO,
 | 
						|
				Material renderMat,
 | 
						|
				Material systemGestureMat,
 | 
						|
				float scale,
 | 
						|
				OVRBoneCapsule boneCapsule)
 | 
						|
		{
 | 
						|
			RenderMaterial = renderMat;
 | 
						|
			SystemGestureMaterial = systemGestureMat;
 | 
						|
 | 
						|
			BoneCapsule = boneCapsule;
 | 
						|
 | 
						|
			CapsuleGO = GameObject.CreatePrimitive(PrimitiveType.Capsule);
 | 
						|
			CapsuleCollider collider = CapsuleGO.GetComponent<CapsuleCollider>();
 | 
						|
			Destroy(collider);
 | 
						|
			Renderer = CapsuleGO.GetComponent<MeshRenderer>();
 | 
						|
			Renderer.sharedMaterial = RenderMaterial;
 | 
						|
 | 
						|
			capsuleScale = Vector3.one;
 | 
						|
			capsuleScale.y = boneCapsule.CapsuleCollider.height / 2;
 | 
						|
			capsuleScale.x = boneCapsule.CapsuleCollider.radius * 2;
 | 
						|
			capsuleScale.z = boneCapsule.CapsuleCollider.radius * 2;
 | 
						|
			CapsuleGO.transform.localScale = capsuleScale * scale;
 | 
						|
		}
 | 
						|
 | 
						|
		public void Update(float scale,
 | 
						|
				bool shouldRender,
 | 
						|
				bool shouldUseSystemGestureMaterial,
 | 
						|
				ConfidenceBehavior confidenceBehavior,
 | 
						|
				SystemGestureBehavior systemGestureBehavior)
 | 
						|
		{
 | 
						|
			if (confidenceBehavior == ConfidenceBehavior.ToggleRenderer)
 | 
						|
			{
 | 
						|
				if (CapsuleGO.activeSelf != shouldRender)
 | 
						|
				{
 | 
						|
					CapsuleGO.SetActive(shouldRender);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			CapsuleGO.transform.rotation = BoneCapsule.CapsuleCollider.transform.rotation * _capsuleRotationOffset;
 | 
						|
			CapsuleGO.transform.position = BoneCapsule.CapsuleCollider.transform.TransformPoint(BoneCapsule.CapsuleCollider.center);
 | 
						|
			CapsuleGO.transform.localScale = capsuleScale * scale;
 | 
						|
 | 
						|
			if (systemGestureBehavior == SystemGestureBehavior.SwapMaterial)
 | 
						|
			{
 | 
						|
				if (shouldUseSystemGestureMaterial && Renderer.sharedMaterial != SystemGestureMaterial)
 | 
						|
				{
 | 
						|
					Renderer.sharedMaterial = SystemGestureMaterial;
 | 
						|
				}
 | 
						|
				else if (!shouldUseSystemGestureMaterial && Renderer.sharedMaterial != RenderMaterial)
 | 
						|
				{
 | 
						|
					Renderer.sharedMaterial = RenderMaterial;
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	private void Awake()
 | 
						|
	{
 | 
						|
		if (_dataProvider == null)
 | 
						|
		{
 | 
						|
			_dataProvider = GetComponent<IOVRSkeletonRendererDataProvider>();
 | 
						|
		}
 | 
						|
 | 
						|
		if (_ovrSkeleton == null)
 | 
						|
		{
 | 
						|
			_ovrSkeleton = GetComponent<OVRSkeleton>();
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	private void Start()
 | 
						|
	{
 | 
						|
		if (_ovrSkeleton == null)
 | 
						|
		{
 | 
						|
			this.enabled = false;
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		Initialize();
 | 
						|
	}
 | 
						|
 | 
						|
	private void Initialize()
 | 
						|
	{
 | 
						|
		_boneVisualizations = new List<BoneVisualization>();
 | 
						|
		_capsuleVisualizations = new List<CapsuleVisualization>();
 | 
						|
		_ovrSkeleton = GetComponent<OVRSkeleton>();
 | 
						|
		_skeletonGO = new GameObject("SkeletonRenderer");
 | 
						|
		_skeletonGO.transform.SetParent(transform, false);
 | 
						|
 | 
						|
		if (_skeletonMaterial == null)
 | 
						|
		{
 | 
						|
			_skeletonDefaultMaterial = new Material(Shader.Find("Diffuse"));
 | 
						|
			_skeletonMaterial = _skeletonDefaultMaterial;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_capsuleMaterial == null)
 | 
						|
		{
 | 
						|
			_capsuleDefaultMaterial = new Material(Shader.Find("Diffuse"));
 | 
						|
			_capsuleMaterial = _capsuleDefaultMaterial;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_systemGestureMaterial == null)
 | 
						|
		{
 | 
						|
			_systemGestureDefaultMaterial = new Material(Shader.Find("Diffuse"));
 | 
						|
			_systemGestureDefaultMaterial.color = Color.blue;
 | 
						|
			_systemGestureMaterial = _systemGestureDefaultMaterial;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_ovrSkeleton.IsInitialized)
 | 
						|
		{
 | 
						|
			for (int i = 0; i < _ovrSkeleton.Bones.Count; i++)
 | 
						|
			{
 | 
						|
				var boneVis = new BoneVisualization(
 | 
						|
					_skeletonGO,
 | 
						|
					_skeletonMaterial,
 | 
						|
					_systemGestureMaterial,
 | 
						|
					_scale,
 | 
						|
					_ovrSkeleton.Bones[i].Transform,
 | 
						|
					_ovrSkeleton.Bones[i].Transform.parent);
 | 
						|
 | 
						|
				_boneVisualizations.Add(boneVis);
 | 
						|
			}
 | 
						|
 | 
						|
			if (_renderPhysicsCapsules && _ovrSkeleton.Capsules != null)
 | 
						|
			{
 | 
						|
				for (int i = 0; i < _ovrSkeleton.Capsules.Count; i++)
 | 
						|
				{
 | 
						|
					var capsuleVis = new CapsuleVisualization(
 | 
						|
						_skeletonGO,
 | 
						|
						_capsuleMaterial,
 | 
						|
						_systemGestureMaterial,
 | 
						|
						_scale,
 | 
						|
						_ovrSkeleton.Capsules[i]);
 | 
						|
 | 
						|
					_capsuleVisualizations.Add(capsuleVis);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
#if UNITY_EDITOR
 | 
						|
			_ovrSkeleton.ShouldUpdateBonePoses = true;
 | 
						|
#endif
 | 
						|
			IsInitialized = true;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	public void Update()
 | 
						|
	{
 | 
						|
		IsDataValid = false;
 | 
						|
		IsDataHighConfidence = false;
 | 
						|
		ShouldUseSystemGestureMaterial = false;
 | 
						|
 | 
						|
		if (IsInitialized)
 | 
						|
		{
 | 
						|
			bool shouldRender = false;
 | 
						|
 | 
						|
			if (_dataProvider != null)
 | 
						|
			{
 | 
						|
				var data = _dataProvider.GetSkeletonRendererData();
 | 
						|
 | 
						|
				IsDataValid = data.IsDataValid;
 | 
						|
				IsDataHighConfidence = data.IsDataHighConfidence;
 | 
						|
				ShouldUseSystemGestureMaterial = data.ShouldUseSystemGestureMaterial;
 | 
						|
 | 
						|
				shouldRender = data.IsDataValid && data.IsDataHighConfidence;
 | 
						|
 | 
						|
				if (data.IsDataValid)
 | 
						|
				{
 | 
						|
					_scale = data.RootScale;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			for (int i = 0; i < _boneVisualizations.Count; i++)
 | 
						|
			{
 | 
						|
				_boneVisualizations[i].Update(_scale, shouldRender, ShouldUseSystemGestureMaterial, _confidenceBehavior, _systemGestureBehavior);
 | 
						|
			}
 | 
						|
 | 
						|
			for (int i = 0; i < _capsuleVisualizations.Count; i++)
 | 
						|
			{
 | 
						|
				_capsuleVisualizations[i].Update(_scale, shouldRender, ShouldUseSystemGestureMaterial, _confidenceBehavior, _systemGestureBehavior);
 | 
						|
			}
 | 
						|
		}
 | 
						|
#if UNITY_EDITOR
 | 
						|
		else
 | 
						|
		{
 | 
						|
			if (OVRInput.IsControllerConnected(OVRInput.Controller.Hands) && !IsInitialized)
 | 
						|
			{
 | 
						|
				Initialize();
 | 
						|
			}
 | 
						|
		}
 | 
						|
#endif
 | 
						|
	}
 | 
						|
 | 
						|
	private void OnDestroy()
 | 
						|
	{
 | 
						|
		if (_skeletonDefaultMaterial != null)
 | 
						|
		{
 | 
						|
			DestroyImmediate(_skeletonDefaultMaterial, false);
 | 
						|
		}
 | 
						|
 | 
						|
		if (_capsuleDefaultMaterial != null)
 | 
						|
		{
 | 
						|
			DestroyImmediate(_capsuleDefaultMaterial, false);
 | 
						|
		}
 | 
						|
 | 
						|
		if (_systemGestureDefaultMaterial != null)
 | 
						|
		{
 | 
						|
			DestroyImmediate(_systemGestureDefaultMaterial, false);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |