244 lines
8.1 KiB
C#
244 lines
8.1 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus 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/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus 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 Oculus.Interaction.Grab;
|
|
using Oculus.Interaction.HandGrab;
|
|
using Oculus.Interaction.Input;
|
|
using UnityEngine;
|
|
|
|
namespace Oculus.Interaction
|
|
{
|
|
public class GrabStrengthIndicator : MonoBehaviour
|
|
{
|
|
[SerializeField, Interface(typeof(IHandGrabInteractor), typeof(IInteractor))]
|
|
private UnityEngine.Object _handGrabInteractor;
|
|
private IHandGrabInteractor HandGrab { get; set; }
|
|
private IInteractor Interactor { get; set; }
|
|
|
|
[SerializeField]
|
|
private MaterialPropertyBlockEditor _handMaterialPropertyBlockEditor;
|
|
|
|
[SerializeField]
|
|
private float _glowLerpSpeed = 2f;
|
|
[SerializeField]
|
|
private float _glowColorLerpSpeed = 2f;
|
|
|
|
[SerializeField]
|
|
private Color _fingerGlowColorWithInteractable;
|
|
[SerializeField]
|
|
private Color _fingerGlowColorWithNoInteractable;
|
|
[SerializeField]
|
|
private Color _fingerGlowColorHover;
|
|
|
|
#region public properties
|
|
public float GlowLerpSpeed
|
|
{
|
|
get
|
|
{
|
|
return _glowLerpSpeed;
|
|
}
|
|
set
|
|
{
|
|
_glowLerpSpeed = value;
|
|
}
|
|
}
|
|
|
|
|
|
public float GlowColorLerpSpeed
|
|
{
|
|
get
|
|
{
|
|
return _glowColorLerpSpeed;
|
|
}
|
|
set
|
|
{
|
|
_glowColorLerpSpeed = value;
|
|
}
|
|
}
|
|
|
|
public Color FingerGlowColorWithInteractable
|
|
{
|
|
get
|
|
{
|
|
return _fingerGlowColorWithInteractable;
|
|
}
|
|
set
|
|
{
|
|
_fingerGlowColorWithInteractable = value;
|
|
}
|
|
}
|
|
|
|
public Color FingerGlowColorWithNoInteractable
|
|
{
|
|
get
|
|
{
|
|
return _fingerGlowColorWithNoInteractable;
|
|
}
|
|
set
|
|
{
|
|
_fingerGlowColorWithNoInteractable = value;
|
|
}
|
|
}
|
|
|
|
public Color FingerGlowColorHover
|
|
{
|
|
get
|
|
{
|
|
return _fingerGlowColorHover;
|
|
}
|
|
set
|
|
{
|
|
_fingerGlowColorHover = value;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
private readonly int[] _handShaderGlowPropertyIds = new int[]
|
|
{
|
|
Shader.PropertyToID("_ThumbGlowValue"),
|
|
Shader.PropertyToID("_IndexGlowValue"),
|
|
Shader.PropertyToID("_MiddleGlowValue"),
|
|
Shader.PropertyToID("_RingGlowValue"),
|
|
Shader.PropertyToID("_PinkyGlowValue"),
|
|
};
|
|
|
|
private readonly int _fingerGlowColorPropertyId = Shader.PropertyToID("_FingerGlowColor");
|
|
|
|
private Color _currentGlowColor;
|
|
|
|
protected bool _started = false;
|
|
|
|
private void Awake()
|
|
{
|
|
HandGrab = _handGrabInteractor as IHandGrabInteractor;
|
|
Interactor = _handGrabInteractor as IInteractor;
|
|
}
|
|
|
|
protected virtual void Start()
|
|
{
|
|
this.BeginStart(ref _started);
|
|
|
|
this.AssertField(_handMaterialPropertyBlockEditor, nameof(_handMaterialPropertyBlockEditor));
|
|
this.AssertField(HandGrab, nameof(HandGrab));
|
|
this.AssertField(Interactor, nameof(Interactor));
|
|
|
|
this.EndStart(ref _started);
|
|
}
|
|
|
|
protected virtual void OnEnable()
|
|
{
|
|
if (_started)
|
|
{
|
|
Interactor.WhenPostprocessed += UpdateVisual;
|
|
_currentGlowColor = _fingerGlowColorWithNoInteractable;
|
|
}
|
|
}
|
|
|
|
protected virtual void OnDisable()
|
|
{
|
|
if (_started)
|
|
{
|
|
Interactor.WhenPostprocessed -= UpdateVisual;
|
|
}
|
|
}
|
|
|
|
private void UpdateVisual()
|
|
{
|
|
bool isSelecting = Interactor.State == InteractorState.Select;
|
|
bool isSelectingInteractable = Interactor.HasSelectedInteractable;
|
|
bool hasHoverTarget = Interactor.HasCandidate;
|
|
|
|
Color desiredGlowColor = _fingerGlowColorHover;
|
|
if (isSelecting)
|
|
{
|
|
desiredGlowColor = isSelectingInteractable
|
|
? _fingerGlowColorWithInteractable
|
|
: _fingerGlowColorWithNoInteractable;
|
|
}
|
|
|
|
_currentGlowColor = Color.Lerp(_currentGlowColor, desiredGlowColor,
|
|
Time.deltaTime * _glowColorLerpSpeed);
|
|
_handMaterialPropertyBlockEditor.MaterialPropertyBlock.SetColor(_fingerGlowColorPropertyId, _currentGlowColor);
|
|
|
|
for (int i = 0; i < Constants.NUM_FINGERS; ++i)
|
|
{
|
|
if ((isSelecting && !isSelectingInteractable) ||
|
|
(!isSelecting && !hasHoverTarget))
|
|
{
|
|
UpdateGlowValue(i, 0f);
|
|
continue;
|
|
}
|
|
|
|
float glowValue = 0f;
|
|
HandFinger finger = (HandFinger)i;
|
|
if ((HandGrab.SupportedGrabTypes & GrabTypeFlags.Pinch) != 0
|
|
&& HandGrab.TargetInteractable != null
|
|
&& (HandGrab.TargetInteractable.SupportedGrabTypes & GrabTypeFlags.Pinch) != 0
|
|
&& HandGrab.TargetInteractable.PinchGrabRules[finger] != GrabAPI.FingerRequirement.Ignored)
|
|
{
|
|
glowValue = Mathf.Max(glowValue, HandGrab.HandGrabApi.GetFingerPinchStrength(finger));
|
|
}
|
|
|
|
if ((HandGrab.SupportedGrabTypes & GrabTypeFlags.Palm) != 0
|
|
&& HandGrab.TargetInteractable != null
|
|
&& (HandGrab.TargetInteractable.SupportedGrabTypes & GrabTypeFlags.Palm) != 0
|
|
&& HandGrab.TargetInteractable.PalmGrabRules[finger] != GrabAPI.FingerRequirement.Ignored)
|
|
{
|
|
glowValue = Mathf.Max(glowValue, HandGrab.HandGrabApi.GetFingerPalmStrength(finger));
|
|
}
|
|
|
|
UpdateGlowValue(i, glowValue);
|
|
}
|
|
|
|
_handMaterialPropertyBlockEditor.UpdateMaterialPropertyBlock();
|
|
}
|
|
|
|
private void UpdateGlowValue(int fingerIndex, float glowValue)
|
|
{
|
|
float currentGlowValue = _handMaterialPropertyBlockEditor.MaterialPropertyBlock.GetFloat(_handShaderGlowPropertyIds[fingerIndex]);
|
|
float newGlowValue = Mathf.MoveTowards(currentGlowValue, glowValue, _glowLerpSpeed * Time.deltaTime);
|
|
_handMaterialPropertyBlockEditor.MaterialPropertyBlock.SetFloat(_handShaderGlowPropertyIds[fingerIndex], newGlowValue);
|
|
}
|
|
|
|
#region Inject
|
|
|
|
public void InjectAllGrabStrengthIndicator(IHandGrabInteractor handGrabInteractor,
|
|
MaterialPropertyBlockEditor handMaterialPropertyBlockEditor)
|
|
{
|
|
InjectHandGrab(handGrabInteractor);
|
|
InjectHandMaterialPropertyBlockEditor(handMaterialPropertyBlockEditor);
|
|
}
|
|
|
|
public void InjectHandGrab(IHandGrabInteractor handGrab)
|
|
{
|
|
_handGrabInteractor = handGrab as UnityEngine.Object;
|
|
HandGrab = handGrab;
|
|
Interactor = handGrab as IInteractor;
|
|
}
|
|
|
|
public void InjectHandMaterialPropertyBlockEditor(MaterialPropertyBlockEditor handMaterialPropertyBlockEditor)
|
|
{
|
|
_handMaterialPropertyBlockEditor = handMaterialPropertyBlockEditor;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|