/*************************************************************************** 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); } // Apple transform to all shapes. vector::iterator shapeIter = g->m_vShape3D.begin(); vector::iterator shapeEnd = g->m_vShape3D.end(); for ( ; shapeIter != shapeEnd; ++shapeIter) { vector::iterator polyIter = (*shapeIter)->m_vPolygon.begin(); vector::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::iterator srcIter = (*shapeIter)->m_vVtxSrc.begin(); vector::iterator srcEnd = (*shapeIter)->m_vVtxSrc.end(); vector::iterator transIter = (*shapeIter)->m_vVtxTrans.begin(); vector::iterator nmlSrcIter = (*shapeIter)->m_vNmlSrc.begin(); vector::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); } }