// Copyright 2017 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // 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. // Modified by Unity from originals located // https://github.com/googlevr/daydream-elements/blob/master/Assets/DaydreamElements/Elements/ArmModels/Scripts/ArmModels/SwingArmModel.cs using System.Collections; using System.Collections.Generic; using UnityEngine; #if ENABLE_VR || ENABLE_AR using UnityEngine.Experimental.XR.Interaction; namespace UnityEngine.XR.LegacyInputHelpers { public class SwingArmModel : ArmModel { [Tooltip("Portion of controller rotation applied to the shoulder joint.")] [SerializeField] [Range(0.0f, 1.0f)] float m_ShoulderRotationRatio = 0.5f; /// /// Portion of controller rotation applied to the shoulder joint. /// public float shoulderRotationRatio { get { return m_ShoulderRotationRatio; } set { m_ShoulderRotationRatio = value; } } [Tooltip("Portion of controller rotation applied to the elbow joint.")] [Range(0.0f, 1.0f)] [SerializeField] float m_ElbowRotationRatio = 0.3f; /// /// Portion of controller rotation applied to the elbow joint. /// public float elbowRotationRatio { get { return m_ElbowRotationRatio; } set { m_ElbowRotationRatio = value; } } [Tooltip("Portion of controller rotation applied to the wrist joint.")] [Range(0.0f, 1.0f)] [SerializeField] float m_WristRotationRatio = 0.2f; /// /// Portion of controller rotation applied to the wrist joint. /// public float wristRotationRatio { get { return m_WristRotationRatio; } set { m_WristRotationRatio = value; } } [SerializeField] Vector2 m_JointShiftAngle = new Vector2(160.0f, 180.0f); /// /// Min angle of the controller before starting to lerp towards the shifted joint ratios. /// public float minJointShiftAngle { get { return m_JointShiftAngle.x; } set { m_JointShiftAngle.x = value; } } /// /// Max angle of the controller before starting to lerp towards the shifted joint ratios. /// public float maxJointShiftAngle { get { return m_JointShiftAngle.y; } set { m_JointShiftAngle.y = value; } } [Tooltip("Exponent applied to the joint shift ratio to control the curve of the shift.")] [Range(1.0f, 20.0f)] [SerializeField] float m_JointShiftExponent = 6.0f; /// /// Exponent applied to the joint shift ratio to control the curve of the shift. /// public float jointShiftExponent { get { return m_JointShiftExponent; } set { m_JointShiftExponent = value; } } [Tooltip("Portion of controller rotation applied to the shoulder joint when the controller is backwards.")] [Range(0.0f, 1.0f)] [SerializeField] float m_ShiftedShoulderRotationRatio = 0.1f; /// /// Portion of controller rotation applied to the shoulder joint when the controller is backwards. /// public float shiftedShoulderRotationRatio { get { return m_ShiftedShoulderRotationRatio; } set { m_ShiftedShoulderRotationRatio = value; } } [Tooltip("Portion of controller rotation applied to the elbow joint when the controller is backwards.")] [Range(0.0f, 1.0f)] [SerializeField] float m_ShiftedElbowRotationRatio = 0.4f; /// /// Portion of controller rotation applied to the elbow joint when the controller is backwards. /// public float shiftedElbowRotationRatio { get { return m_ShiftedElbowRotationRatio; } set { m_ShiftedElbowRotationRatio = value; } } [Tooltip("Portion of controller rotation applied to the wrist joint when the controller is backwards.")] [Range(0.0f, 1.0f)] [SerializeField] float m_ShiftedWristRotationRatio = 0.5f; /// /// Portion of controller rotation applied to the wrist joint when the controller is backwards. /// public float shiftedWristRotationRatio { get { return m_ShiftedWristRotationRatio; } set { m_ShiftedWristRotationRatio = value; } } protected override void CalculateFinalJointRotations(Quaternion controllerOrientation, Quaternion xyRotation, Quaternion lerpRotation) { // As the controller angle increases the ratio of the rotation applied to each joint shifts. float totalAngle = Quaternion.Angle(xyRotation, Quaternion.identity); float jointShiftAngleRange = maxJointShiftAngle - minJointShiftAngle; float angleRatio = Mathf.Clamp01((totalAngle - minJointShiftAngle) / jointShiftAngleRange); float jointShiftRatio = Mathf.Pow(angleRatio, m_JointShiftExponent); // Calculate what portion of the rotation is applied to each joint. float finalShoulderRatio = Mathf.Lerp(m_ShoulderRotationRatio, m_ShiftedShoulderRotationRatio, jointShiftRatio); float finalElbowRatio = Mathf.Lerp(m_ElbowRotationRatio, m_ShiftedElbowRotationRatio, jointShiftRatio); float finalWristRatio = Mathf.Lerp(m_WristRotationRatio, m_ShiftedWristRotationRatio, jointShiftRatio); // Calculate relative rotations for each joint. Quaternion swingShoulderRot = Quaternion.Lerp(Quaternion.identity, xyRotation, finalShoulderRatio); Quaternion swingElbowRot = Quaternion.Lerp(Quaternion.identity, xyRotation, finalElbowRatio); Quaternion swingWristRot = Quaternion.Lerp(Quaternion.identity, xyRotation, finalWristRatio); // Calculate final rotations. Quaternion shoulderRotation = m_TorsoRotation * swingShoulderRot; m_ElbowRotation = shoulderRotation * swingElbowRot; m_WristRotation = elbowRotation * swingWristRot; m_ControllerRotation = m_TorsoRotation * controllerOrientation; m_TorsoRotation = shoulderRotation; } } } #endif