Spectrum MIPMap::getValue(Float u, Float v, Float dudx, Float dudy, Float dvdx, Float dvdy) const { if (m_filterType == ETrilinear) { ++mipmapLookups; /* Conservatively estimate a square lookup region */ Float width = 2.0f * std::max( std::max(std::abs(dudx), std::abs(dudy)), std::max(std::abs(dvdx), std::abs(dvdy))); Float mipmapLevel = m_levels - 1 + log2(std::max(width, (Float) 1e-8f)); if (mipmapLevel < 0) { /* The lookup is smaller than one pixel */ return triangle(0, u, v); } else if (mipmapLevel >= m_levels - 1) { /* The lookup is larger than the whole texture */ return getTexel(m_levels - 1, 0, 0); } else { /* Tri-linear interpolation */ int level = (int) mipmapLevel; Float delta = mipmapLevel - level; return triangle(level, u, v) * (1.0f - delta) + triangle(level, u, v) * delta; } } else if (m_filterType == EEWA) { if (dudx*dudx + dudy*dudy < dvdx*dvdx + dvdy*dvdy) { std::swap(dudx, dvdx); std::swap(dudy, dvdy); } Float majorLength = std::sqrt(dudx * dudx + dudy * dudy); Float minorLength = std::sqrt(dvdx * dvdx + dvdy * dvdy); if (minorLength * m_maxAnisotropy < majorLength && minorLength > 0.0f) { Float scale = majorLength / (minorLength * m_maxAnisotropy); dvdx *= scale; dvdy *= scale; minorLength *= scale; } if (minorLength == 0) return triangle(0, u, v); // The min() below avoids overflow in the int conversion when lod=inf Float lod = std::min(std::max((Float) 0, m_levels - 1 + log2(minorLength)), (Float) (m_levels-1)); int ilod = floorToInt(lod); Float d = lod - ilod; return EWA(u, v, dudx, dudy, dvdx, dvdy, ilod) * (1-d) + EWA(u, v, dudx, dudy, dvdx, dvdy, ilod+1) * d; } else { int xPos = floorToInt(u*m_levelWidth[0]), yPos = floorToInt(v*m_levelHeight[0]); return getTexel(0, xPos, yPos); } }
void ESPSerialWiFiManager::_write_config(){ EWA(_eeprom_offset + 1, _network_config); }