/// <summary> /// Looks at target. /// </summary> /// <param name="target">Target.</param> public void LookAt(UTransform target) { var dir = target.position - this.position; if (dir.sqrMagnitude < MathHelper.Epsilon) { return; } rotation = UQuaternion.LookRotation(dir.normalized); }
/// <param name="q">Q.</param> /// <param name="v">V.</param> public static UVector3 operator *(UQuaternion q, UVector3 v) { var n = v; UQuaternion vecq = identity, resQ = identity; vecq.Xyz = n; vecq.w = 1; resQ = vecq * q.conjugated; resQ = q * resQ; return(new UVector3(resQ.x, resQ.y, resQ.z)); }
/// <summary> /// Do Spherical linear interpolation between two quaternions /// </summary> /// <param name="q1">The first quaternion</param> /// <param name="q2">The second quaternion</param> /// <param name="blend">The blend factor</param> /// <returns>A smooth blend between the given quaternions</returns> public static UQuaternion Slerp(UQuaternion q1, UQuaternion q2, float blend) { // if either input is zero, return the other. if (q1.LengthSquared == 0.0f) { if (q2.LengthSquared == 0.0f) { return(identity); } return(q2); } else if (q2.LengthSquared == 0.0f) { return(q1); } float cosHalfAngle = q1.w * q2.w + UVector3.Dot(q1.Xyz, q2.Xyz); if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) { // angle = 0.0f, so just return one input. return(q1); } else if (cosHalfAngle < 0.0f) { q2.Xyz = -q2.Xyz; q2.w = -q2.w; cosHalfAngle = -cosHalfAngle; } float blendA; float blendB; if (cosHalfAngle < 0.99f) { // do proper slerp for big angles float halfAngle = (float)System.Math.Acos(cosHalfAngle); float sinHalfAngle = (float)System.Math.Sin(halfAngle); float oneOverSinHalfAngle = 1.0f / sinHalfAngle; blendA = (float)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle; blendB = (float)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle; } else { // do lerp if angle is really small. blendA = 1.0f - blend; blendB = blend; } var result = new UQuaternion( blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.w + blendB * q2.w); if (result.LengthSquared > 0.0f) { return(Normalize(result)); } else { return(identity); } }
/// <summary> /// Normaliz the specified q. /// </summary> /// <param name="q">Q.</param> public static UQuaternion Normalize(UQuaternion q) { q.Normalize(); return(q); }
/// <summary> /// Decompose the specified m, trans, rotation and scale. /// </summary> /// <param name="m">M.</param> /// <param name="trans">Trans.</param> /// <param name="rotation">Rotation.</param> /// <param name="scale">Scale.</param> public static void Decompose(UMatrix4x4 m, out UVector3 trans, out UQuaternion rotation, out UVector3 scale) { trans = m.Translate; rotation = m.Rotation; scale = m.Scale; }
/// <summary> /// Creates the rotation. /// </summary> /// <returns>The rotation.</returns> /// <param name="rot">Rot.</param> public static UMatrix4x4 CreateRotation(UQuaternion rot) { return(rot.ToMartix()); }
/// <summary> /// Creates the TRS. /// </summary> /// <returns>The TR.</returns> /// <param name="trans">Trans.</param> /// <param name="rot">Rot.</param> /// <param name="scale">Scale.</param> public static UMatrix4x4 TRS(UVector3 trans, UQuaternion rot, UVector3 scale) { return(CreateTranslate(trans) * CreateRotation(rot) * CreateScale(scale)); }