EnvironmentMap.cpp

Go to the documentation of this file.
00001 /**<!-------------------------------------------------------------------->
00002    @file   EnvironmentMap.cpp
00003    @author Travis Fischer (fisch0920@gmail.com)
00004    @date   Fall 2008
00005    
00006    @brief
00007       Environment map using latitude-longitude format.  An environment map 
00008    roughly models distant illumination surrounding a scene by conceptually 
00009    surrounding the scene with a spherical emitter that emits light inwards 
00010    according to a distribution defined by a 2D 'environment' texture map that 
00011    is projected onto the surface of the sphere.  Note the term HDR environment 
00012    map is thrown around a lot; the only difference is that the underlying 
00013    environment texture is stored in some type of high dynamic range format, 
00014    such as OpenEXR or HDR.
00015    <!-------------------------------------------------------------------->**/
00016 
00017 #include "EnvironmentMap.h"
00018 #include <ResourceManager.h>
00019 #include <filters.h>
00020 #include <QtCore>
00021 
00022 void EnvironmentMap::init() {
00023    ASSERT(m_parent);
00024    Emitter::init();
00025    
00026    m_filter = m_parent->getFilter();
00027    
00028    ASSERT(m_parent->contains("path"));
00029    const std::string &filename = m_parent->getValue<std::string>("path");
00030    m_image = ResourceManager::getImage(filename);
00031    
00032    if (!m_image) {
00033       cerr << "failed to load environment map image '" << filename << "'" 
00034            << endl << endl;
00035       ASSERT(0);
00036    }
00037 }
00038 
00039 void EnvironmentMap::preview(Shape *shape)
00040 { }
00041 
00042 SpectralSampleSet EnvironmentMap::getLe(const Vector3 &w) {
00043    ASSERT(m_filter);
00044    ASSERT(m_image);
00045    
00046    const UV &uv = getUV(w);
00047    
00048    const real_t repeatU  = m_parent->getValue<real_t>("repeatU", 1);
00049    const real_t repeatV  = m_parent->getValue<real_t>("repeatV", 1);
00050    const unsigned width  = m_image->getWidth();
00051    const unsigned height = m_image->getHeight();
00052    
00053    const real_t s = uv.u * repeatU;
00054    const real_t t = uv.v * repeatV;
00055    const real_t x = CAP((s - floor(s)) * width,  0, width  - 1);
00056    const real_t y = CAP((t - floor(t)) * height, 0, height - 1);
00057    
00058    return SpectralSampleSet(m_filter->apply(m_image.get(), x, y));
00059 }
00060 
00061 Vector2 EnvironmentMap::getSphericalCoords(const Vector3 &w) {
00062    const real_t rho   = sqrt(w[0] * w[0] + w[2] * w[2]);
00063    const real_t mag   = w.getMagnitude();
00064    
00065    const real_t theta = (rho < ABS(w[1]) ? 
00066                          acos(rho / mag) * (w[1] >= 0 ? 1 : -1) : 
00067                          asin(w[1] / mag));
00068    const real_t phi   = (w[0] == 0 && w[2] == 0) ? 0 : atan2(w[0], w[2]);
00069    
00070    return Vector2(theta, phi);
00071 }
00072 
00073 Vector2 EnvironmentMap::getSphericalCoords(const UV &uv) {
00074    return Vector2(-M_PI * uv.v - 0.5, -2 * M_PI * uv.u - 0.5);
00075 }
00076 
00077 UV EnvironmentMap::getUV(const Vector3 &w) {
00078    return getUV(getSphericalCoords(w));
00079 }
00080 
00081 UV EnvironmentMap::getUV(const Vector2 &coords) {
00082    return UV(coords[1] / (-2 * M_PI) + 0.5, coords[0] / -M_PI + 0.5);
00083 }
00084 
00085 Vector3 EnvironmentMap::getDirection(const UV &uv) {
00086    const Vector2 &coords = getSphericalCoords(uv);
00087    
00088    return Vector3(sin(coords[1]) * cos(coords[0]), 
00089                   sin(coords[0]), 
00090                   cos(coords[1]) * cos(coords[0]));
00091 }
00092 

Generated on 28 Feb 2009 for Milton by doxygen 1.5.6