/// <summary> /// Convert a Transform array into matrix 4x3 format, stored as a Vector4 array /// </summary> public static Vector4[] GetTransformArrayAsMatrix4x3(Transform[] source, Vector4[] transforms) { if (source == null) throw new ArgumentNullException(); for (int i = 0, j = 0; i < source.Length; i++) { float xx = source[i].Rotation.X * source[i].Rotation.X; float yy = source[i].Rotation.Y * source[i].Rotation.Y; float zz = source[i].Rotation.Z * source[i].Rotation.Z; float xy = source[i].Rotation.X * source[i].Rotation.Y; float zw = source[i].Rotation.Z * source[i].Rotation.W; float zx = source[i].Rotation.Z * source[i].Rotation.X; float yw = source[i].Rotation.Y * source[i].Rotation.W; float yz = source[i].Rotation.Y * source[i].Rotation.Z; float xw = source[i].Rotation.X * source[i].Rotation.W; if (source[i].Scale == 1) { transforms[j].X = 1f - (2f * (yy + zz));//x transforms[j].Y = 2f * (xy - zw);//y transforms[j].Z = 2f * (zx + yw);//z transforms[j].W = source[i].Translation.X; j++; transforms[j].X = 2f * (xy + zw);//x transforms[j].Y = 1f - (2f * (zz + xx));//y transforms[j].Z = 2f * (yz - xw);//z transforms[j].W = source[i].Translation.Y; j++; transforms[j].X = 2f * (zx - yw);//x transforms[j].Y = 2f * (yz + xw);//y transforms[j].Z = 1f - (2f * (yy + xx));//z transforms[j].W = source[i].Translation.Z; j++; } else { transforms[j].X = (1f - (2f * (yy + zz))) * source[i].Scale;//x transforms[j].Y = (2f * (xy - zw)) * source[i].Scale;//y transforms[j].Z = (2f * (zx + yw)) * source[i].Scale;//z transforms[j].W = source[i].Translation.X; j++; transforms[j].X = (2f * (xy + zw)) * source[i].Scale;//x transforms[j].Y = (1f - (2f * (zz + xx))) * source[i].Scale;//y transforms[j].Z = (2f * (yz - xw)) * source[i].Scale;//z transforms[j].W = source[i].Translation.Y; j++; transforms[j].X = (2f * (zx - yw)) * source[i].Scale;//x transforms[j].Y = (2f * (yz + xw)) * source[i].Scale;//y transforms[j].Z = (1f - (2f * (yy + xx))) * source[i].Scale;//z transforms[j].W = source[i].Translation.Z; j++; } } return transforms; }
/// <summary> /// Multiply two transforms /// </summary> /// <param name="transform1"></param> /// <param name="transform2"></param> /// <param name="result"></param> public static void Multiply(ref Transform transform1, ref Transform transform2, out Transform result) { Quaternion q; Vector3 t; float s = transform2.Scale * transform1.Scale; transform2.Rotation.Normalize(); if (transform2.Rotation.W == 1 && (transform2.Rotation.X == 0 && transform2.Rotation.Y == 0 && transform2.Rotation.Z == 0)) { q.X = transform1.Rotation.X; q.Y = transform1.Rotation.Y; q.Z = transform1.Rotation.Z; q.W = transform1.Rotation.W; t.X = transform1.Translation.X; t.Y = transform1.Translation.Y; t.Z = transform1.Translation.Z; } else { float num12 = transform2.Rotation.X + transform2.Rotation.X; float num2 = transform2.Rotation.Y + transform2.Rotation.Y; float num = transform2.Rotation.Z + transform2.Rotation.Z; float num11 = transform2.Rotation.W * num12; float num10 = transform2.Rotation.W * num2; float num9 = transform2.Rotation.W * num; float num8 = transform2.Rotation.X * num12; float num7 = transform2.Rotation.X * num2; float num6 = transform2.Rotation.X * num; float num5 = transform2.Rotation.Y * num2; float num4 = transform2.Rotation.Y * num; float num3 = transform2.Rotation.Z * num; t.X = ((transform1.Translation.X * ((1f - num5) - num3)) + (transform1.Translation.Y * (num7 - num9))) + (transform1.Translation.Z * (num6 + num10)); t.Y = ((transform1.Translation.X * (num7 + num9)) + (transform1.Translation.Y * ((1f - num8) - num3))) + (transform1.Translation.Z * (num4 - num11)); t.Z = ((transform1.Translation.X * (num6 - num10)) + (transform1.Translation.Y * (num4 + num11))) + (transform1.Translation.Z * ((1f - num8) - num5)); num12 = (transform2.Rotation.Y * transform1.Rotation.Z) - (transform2.Rotation.Z * transform1.Rotation.Y); num11 = (transform2.Rotation.Z * transform1.Rotation.X) - (transform2.Rotation.X * transform1.Rotation.Z); num10 = (transform2.Rotation.X * transform1.Rotation.Y) - (transform2.Rotation.Y * transform1.Rotation.X); num9 = ((transform2.Rotation.X * transform1.Rotation.X) + (transform2.Rotation.Y * transform1.Rotation.Y)) + (transform2.Rotation.Z * transform1.Rotation.Z); q.X = ((transform2.Rotation.X * transform1.Rotation.W) + (transform1.Rotation.X * transform2.Rotation.W)) + num12; q.Y = ((transform2.Rotation.Y * transform1.Rotation.W) + (transform1.Rotation.Y * transform2.Rotation.W)) + num11; q.Z = ((transform2.Rotation.Z * transform1.Rotation.W) + (transform1.Rotation.Z * transform2.Rotation.W)) + num10; q.W = (transform2.Rotation.W * transform1.Rotation.W) - num9; } t.X = t.X * transform2.Scale + transform2.Translation.X; t.Y = t.Y * transform2.Scale + transform2.Translation.Y; t.Z = t.Z * transform2.Scale + transform2.Translation.Z; #if XBOX360 result = new Transform(); #endif result.Rotation.X = q.X; result.Rotation.Y = q.Y; result.Rotation.Z = q.Z; result.Rotation.W = q.W; result.Translation.X = t.X; result.Translation.Y = t.Y; result.Translation.Z = t.Z; result.Scale = s; }
/// <summary> /// Interpolate to another transform /// </summary> /// <param name="to"></param> /// <param name="amount"></param> /// <returns></returns> public Transform Interpolate(Transform to, float amount) { Transform result; Interpolate(ref this, ref to, amount, out result); return result; }
/// <summary> /// Construct the transform from a binary source /// </summary> /// <param name="reader"></param> public Transform(BinaryReader reader) { #if XBOX360 this = new Transform(); #endif Rotation.X = reader.ReadSingle(); Rotation.Y = reader.ReadSingle(); Rotation.Z = reader.ReadSingle(); Rotation.W = reader.ReadSingle(); Translation.X = reader.ReadSingle(); Translation.Y = reader.ReadSingle(); Translation.Z = reader.ReadSingle(); Scale = reader.ReadSingle(); }
/// <summary> /// Interpolate between two transforms /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="amount"></param> /// <param name="result"></param> public static void Interpolate(ref Transform from, ref Transform to, float amount, out Transform result) { result = new Transform(); Quaternion.Lerp(ref from.Rotation, ref to.Rotation, amount, out result.Rotation); Vector3.Lerp(ref from.Translation, ref to.Translation, amount, out result.Translation); result.Scale = from.Scale + ((to.Scale - from.Scale) * amount); }