You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					220 lines
				
				6.4 KiB
			
		
		
			
		
	
	
					220 lines
				
				6.4 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using System;
							 | 
						||
| 
								 | 
							
								using UnityEngine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace HTC.UnityPlugin.Utility
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    [Serializable]
							 | 
						||
| 
								 | 
							
								    public struct RigidPose
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        public Vector3 pos;
							 | 
						||
| 
								 | 
							
								        public Quaternion rot;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static RigidPose identity
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            get { return new RigidPose(Vector3.zero, Quaternion.identity); }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public RigidPose(Vector3 pos, Quaternion rot)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            this.pos = pos;
							 | 
						||
| 
								 | 
							
								            this.rot = rot;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public RigidPose(Transform t, bool useLocal = false)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (t == null)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                pos = Vector3.zero;
							 | 
						||
| 
								 | 
							
								                rot = Quaternion.identity;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (!useLocal)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                pos = t.position;
							 | 
						||
| 
								 | 
							
								                rot = t.rotation;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                pos = t.localPosition;
							 | 
						||
| 
								 | 
							
								                rot = t.localRotation;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public Vector3 forward { get { return rot * Vector3.forward; } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public Vector3 right { get { return rot * Vector3.right; } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public Vector3 up { get { return rot * Vector3.up; } }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public override bool Equals(object o)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (o is RigidPose)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                var t = (RigidPose)o;
							 | 
						||
| 
								 | 
							
								                return pos == t.pos && rot == t.rot;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public override int GetHashCode()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return pos.GetHashCode() ^ rot.GetHashCode();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static bool operator ==(RigidPose a, RigidPose b)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								                a.pos.x == b.pos.x &&
							 | 
						||
| 
								 | 
							
								                a.pos.y == b.pos.y &&
							 | 
						||
| 
								 | 
							
								                a.pos.z == b.pos.z &&
							 | 
						||
| 
								 | 
							
								                a.rot.x == b.rot.x &&
							 | 
						||
| 
								 | 
							
								                a.rot.y == b.rot.y &&
							 | 
						||
| 
								 | 
							
								                a.rot.z == b.rot.z &&
							 | 
						||
| 
								 | 
							
								                a.rot.w == b.rot.w;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static bool operator !=(RigidPose a, RigidPose b)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return !(a == b);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static RigidPose operator *(RigidPose a, RigidPose b)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return new RigidPose
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                rot = a.rot * b.rot,
							 | 
						||
| 
								 | 
							
								                pos = a.pos + a.rot * b.pos
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void Multiply(RigidPose a, RigidPose b)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            rot = a.rot * b.rot;
							 | 
						||
| 
								 | 
							
								            pos = a.pos + a.rot * b.pos;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void Inverse()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            rot = Quaternion.Inverse(rot);
							 | 
						||
| 
								 | 
							
								            pos = -(rot * pos);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public RigidPose GetInverse()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            var t = new RigidPose(pos, rot);
							 | 
						||
| 
								 | 
							
								            t.Inverse();
							 | 
						||
| 
								 | 
							
								            return t;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public Vector3 InverseTransformPoint(Vector3 point)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return Quaternion.Inverse(rot) * (point - pos);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public Vector3 TransformPoint(Vector3 point)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return pos + (rot * point);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static RigidPose Lerp(RigidPose a, RigidPose b, float t)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return new RigidPose(Vector3.Lerp(a.pos, b.pos, t), Quaternion.Slerp(a.rot, b.rot, t));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void Lerp(RigidPose to, float t)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            pos = Vector3.Lerp(pos, to.pos, t);
							 | 
						||
| 
								 | 
							
								            rot = Quaternion.Slerp(rot, to.rot, t);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static RigidPose LerpUnclamped(RigidPose a, RigidPose b, float t)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return new RigidPose(Vector3.LerpUnclamped(a.pos, b.pos, t), Quaternion.SlerpUnclamped(a.rot, b.rot, t));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public void LerpUnclamped(RigidPose to, float t)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            pos = Vector3.LerpUnclamped(pos, to.pos, t);
							 | 
						||
| 
								 | 
							
								            rot = Quaternion.SlerpUnclamped(rot, to.rot, t);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void SetPose(Transform target, RigidPose pose, Transform origin = null)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (origin != null && origin != target.parent)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                target.position = origin.transform.TransformPoint(pose.pos);
							 | 
						||
| 
								 | 
							
								                target.rotation = origin.rotation * pose.rot;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                target.localPosition = pose.pos;
							 | 
						||
| 
								 | 
							
								                target.localRotation = pose.rot;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // proper following duration is larger then 0.02 second, depends on the update rate
							 | 
						||
| 
								 | 
							
								        public static void SetRigidbodyVelocity(Rigidbody rigidbody, Vector3 from, Vector3 to, float duration)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            var diffPos = to - from;
							 | 
						||
| 
								 | 
							
								            if (Mathf.Approximately(diffPos.sqrMagnitude, 0f))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                rigidbody.velocity = Vector3.zero;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                rigidbody.velocity = diffPos / duration;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // proper folloing duration is larger then 0.02 second, depends on the update rate
							 | 
						||
| 
								 | 
							
								        public static void SetRigidbodyAngularVelocity(Rigidbody rigidbody, Quaternion from, Quaternion to, float duration, bool overrideMaxAngularVelocity = true)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            float angle;
							 | 
						||
| 
								 | 
							
								            Vector3 axis;
							 | 
						||
| 
								 | 
							
								            var fromToRot = to * Quaternion.Inverse(from);
							 | 
						||
| 
								 | 
							
								            fromToRot.ToAngleAxis(out angle, out axis);
							 | 
						||
| 
								 | 
							
								            while (angle > 180f) { angle -= 360f; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (Mathf.Approximately(angle, 0f) || float.IsNaN(axis.x) || float.IsNaN(axis.y) || float.IsNaN(axis.z))
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                rigidbody.angularVelocity = Vector3.zero;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                angle *= Mathf.Deg2Rad / duration; // convert to radius speed
							 | 
						||
| 
								 | 
							
								                if (overrideMaxAngularVelocity && rigidbody.maxAngularVelocity < angle) { rigidbody.maxAngularVelocity = angle; }
							 | 
						||
| 
								 | 
							
								                rigidbody.angularVelocity = axis * angle;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static RigidPose FromToPose(RigidPose from, RigidPose to)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            var invRot = Quaternion.Inverse(from.rot);
							 | 
						||
| 
								 | 
							
								            return new RigidPose(invRot * (to.pos - from.pos), invRot * to.rot);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if  UNITY_2017_2_OR_NEWER
							 | 
						||
| 
								 | 
							
								        public static implicit operator RigidPose(Pose v)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return new RigidPose(v.position, v.rotation);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static implicit operator Pose(RigidPose v)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return new Pose(v.pos, v.rot);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public override string ToString()
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return "{p" + pos.ToString() + ",r" + rot.ToString() + "}";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public string ToString(string format)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            return "{p" + pos.ToString(format) + ",r" + rot.ToString(format) + "}";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |