VR4RoboticArm2/VR4RoboticArm/Library/PackageCache/com.meta.xr.sdk.interaction/Runtime/Scripts/HandGlow/HandPokeOvershootGlow.cs
IonutMocanu d7aba243a2 Main
2025-09-08 11:04:02 +03:00

223 lines
7.3 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.Input;
using UnityEngine;
using UnityEngine.Assertions;
namespace Oculus.Interaction
{
/// <summary>
/// HandPokeOvershootGlow controls the glow properties of the OculusHand material to
/// get a glow effect when the real hand and the virtual hand are not in the same position in 3d
/// space. This can only happen when a synthetic hand is used and wrist locking is enabled.
/// It generates a sphere gradient with the wrist position as the center and a 0.144 units of radius.
/// </summary>
public class HandPokeOvershootGlow : MonoBehaviour
{
[SerializeField, Interface(typeof(IHand))]
private UnityEngine.Object _hand;
[SerializeField]
private PokeInteractor _pokeInteractor;
[SerializeField]
private HandVisual _handVisual;
[SerializeField]
private SkinnedMeshRenderer _handRenderer;
[SerializeField]
private MaterialPropertyBlockEditor _materialEditor;
[SerializeField]
private Color _glowColor;
[SerializeField]
private float _overshootMaxDistance = 0.15f;
[SerializeField]
private HandFinger _pokeFinger = HandFinger.Index;
[SerializeField]
[Range(0.0f, 1.0f)]
private float _maxGradientLength;
public enum GlowType
{
Fill = 30,
Outline = 31,
Both = 32
}
[SerializeField]
private GlowType _glowType = GlowType.Outline;
private IHand Hand;
private bool _glowEnabled;
private readonly int _glowFingerIndexID = Shader.PropertyToID("_FingerGlowIndex");
private readonly int _generateGlowID = Shader.PropertyToID("_GenerateGlow");
private readonly int _glowColorID = Shader.PropertyToID("_GlowColor");
private readonly int _glowTypeID = Shader.PropertyToID("_GlowType");
private readonly int _glowParameterID = Shader.PropertyToID("_GlowParameter");
private readonly int _glowMaxLengthID = Shader.PropertyToID("_GlowMaxLength");
protected bool _started = false;
protected virtual void Awake()
{
Hand = _hand as IHand;
}
protected virtual void Start()
{
_glowEnabled = false;
this.BeginStart(ref _started);
Assert.IsNotNull(Hand);
Assert.IsNotNull(_pokeInteractor);
Assert.IsNotNull(_materialEditor);
HandFingerMaskGenerator.GenerateFingerMask(_handRenderer, _handVisual,
_materialEditor.MaterialPropertyBlock);
this.EndStart(ref _started);
}
protected virtual void OnEnable()
{
if (_started)
{
_pokeInteractor.WhenPostprocessed += UpdateVisual;
}
}
protected virtual void OnDisable()
{
if (_started)
{
_pokeInteractor.WhenPostprocessed -= UpdateVisual;
}
}
private void UpdateOvershoot(float normalizedDistance)
{
if (_materialEditor == null) return;
var _block = _materialEditor.MaterialPropertyBlock;
_block.SetFloat(_glowParameterID, Mathf.Clamp01(normalizedDistance));
_block.SetInt(_generateGlowID, 1);
_block.SetColor(_glowColorID, _glowColor);
_block.SetInt(_glowTypeID, (int)_glowType);
_block.SetInt(_glowFingerIndexID, (int)_pokeFinger);
_block.SetFloat(_glowMaxLengthID, _maxGradientLength);
}
private void UpdateVisual()
{
if (_pokeInteractor.State == InteractorState.Select)
{
_glowEnabled = true;
Vector3 planeCenter = _pokeInteractor.TouchPoint;
Vector3 pokeOrigin = _pokeInteractor.Origin;
float normalizedDistance =
Mathf.Clamp01(Vector3.Distance(planeCenter, pokeOrigin) /
_overshootMaxDistance);
UpdateOvershoot(normalizedDistance);
}
else
{
if (_glowEnabled)
{
if (_materialEditor == null) return;
var _block = _materialEditor.MaterialPropertyBlock;
_block.SetInt(_generateGlowID, 0);
_glowEnabled = false;
}
}
}
#region Inject
public void InjectAllHandPokeOvershootGlow(IHand hand, PokeInteractor pokeInteractor,
MaterialPropertyBlockEditor materialEditor, Color glowColor, float distanceMultiplier,
Transform wristTransform, GlowType glowType)
{
InjectHand(hand);
InjectPokeInteractor(pokeInteractor);
InjectMaterialPropertyBlockEditor(materialEditor);
InjectGlowColor(glowColor);
InjectOvershootMaxDistance(distanceMultiplier);
InjectGlowType(glowType);
}
public void InjectAllHandPokeOvershootGlow(IHand hand, PokeInteractor pokeInteractor, HandVisual handVisual, SkinnedMeshRenderer handRenderer, MaterialPropertyBlockEditor materialEditor)
{
InjectHand(hand);
InjectPokeInteractor(pokeInteractor);
InjectHandVisual(handVisual);
InjectHandRenderer(handRenderer);
InjectMaterialPropertyBlockEditor(materialEditor);
}
public void InjectHand(IHand hand)
{
_hand = hand as UnityEngine.Object;
Hand = hand;
}
public void InjectPokeInteractor(PokeInteractor pokeInteractor)
{
_pokeInteractor = pokeInteractor;
}
public void InjectHandRenderer(SkinnedMeshRenderer handRenderer)
{
_handRenderer = handRenderer;
}
public void InjectHandVisual(HandVisual handVisual)
{
_handVisual = handVisual;
}
public void InjectMaterialPropertyBlockEditor(MaterialPropertyBlockEditor materialEditor)
{
_materialEditor = materialEditor;
}
public void InjectGlowColor(Color glowColor)
{
_glowColor = glowColor;
}
public void InjectOvershootMaxDistance(float overshootMaxDistance)
{
_overshootMaxDistance = overshootMaxDistance;
}
public void InjectGlowType(GlowType glowType)
{
_glowType = glowType;
}
#endregion
}
}