File: TransformVisitor.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 (132 lines) | stat: -rw-r--r-- 4,794 bytes parent folder | download | duplicates (2)
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
/***************************************************************************
                          TransformVisitor.cpp  -  description
                             -------------------
    begin                : Wed Jan 26 2000
    copyright            : (C) 2000 by Henrik Enqvist IB (GPL)
    email                : henqvist@excite.com
 ***************************************************************************/

#include "Private.h"
#include "TransformVisitor.h"
#include "Group.h"
#include "Shape3D.h"
#include "Sound.h"
#include "Camera.h"
#include "Light.h"
#include "BillBoard.h"
#include "CollisionBounds.h"
#include "Polygon.h"

#include "EMath.h"

TransformVisitor * TransformVisitor::p_TransformVisitor = NULL;

TransformVisitor::TransformVisitor() {
  p_GroupCamera = NULL;
}

TransformVisitor::~TransformVisitor() {
  p_TransformVisitor = NULL;
}

TransformVisitor * TransformVisitor::getInstance() {
  if (p_TransformVisitor == NULL) {
    p_TransformVisitor = new TransformVisitor();
  }
  return p_TransformVisitor;
}

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

void TransformVisitor::empty() {
}

void TransformVisitor::visit(Group* g) {
  // Check properties before applying transform
  if (g->m_iProperties & EM_GROUP_NO_TRANSFORM) return;

  if (g->m_iProperties & EM_GROUP_TRANSFORM_ONCE) {
    g->unsetProperty(EM_GROUP_TRANSFORM_ONCE);
    g->setProperty(EM_GROUP_NO_TRANSFORM);
  }
  // Apply the transform to the Group.
  if (g->p_Parent == NULL) {
    // The group with no parent must be the engine!
    EMath::matrixMulti(g->m_mtxSrc, EMath::identityMatrix, g->m_mtxTrans);
  } else {
    EMath::matrixMulti(g->m_mtxSrc, g->p_Parent->m_mtxTrans, g->m_mtxTrans);
  }
	
  // Apply transform to all shapes.
  vector<Shape3D*>::iterator shapeIter = g->m_vShape3D.begin();
  vector<Shape3D*>::iterator shapeEnd = g->m_vShape3D.end();
  for ( ; shapeIter != shapeEnd; ++shapeIter) {
	  
    vector<Polygon3D*>::iterator polyIter = (*shapeIter)->m_vPolygon.begin();
    vector<Polygon3D*>::iterator polyEnd = (*shapeIter)->m_vPolygon.end();
	  
    // Apply transform to all polygon normals
    for ( ; polyIter != polyEnd; ++polyIter) {
      // Rotate the normal.
      //EMath::applyMatrixRot(g->m_mtxTrans, (*polyIter)->m_nmlSrc, (*polyIter)->m_nmlTrans);
      EMathApplyMatrixRot(g->m_mtxTrans, (*polyIter)->m_nmlSrc, (*polyIter)->m_nmlTrans);
	    
      //EMath::normalizeVector((*polyIter)->m_nmlTrans); 
      // TODO: optimze - remove normalize
    }
	  
    // Apply transform to all vertices and normals
    vector<Vertex3D>::iterator srcIter = (*shapeIter)->m_vVtxSrc.begin();
    vector<Vertex3D>::iterator srcEnd = (*shapeIter)->m_vVtxSrc.end();
    vector<Vertex3D>::iterator transIter = (*shapeIter)->m_vVtxTrans.begin();
    vector<Vertex3D>::iterator nmlSrcIter = (*shapeIter)->m_vNmlSrc.begin();
    vector<Vertex3D>::iterator nmlTransIter = (*shapeIter)->m_vNmlTrans.begin();
	  
    // 		EmAssert(((*shapeIter)->m_vVtxSrc.size() ==
    // 							(*shapeIter)->m_vVtxTrans.size()) &&
    // 						 ((*shapeIter)->m_vNmlSrc.size() ==
    // 						 (*shapeIter)->m_vNmlTrans.size()), 
    // 						 "size miss match " <<
    // 						 (*shapeIter)->m_vVtxSrc.size() <<" "<<
    // 						 (*shapeIter)->m_vVtxTrans.size() <<" "<<
    // 						 (*shapeIter)->m_vNmlSrc.size() <<" "<<
    // 						 (*shapeIter)->m_vNmlTrans.size() );
	  
    for ( ; srcIter != srcEnd; 
	  ++srcIter, ++transIter, ++nmlSrcIter, ++nmlTransIter) {
      //EMath::applyMatrix(g->m_mtxTrans, (*srcIter), (*transIter));
      //EMath::applyMatrixRot(g->m_mtxTrans, (*nmlSrcIter), (*nmlTransIter));
      EMathApplyMatrix(g->m_mtxTrans, (*srcIter), (*transIter));
      EMathApplyMatrixRot(g->m_mtxTrans, (*nmlSrcIter), (*nmlTransIter));
	    
      //EMath::normalizeVector(*nmlTransIter);
      // TODO: optimize - macro instead of apply-fct calls, remove normalize
	    
      EM_COUT_D("TransformVisitor::visit() " << srcIter <<" "<<
		(*srcIter).x <<" "<< (*srcIter).y <<" "<< (*srcIter).z <<" -> "<<
		(*transIter).x <<" "<< (*transIter).y <<" "<< (*transIter).z, 0);
    }
  }
  // Apply transform to Sound.
  /*	
    if (g->oSound != NULL) {
    Vertex3D* vtx = &(g->oSound->vtxPos);
    Vertex3D* trVtx = &(g->oSound->vtxTrPos);
    EMath::applyMatrix(g->trMatrix, vtx, trVtx);
    }
  */
  // Apply transform to BillBoard.
  if (g->p_BillBoard != NULL) {
    EMath::applyMatrix(g->m_mtxTrans, g->p_BillBoard->m_vtxSrc, g->p_BillBoard->m_vtxTrans);
  }
  // Apply transform to Light.
  if (g->p_Light != NULL) {
    EMath::applyMatrix(g->m_mtxTrans, g->p_Light->m_vtxSrc, g->p_Light->m_vtxTrans);
  }
  // Apply transform to CollisionBounds
  if (g->p_CollisionBounds != NULL) {
    g->p_CollisionBounds->transform(g->m_mtxTrans);
  }
}