public static Quaternion EulerToQuaternion(Vector3 eulerAngle) { //角度转弧度 eulerAngle = MoMath.Deg2Rad(eulerAngle); float cX = MathF.Cos(eulerAngle.X / 2.0f); float sX = MathF.Sin(eulerAngle.X / 2.0f); float cY = MathF.Cos(eulerAngle.Y / 2.0f); float sY = MathF.Sin(eulerAngle.Y / 2.0f); float cZ = MathF.Cos(eulerAngle.Z / 2.0f); float sZ = MathF.Sin(eulerAngle.Z / 2.0f); Quaternion qX = new Quaternion(sX, 0, 0, cX); Quaternion qY = new Quaternion(0, sY, 0, cY); Quaternion qZ = new Quaternion(0, 0, sZ, cZ); Quaternion q = (qY * qX) * qZ; #if DEBUG if (!MoMath.CompareApproximate(q.LengthSquared(), 1f)) { string msg = string.Format($"EulerToQuaternion failed, {q.X} {q.Y} {q.Z} {q.W} sqrLength={q.LengthSquared()}"); MoLog.Log(ELogType.Assert, msg); } #endif return(q); }
/// <summary> /// Rotates the transform around axis by angle /// </summary> public void Rotate(Vector3 worldAxis, float degreeAngle) { float radianAngle = MoMath.Deg2Rad(degreeAngle); Vector3 localAxis = InverseTransformDirection(worldAxis); if (localAxis.LengthSquared() > Vector3Helper.Epsilon) { localAxis = Vector3Helper.NormalizeSafe(localAxis); Quaternion q = QuaternionHelper.AxisAngleToQuaternionSafe(localAxis, radianAngle); Rotation = QuaternionHelper.NormalizeSafe(_rotation * q); } }
/// <summary> /// Rotates the transform around axis by angle /// </summary> public void Rotate(Vector3 worldPoint, Vector3 worldAxis, float degreeAngle) { // 先移动位置 Quaternion q = QuaternionHelper.AxisAngleToQuaternionSafe(worldAxis, MoMath.Deg2Rad(degreeAngle)); Vector3 dif = _position - worldPoint; dif = QuaternionHelper.RotateVectorByQuat(q, dif); Position = worldPoint + dif; // 再移动朝向 Rotate(worldAxis, degreeAngle); }