00001 #include <esg/energy/LightMap.h>
00002
00003 using namespace esg;
00004
00005 LightMap::LightMap(unsigned u, unsigned v, const Vector3& c, const Vector3& e)
00006 : EnergyMap(u,v), _centroid(c), _extent(e)
00007 {
00008 #ifdef WIN32
00009 _lightMap = (Color3f**) malloc(6 * _vRes * sizeof(Color3f*));
00010 #else
00011 _lightMap = new Color3f* [6 * _vRes];
00012 #endif
00013 for (register unsigned i = 0; i < 6 * _vRes; i++) {
00014 _lightMap[i] = new Color3f[u];
00015 for (register unsigned j = 0; j < _uRes; j++)
00016 _lightMap[i][j].set(.0, .0, .0);
00017 }
00018 }
00019
00020 LightMap::~LightMap()
00021 {
00022 for (register unsigned i = 0; i < 6 * _vRes; i++) delete [] _lightMap[i];
00023 delete [] _lightMap;
00024 }
00025
00026 bool LightMap::getPointEnergy(const Vector3& p, Vector3& e)
00027 {
00028 unsigned u, v;
00029 MapIndex i;
00030 if (!getMapCoords(p, i, u, v)) return false;
00031 e.set(_lightMap[i*_vRes+v][u]);
00032 return true;
00033 }
00034
00035 bool LightMap::setPointEnergy(const Vector3& p, const Vector3& e)
00036 {
00037 unsigned u, v;
00038 MapIndex i;
00039 if (!getMapCoords(p, i, u, v)) return false;
00040 _lightMap[i*_vRes+v][u].set(e);
00041 return true;
00042 }
00043
00044 bool LightMap::setValue(MapIndex i, unsigned u, unsigned v, const Color3f& c)
00045 {
00046 if (u >= _uRes || v >= _vRes || i > 5) return false;
00047 _lightMap[i*_vRes+v][u].set(c);
00048 return true;
00049 }
00050
00051 bool LightMap::getValue(MapIndex i, unsigned u, unsigned v, Color3f& c) const
00052 {
00053 if (u >= _uRes || v >= _vRes || i > 5) return false;
00054 c.set(_lightMap[i*_vRes+v][u]);
00055 return true;
00056 }
00057
00058 bool LightMap::getMapCoords(const Vector3& p,
00059 MapIndex& i,
00060 unsigned& u,
00061 unsigned& v) const
00062 {
00063 Vector3 dir(p);
00064 dir.sub(_centroid);
00065 Vector3 adir(dir);
00066 adir.absolute();
00067
00068 if (adir.x > adir.y) {
00069 if (adir.x > adir.z) {
00070 if (dir.x > 0) i = RIGHT_MAP;
00071 else i = LEFT_MAP;
00072 } else {
00073 if (dir.z > 0) i = NEAR_MAP;
00074 else i = FAR_MAP;
00075 }
00076 } else {
00077 if (adir.y > adir.z) {
00078 if (dir.y > 0) i = TOP_MAP;
00079 else i = BOTTOM_MAP;
00080 } else {
00081 if (dir.z > 0) i = NEAR_MAP;
00082 else i = FAR_MAP;
00083 }
00084 }
00085
00086 if (i == RIGHT_MAP || i == LEFT_MAP) {
00087
00088 float a = dir.y / sqrt(dir.x*dir.x + dir.y*dir.y);
00089
00090 a += 1/sqrt(2.0);
00091
00092 a /= PI/2;
00093
00094 v = (unsigned) (a * (_vRes - 1));
00095
00096 a = dir.z / sqrt(dir.x*dir.x + dir.z*dir.z);
00097 a += 1/sqrt(2.0);
00098 a /= PI/2;
00099 if (i == LEFT_MAP) a = 1 - a;
00100 u = (unsigned) (a * (_uRes - 1));
00101
00102 return true;
00103 }
00104
00105 if (i == FAR_MAP || i == NEAR_MAP) {
00106 float a = dir.y / sqrt(dir.z*dir.z + dir.y*dir.y);
00107 a += 1/sqrt(2.0);
00108 a /= PI/2;
00109 v = (unsigned) (a * (_vRes - 1));
00110
00111 a = dir.x / sqrt(dir.z*dir.z + dir.x*dir.x);
00112 a += 1/sqrt(2.0);
00113 a /= PI/2;
00114 if (i == FAR_MAP) a = 1 - a;
00115 u = (unsigned) (a * (_uRes - 1));
00116
00117 return true;
00118 }
00119
00120 if (i == BOTTOM_MAP || i == TOP_MAP) {
00121 float a = dir.z / sqrt(dir.z*dir.z + dir.y*dir.y);
00122 a += 1/sqrt(2.0);
00123 a /= PI/2;
00124 if (i == TOP_MAP) a = 1 - a;
00125 v = (unsigned) (a * (_vRes - 1));
00126
00127 a = dir.x / sqrt(dir.y*dir.y + dir.x*dir.x);
00128 a += 1/sqrt(2.0);
00129 a /= PI/2;
00130 u = (unsigned) (a * (_uRes - 1));
00131
00132 return true;
00133 }
00134
00135 return false;
00136 }