Transformations.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // A class containing all the basic transformations a renderable object can have.
  4. // This include: Translation, Rotation, and Scale.
  5. //
  6. // Author: Ronen Ness.
  7. // Since: 2017.
  8. //-----------------------------------------------------------------------------
  9. #endregion
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Graphics;
  12. namespace MonoGameSceneGraph
  13. {
  14. /// <summary>
  15. /// Different way to build matrix from transformations.
  16. /// </summary>
  17. public enum TransformOrder
  18. {
  19. /// <summary>
  20. /// Apply position, then rotation, then scale.
  21. /// </summary>
  22. PositionRotationScale,
  23. /// <summary>
  24. /// Apply position, then scale, then rotation.
  25. /// </summary>
  26. PositionScaleRotation,
  27. /// <summary>
  28. /// Apply scale, then position, then rotation.
  29. /// </summary>
  30. ScalePositionRotation,
  31. /// <summary>
  32. /// Apply scale, then rotation, then position.
  33. /// </summary>
  34. ScaleRotationPosition,
  35. /// <summary>
  36. /// Apply rotation, then scale, then position.
  37. /// </summary>
  38. RotationScalePosition,
  39. /// <summary>
  40. /// Apply rotation, then position, then scale.
  41. /// </summary>
  42. RotationPositionScale,
  43. }
  44. /// <summary>
  45. /// Different ways to apply rotation (order in which we rotate the different axis).
  46. /// </summary>
  47. public enum RotationOrder
  48. {
  49. /// <summary>
  50. /// Rotate by axis order X, Y, Z.
  51. /// </summary>
  52. RotateXYZ,
  53. /// <summary>
  54. /// Rotate by axis order X, Z, Y.
  55. /// </summary>
  56. RotateXZY,
  57. /// <summary>
  58. /// Rotate by axis order Y, X, Z.
  59. /// </summary>
  60. RotateYXZ,
  61. /// <summary>
  62. /// Rotate by axis order Y, Z, X.
  63. /// </summary>
  64. RotateYZX,
  65. /// <summary>
  66. /// Rotate by axis order Z, X, Y.
  67. /// </summary>
  68. RotateZXY,
  69. /// <summary>
  70. /// Rotate by axis order Z, Y, X.
  71. /// </summary>
  72. RotateZYX,
  73. }
  74. /// <summary>
  75. /// Contain all the possible node transformations.
  76. /// </summary>
  77. public class Transformations
  78. {
  79. /// <summary>
  80. /// Node position / translation.
  81. /// </summary>
  82. public Vector3 Position;
  83. /// <summary>
  84. /// Node rotation.
  85. /// </summary>
  86. public Vector3 Rotation;
  87. /// <summary>
  88. /// Node scale.
  89. /// </summary>
  90. public Vector3 Scale;
  91. /// <summary>
  92. /// Create new default transformations.
  93. /// </summary>
  94. public Transformations()
  95. {
  96. Position = Vector3.Zero;
  97. Rotation = Vector3.Zero;
  98. Scale = Vector3.One;
  99. }
  100. /// <summary>
  101. /// Clone transformations.
  102. /// </summary>
  103. public Transformations(Transformations other)
  104. {
  105. Position = other.Position;
  106. Rotation = other.Rotation;
  107. Scale = other.Scale;
  108. }
  109. /// <summary>
  110. /// Build and return just the rotation matrix for this treansformations.
  111. /// </summary>
  112. /// <param name="rotationOrder">In which order to apply rotation (axis order) when applying rotation.</param>
  113. /// <returns></returns>
  114. public Matrix BuildRotationMatrix(RotationOrder rotationOrder = RotationOrder.RotateYXZ)
  115. {
  116. switch (rotationOrder)
  117. {
  118. case RotationOrder.RotateXYZ:
  119. return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z);
  120. case RotationOrder.RotateXZY:
  121. return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y);
  122. case RotationOrder.RotateYXZ:
  123. return Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
  124. case RotationOrder.RotateYZX:
  125. return Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X);
  126. case RotationOrder.RotateZXY:
  127. return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y);
  128. case RotationOrder.RotateZYX:
  129. return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationX(Rotation.X);
  130. default:
  131. throw new System.Exception("Unknown rotation order!");
  132. }
  133. }
  134. /// <summary>
  135. /// Build and return a matrix from current transformations.
  136. /// </summary>
  137. /// <param name="transformOrder">In which order to apply transformations to produce final matrix.</param>
  138. /// <param name="rotationOrder">In which order to apply rotation (axis order) when applying rotation.</param>
  139. /// <returns>Matrix with all transformations applied.</returns>
  140. public Matrix BuildMatrix(TransformOrder transformOrder = TransformOrder.ScaleRotationPosition,
  141. RotationOrder rotationOrder = RotationOrder.RotateYXZ)
  142. {
  143. // create the matrix parts
  144. Matrix pos = Matrix.CreateTranslation(Position);
  145. Matrix rot = BuildRotationMatrix(rotationOrder);
  146. Matrix scale = Matrix.CreateScale(Scale);
  147. // build and return matrix based on order
  148. switch (transformOrder)
  149. {
  150. case TransformOrder.PositionRotationScale:
  151. return pos * rot * scale;
  152. case TransformOrder.PositionScaleRotation:
  153. return pos * scale * rot;
  154. case TransformOrder.ScalePositionRotation:
  155. return scale * pos * rot;
  156. case TransformOrder.ScaleRotationPosition:
  157. return scale * rot * pos;
  158. case TransformOrder.RotationScalePosition:
  159. return rot * scale * pos;
  160. case TransformOrder.RotationPositionScale:
  161. return rot * pos * scale;
  162. default:
  163. throw new System.Exception("Unknown build matrix order!");
  164. }
  165. }
  166. }
  167. }