/* * 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 UnityEngine; namespace Oculus.Interaction.HandGrab.Visuals { /// /// A static (non-user controlled) representation of a hand. This script is used /// to be able to manually visualize hand grab poses. /// [RequireComponent(typeof(HandPuppet))] public class HandGhost : MonoBehaviour { /// /// The puppet is used to actually move the representation of the hand. /// [SerializeField] private HandPuppet _puppet; /// /// The actual root of the hand hierarchy /// [SerializeField, Optional] private Transform _root; public Transform Root => _root; /// /// The HandGrab point can be set so the ghost automatically /// adopts the desired pose of said point. /// [SerializeField, Optional] [UnityEngine.Serialization.FormerlySerializedAs("_handGrabPoint")] private HandGrabPose _handGrabPose; #region editor events protected virtual void Reset() { _puppet = this.GetComponent(); _handGrabPose = this.GetComponentInParent(); } protected virtual void OnValidate() { if (_puppet == null) { return; } if (_handGrabPose == null) { HandGrabPose point = this.GetComponentInParent(); if (point != null) { SetPose(point); } } else if (_handGrabPose != null) { SetPose(_handGrabPose); } } #endregion protected virtual void Start() { this.AssertField(_puppet, nameof(_puppet)); if (_root == null) { _root = this.transform; } } /// /// Relay to the Puppet to set the ghost hand to the desired static pose /// /// The point to read the HandPose from public void SetPose(HandGrabPose handGrabPose) { HandPose userPose = handGrabPose.HandPose; if (userPose == null) { return; } _puppet.SetJointRotations(userPose.JointRotations); SetRootPose(handGrabPose.RelativePose, handGrabPose.RelativeTo); } public void SetPose(HandPose userPose, Pose rootPose) { _puppet.SetJointRotations(userPose.JointRotations); _puppet.SetRootPose(rootPose); } /// /// Moves the underlying puppet so the wrist point aligns with the given parameters /// /// The relative wrist pose to align the hand to /// The object to use as anchor public void SetRootPose(Pose rootPose, Transform relativeTo) { Pose pose = rootPose; if (relativeTo != null) { pose = PoseUtils.GlobalPoseScaled(relativeTo, rootPose); } _puppet.SetRootPose(pose); } #region Inject public void InjectAllHandGhost(HandPuppet puppet) { InjectHandPuppet(puppet); } public void InjectHandPuppet(HandPuppet puppet) { _puppet = puppet; } public void InjectOptionalHandGrabPose(HandGrabPose handGrabPose) { _handGrabPose = handGrabPose; } public void InjectOptionalRoot(Transform root) { _root = root; } #endregion } }