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