File: AlignVisitor.cpp

package info (click to toggle)
pinball 0.3.20201218-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 8,452 kB
  • sloc: cpp: 15,230; makefile: 840; sh: 381; xml: 24
file content (145 lines) | stat: -rw-r--r-- 5,387 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//#ident "$Id: AlignVisitor.cpp,v 1.5 2003/07/25 01:01:54 rzr Exp $"
/***************************************************************************
                          AlignVisitor.cpp  -  description
                             -------------------
    begin                : Wed Jan 26 2000
    copyright            : (C) 2000 by Henrik Enqvist
    email                : henqvist@excite.com
***************************************************************************/

#include "Private.h"
#include "AlignVisitor.h"
#include "Group.h"
#include "Shape3D.h"
#include "Sound.h"
#include "Light.h"
#include "BillBoard.h"
#include "EMath.h"

AlignVisitor * AlignVisitor::p_AlignVisitor = NULL;

AlignVisitor::AlignVisitor() {
  p_GroupCamera = NULL;
  m_mtxInverse = EMath::identityMatrix;
  m_vtxFront.x = 0.0;
  m_vtxFront.y = 0.0;
  m_vtxFront.z = -1.0;
  m_vtxUp.x = 0.0;
  m_vtxUp.y = 1.0;
  m_vtxUp.z = 0.0;
}

AlignVisitor::~AlignVisitor() {
  p_AlignVisitor = NULL;
}

AlignVisitor * AlignVisitor::getInstance() {
  if (p_AlignVisitor == NULL) {
    p_AlignVisitor = new AlignVisitor();
  }
  return p_AlignVisitor;
}

/* Clean up camera matrix. */
void AlignVisitor::empty() {
  if (p_GroupCamera == NULL) return;
        
  EM_COUT("AlignVisitor::empty()", 0);
  // backward matrix multiplication for the camera
  if (p_GroupCamera == NULL) {
    return;
  }
        
#if EM_USE_ALLEGRO
  Matrix mtxTmp;
  Matrix mtxScale = EMath::identityMatrix;
  mtxScale.v[0][0] = 0.8;
  mtxScale.v[1][1] = -0.6;
  mtxScale.v[2][2] = -1;
  EMath::matrixMulti(mtxScale, p_GroupCamera->m_mtxTrans, mtxTmp);
  EMath::inverse(mtxTmp, m_mtxInverse);
#else
  EMath::inverse(p_GroupCamera->m_mtxTrans, m_mtxInverse);
#endif
}

void AlignVisitor::setCamera(Group * g) {
  p_GroupCamera = g;
}

/* Apply camera transform to all vertices and sounds. */
void AlignVisitor::visit(Group * g) {
  EM_COUT("AlignVisitor::visit() *", 0);
  // Apply transform to vertices in oShape3D.
  vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  for ( ; shapeIter != shapeEnd; shapeIter++) {
    
    vector<Vertex3D>::iterator transIter = (*shapeIter)->m_vVtxTrans.begin();
    vector<Vertex3D>::iterator transEnd = (*shapeIter)->m_vVtxTrans.end();
    vector<Vertex3D>::iterator alignIter = (*shapeIter)->m_vVtxAlign.begin();
    //vector<Vertex3D>::iterator alignEnd = (*shapeIter)->m_vVtxAlign.end();
    vector<Vertex3D>::iterator nmlTransIter = (*shapeIter)->m_vNmlTrans.begin();
    //vector<Vertex3D>::iterator nmlTransEnd = (*shapeIter)->m_vNmlTrans.end();
    vector<Vertex3D>::iterator nmlAlignIter = (*shapeIter)->m_vNmlAlign.begin();
    //vector<Vertex3D>::iterator nmlAlignEnd = (*shapeIter)->m_vNmlAlign.end();
    
    EmAssert(((*shapeIter)->m_vVtxTrans.size () ==
              (*shapeIter)->m_vVtxAlign.size ()) &&
             ((*shapeIter)->m_vNmlTrans.size () ==
              (*shapeIter)->m_vNmlAlign.size ()), "size miss match");
    
    for ( ; transIter != transEnd; 
          transIter++, alignIter++, nmlTransIter++, nmlAlignIter++) {
      // Translation and rotation needs to be applied in wrong order
      Vertex3D vtx;
      vtx.x = (*transIter).x + m_mtxInverse.t[0];
      vtx.y = (*transIter).y + m_mtxInverse.t[1];
      vtx.z = (*transIter).z + m_mtxInverse.t[2];
      EMath::applyMatrixRot(m_mtxInverse, vtx, (*alignIter));
      // Normals only needs rotation
      EMath::applyMatrixRot(m_mtxInverse, (*nmlTransIter), (*nmlAlignIter));
      EMath::normalizeVector(*nmlAlignIter);
      // TODO: optimize = macro instead of apply-fct calls, remove normalize
      
      EM_COUT("AlignVisitor::visit() " <<
              (*transIter).x <<" "<< (*transIter).y <<" "<< (*transIter).z <<" -> "<<
              (*alignIter).x <<" "<< (*alignIter).y <<" "<< (*alignIter).z, 0);
    }
  }
  // Apply transform to BillBoard.
  if (g->p_BillBoard != NULL) {
    // Translation and rotation needs to be applied in wrong order
    Vertex3D vtx = { 0 , 0 , 0 } ; //!rzr UMR
    vtx.x = g->p_BillBoard->m_vtxTrans.x + m_mtxInverse.t[0];
    vtx.y = g->p_BillBoard->m_vtxTrans.y + m_mtxInverse.t[1];
    vtx.z = g->p_BillBoard->m_vtxTrans.z + m_mtxInverse.t[2];
    EMath::applyMatrixRot(m_mtxInverse, vtx,  g->p_BillBoard->m_vtxAlign);
    EM_COUT("AlignVisitor::visit() billboard " <<
            g->p_BillBoard->m_vtxTrans.x <<" "<< 
            g->p_BillBoard->m_vtxTrans.y <<" "<< 
            g->p_BillBoard->m_vtxTrans.z <<" -> "<< 
            g->p_BillBoard->m_vtxAlign.x <<" "<< 
            g->p_BillBoard->m_vtxAlign.y <<" "<< 
            g->p_BillBoard->m_vtxAlign.z , 0);
  }
  // Apply transform to Light.
  if (g->p_Light != NULL) {
    // Translation and rotation needs to be applied in wrong order
    Vertex3D vtx;
    vtx.x = g->p_Light->m_vtxTrans.x + m_mtxInverse.t[0];
    vtx.y = g->p_Light->m_vtxTrans.y + m_mtxInverse.t[1];
    vtx.z = g->p_Light->m_vtxTrans.z + m_mtxInverse.t[2];
    EMath::applyMatrixRot(m_mtxInverse, vtx,  g->p_Light->m_vtxAlign);
  }
  // Apply transform to oSound.
  //    if (g->m_Sound != NULL) {
  //            EMath::applyMatrix(mtxCamera, g->m_Sound->vtxTrans, g->m_Sound->vtxAlign);
  //    }
  
  //    Apply transform to oNestedBounds.
  //    if (g->m_CollisionBounds != NULL)       {
  //            this->visit(g->oNestedBounds);
  //    }
}