Skip to content

Commit 5ecf50e

Browse files
author
devsh
committed
fix IES Profile average emission and domain calculations
1 parent 199b75a commit 5ecf50e

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

examples_tests

src/nbl/asset/utils/CIESProfile.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ namespace nbl
7272
inline IES_STORAGE_FORMAT getAvgEmmision(const bool fullDomain=false) const
7373
{
7474
if (fullDomain)
75-
return totalEmissionIntegral*0.25/core::radians(vAngles.back()-vAngles.front());
75+
{
76+
const float cosLo = std::cos(core::radians(vAngles.front()));
77+
const float cosHi = std::cos(core::radians<float>(vAngles.back()));
78+
const float dsinTheta = cosLo - cosHi;
79+
return totalEmissionIntegral*(0.5/core::PI<float>())/dsinTheta;
80+
}
7681
return avgEmmision;
7782
}
7883

src/nbl/asset/utils/CIESProfileParser.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,23 @@ bool CIESProfileParser::parse(CIESProfile& result)
180180
float totalEmissionIntegral = 0.0, nonZeroEmissionDomainSize = 0.0;
181181
constexpr auto FULL_SOLID_ANGLE = 4.0f * core::PI<float>();
182182

183+
// TODO: this code could have two separate inner for loops for `result.symmetry != CIESProfile::ISOTROPIC` cases
183184
const auto H_ANGLES_I_RANGE = result.symmetry != CIESProfile::ISOTROPIC ? result.hAngles.size() - 1 : 1;
184185
const auto V_ANGLES_I_RANGE = result.vAngles.size() - 1;
185186

186-
for (size_t i = 0; i < H_ANGLES_I_RANGE; i++)
187+
for (size_t j = 0; j < V_ANGLES_I_RANGE; j++)
187188
{
188-
const float dPhiRad = result.symmetry != CIESProfile::ISOTROPIC ? (hAngles[i + 1] - hAngles[i]) : core::PI<float>() * 2.0f;
189-
190-
for (size_t j = 0; j < V_ANGLES_I_RANGE; j++)
189+
const float thetaRad = core::radians<float>(result.vAngles[j]);
190+
const float cosLo = std::cos(thetaRad);
191+
const float cosHi = std::cos(core::radians<float>(result.vAngles[j+1]));
192+
const float dsinTheta = cosLo - cosHi;
193+
194+
float stripIntegral = 0.f;
195+
float nonZeroStripDomain = 0.f;
196+
for (size_t i = 0; i < H_ANGLES_I_RANGE; i++)
191197
{
198+
const float dPhiRad = result.symmetry != CIESProfile::ISOTROPIC ? core::radians<float>(hAngles[i + 1] - hAngles[i]) : (core::PI<float>() * 2.0f);
199+
192200
const auto candelaValue = result.getCandelaValue(i, j);
193201

194202
// interpolate candela value spanned onto a solid angle
@@ -199,23 +207,17 @@ bool CIESProfileParser::parse(CIESProfile& result)
199207
if (result.maxCandelaValue < candelaValue)
200208
result.maxCandelaValue = candelaValue;
201209

202-
const float thetaRad = core::radians<float>(result.vAngles[j]);
203-
const float cosLo = std::cos(core::radians<float>(result.vAngles[j]));
204-
const float cosHi = std::cos(core::radians<float>(result.vAngles[j + 1]));
205-
206-
const auto differentialSolidAngle = dPhiRad*(cosLo - cosHi);
207-
const auto integralV = candelaAverage * differentialSolidAngle;
208-
209-
if (integralV > 0.0)
210-
{
211-
totalEmissionIntegral += integralV;
212-
nonZeroEmissionDomainSize += differentialSolidAngle;
213-
}
210+
stripIntegral += candelaAverage*dPhiRad;
211+
if (candelaAverage>0.f)
212+
nonZeroStripDomain += dPhiRad;
214213
}
214+
totalEmissionIntegral += stripIntegral*dsinTheta;
215+
nonZeroEmissionDomainSize += nonZeroStripDomain*dsinTheta;
215216
}
216217

217-
nonZeroEmissionDomainSize = std::clamp<float>(nonZeroEmissionDomainSize, 0.0, FULL_SOLID_ANGLE);
218-
if (nonZeroEmissionDomainSize <= 0) // protect us from division by 0 (just in case, we should never hit it)
218+
assert(nonZeroEmissionDomainSize >= 0.f);
219+
//assert(nonZeroEmissionDomainSize*fluxMultiplier =approx= 2.f*(cosBack-cosFront)*PI);
220+
if (nonZeroEmissionDomainSize <= std::numeric_limits<float>::min()) // protect us from division by small numbers (just in case, we should never hit it)
219221
return false;
220222

221223
result.avgEmmision = totalEmissionIntegral / static_cast<decltype(totalEmissionIntegral)>(nonZeroEmissionDomainSize);

0 commit comments

Comments
 (0)