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);
// }
}
|