PhotonTracing.cc

Go to the documentation of this file.
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     // we have a photon map
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      * We suppose that the given "surr" contains proper point of intersection,
00045      * normal vector and associated primitive
00046      *
00047      * Transform point of intersection and properly orient normal
00048      */
00049     _check_point_of_intersection(surr);
00050 
00051     /*
00052      * Inspect attributes that are necessary for local illumination,
00053      * reflection and transmission. Set correct BRDF and emittance for local
00054      * reflection. If the point of interest is the second point of refraction
00055      * ray then previous material is used (the object was not changed)
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          * Traverse random direction using russian roulette
00064          */
00065         if (actDepth < _maxDepth) 
00066             _cast_secondary_rays(surr, actDepth, firstObjHit,
00067                                  unused, *pMatVisitor);
00068     } else {
00069         /*
00070          * store photon falled on a diffuse surface
00071          */
00072         _store_photon(surr, false);
00073     }
00074 }
00075 
00076 
00077 // --------- public ----------------
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 

Generated on Tue Nov 21 15:11:42 2006 for gra by  doxygen 1.4.6