SwingArmModel.cs
6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// 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;
/// <summary>
/// Portion of controller rotation applied to the shoulder joint.
/// </summary>
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;
/// <summary>
/// Portion of controller rotation applied to the elbow joint.
/// </summary>
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;
/// <summary>
/// Portion of controller rotation applied to the wrist joint.
/// </summary>
public float wristRotationRatio
{
get { return m_WristRotationRatio; }
set { m_WristRotationRatio = value; }
}
[SerializeField]
Vector2 m_JointShiftAngle = new Vector2(160.0f, 180.0f);
/// <summary>
/// Min angle of the controller before starting to lerp towards the shifted joint ratios.
/// </summary>
public float minJointShiftAngle
{
get { return m_JointShiftAngle.x; }
set { m_JointShiftAngle.x = value; }
}
/// <summary>
/// Max angle of the controller before starting to lerp towards the shifted joint ratios.
/// </summary>
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;
/// <summary>
/// Exponent applied to the joint shift ratio to control the curve of the shift.
/// </summary>
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;
/// <summary>
/// Portion of controller rotation applied to the shoulder joint when the controller is backwards.
/// </summary>
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;
/// <summary>
/// Portion of controller rotation applied to the elbow joint when the controller is backwards.
/// </summary>
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;
/// <summary>
/// Portion of controller rotation applied to the wrist joint when the controller is backwards.
/// </summary>
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