119 lines
4.2 KiB
C#
119 lines
4.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Fusion;
|
|
using Fusion.XR.Host.Rig;
|
|
|
|
namespace Fusion.XR.Host.SimpleHands
|
|
{
|
|
public class OSFHandRepresentation : MonoBehaviour, IHandRepresentation
|
|
{
|
|
|
|
public HandCommand currentCommand;
|
|
|
|
public SkinnedMeshRenderer handMeshRenderer;
|
|
public Animator handAnimator;
|
|
|
|
[Header("Animation layers and configuration")]
|
|
public string pinchAnimationParameter = "Pinch";
|
|
public string flexAnimationParameter = "Flex";
|
|
public string poseAnimationParameter = "Pose";
|
|
public string pointAnimationLayer = "Point Layer";
|
|
public string thumbAnimationLayer = "Thumb Layer";
|
|
public float maxGripToPinch = 0.05f;
|
|
|
|
private void Awake()
|
|
{
|
|
if (handMeshRenderer == null) handMeshRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
|
if (handAnimator == null) handAnimator = GetComponentInChildren<Animator>();
|
|
if (handAnimator == null) handAnimator = GetComponentInParent<Animator>();
|
|
}
|
|
|
|
public bool IsMeshDisplayed => handMeshRenderer.enabled;
|
|
|
|
public void DisplayMesh(bool shouldDisplay)
|
|
{
|
|
if(handMeshRenderer && handMeshRenderer.enabled != shouldDisplay) handMeshRenderer.enabled = shouldDisplay;
|
|
}
|
|
|
|
public Material SharedHandMaterial => handMeshRenderer != null ? handMeshRenderer.sharedMaterial : null;
|
|
|
|
public virtual void SetHandColor(Color color)
|
|
{
|
|
handMeshRenderer.material.color = color;
|
|
}
|
|
public virtual void SetHandMaterial(Material material)
|
|
{
|
|
handMeshRenderer.sharedMaterial = material;
|
|
}
|
|
|
|
public void SetHandCommand(HandCommand command)
|
|
{
|
|
currentCommand = AnalyseCommand(command);
|
|
}
|
|
|
|
public virtual HandCommand AnalyseCommand(HandCommand command)
|
|
{
|
|
if (command.indexTouchedCommand == 1)
|
|
{
|
|
// Index is resting on the button: force a minimal value for trigger
|
|
command.triggerCommand = 0.5f + command.triggerCommand/2;
|
|
}
|
|
if (command.thumbTouchedCommand == 1 && command.triggerCommand >= 0.5f)
|
|
{
|
|
// Thumb and index are pressed: should we pinch ? => only if grip is not pressed
|
|
if (command.gripCommand < maxGripToPinch)
|
|
{
|
|
command.pinchCommand = 1f - command.triggerCommand;
|
|
}
|
|
}
|
|
return command;
|
|
}
|
|
|
|
int pointAnimationLayerIndex = -1;
|
|
int thumbAnimationLayerIndex = -1;
|
|
bool layerIndexFound = false;
|
|
public virtual void ApplyCommand(HandCommand command) {
|
|
command = AnalyseCommand(command);
|
|
|
|
if (!layerIndexFound)
|
|
{
|
|
layerIndexFound = true;
|
|
pointAnimationLayerIndex = handAnimator.GetLayerIndex(pointAnimationLayer);
|
|
thumbAnimationLayerIndex = handAnimator.GetLayerIndex(thumbAnimationLayer);
|
|
}
|
|
// Apply layers
|
|
float pointRaisedLayerWeight = 1f - command.triggerCommand;
|
|
handAnimator.SetLayerWeight(pointAnimationLayerIndex, pointRaisedLayerWeight);
|
|
float thumbRaisedLayerWeight = 1f - command.thumbTouchedCommand;
|
|
handAnimator.SetLayerWeight(thumbAnimationLayerIndex, thumbRaisedLayerWeight);
|
|
|
|
// Apply parameters
|
|
float flexParameterValue = command.gripCommand;
|
|
handAnimator.SetFloat(flexAnimationParameter, flexParameterValue);
|
|
float pinchParameterValue = 1f - command.pinchCommand;
|
|
handAnimator.SetFloat(pinchAnimationParameter, pinchParameterValue);
|
|
int poseParameterValue = command.poseCommand;
|
|
handAnimator.SetInteger(poseAnimationParameter, poseParameterValue);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!isVisible) return;
|
|
ApplyCommand(currentCommand);
|
|
}
|
|
|
|
public bool isVisible { get; set; } = false;
|
|
private void OnBecameVisible()
|
|
{
|
|
isVisible = true;
|
|
}
|
|
|
|
private void OnBecameInvisible()
|
|
{
|
|
isVisible = false;
|
|
}
|
|
|
|
}
|
|
}
|