matrixSet.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _MATRIXSET_H_
  23. #define _MATRIXSET_H_
  24. #ifndef _MMATRIX_H_
  25. #include "math/mMatrix.h"
  26. #endif
  27. #ifndef _UTIL_DELEGATE_H_
  28. #include "core/util/delegate.h"
  29. #endif
  30. #ifndef _MATRIXSETDELEGATES_H_
  31. #include "math/util/matrixSetDelegateMethods.h"
  32. #endif
  33. dALIGN_BEGIN
  34. class MatrixSet
  35. {
  36. typedef Delegate<const MatrixF &()> MatrixEvalDelegate;
  37. enum _Transforms
  38. {
  39. ObjectToWorld = 0, // World
  40. WorldToCamera, // View
  41. CameraToScreen, // Projection
  42. ScreenToCamera, // Projection^-1
  43. ObjectToScreen, // World * View * Proj
  44. ObjectToCamera, // World * View
  45. WorldToObject, // World^-1
  46. CameraToWorld, // View^-1
  47. CameraToObject, // (World * View)^-1
  48. WorldToScreen, // View * Projection
  49. SceneView, // The View matrix for the SceneState
  50. SceneProjection, // The Projection matrix for the SceneState
  51. NumTransforms,
  52. };
  53. MatrixF mTransform[NumTransforms];
  54. MatrixEvalDelegate mEvalDelegate[NumTransforms];
  55. const MatrixF *mViewSource;
  56. const MatrixF *mProjectionSource;
  57. MATRIX_SET_GET_VALUE(ObjectToWorld);
  58. MATRIX_SET_GET_VALUE(WorldToCamera);
  59. MATRIX_SET_GET_VALUE(CameraToScreen);
  60. MATRIX_SET_GET_VALUE(ScreenToCamera);
  61. MATRIX_SET_GET_VALUE(ObjectToCamera);
  62. MATRIX_SET_GET_VALUE(WorldToObject);
  63. MATRIX_SET_GET_VALUE(CameraToWorld);
  64. MATRIX_SET_GET_VALUE(ObjectToScreen);
  65. MATRIX_SET_GET_VALUE(CameraToObject);
  66. MATRIX_SET_GET_VALUE(WorldToScreen);
  67. MATRIX_SET_GET_VALUE(SceneView);
  68. MATRIX_SET_GET_VALUE(SceneProjection);
  69. MATRIX_SET_IS_INVERSE_OF(WorldToObject, ObjectToWorld);
  70. MATRIX_SET_IS_INVERSE_OF(CameraToWorld, WorldToCamera);
  71. MATRIX_SET_MULT_ASSIGN(WorldToCamera, ObjectToWorld, ObjectToCamera);
  72. MATRIX_SET_IS_INVERSE_OF(CameraToObject, ObjectToCamera);
  73. MATRIX_SET_MULT_ASSIGN(CameraToScreen, WorldToCamera, WorldToScreen);
  74. MATRIX_SET_MULT_ASSIGN(WorldToScreen, ObjectToWorld, ObjectToScreen);
  75. MATRIX_SET_IS_INVERSE_OF(ScreenToCamera, CameraToScreen);
  76. public:
  77. MatrixSet();
  78. // Direct accessors
  79. inline const MatrixF &getObjectToWorld() const { return mTransform[ObjectToWorld]; }
  80. inline const MatrixF &getWorldToCamera() const { return mTransform[WorldToCamera]; }
  81. inline const MatrixF &getCameraToScreen() const { return mTransform[CameraToScreen]; }
  82. inline const MatrixF &getScreenToCamera() const { return mTransform[ScreenToCamera]; }
  83. // Delegate driven, lazy-evaluation accessors
  84. inline const MatrixF &getWorldToScreen() const { return mEvalDelegate[WorldToScreen](); }
  85. inline const MatrixF &getWorldViewProjection() const { return mEvalDelegate[ObjectToScreen](); }
  86. inline const MatrixF &getWorldToObject() const { return mEvalDelegate[WorldToObject](); }
  87. inline const MatrixF &getCameraToWorld() const { return mEvalDelegate[CameraToWorld](); }
  88. inline const MatrixF &getObjectToCamera() const { return mEvalDelegate[ObjectToCamera](); }
  89. inline const MatrixF &getCameraToObject() const { return mEvalDelegate[CameraToObject](); }
  90. // Assignment for the world/view/projection matrices
  91. inline void setWorld(const MatrixF &world)
  92. {
  93. mTransform[ObjectToWorld] = world;
  94. mEvalDelegate[WorldToObject].bind(this, &MatrixSet::MATRIX_SET_IS_INVERSE_OF_FN(WorldToObject, ObjectToWorld));
  95. mEvalDelegate[ObjectToScreen].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(WorldToScreen, ObjectToWorld, ObjectToScreen));
  96. mEvalDelegate[ObjectToCamera].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(WorldToCamera, ObjectToWorld, ObjectToCamera));
  97. mEvalDelegate[CameraToObject].bind(this, &MatrixSet::MATRIX_SET_IS_INVERSE_OF_FN(CameraToObject, ObjectToCamera));
  98. }
  99. inline void setView(const MatrixF &view)
  100. {
  101. if(&view == mViewSource)
  102. return;
  103. mViewSource = &view;
  104. mTransform[WorldToCamera] = view;
  105. mEvalDelegate[CameraToWorld].bind(this, &MatrixSet::MATRIX_SET_IS_INVERSE_OF_FN(CameraToWorld, WorldToCamera));
  106. mEvalDelegate[ObjectToScreen].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(WorldToScreen, ObjectToWorld, ObjectToScreen));
  107. mEvalDelegate[WorldToScreen].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(CameraToScreen, WorldToCamera, WorldToScreen));
  108. mEvalDelegate[ObjectToCamera].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(WorldToCamera, ObjectToWorld, ObjectToCamera));
  109. mEvalDelegate[CameraToObject].bind(this, &MatrixSet::MATRIX_SET_IS_INVERSE_OF_FN(CameraToObject, ObjectToCamera));
  110. }
  111. inline void setProjection(const MatrixF &projection)
  112. {
  113. if(&projection == mProjectionSource)
  114. return;
  115. mProjectionSource = &projection;
  116. mTransform[CameraToScreen] = projection;
  117. mEvalDelegate[ObjectToScreen].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(WorldToScreen, ObjectToWorld, ObjectToScreen));
  118. mEvalDelegate[WorldToScreen].bind(this, &MatrixSet::MATRIX_SET_MULT_ASSIGN_FN(CameraToScreen, WorldToCamera, WorldToScreen));
  119. mEvalDelegate[ScreenToCamera].bind(this, &MatrixSet::MATRIX_SET_IS_INVERSE_OF_FN(ScreenToCamera, CameraToScreen));
  120. }
  121. void setSceneView(const MatrixF &view)
  122. {
  123. mViewSource = NULL;
  124. setView(view);
  125. mViewSource = &mTransform[WorldToCamera];
  126. mTransform[SceneView] = view;
  127. }
  128. void setSceneProjection(const MatrixF &projection)
  129. {
  130. mProjectionSource = NULL;
  131. setProjection(projection);
  132. mProjectionSource = &mTransform[CameraToScreen];
  133. mTransform[SceneProjection] = projection;
  134. }
  135. void restoreSceneViewProjection()
  136. {
  137. mViewSource = NULL;
  138. mProjectionSource = NULL;
  139. setView(mTransform[SceneView]);
  140. setProjection(mTransform[SceneProjection]);
  141. mViewSource = &mTransform[WorldToCamera];
  142. mProjectionSource = &mTransform[CameraToScreen];
  143. }
  144. }
  145. dALIGN_END;
  146. #endif // _MATRIXSET_H_