00001 #include <gra/reflection/PhotonTracing.h>
00002 #include <esg/visitor/PhotonMapBhvVisitor.h>
00003 #include <esg/energy/PhotonMapEnergy.h>
00004
00005 using namespace gra;
00006
00007 void PhotonTracing::_store_photon(PointEnv& surr, bool caustics)
00008 {
00009 AutoPtr<EnergyCoat>* pAMap = surr.pVisitableObj->getEnergyState();
00010 if (!pAMap) return;
00011
00012 EnergyCoat* pCoat = pAMap->origObject();
00013 if (!pCoat) return;
00014
00015 PhotonMapEnergy* pMap = dynamic_cast<PhotonMapEnergy*>(pCoat);
00016 if (!pMap) return;
00017
00018
00019 PhotonMapBhvVisitor pmbVisitor;
00020 surr.pVisitableObj->inspectAttributes(pmbVisitor);
00021 if (!pmbVisitor.behaviour()) return;
00022
00023 if (caustics && pmbVisitor.behaviour()->acceptsCaustics()) {
00024 pMap->storeCausticPhoton(Photon(surr.intersection,
00025 surr.viewerDir,
00026 surr.energy));
00027 return;
00028 }
00029
00030 if (pmbVisitor.behaviour()->acceptsGlobalPhotons())
00031 pMap->storeGlobalPhoton(Photon(surr.intersection,
00032 surr.viewerDir,
00033 surr.energy));
00034 }
00035
00036 void PhotonTracing::_illuminate(PointEnv& surr,
00037 unsigned actDepth,
00038 bool firstObjHit,
00039 Color3f& unused)
00040 {
00041 if (actDepth >= _maxDepth) return;
00042
00043
00044
00045
00046
00047
00048
00049 _check_point_of_intersection(surr);
00050
00051
00052
00053
00054
00055
00056
00057 MatVisitor* pMatVisitor = _check_material(surr.pVisitableObj, firstObjHit);
00058
00059 const Vector3& refl = pMatVisitor->reflection();
00060 const Vector3& transp = pMatVisitor->transparency();
00061 if (refl.x || refl.y || refl.z || transp.x || transp.y || transp.z) {
00062
00063
00064
00065 if (actDepth < _maxDepth)
00066 _cast_secondary_rays(surr, actDepth, firstObjHit,
00067 unused, *pMatVisitor);
00068 } else {
00069
00070
00071
00072 _store_photon(surr, false);
00073 }
00074 }
00075
00076
00077
00078
00079 Color3f* PhotonTracing::illuminatePoint(PointEnv & env)
00080 {
00081 if (!(_pDiffuseBRDF || _pSpecularBRDF)) return NULL;
00082 if (!(_pScene && _pScene->root())) return NULL;
00083 if (!_pIntersector) return NULL;
00084 if (!(env.mask & (ENV_HAVE_INTERSECTION|
00085 ENV_HAVE_NORMAL|
00086 ENV_HAVE_ASOC_PRIMITIVE|
00087 ENV_HAVE_VIEWER_DIR))) return NULL;
00088
00089 if (! env.pVisitableObj) return NULL;
00090
00091 if (!(env.mask & ENV_HAVE_ENERGY)) env.energy.set(1.,1.,1.);
00092
00093 Color3f* pColor = new Color3f(0.0, 0.0, 0.0);
00094
00095 #ifdef ESG_STATISTICS
00096 _numReflections = (_numRefractions = 0);
00097 #endif
00098 _illuminate(env, 0, true, *pColor);
00099
00100 #ifdef ESG_STATISTICS
00101 ((Counter*)Statistics::instance()->get(Statistics::OID_REFLECTIONS)->receptor())->add(_numReflections);
00102 ((Counter*)Statistics::instance()->get(Statistics::OID_REFRACTIONS)->receptor())->add(_numRefractions);
00103 #endif
00104
00105
00106 return pColor;
00107 }
00108
00109
00110