mitsuba/include/mitsuba/core/util.h

241 lines
8.0 KiB
C++

#if !defined(__UTIL_H)
#define __UTIL_H
MTS_NAMESPACE_BEGIN
class Random;
// -----------------------------------------------------------------------
// Miscellaneous
// -----------------------------------------------------------------------
static const int primeTableSize = 1000;
/// Table of the first 1000 prime numbers
extern const int MTS_EXPORT_CORE primeTable[primeTableSize];
/**
* \brief Given a list of delimiters, tokenize
* a std::string into a vector of strings
*/
extern MTS_EXPORT_CORE std::vector<std::string> tokenize(
const std::string &string,
const std::string &delim
);
/// Indent a string (Used for recursive toString() structure dumping)
extern MTS_EXPORT_CORE std::string indent(const std::string &string, int amount=1);
/// Convert a time difference (in ms) to a string representation
extern MTS_EXPORT_CORE std::string timeToString(Float time);
/// Convert a string to lower case
extern MTS_EXPORT_CORE std::string toLowerCase(const std::string &string);
/// Convert a string to upper case
extern MTS_EXPORT_CORE std::string toUpperCase(const std::string &string);
/// Trim spaces (' ', '\n', '\r', '\t') from the ends of a string
extern MTS_EXPORT_CORE std::string trim(const std::string& str);
/// Determines whether a string ends with the string given as second parameter
extern MTS_EXPORT_CORE bool endsWith(const std::string& str, const std::string& end);
/// Allocate an aligned region of memory
extern MTS_EXPORT_CORE void * __restrict allocAligned(size_t size);
#if defined(WIN32)
/// Return a string version of GetLastError()
extern std::string MTS_EXPORT_CORE lastErrorText();
#endif
/// Free an aligned region of memory
extern MTS_EXPORT_CORE void freeAligned(void *ptr);
/// Determine the number of available CPU cores
extern MTS_EXPORT_CORE int getProcessorCount();
/// Return the host name of this machine
extern MTS_EXPORT_CORE std::string getHostName();
/// Return the fully qualified domain name of this machine
extern MTS_EXPORT_CORE std::string getFQDN();
/// Wrapped snprintf
extern MTS_EXPORT_CORE std::string formatString(const char *pFmt, ...);
/// Base-2 logarithm
extern MTS_EXPORT_CORE Float log2(Float value);
/// Base-2 logarithm (integer version)
extern MTS_EXPORT_CORE int log2i(int value);
/// Friendly modulo function (always positive)
extern MTS_EXPORT_CORE int modulo(int a, int b);
/// Check if an integer is a power of two
extern MTS_EXPORT_CORE bool isPowerOfTwo(unsigned int i);
/// Round an integer to the next power of two
extern MTS_EXPORT_CORE unsigned int roundToPowerOfTwo(unsigned int i);
//// Windowed sinc filter (Lanczos envelope, tau=number of cycles)
extern MTS_EXPORT_CORE Float lanczosSinc(Float t, Float tau = 2);
/**
* \brief Solve a quadratic equation of the form a*x^2 + b*x + c = 0.
* Returns true if a solution could be found
*/
extern MTS_EXPORT_CORE bool solveQuadratic(Float a, Float b, Float c, Float &x0, Float &x1);
/**
* \brief Solve a 2x2 linear equation system using basic linear algebra
*/
extern MTS_EXPORT_CORE bool solveLinearSystem2x2(const Float a[2][2], const Float b[2], Float x[2]);
/// Complete the set {a} to an orthonormal base
extern MTS_EXPORT_CORE void coordinateSystem(const Vector &a, Vector &b, Vector &c);
/**
* \brief Generate optionally jittered, stratified 1D samples
* @param dest A pointer to a floating point array with at least
* count entries
* @param count The interval [0, 1] is split into count strata
* @param jitter Randomly jitter the samples?
*/
extern MTS_EXPORT_CORE void stratifiedSample1D(Random *random, Float *dest,
int count, bool jitter);
/**
* \brief Generate optionally jittered, stratified 2D samples
* @param dest A pointer to a floating point array
* @param countX The X axis interval [0, 1] is split into countX strata
* @param countY The Y axis interval [0, 1] is split into countY strata
* @param jitter Randomly jitter the samples?
*/
extern MTS_EXPORT_CORE void stratifiedSample2D(Random *random, Point2 *dest,
int countX, int countY, bool jitter);
/// Generate latin hypercube samples
extern MTS_EXPORT_CORE void latinHypercube(Random *random, Float *dest, int nSamples, int nDim);
/// Convert spherical coordinates to a direction
extern MTS_EXPORT_CORE Vector sphericalDirection(Float theta, Float phi);
/// Convert a direction to spherical coordinates
extern MTS_EXPORT_CORE Point2 toSphericalCoordinates(const Vector &v);
/// Sample a vector on the unit sphere (PDF: 1/(4 * PI), wrt. solid angles)
extern MTS_EXPORT_CORE Vector squareToSphere(const Point2 &sample);
/// Sample a vector on the unit hemisphere (PDF: 1/(2 * PI), wrt. solid angles)
extern MTS_EXPORT_CORE Vector squareToHemisphere(const Point2 &sample);
/// Sample a vector on the unit hemisphere (PDF: cos(theta) / PI, wrt. solid angles)
extern MTS_EXPORT_CORE Vector squareToHemispherePSA(const Point2 &sample);
/// Sample a vector that lies in a cone of angles
extern MTS_EXPORT_CORE Vector squareToCone(Float cosCutoff, const Point2 &sample);
extern MTS_EXPORT_CORE Float squareToConePdf(Float cosCutoff);
/// Sample a vector on a 2D disk (PDF: 1/(2 * PI))
extern MTS_EXPORT_CORE Point2 squareToDisk(const Point2 &sample);
/// Low-distortion concentric square to disk mapping by Peter Shirley (PDF: 1/(2 * PI))
extern MTS_EXPORT_CORE Point2 squareToDiskConcentric(const Point2 &sample);
/// Convert an uniformly distributed square sample into barycentric coordinates
extern MTS_EXPORT_CORE Point2 squareToTriangle(const Point2 &sample);
/// Convert radians to degrees
inline Float radToDeg(Float rad) {
return 180.0f*rad/M_PI;
}
/// Convert degrees to radians
inline Float degToRad(Float deg) {
return deg*M_PI/180.0f;
}
/// Simple floating point clamping function
inline Float clamp(Float value, Float min, Float max) {
if (value < min)
return min;
else if (value > max)
return max;
else return value;
}
/// Simple integer clamping function
inline int clamp(int value, int min, int max) {
if (value < min)
return min;
else if (value > max)
return max;
else return value;
}
/**
* Calculates the unpolarized fresnel reflection coefficient for a
* dielectric material
*
* @param cosTheta1
* Cosine of the angle between the normal and the incident ray
* @param cosTheta2
* Cosine of the angle between the normal and the transmitted ray
* @param etaExt
* Refraction coefficient outside of the material
* @param etaInt
* Refraction coefficient inside the material
*/
extern MTS_EXPORT_CORE Float fresnelDielectric(Float cosTheta1, Float cosTheta2,
Float etaExt, Float etaInt);
/**
* Calculates the unpolarized fresnel reflection coefficient for a
* dielectric material. Handles incidence from either sides.
*
* @param cosTheta1
* Cosine of the angle between the normal and the incident ray
* @param etaExt
* Refraction coefficient outside of the material
* @param etaInt
* Refraction coefficient inside the material
*/
extern MTS_EXPORT_CORE Float fresnel(Float cosTheta1, Float etaExt, Float etaInt);
/**
* Calculates the unpolarized fresnel reflection coefficient on
* an interface to a conductor.
*
* @param cosTheta
* Cosine of the angle between the normal and the incident ray
* @param eta
* Relative refractive index (per wavelength)
* @param k
* Absorption coefficient (per wavelength)
*/
extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosTheta, const Spectrum &eta, const Spectrum &k);
/**
* Calculate the radical inverse function
* (Implementation based on "Instant Radiosity" by Alexander Keller
* in Computer Graphics Proceedings, Annual Conference Series,
* SIGGRAPH 97, pp. 49-56.
*/
extern MTS_EXPORT_CORE Float radicalInverse(int b, int i);
/**
* Incrementally calculate the radical inverse function
* (Implementation based on "Instant Radiosity" by Alexander Keller
* in Computer Graphics Proceedings, Annual Conference Series,
* SIGGRAPH 97, pp. 49-56.
*/
extern MTS_EXPORT_CORE Float radicalInverseIncremental(int b, Float x);
/* Rational approximation to the inverse normal cumulative distribution function */
extern MTS_EXPORT_CORE double normalQuantile(double p);
MTS_NAMESPACE_END
#endif /* __UTIL_H */