AlignVisitor.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //#ident "$Id: AlignVisitor.cpp,v 1.5 2003/07/25 01:01:54 rzr Exp $"
  2. /***************************************************************************
  3. AlignVisitor.cpp - description
  4. -------------------
  5. begin : Wed Jan 26 2000
  6. copyright : (C) 2000 by Henrik Enqvist
  7. email : henqvist@excite.com
  8. ***************************************************************************/
  9. #include "Private.h"
  10. #include "AlignVisitor.h"
  11. #include "Group.h"
  12. #include "Shape3D.h"
  13. #include "Sound.h"
  14. #include "Light.h"
  15. #include "BillBoard.h"
  16. #include "EMath.h"
  17. AlignVisitor * AlignVisitor::p_AlignVisitor = NULL;
  18. AlignVisitor::AlignVisitor() {
  19. p_GroupCamera = NULL;
  20. m_mtxInverse = EMath::identityMatrix;
  21. m_vtxFront.x = 0.0;
  22. m_vtxFront.y = 0.0;
  23. m_vtxFront.z = -1.0;
  24. m_vtxUp.x = 0.0;
  25. m_vtxUp.y = 1.0;
  26. m_vtxUp.z = 0.0;
  27. }
  28. AlignVisitor::~AlignVisitor() {
  29. p_AlignVisitor = NULL;
  30. }
  31. AlignVisitor * AlignVisitor::getInstance() {
  32. if (p_AlignVisitor == NULL) {
  33. p_AlignVisitor = new AlignVisitor();
  34. }
  35. return p_AlignVisitor;
  36. }
  37. /* Clean up camera matrix. */
  38. void AlignVisitor::empty() {
  39. if (p_GroupCamera == NULL) return;
  40. EM_COUT("AlignVisitor::empty()", 0);
  41. // backward matrix multiplication for the camera
  42. if (p_GroupCamera == NULL) {
  43. return;
  44. }
  45. #if EM_USE_ALLEGRO
  46. Matrix mtxTmp;
  47. Matrix mtxScale = EMath::identityMatrix;
  48. mtxScale.v[0][0] = 0.8;
  49. mtxScale.v[1][1] = -0.6;
  50. mtxScale.v[2][2] = -1;
  51. EMath::matrixMulti(mtxScale, p_GroupCamera->m_mtxTrans, mtxTmp);
  52. EMath::inverse(mtxTmp, m_mtxInverse);
  53. #else
  54. EMath::inverse(p_GroupCamera->m_mtxTrans, m_mtxInverse);
  55. #endif
  56. }
  57. void AlignVisitor::setCamera(Group * g) {
  58. p_GroupCamera = g;
  59. }
  60. /* Apply camera transform to all vertices and sounds. */
  61. void AlignVisitor::visit(Group * g) {
  62. EM_COUT("AlignVisitor::visit() *", 0);
  63. // Apply transform to vertices in oShape3D.
  64. vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  65. vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  66. for ( ; shapeIter != shapeEnd; shapeIter++) {
  67. vector<Vertex3D>::iterator transIter = (*shapeIter)->m_vVtxTrans.begin();
  68. vector<Vertex3D>::iterator transEnd = (*shapeIter)->m_vVtxTrans.end();
  69. vector<Vertex3D>::iterator alignIter = (*shapeIter)->m_vVtxAlign.begin();
  70. //vector<Vertex3D>::iterator alignEnd = (*shapeIter)->m_vVtxAlign.end();
  71. vector<Vertex3D>::iterator nmlTransIter = (*shapeIter)->m_vNmlTrans.begin();
  72. //vector<Vertex3D>::iterator nmlTransEnd = (*shapeIter)->m_vNmlTrans.end();
  73. vector<Vertex3D>::iterator nmlAlignIter = (*shapeIter)->m_vNmlAlign.begin();
  74. //vector<Vertex3D>::iterator nmlAlignEnd = (*shapeIter)->m_vNmlAlign.end();
  75. EmAssert(((*shapeIter)->m_vVtxTrans.size () ==
  76. (*shapeIter)->m_vVtxAlign.size ()) &&
  77. ((*shapeIter)->m_vNmlTrans.size () ==
  78. (*shapeIter)->m_vNmlAlign.size ()), "size miss match");
  79. for ( ; transIter != transEnd;
  80. transIter++, alignIter++, nmlTransIter++, nmlAlignIter++) {
  81. // Translation and rotation needs to be applied in wrong order
  82. Vertex3D vtx;
  83. vtx.x = (*transIter).x + m_mtxInverse.t[0];
  84. vtx.y = (*transIter).y + m_mtxInverse.t[1];
  85. vtx.z = (*transIter).z + m_mtxInverse.t[2];
  86. EMath::applyMatrixRot(m_mtxInverse, vtx, (*alignIter));
  87. // Normals only needs rotation
  88. EMath::applyMatrixRot(m_mtxInverse, (*nmlTransIter), (*nmlAlignIter));
  89. EMath::normalizeVector(*nmlAlignIter);
  90. // TODO: optimize = macro instead of apply-fct calls, remove normalize
  91. EM_COUT("AlignVisitor::visit() " <<
  92. (*transIter).x <<" "<< (*transIter).y <<" "<< (*transIter).z <<" -> "<<
  93. (*alignIter).x <<" "<< (*alignIter).y <<" "<< (*alignIter).z, 0);
  94. }
  95. }
  96. // Apply transform to BillBoard.
  97. if (g->p_BillBoard != NULL) {
  98. // Translation and rotation needs to be applied in wrong order
  99. Vertex3D vtx = { 0 , 0 , 0 } ; //!rzr UMR
  100. vtx.x = g->p_BillBoard->m_vtxTrans.x + m_mtxInverse.t[0];
  101. vtx.y = g->p_BillBoard->m_vtxTrans.y + m_mtxInverse.t[1];
  102. vtx.z = g->p_BillBoard->m_vtxTrans.z + m_mtxInverse.t[2];
  103. EMath::applyMatrixRot(m_mtxInverse, vtx, g->p_BillBoard->m_vtxAlign);
  104. EM_COUT("AlignVisitor::visit() billboard " <<
  105. g->p_BillBoard->m_vtxTrans.x <<" "<<
  106. g->p_BillBoard->m_vtxTrans.y <<" "<<
  107. g->p_BillBoard->m_vtxTrans.z <<" -> "<<
  108. g->p_BillBoard->m_vtxAlign.x <<" "<<
  109. g->p_BillBoard->m_vtxAlign.y <<" "<<
  110. g->p_BillBoard->m_vtxAlign.z , 0);
  111. }
  112. // Apply transform to Light.
  113. if (g->p_Light != NULL) {
  114. // Translation and rotation needs to be applied in wrong order
  115. Vertex3D vtx;
  116. vtx.x = g->p_Light->m_vtxTrans.x + m_mtxInverse.t[0];
  117. vtx.y = g->p_Light->m_vtxTrans.y + m_mtxInverse.t[1];
  118. vtx.z = g->p_Light->m_vtxTrans.z + m_mtxInverse.t[2];
  119. EMath::applyMatrixRot(m_mtxInverse, vtx, g->p_Light->m_vtxAlign);
  120. }
  121. // Apply transform to oSound.
  122. // if (g->m_Sound != NULL) {
  123. // EMath::applyMatrix(mtxCamera, g->m_Sound->vtxTrans, g->m_Sound->vtxAlign);
  124. // }
  125. // Apply transform to oNestedBounds.
  126. // if (g->m_CollisionBounds != NULL) {
  127. // this->visit(g->oNestedBounds);
  128. // }
  129. }