// HaltonSampler Method Definitions HaltonSampler::HaltonSampler(int samplesPerPixel, const Bounds2i &sampleBounds) : GlobalSampler(samplesPerPixel) { // Generate random digit permutations for Halton sampler if (radicalInversePermutations.size() == 0) { RNG rng; radicalInversePermutations = ComputeRadicalInversePermutations(rng); } // Find radical inverse base scales and exponents that cover sampling area Vector2i res = sampleBounds.pMax - sampleBounds.pMin; for (int i = 0; i < 2; ++i) { int base = (i == 0) ? 2 : 3; int scale = 1, exp = 0; while (scale < std::min(res[i], kMaxResolution)) { scale *= base; ++exp; } baseScales[i] = scale; baseExponents[i] = exp; } // Compute stride in samples for visiting each pixel area sampleStride = baseScales[0] * baseScales[1]; // Compute multiplicative inverses for _baseScales_ multInverse[0] = multiplicativeInverse(baseScales[1], baseScales[0]); multInverse[1] = multiplicativeInverse(baseScales[0], baseScales[1]); }
void setFilmResolution(const Vector2i &res, bool blocked) { if (blocked) { /* Determine parameters of the space partition in the first two dimensions. This is required to support bucketed rendering. */ m_primeExponents = Vector2i(0, 0); m_stride = 1; for (int i=0; i<2; ++i) { int prime = primeTable[i], value = 1, exp = 0; while (value < std::min(res[i], MAX_RESOLUTION)) { value *= prime; ++exp; } m_primePowers[i] = value; m_primeExponents[i] = exp; m_stride *= value; } m_multInverse[0] = multiplicativeInverse(m_primePowers.y, m_primePowers.x); m_multInverse[1] = multiplicativeInverse(m_primePowers.x, m_primePowers.y); } else { m_primeExponents[0] = m_primeExponents[1] = 0; m_primePowers[0] = m_primePowers[1] = 1; m_multInverse[0] = m_multInverse[1] = 0; m_stride = 1; } m_pixelPosition = Point2i(0); m_offset = 0; }
IFloat multiplicativeInverse(const IFloat &ifloat) { if (ifloat.isempty) return IFloat::empty; if (ifloat <= 0) return -multiplicativeInverse(-ifloat); if (!(ifloat >= 0)) return IFloat(-std::numeric_limits<Float>::infinity(), std::numeric_limits<Float>::infinity()); ProtectRounding pr; Float r; // For rounding r = 1 / -ifloat.b; // For rounding return IFloat(-r, 1 / ifloat.a); }
Quat operator/(const Quat& lhs, const Quat& rhs) { Quat r = lhs * multiplicativeInverse(rhs); return r; }
// divide-assign (needs to be declared after multiplicativeInverse) inline quat & operator/=(const quat &lhs, const quat &rhs) { quat q = lhs; quat inv = multiplicativeInverse(rhs); return q *= inv; }
int* divideRowBy(int* row, int row_size, int value) { return multiplyRowBy(row, row_size, multiplicativeInverse(value)); }