00001
00002
00003 #ifndef __LIGHT_ARRAY_EXPLORER_H
00004 #define __LIGHT_ARRAY_EXPLORER_H
00005
00006 #include <esg/explorer/Explorer.h>
00007 #include <esg/Export>
00008
00009 namespace esg {
00010
00017 class OGSCENE_EXPORT LightArray {
00018 friend class LightsExplorer;
00019
00020 public:
00021 static const ESGint MAX_LIGHTS = 8;
00022 static const ESGint LIGHT0;
00023 static const ESGint LIGHT1;
00024 static const ESGint LIGHT2;
00025 static const ESGint LIGHT3;
00026 static const ESGint LIGHT4;
00027 static const ESGint LIGHT5;
00028 static const ESGint LIGHT6;
00029 static const ESGint LIGHT7;
00030
00034 struct Light {
00035 Emittance * pEmittance;
00036 Matrix4 * pTrMat;
00037 Geometry * pGeometry;
00038 SceneGraphObject::OID oid;
00039 Light ()
00040 : pEmittance(NULL),pTrMat(NULL),pGeometry(NULL),oid(0) {}
00041 ~Light () { if (pTrMat) delete pTrMat; }
00042 void clear () {
00043 if (pTrMat) delete pTrMat;
00044 pTrMat = NULL;
00045 pEmittance = NULL;
00046 pGeometry = NULL;
00047 }
00048 };
00049
00055 struct BlockingObj {
00056 SceneGraphObject * pObj;
00057 Matrix4 trMat;
00058 bool transformed;
00059 BlockingObj () : pObj(NULL), transformed(false) {}
00060 };
00061
00062 protected:
00063 Light _lightArray[MAX_LIGHTS];
00064 ESGbitmask _set;
00065 ESGbitmask _on;
00066 BlockingObj (*_blockingObjCache)[MAX_LIGHTS];
00067 unsigned _numCaches;
00068
00069 public:
00075 LightArray (unsigned cache = 0) : _set(0), _on(0), _numCaches(cache){
00076 _blockingObjCache = new BlockingObj [_numCaches][MAX_LIGHTS];
00077 for (ESGint i = 0; i < MAX_LIGHTS; i++)
00078 for (unsigned j = 0; j < _numCaches; j++) {
00079 _blockingObjCache[j][i].pObj = NULL;
00080 _blockingObjCache[j][i].transformed = false;
00081 }
00082 }
00083
00087 virtual ~LightArray () {
00088 for (register ESGint i = 0; i < MAX_LIGHTS; i++)
00089 if (isSet(i)) _lightArray[i].clear();
00090 delete [] _blockingObjCache;
00091 }
00092
00097 bool isSet (ESGint i) const { return (_set&(1<<i)); }
00098
00103 bool isOn (ESGint i) const { return (_on&(1<<i)); }
00104
00109 bool isAnyOn (void) const { return (_on != 0); }
00110
00116 void turnLightOn (ESGint i) { _on |= (_set&(1<<i)); }
00117
00123 void turnLightOff (ESGint i) { _on &= ~(_set&(1<<i)); }
00124
00128 void turnAllOn (void) { _on = _set; }
00129
00133 void turnAllOff (void) { _on = 0; }
00134
00140 void turnOn (ESGbitmask m) { _on = (_set&m); }
00141
00145 ESGbitmask getOnMask (void) const { return _on; }
00146
00150 ESGbitmask getSetMask (void) const { return _set; }
00151
00155 void clear (void) {
00156 for (register ESGint i = 0; i < MAX_LIGHTS; i++)
00157 if (_set&(1<<i)) _lightArray[i].clear();
00158 _set = 0;
00159 }
00160
00161
00162
00167 Light& light (ESGint i) { return _lightArray[i]; }
00168
00175 void setEmittance (ESGint i, Emittance* e) {
00176 _lightArray[i].pEmittance = e;
00177 if (e) { isSet(i); isOn(i); }
00178 }
00179
00184 Emittance* getEmittance (ESGint i) { return _lightArray[i].pEmittance; }
00185
00192 void setTransformation (ESGint i, const Matrix4& m) {
00193 if (_lightArray[i].pTrMat) delete _lightArray[i].pTrMat;
00194 _lightArray[i].pTrMat = new Matrix4(m);
00195 }
00196
00201 Matrix4* getTransformation (ESGint i) { return _lightArray[i].pTrMat; }
00202
00209 void setGeometry (ESGint i, Geometry* g) {
00210 _lightArray[i].pGeometry = g;
00211 }
00212
00217 Geometry* getGeometry (ESGint i) { return _lightArray[i].pGeometry; }
00218
00225 void setOID (ESGint i, SceneGraphObject::OID oid) {
00226 _lightArray[i].oid = oid;
00227 }
00228
00233 SceneGraphObject::OID getOID(ESGint i) const {
00234 return _lightArray[i].oid;
00235 }
00236
00247 bool emitPhoton (Vector3& o, Vector3& d, Color3f& p, ESGint i) const {
00248 const Light* l = &_lightArray[i];
00249 if (!l->pEmittance) return false;
00250 if (!l->pEmittance->stochasticEmission(d)) return false;
00251 if (!l->pEmittance->intensity(p)) return false;
00252 if (l->pEmittance->fitToGeometry() && l->pGeometry) {
00253 PointEnv pe;
00254 l->pGeometry->randomSample(ENV_WANT_SURFACE_POINT | (l->pEmittance->haveDirection() ? ENV_WANT_NORMAL : ENV_WANT_NOTHING), pe, NULL);
00255 if (pe.mask & ENV_HAVE_SURFACE_POINT) o.set(pe.intersection);
00256 if (l->pEmittance->haveDirection() && (pe.mask & ENV_HAVE_NORMAL))
00257 l->pEmittance->setBeamDirection(pe.normal);
00258 } else {
00259 if (!l->pEmittance->haveLocation()) return false;
00260 if (!l->pEmittance->sourceLocation(o)) return false;
00261 }
00262
00263 if (l->pTrMat) {
00264 Matrix3 rMat;
00265 l->pTrMat->get(rMat);
00266 l->pTrMat->transform(o);
00267 rMat.transform(d);
00268 }
00269
00270 return true;
00271 }
00272
00282 const BlockingObj* getBlockingObject (unsigned cache, ESGint light) const {
00283 return ((cache < _numCaches && light < MAX_LIGHTS && light >= 0) ?
00284 &(_blockingObjCache[cache][light]) :
00285 NULL);
00286 }
00287
00299 bool setBlockingObj (unsigned cache,
00300 ESGint light,
00301 SceneGraphObject* pObj,
00302 const Matrix4* pMat) {
00303 if (cache>=_numCaches||light>=MAX_LIGHTS||light<0) return false;
00304 _blockingObjCache[cache][light].pObj = pObj;
00305 if (pMat) {
00306 _blockingObjCache[cache][light].trMat.set(*pMat);
00307 _blockingObjCache[cache][light].transformed = true;
00308 } else
00309 _blockingObjCache[cache][light].transformed = false;
00310 return true;
00311 }
00312 };
00313
00314 };
00315
00316 #endif // __LIGHT_ARRAY_EXPLORER_H