00001 #include "esg/explorer/ObjsInAreaExplorer.h" 00002 #include <esg/iterator/IteratorSDS.h> 00003 00004 using namespace esg; 00005 00006 bool ObjsInAreaExplorer::_iterate(SceneGraphObject& obj) 00007 { 00008 SceneGraphObject* pCandidate; 00009 IteratorSDS* pIter = obj.traverseSubnodes(); 00010 00011 if (!pIter) return false; 00012 00013 pIter->initAreaSearch(_pTrArea); 00014 00015 bool ret = false; 00016 pCandidate = pIter->firstChild(); 00017 while (pCandidate) { 00018 if (_explore(*pCandidate)) ret = true; 00019 pCandidate = pIter->nextChild(); 00020 } 00021 delete pIter; 00022 00023 return ret; 00024 } 00025 00026 bool ObjsInAreaExplorer::_process_leaf(SceneGraphObject& obj) 00027 { 00028 #ifndef _MSC_VER 00029 #warning "FIXME: distance of primitive" 00030 #endif 00031 00032 TrObj * pO = new TrObj; 00033 pO->pObject = &obj; 00034 if (_trStack.empty()) pO->pTrMat = NULL; 00035 else pO->pTrMat = new Matrix4(*_trStack.top()); 00036 _foundObjects.append(pO); 00037 return true; 00038 } 00039 00040 void ObjsInAreaExplorer::_accept_new_transformation(const Matrix4& trMat) 00041 { 00042 static Matrix3 rMat; 00043 static Vector3 tVec; 00044 static Vector3 sVec; 00045 static Matrix4 sMat; 00046 00047 if (!_pArea) return; 00048 00049 trMat.get(rMat, tVec, sVec); 00050 rMat.transpose(); 00051 tVec.negate(); 00052 if (sVec.x && sVec.y && sVec.z) { 00053 sVec.x = 1.0 / sVec.x; 00054 sVec.y = 1.0 / sVec.y; 00055 sVec.z = 1.0 / sVec.z; 00056 sMat.set(rMat, tVec, sVec); 00057 } else 00058 sMat.set(rMat, tVec, 1); 00059 00060 if (_pTrArea) delete _pTrArea; 00061 _pTrArea = (Geometry*) _pArea->clone(&sMat); 00062 } 00063 00064 00065 00066 ObjsInAreaExplorer::ObjsInAreaExplorer(const Geometry& area) 00067 { 00068 _pArea = (Geometry*) area.clone(); 00069 _pTrArea = (Geometry*) area.clone(); 00070 } 00071 00072 ObjsInAreaExplorer::~ObjsInAreaExplorer() 00073 { 00074 TrObj * pO; 00075 while ((pO = _foundObjects.firstItem())) { 00076 if (pO->pTrMat) delete pO->pTrMat; 00077 delete pO; 00078 } 00079 if (_pTrArea) delete _pTrArea; 00080 if (_pArea) delete _pArea; 00081 } 00082 00083 SceneGraphObject* ObjsInAreaExplorer::result(Matrix4& trMat, bool& hasMat) 00084 { 00085 SceneGraphObject * pObject; 00086 TrObj * o = _foundObjects.remove(_foundObjects.firstItem()); 00087 00088 if (!o) return NULL; 00089 00090 pObject = o->pObject; 00091 00092 if (o->pTrMat) { 00093 trMat.set(*(o->pTrMat)); 00094 hasMat = true; 00095 delete o->pTrMat; 00096 } else 00097 hasMat = false; 00098 00099 delete o; 00100 return pObject; 00101 } 00102