7 #if UNITY_WSA && UNITY_2017_2_OR_NEWER 19 private Transform transformToAffect;
22 private Vector3 initialHandPosition;
23 private Vector3 initialScale;
24 private Vector3 initialPosition;
25 private Vector3 initialOrientation;
26 private Quaternion initialRotation;
27 private Quaternion initialHandOrientation;
28 private Vector3 initialScaleOrigin;
30 private bool isHandRotationAvailable;
31 private bool isLeftHandedRotation =
false;
32 private Vector3 rotationFromPositionScale =
new Vector3(-300.0f, -300.0f, -300.0f);
33 private float minimumScaleNav = 0.001f;
34 private float scaleRate = 1.0f;
35 private float maxScale = 10.0f;
38 private Vector3 lastHandWorldPos = Vector3.zero;
64 public bool IsLeftHandedRotation
68 return isLeftHandedRotation;
73 isLeftHandedRotation = value;
76 public Transform TransformToAffect
80 return transformToAffect;
85 transformToAffect = value;
92 return rotationCoordinateSystem;
96 rotationCoordinateSystem = value;
103 return handMotionForRotation;
107 handMotionForRotation = value;
110 public float ScaleRate
121 public float MaxScale
144 public bool RotateAroundPivot {
get;
set; }
148 isHandRotationAvailable =
true;
150 #if UNITY_WSA && UNITY_2017_2_OR_NEWER 151 if (HolographicSettings.IsDisplayOpaque ==
false)
153 isHandRotationAvailable =
false;
156 cachedRenderer = gameObject.GetComponent<Renderer>();
158 private void Update()
160 if (inputDownEventData != null)
162 Vector3 currentHandPosition = Vector3.zero;
163 Quaternion currentHandOrientation = Quaternion.identity;
166 currentHandPosition = GetHandPosition(inputDownEventData.
SourceId);
167 if (isHandRotationAvailable)
169 currentHandOrientation = GetHandOrientation(inputDownEventData.
SourceId);
175 ApplyScale(currentHandPosition);
181 ApplyRotation(currentHandOrientation);
185 ApplyRotation(currentHandPosition);
189 lastHandWorldPos = currentHandPosition;
193 private Vector3 GetHandPosition(uint sourceId)
195 Vector3 handPosition =
new Vector3(0, 0, 0);
199 private Quaternion GetHandOrientation(uint sourceId)
201 Quaternion handOrientation = Quaternion.identity;
203 return handOrientation;
205 private void ApplyScale(Vector3 currentHandPosition)
207 if ((transformToAffect.position - initialHandPosition).magnitude > minimumScaleNav)
209 float scaleScalar = (currentHandPosition - transformToAffect.position).magnitude / (transformToAffect.position - initialHandPosition).magnitude;
210 scaleScalar = Mathf.Pow(scaleScalar, scaleRate);
211 Vector3 changeScale =
new Vector3(scaleScalar, scaleScalar, scaleScalar);
212 changeScale = GetBoundedScaleChange(changeScale);
214 Vector3 newScale = changeScale;
215 newScale.Scale(initialScale);
218 transformToAffect.localScale = newScale;
221 Vector3 currentScaleOrigin = initialScaleOrigin;
222 currentScaleOrigin.Scale(changeScale);
223 Vector3 postScaleOffset = currentScaleOrigin - initialScaleOrigin;
226 transformToAffect.position = initialPosition - postScaleOffset;
229 private void ApplyRotation(Quaternion currentHandOrientation)
231 #if UNITY_2017_1_OR_NEWER 232 Matrix4x4 m = Matrix4x4.Rotate(initialHandOrientation);
233 Vector3 initRay =
new Vector3(0, 0, 1);
234 initRay = m.MultiplyPoint(initRay);
237 m = Matrix4x4.Rotate(currentHandOrientation);
238 Vector3 currentRay =
new Vector3(0, 0, 1);
239 currentRay = m.MultiplyPoint(currentRay);
240 currentRay.Normalize();
242 float angle = Vector3.Dot(initRay, currentRay);
243 angle = Mathf.Acos(angle) * Mathf.Rad2Deg;
244 if (Mathf.Abs(initRay.y - currentRay.y) < Mathf.Abs(initRay.x - currentRay.x))
246 if (Vector3.Cross(initRay, currentRay).y > 0)
251 else if (Vector3.Cross(initRay, currentRay).x > 0)
259 newEulers += initialOrientation;
260 transformToAffect.rotation = Quaternion.Euler(newEulers);
265 transformToAffect.localRotation = initialRotation;
266 transformToAffect.Rotate(axis, angle * 5.0f);
268 #endif // UNITY_2017_1_OR_NEWER 270 private void ApplyRotation(Vector3 currentHandPosition)
272 if (RotateAroundPivot)
274 ApplyRotationPivot(currentHandPosition);
278 ApplyRotationContinuous(currentHandPosition);
282 private void ApplyRotationContinuous(Vector3 currentHandPosition)
284 Vector3 initialRay = initialHandPosition - transformToAffect.position;
285 initialRay.Normalize();
287 Vector3 currentRay = currentHandPosition - transformToAffect.position;
288 currentRay.Normalize();
290 Vector3 delta = currentRay - initialRay;
291 delta.Scale(rotationFromPositionScale);
293 Vector3 newEulers =
new Vector3(0, 0, 0);
296 newEulers =
new Vector3(-delta.y, 0, 0);
300 newEulers =
new Vector3(0, delta.x, 0);
304 newEulers =
new Vector3(0, 0, delta.y);
306 if (IsLeftHandedRotation)
308 newEulers.Scale(
new Vector3(-1.0f, -1.0f, -1.0f));
313 newEulers += initialOrientation;
314 transformToAffect.rotation = Quaternion.Euler(newEulers);
319 transformToAffect.localRotation = initialRotation;
320 float angle = newEulers.x != 0 ? newEulers.x : newEulers.y != 0 ? newEulers.y : newEulers.z;
321 transformToAffect.Rotate(axis, angle * 2.0f);
325 private void ApplyRotationPivot(Vector3 currentHandPosition)
327 Vector3 delta = currentHandPosition - lastHandWorldPos;
329 if (delta.sqrMagnitude == 0) {
return; }
331 delta.Scale(rotationFromPositionScale);
333 var pivotToHandleDir = (transform.position - transformToAffect.position).normalized;
338 transformToAffect.Rotate(Vector3.right, Vector3.Dot(delta, Vector3.Cross(pivotToHandleDir, transformToAffect.right)), Space.Self);
341 transformToAffect.Rotate(Vector3.up, Vector3.Dot(delta, Vector3.Cross(pivotToHandleDir, transformToAffect.up)), Space.Self);
344 transformToAffect.Rotate(Vector3.forward, Vector3.Dot(delta, Vector3.Cross(pivotToHandleDir, transformToAffect.forward)), Space.Self);
349 private Vector3 GetBoundedScaleChange(Vector3 scale)
351 Vector3 maximumScale =
new Vector3(initialScale.x * maxScale, initialScale.y * maxScale, initialScale.z * maxScale);
352 Vector3 intendedFinalScale =
new Vector3(initialScale.x, initialScale.y, initialScale.z);
353 intendedFinalScale.Scale(scale);
354 if (intendedFinalScale.x > maximumScale.x || intendedFinalScale.y > maximumScale.y || intendedFinalScale.z > maximumScale.z)
356 return new Vector3(maximumScale.x / initialScale.x, maximumScale.y / initialScale.y, maximumScale.z / initialScale.z);
362 private Renderer cachedRenderer;
364 private void ResetRigHandles()
366 inputDownEventData = null;
370 cachedRenderer.sharedMaterial = Rig.ScaleHandleMaterial;
374 cachedRenderer.sharedMaterial = Rig.RotateHandleMaterial;
378 Rig.FocusOnHandle(null);
383 inputDownEventData = eventData;
385 initialHandPosition = GetHandPosition(eventData.
SourceId);
386 lastHandWorldPos = initialHandPosition;
387 initialScale = transformToAffect.localScale;
388 initialPosition = transformToAffect.position;
389 initialOrientation = transformToAffect.rotation.eulerAngles;
390 initialRotation = transformToAffect.rotation;
391 initialHandOrientation = GetHandOrientation(eventData.
SourceId);
392 initialScaleOrigin = transformToAffect.position - this.transform.position;
396 cachedRenderer.sharedMaterial = Rig.InteractingMaterial;
397 Rig.FocusOnHandle(this.gameObject);
402 inputDownEventData = null;
405 if (eventData != null)
416 if ((inputDownEventData != null) &&
419 inputDownEventData = null;