OCD: remove trailing spaces from all files
parent
ac8c7ad6d7
commit
efe33e9212
|
@ -30,17 +30,17 @@ MTS_NAMESPACE_BEGIN
|
|||
#if MTS_BD_DEBUG == 1
|
||||
#define BDAssert(expr) SAssert(expr)
|
||||
#else
|
||||
#define BDAssert(expr)
|
||||
#define BDAssert(expr)
|
||||
#endif
|
||||
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
/**
|
||||
* \brief Data record associated with path endpoints (aka supernodes)
|
||||
* \brief Data record associated with path endpoints (aka supernodes)
|
||||
* in the path-space framework
|
||||
*
|
||||
* This record stores the desired time value when starting a new path.
|
||||
* For sensor subpaths, it optionally specifies the desired pixel
|
||||
* This record stores the desired time value when starting a new path.
|
||||
* For sensor subpaths, it optionally specifies the desired pixel
|
||||
* position of the path.
|
||||
*
|
||||
* \ingroup libbidir
|
||||
|
@ -50,10 +50,10 @@ struct EndpointRecord {
|
|||
Float time;
|
||||
|
||||
/// Create a new endpoint record for a given time value
|
||||
inline EndpointRecord(Float time)
|
||||
inline EndpointRecord(Float time)
|
||||
: time(time) { }
|
||||
|
||||
/// Create a new endpoint record for a given time value
|
||||
/// Create a new endpoint record for a given time value
|
||||
inline EndpointRecord(Float time,
|
||||
const Point2 &uv) : time(time) { }
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Bidirectional path edge data structure
|
||||
*
|
||||
* The path edge data structure is responsible for representing the transport of
|
||||
* The path edge data structure is responsible for representing the transport of
|
||||
* light between pairs of scattering or emission events.
|
||||
* Amongst other things, it keeps track of the medium that fills the space between
|
||||
* adjacent vertices of a \ref Path. Furthermore, it can be used to evaluate and
|
||||
* Amongst other things, it keeps track of the medium that fills the space between
|
||||
* adjacent vertices of a \ref Path. Furthermore, it can be used to evaluate and
|
||||
* sample the visibility and transmittance functions of the scene.
|
||||
*
|
||||
* Although they do not correspond to any real transport, this implementation
|
||||
|
@ -45,7 +45,7 @@ MTS_NAMESPACE_BEGIN
|
|||
*/
|
||||
struct MTS_EXPORT_BIDIR PathEdge {
|
||||
/* ==================================================================== */
|
||||
//! @{ \name Enumerations and Fields
|
||||
//! @{ \name Enumerations and Fields
|
||||
/* ==================================================================== */
|
||||
|
||||
/// Pointer to the medium that contains this edge (where \c NULL is vacuum)
|
||||
|
@ -59,7 +59,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
/**
|
||||
* \brief Length of this edge in world-space distance units
|
||||
*
|
||||
* Note that edges adjacent to supernodes have length zero to
|
||||
* Note that edges adjacent to supernodes have length zero to
|
||||
* mark them as such.
|
||||
*/
|
||||
Float length;
|
||||
|
@ -84,14 +84,14 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
/**
|
||||
* \brief Medium sampling density of the adjacent vertices
|
||||
*
|
||||
* This field stores the probability of sampling the preceding and
|
||||
* This field stores the probability of sampling the preceding and
|
||||
* successive path vertices using the sampling technique implemented by
|
||||
* the function \ref PathEdge::sampleNext(). Depending on whether or not
|
||||
* they are medium interactions, this eintries either store a density per
|
||||
* unit length or a discrete probability.
|
||||
*/
|
||||
Float pdf[ETransportModes];
|
||||
|
||||
|
||||
//! @}
|
||||
/* ==================================================================== */
|
||||
|
||||
|
@ -100,7 +100,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
/* ==================================================================== */
|
||||
|
||||
/**
|
||||
* \brief Given a ray \c ray, sample a distance in this direction and
|
||||
* \brief Given a ray \c ray, sample a distance in this direction and
|
||||
* fill the edge data structure, as well as its target vertex with content.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -114,24 +114,24 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* endpoint of the edge. The sampling routine will then determine
|
||||
* the other endpoint.
|
||||
* \param succ
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \return \c true on success
|
||||
*/
|
||||
bool sampleNext(const Scene *scene, Sampler *sampler,
|
||||
bool sampleNext(const Scene *scene, Sampler *sampler,
|
||||
const PathVertex *pred, const Ray &ray, PathVertex *next,
|
||||
ETransportMode mode);
|
||||
|
||||
/**
|
||||
* \brief Create a perturbed successor vertex and edge
|
||||
*
|
||||
* This function behaves similar to \ref sampleNext() in that it
|
||||
* generates a successor edge and vertex.
|
||||
* This function behaves similar to \ref sampleNext() in that it
|
||||
* generates a successor edge and vertex.
|
||||
*
|
||||
* The main difference is that the desired direction, distance, and
|
||||
* type of the successor vertex are all specified, which makes the
|
||||
* The main difference is that the desired direction, distance, and
|
||||
* type of the successor vertex are all specified, which makes the
|
||||
* sampling process completely deterministic. This is useful for
|
||||
* implementing path-space perturbation strategies.
|
||||
*
|
||||
|
@ -147,15 +147,15 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* Specifies the desired distance between the current vertex and \c succ
|
||||
* (this only applies when <tt>desiredType=EMediumInteraction</tt>)
|
||||
* \param desiredType
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* \param succ
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \return \c true on success
|
||||
*/
|
||||
bool perturbDirection(const Scene *scene, const PathVertex *pred,
|
||||
bool perturbDirection(const Scene *scene, const PathVertex *pred,
|
||||
const Ray &ray, Float dist, PathVertex::EVertexType desiredType,
|
||||
PathVertex *next, ETransportMode mode);
|
||||
|
||||
|
@ -187,7 +187,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
*
|
||||
* This function computes the product of certain terms that are cached
|
||||
* in this edge and its adjacent vertices. The \c what parameter specifies
|
||||
* the terms to be included; it must be a combination of the flags
|
||||
* the terms to be included; it must be a combination of the flags
|
||||
* in the enumeration \ref ECachedValues.
|
||||
*
|
||||
* \remark This function assumes that \c pred and \c succ are the
|
||||
|
@ -199,28 +199,28 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* \param succ
|
||||
* The successor vertex of this edge
|
||||
*/
|
||||
Spectrum evalCached(const PathVertex *pred, const PathVertex *succ,
|
||||
Spectrum evalCached(const PathVertex *pred, const PathVertex *succ,
|
||||
unsigned int what) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the density of a successor node
|
||||
*
|
||||
* This function computes the hypothetical transport-related sampling density
|
||||
* of a given successor node conditioned on a specified predecessor when
|
||||
* using the sampling technique implemented by \ref sampleNext(). Depending
|
||||
* on whether or not the successor node is a medium interaction, the returned
|
||||
* This function computes the hypothetical transport-related sampling density
|
||||
* of a given successor node conditioned on a specified predecessor when
|
||||
* using the sampling technique implemented by \ref sampleNext(). Depending
|
||||
* on whether or not the successor node is a medium interaction, the returned
|
||||
* value is either a density per unit length or a discrete probability.
|
||||
*
|
||||
* Note: this function only computes terms associated with the transport
|
||||
* between vertices -- to account for the vertices themselves,
|
||||
* Note: this function only computes terms associated with the transport
|
||||
* between vertices -- to account for the vertices themselves,
|
||||
* refer to \ref PathEdge::evalPdf.
|
||||
*
|
||||
* \param scene
|
||||
* Pointer to the underlying scene
|
||||
* \param pred
|
||||
* Pointer to the preceding vertex
|
||||
* Pointer to the preceding vertex
|
||||
* \param succ
|
||||
* Pointer to the successor vertex
|
||||
* Pointer to the successor vertex
|
||||
*
|
||||
* \return The computed probability density
|
||||
*/
|
||||
|
@ -234,9 +234,9 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* transmittance between an arbitrary pair of nodes, \c pred and \c succ.
|
||||
*
|
||||
* \param pred
|
||||
* Pointer to the preceding vertex
|
||||
* Pointer to the preceding vertex
|
||||
* \param succ
|
||||
* Pointer to the successor vertex
|
||||
* Pointer to the successor vertex
|
||||
*
|
||||
* \return A spectrally varying transmittance value
|
||||
*/
|
||||
|
@ -246,9 +246,9 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* \brief Return the transmittance value associated with this edge
|
||||
*
|
||||
* \param pred
|
||||
* Pointer to the preceding vertex
|
||||
* Pointer to the preceding vertex
|
||||
* \param succ
|
||||
* Pointer to the successor vertex
|
||||
* Pointer to the successor vertex
|
||||
*
|
||||
* \return A spectrally varying transmittance value
|
||||
*/
|
||||
|
@ -259,13 +259,13 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* term over an edge
|
||||
*/
|
||||
Float evalCosine(const PathVertex *pred, const PathVertex *succ, const PathVertex *base) const;
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
/* ==================================================================== */
|
||||
|
||||
/* ==================================================================== */
|
||||
//! @{ \name Miscellaneous
|
||||
//! @{ \name Miscellaneous
|
||||
/* ==================================================================== */
|
||||
|
||||
/**
|
||||
|
@ -274,7 +274,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
*
|
||||
* This function re-evaluates a series of quantities associated with
|
||||
* this edge and compares them to locally cached values.
|
||||
* If any mismatch is found, the function sends debug output to a
|
||||
* If any mismatch is found, the function sends debug output to a
|
||||
* specified output stream and returns \c false.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -288,7 +288,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* \param os
|
||||
* Target output stream for error messages
|
||||
*/
|
||||
bool verify(const Scene *scene, const PathVertex *adjL,
|
||||
bool verify(const Scene *scene, const PathVertex *adjL,
|
||||
const PathVertex *adjE, ETransportMode mode, std::ostream &os) const;
|
||||
|
||||
/**
|
||||
|
@ -315,19 +315,19 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* throughput or an inconsistency has been detected.
|
||||
*/
|
||||
bool connect(const Scene *scene, const PathEdge *predEdge,
|
||||
const PathVertex *vs, const PathVertex *vt,
|
||||
const PathVertex *vs, const PathVertex *vt,
|
||||
const PathEdge *succEdge);
|
||||
|
||||
/**
|
||||
* \brief Create a connection path between two vertices
|
||||
*
|
||||
* This function is conceptually similar to \ref connect().
|
||||
* However, instead of a single edge, it potentially generates
|
||||
* This function is conceptually similar to \ref connect().
|
||||
* However, instead of a single edge, it potentially generates
|
||||
* an entire connection path, where intermediate vertices are
|
||||
* either index-matched medium transitions or other surface
|
||||
* either index-matched medium transitions or other surface
|
||||
* scattering events of type \ref BSDF::ENull.
|
||||
*
|
||||
* This is important to support efficient direct illumination sampling
|
||||
* This is important to support efficient direct illumination sampling
|
||||
* through such surfaces (e.g. a heterogeneous medium or a leaf with
|
||||
* textured alpha transparency).
|
||||
*
|
||||
|
@ -364,22 +364,22 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* collapse it into a single edge that summarizes its properties
|
||||
*
|
||||
* This function can be thought of as being half-way in between
|
||||
* \c connect() and \c pathConnect(). Like \c pathConnect(), it
|
||||
* \c connect() and \c pathConnect(). Like \c pathConnect(), it
|
||||
* potentially generates an entire connection path between the
|
||||
* specified endpoints, where intermediate vertices are
|
||||
* either index-matched medium transitions or other surface
|
||||
* either index-matched medium transitions or other surface
|
||||
* scattering events of type \ref BSDF::ENull.
|
||||
*
|
||||
* This is important to support efficient direct illumination sampling
|
||||
* This is important to support efficient direct illumination sampling
|
||||
* through such surfaces (e.g. a heterogeneous medium or a leaf with
|
||||
* textured alpha transparency).
|
||||
*
|
||||
* However, this variant does not return the intermediate vertices
|
||||
* and edges -- instead, everything is collapsed into a single
|
||||
* edge that captures the aggregate weight and probability densities.
|
||||
*
|
||||
* This function is used by bidirectional path tracing, since it creates
|
||||
* connections through index-matched boundaries but does not require
|
||||
*
|
||||
* This function is used by bidirectional path tracing, since it creates
|
||||
* connections through index-matched boundaries but does not require
|
||||
* explicit knowledge about the associated path vertices.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -394,7 +394,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* \param succEdge
|
||||
* Pointer to an edge between \c vt and its successor
|
||||
* (which is not needed by this function)
|
||||
* \param interactions
|
||||
* \param interactions
|
||||
* Specifies the maximum permissible number of index-matched medium
|
||||
* transitions or \ref BSDF::ENull scattering events on the way
|
||||
* to the light source. (<tt>interactions<0</tt> means arbitrarily many).
|
||||
|
@ -404,8 +404,8 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
* \return \c true upon success, \c false when there is no
|
||||
* throughput or an inconsistency has been detected.
|
||||
*/
|
||||
bool pathConnectAndCollapse(const Scene *scene, const PathEdge *predEdge,
|
||||
const PathVertex *vs, const PathVertex *vt,
|
||||
bool pathConnectAndCollapse(const Scene *scene, const PathEdge *predEdge,
|
||||
const PathVertex *vs, const PathVertex *vt,
|
||||
const PathEdge *succEdge, int &interactions);
|
||||
|
||||
/// Create a deep copy of this edge
|
||||
|
@ -413,7 +413,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
|
||||
/// Compare this edge against another edge
|
||||
bool operator==(const PathEdge &edge) const;
|
||||
|
||||
|
||||
/// Compare this edge against another edge
|
||||
inline bool operator!=(const PathEdge &edge) const {
|
||||
return !operator==(edge);
|
||||
|
@ -421,7 +421,7 @@ struct MTS_EXPORT_BIDIR PathEdge {
|
|||
|
||||
/// Return a string representation of the information stored in this vertex
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
//! @}
|
||||
/* ==================================================================== */
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Clamped two-tailed geometric distribution
|
||||
*
|
||||
* This class implements a specialized clamped two-tailed geometric
|
||||
* This class implements a specialized clamped two-tailed geometric
|
||||
* distribution with support for sample generation and evaluation
|
||||
* of the probability mass and cumulative distribution functions.
|
||||
*
|
||||
|
@ -42,10 +42,10 @@ MTS_NAMESPACE_BEGIN
|
|||
*
|
||||
* where \f$b\in\mathbb{R}\f$ is the base parameter of the distribution,
|
||||
* \f$[l,r]\subseteq\mathbb{Z}\f$ denotes the domain of the probability
|
||||
* mass function, \f$o\in\mathbb{Z}\f$ is offset, and \f$c\f$ is a suitably
|
||||
* chosen normalization constant.
|
||||
* mass function, \f$o\in\mathbb{Z}\f$ is offset, and \f$c\f$ is a suitably
|
||||
* chosen normalization constant.
|
||||
*
|
||||
* This function is used to propose bidirectional mutations; see the
|
||||
* This function is used to propose bidirectional mutations; see the
|
||||
* MLT writeup for details.
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
|
@ -90,9 +90,9 @@ public:
|
|||
return (R(i) - m_offset) / m_normalization;
|
||||
}
|
||||
|
||||
/// Draw a position according to the probability mass function
|
||||
/// Draw a position according to the probability mass function
|
||||
inline int sample(Float xi) const {
|
||||
return std::max(m_start,
|
||||
return std::max(m_start,
|
||||
Rinv(xi * m_normalization + m_offset)) + m_center;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,14 +38,14 @@ public:
|
|||
SpecularManifold(const Scene *scene, int maxIterations = -1);
|
||||
|
||||
/**
|
||||
* \brief Initialize the specular manifold with the specified
|
||||
* \brief Initialize the specular manifold with the specified
|
||||
* path segment
|
||||
*/
|
||||
bool init(const Path &path, int start, int end);
|
||||
|
||||
/**
|
||||
* \brief Update the provided path segment based on the stored
|
||||
* specular manifold configuration
|
||||
* specular manifold configuration
|
||||
*/
|
||||
bool update(Path &path, int start, int end);
|
||||
|
||||
|
@ -98,7 +98,7 @@ private:
|
|||
/* Position and partials */
|
||||
Point p;
|
||||
Vector dpdu, dpdv;
|
||||
|
||||
|
||||
/* Normal and partials */
|
||||
Normal n, gn;
|
||||
Vector dndu, dndv;
|
||||
|
@ -109,7 +109,7 @@ private:
|
|||
/* Further information about the vertex */
|
||||
Float eta;
|
||||
const Object *object;
|
||||
|
||||
|
||||
/* Scratch space for matrix assembly */
|
||||
Matrix2x2 a, b, c, u;
|
||||
|
||||
|
@ -118,8 +118,8 @@ private:
|
|||
|
||||
/// Initialize certain fields to zero by default
|
||||
inline SimpleVertex(EType type, const Point &p) :
|
||||
degenerate(false), type(type), p(p), dpdu(0.0f),
|
||||
dpdv(0.0f), n(0.0f), dndu(0.0f), dndv(0.0f),
|
||||
degenerate(false), type(type), p(p), dpdu(0.0f),
|
||||
dpdv(0.0f), n(0.0f), dndu(0.0f), dndv(0.0f),
|
||||
m(0.0f), eta(1.0f), object(NULL) { }
|
||||
|
||||
/// Map a tangent space displacement into world space
|
||||
|
|
|
@ -29,7 +29,7 @@ MTS_NAMESPACE_BEGIN
|
|||
class MemoryPool {
|
||||
public:
|
||||
/// Create a new memory pool with aninitial set of 128 entries
|
||||
MemoryPool(size_t nEntries = 128)
|
||||
MemoryPool(size_t nEntries = 128)
|
||||
: m_vertexPool(nEntries), m_edgePool(nEntries) { }
|
||||
|
||||
/// Destruct the memory pool and release all entries
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
inline size_t edgeSize() {
|
||||
return m_edgePool.size();
|
||||
}
|
||||
|
||||
|
||||
/// Return the currently allocated amount of storage for vertices
|
||||
inline size_t vertexSize() {
|
||||
return m_vertexPool.size();
|
||||
|
|
|
@ -27,8 +27,8 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Bidirectional mutatation strategy
|
||||
*
|
||||
* This class implements a slightly extended version of the bidirectional
|
||||
* mutation proposed by Veach. The main change is that it builds on top of
|
||||
* This class implements a slightly extended version of the bidirectional
|
||||
* mutation proposed by Veach. The main change is that it builds on top of
|
||||
* a two-tailed geometric distribution that is used to sample path
|
||||
* configuration proposals in a more flexible manner.
|
||||
*
|
||||
|
@ -50,11 +50,11 @@ public:
|
|||
* A memory pool used to allocate new path vertices and edges
|
||||
*
|
||||
* \param kmin
|
||||
* Minimum number of edges in newly proposed paths. This can
|
||||
* Minimum number of edges in newly proposed paths. This can
|
||||
* be used to exclude direct illumination.
|
||||
*
|
||||
* \param kmax
|
||||
* Minimum number of edges in newly proposed paths.
|
||||
* Minimum number of edges in newly proposed paths.
|
||||
*/
|
||||
BidirectionalMutator(const Scene *scene, Sampler *sampler,
|
||||
MemoryPool &pool, int kmin, int kmax);
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
/**
|
||||
* \brief Compute the probability mass associated with one
|
||||
* \brief Compute the probability mass associated with one
|
||||
* of the internally implemented mutation strategies
|
||||
*/
|
||||
Float pmfMutation(const Path &source, const MutationRecord &muRec) const;
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
* Minimum jump distance in fractional pixel coordinates
|
||||
*
|
||||
* \param coveredArea
|
||||
* Approximate fractional image plane area that is
|
||||
* Approximate fractional image plane area that is
|
||||
* reachable using the caustic perturbation
|
||||
*/
|
||||
CausticPerturbation(const Scene *scene, Sampler *sampler,
|
||||
|
@ -62,9 +62,9 @@ public:
|
|||
|
||||
EMutationType getType() const;
|
||||
Float suitability(const Path &path) const;
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
MutationRecord &muRec);
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
const MutationRecord &muRec) const;
|
||||
void accept(const MutationRecord &muRec);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
* Minimum jump distance in fractional pixel coordinates
|
||||
*
|
||||
* \param coveredArea
|
||||
* Approximate fractional image plane area that is
|
||||
* Approximate fractional image plane area that is
|
||||
* reachable using the lens perturbation
|
||||
*/
|
||||
LensPerturbation(const Scene *scene, Sampler *sampler,
|
||||
|
@ -62,9 +62,9 @@ public:
|
|||
|
||||
EMutationType getType() const;
|
||||
Float suitability(const Path &path) const;
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
MutationRecord &muRec);
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
const MutationRecord &muRec) const;
|
||||
void accept(const MutationRecord &muRec);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
* A memory pool used to allocate new path vertices and edges
|
||||
*/
|
||||
ManifoldPerturbation(const Scene *scene, Sampler *sampler,
|
||||
MemoryPool &pool,
|
||||
MemoryPool &pool,
|
||||
Float probFactor,
|
||||
bool enableOffsetManifolds,
|
||||
bool enableSpecularMedia,
|
||||
|
@ -60,9 +60,9 @@ public:
|
|||
|
||||
EMutationType getType() const;
|
||||
Float suitability(const Path &path) const;
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
MutationRecord &muRec);
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
const MutationRecord &muRec) const;
|
||||
void accept(const MutationRecord &muRec);
|
||||
|
||||
|
@ -75,7 +75,7 @@ protected:
|
|||
virtual ~ManifoldPerturbation();
|
||||
|
||||
/// Helper function for choosing mutation strategies
|
||||
bool sampleMutationRecord(const Path &source,
|
||||
bool sampleMutationRecord(const Path &source,
|
||||
int &a, int &b, int &c, int &step);
|
||||
|
||||
Float nonspecularProbSurface(Float alpha) const;
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
* Minimum jump distance in fractional pixel coordinates
|
||||
*
|
||||
* \param coveredArea
|
||||
* Approximate fractional image plane area that is
|
||||
* Approximate fractional image plane area that is
|
||||
* reachable using the lens perturbation
|
||||
*/
|
||||
MultiChainPerturbation(const Scene *scene, Sampler *sampler,
|
||||
|
@ -62,9 +62,9 @@ public:
|
|||
|
||||
EMutationType getType() const;
|
||||
Float suitability(const Path &path) const;
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
bool sampleMutation(Path &source, Path &proposal,
|
||||
MutationRecord &muRec);
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
Float Q(const Path &source, const Path &proposal,
|
||||
const MutationRecord &muRec) const;
|
||||
void accept(const MutationRecord &muRec);
|
||||
|
||||
|
|
|
@ -60,21 +60,21 @@ public:
|
|||
*
|
||||
* \param proposal
|
||||
* Path data structure to be filled with the proposed mutated path
|
||||
*
|
||||
* \param muRec
|
||||
*
|
||||
* \param muRec
|
||||
* Data record that describes the sampled mutation strategy
|
||||
*
|
||||
* \return \a true upon success. When the sampling step is
|
||||
* unsuccessful (this could happen due to various
|
||||
* \return \a true upon success. When the sampling step is
|
||||
* unsuccessful (this could happen due to various
|
||||
* reasons), the function returns <tt>false</tt>.
|
||||
|
||||
*/
|
||||
virtual bool sampleMutation(Path &source, Path &proposal,
|
||||
virtual bool sampleMutation(Path &source, Path &proposal,
|
||||
MutationRecord &muRec) = 0;
|
||||
|
||||
/**
|
||||
* \brief For a pair of paths, this function computes the inverse
|
||||
* transition probability (matching the Q term in [Veach 97])
|
||||
* transition probability (matching the Q term in [Veach 97])
|
||||
*
|
||||
* \param source
|
||||
* A path data structure containing the original path
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
* \param proposal
|
||||
* A path data structure containing the proposed mutated path
|
||||
*
|
||||
* \param muRec
|
||||
* \param muRec
|
||||
* Data record that describes the mutation strategy, which
|
||||
* transformed \c source to \c proposal.
|
||||
*/
|
||||
|
@ -117,8 +117,8 @@ struct MTS_EXPORT_BIDIR MutationRecord {
|
|||
int extra[5];
|
||||
|
||||
inline MutationRecord() { }
|
||||
inline MutationRecord(Mutator::EMutationType type, int l,
|
||||
int m, int ka, const Spectrum &weight)
|
||||
inline MutationRecord(Mutator::EMutationType type, int l,
|
||||
int m, int ka, const Spectrum &weight)
|
||||
: type(type), l(l), m(m), ka(ka), weight(weight) { }
|
||||
|
||||
MutationRecord reverse() const {
|
||||
|
|
|
@ -29,14 +29,14 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Bidirectional path data structure
|
||||
*
|
||||
* In the path-space light transport framework, a path is represented as a
|
||||
* linear sequence of interactions (expressed using vertices) and transport
|
||||
* In the path-space light transport framework, a path is represented as a
|
||||
* linear sequence of interactions (expressed using vertices) and transport
|
||||
* (expressed using edges).
|
||||
*
|
||||
* The \ref Path data structure is responsible for the storage of this
|
||||
* information. It also contains useful utility functions, for instance
|
||||
* information. It also contains useful utility functions, for instance
|
||||
* to perform a random walk, or to splice and connect path segments.
|
||||
*
|
||||
*
|
||||
* \sa PathVertex
|
||||
* \sa PathEdge
|
||||
*
|
||||
|
@ -51,13 +51,13 @@ public:
|
|||
/* ==================================================================== */
|
||||
//! @{ \name Path construction
|
||||
/* ==================================================================== */
|
||||
|
||||
|
||||
/// Create a new, empty path
|
||||
inline Path() { }
|
||||
|
||||
/// Create a new path of the specified size
|
||||
inline Path(size_t size) : m_vertices(size) { }
|
||||
|
||||
|
||||
/// Copy constructor
|
||||
inline Path(const Path &path) : m_vertices(path.m_vertices),
|
||||
m_edges(path.m_edges) { }
|
||||
|
@ -65,7 +65,7 @@ public:
|
|||
/**
|
||||
* \brief Initialize the path with an endpoint vertex
|
||||
*
|
||||
* This function clears the path and initializes it with a single
|
||||
* This function clears the path and initializes it with a single
|
||||
* endpoint vertex of the type implied by the \c mode parameter.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -78,7 +78,7 @@ public:
|
|||
* Reference to a memory pool that will be used to release
|
||||
* and allocate edges and vertices.
|
||||
*/
|
||||
void initialize(const Scene *scene, Float time,
|
||||
void initialize(const Scene *scene, Float time,
|
||||
ETransportMode mode, MemoryPool &pool);
|
||||
|
||||
/**
|
||||
|
@ -92,16 +92,16 @@ public:
|
|||
* Desired number of random walk steps (<tt>-1</tt>=infinite)
|
||||
* \param rrStart
|
||||
* Depth to start using russian roulette
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* bounce, and so on)
|
||||
* \param mode
|
||||
* Denotes whether radiance or importance are being transported
|
||||
* \param pool
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* edges and vertices.
|
||||
* \return The number of successful steps performed by the random walk.
|
||||
*/
|
||||
int randomWalk(const Scene *scene, Sampler *sampler,
|
||||
int randomWalk(const Scene *scene, Sampler *sampler,
|
||||
int nSteps, int rrStart, ETransportMode mode,
|
||||
MemoryPool &pool);
|
||||
|
||||
|
@ -120,21 +120,21 @@ public:
|
|||
* sensor subpath
|
||||
* \param rrStart
|
||||
* Depth to start using russian roulette
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* bounce, and so on)
|
||||
* \param pool
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* edges and vertices.
|
||||
* \return The number of successful steps performed by the random walk.
|
||||
*/
|
||||
int randomWalkFromPixel(const Scene *scene, Sampler *sampler,
|
||||
int nSteps, const Point2i &pixelPosition, int rrStart,
|
||||
int randomWalkFromPixel(const Scene *scene, Sampler *sampler,
|
||||
int nSteps, const Point2i &pixelPosition, int rrStart,
|
||||
MemoryPool &pool);
|
||||
|
||||
/**
|
||||
* \brief Perform two random walks on an emitter and sensor subpath
|
||||
*
|
||||
* This function is almost identical to calling \ref randomWalk() twice
|
||||
* This function is almost identical to calling \ref randomWalk() twice
|
||||
* in sequence. The main difference is that it performs the random
|
||||
* walk steps in a staggered order (i.e. one step on the emitter subpath,
|
||||
* one step on the sensor subpath, and so on..), which is important for
|
||||
|
@ -163,25 +163,25 @@ public:
|
|||
* sensor subpath
|
||||
* \param rrStart
|
||||
* Depth to start using russian roulette
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* (<tt>-1</tt>=never, <tt>0</tt>=starting at the first
|
||||
* bounce, and so on)
|
||||
* \param pool
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* Reference to a memory pool that will be used to allocate
|
||||
* edges and vertices.
|
||||
* \return The number of successful steps performed by the random walk
|
||||
* on the emitter and sensor subpath, respectively.
|
||||
*/
|
||||
static std::pair<int, int> alternatingRandomWalkFromPixel(const Scene *scene,
|
||||
Sampler *sampler, Path &emitterPath, int nEmitterSteps,
|
||||
static std::pair<int, int> alternatingRandomWalkFromPixel(const Scene *scene,
|
||||
Sampler *sampler, Path &emitterPath, int nEmitterSteps,
|
||||
Path &sensorPath, int nSensorSteps, const Point2i &pixelPosition,
|
||||
int rrStart, MemoryPool &pool);
|
||||
|
||||
/**
|
||||
* \brief Verify the cached values stored in this path
|
||||
* \brief Verify the cached values stored in this path
|
||||
*
|
||||
* This function re-evaluates a series of quantities associated with
|
||||
* each vertex and edge and compares them to locally cached values.
|
||||
* If any mismatch is found, the function sends debug output to a
|
||||
* If any mismatch is found, the function sends debug output to a
|
||||
* specified output stream and returns \c false.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -203,7 +203,7 @@ public:
|
|||
/**
|
||||
* \brief Return the number of vertices stored in this path
|
||||
*
|
||||
* For a nonempty path, the number of vertices is always equal
|
||||
* For a nonempty path, the number of vertices is always equal
|
||||
* To \ref edgeCount()+1.
|
||||
*/
|
||||
inline size_t vertexCount() const {
|
||||
|
@ -213,7 +213,7 @@ public:
|
|||
/**
|
||||
* \brief Return the number of edges stored in this path
|
||||
*
|
||||
* For a nonempty path, the number of vertices is always equal
|
||||
* For a nonempty path, the number of vertices is always equal
|
||||
* To \ref vertexCount()-1.
|
||||
*/
|
||||
inline size_t edgeCount() const {
|
||||
|
@ -231,9 +231,9 @@ public:
|
|||
/// Return an vertex by its index
|
||||
inline PathVertexPtr &vertex(size_t index) {
|
||||
#if MTS_BD_DEBUG == 1
|
||||
if (index >= m_vertices.size())
|
||||
if (index >= m_vertices.size())
|
||||
SLog(EError, "Path vertex index " SIZE_T_FMT
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
index, m_vertices.size());
|
||||
#endif
|
||||
return m_vertices[index];
|
||||
|
@ -242,9 +242,9 @@ public:
|
|||
/// Return an vertex by its index (const version)
|
||||
inline const PathVertexPtr &vertex(size_t index) const {
|
||||
#if MTS_BD_DEBUG == 1
|
||||
if (index >= m_vertices.size())
|
||||
if (index >= m_vertices.size())
|
||||
SLog(EError, "Path vertex index " SIZE_T_FMT
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
index, m_vertices.size());
|
||||
#endif
|
||||
return m_vertices[index];
|
||||
|
@ -252,7 +252,7 @@ public:
|
|||
|
||||
/// Return an vertex by its index (or NULL if out of bounds)
|
||||
inline PathVertexPtr vertexOrNull(size_t index) {
|
||||
if (index >= m_vertices.size())
|
||||
if (index >= m_vertices.size())
|
||||
return NULL;
|
||||
return m_vertices[index];
|
||||
}
|
||||
|
@ -267,9 +267,9 @@ public:
|
|||
/// Return an edge by its index
|
||||
inline PathEdgePtr &edge(size_t index) {
|
||||
#if MTS_BD_DEBUG == 1
|
||||
if (index >= m_edges.size())
|
||||
if (index >= m_edges.size())
|
||||
SLog(EError, "Path edge index " SIZE_T_FMT
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
index, m_edges.size());
|
||||
#endif
|
||||
return m_edges[index];
|
||||
|
@ -278,9 +278,9 @@ public:
|
|||
/// Return an edge by its index (const version)
|
||||
inline const PathEdgePtr &edge(size_t index) const {
|
||||
#if MTS_BD_DEBUG == 1
|
||||
if (index >= m_edges.size())
|
||||
if (index >= m_edges.size())
|
||||
SLog(EError, "Path edge index " SIZE_T_FMT
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
" is out of bounds, array size: " SIZE_T_FMT,
|
||||
index, m_edges.size());
|
||||
#endif
|
||||
return m_edges[index];
|
||||
|
@ -288,24 +288,24 @@ public:
|
|||
|
||||
/// Return an edge by its index (or \c NULL if out of bounds)
|
||||
inline PathEdgePtr edgeOrNull(size_t index) {
|
||||
if (index >= m_edges.size())
|
||||
if (index >= m_edges.size())
|
||||
return NULL;
|
||||
return m_edges[index];
|
||||
}
|
||||
|
||||
/// Return an edge by its index (or \c NULL if out of bounds, const version)
|
||||
inline PathEdgePtr edgeOrNull(size_t index) const {
|
||||
if (index >= m_edges.size())
|
||||
if (index >= m_edges.size())
|
||||
return NULL;
|
||||
return m_edges[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
/* ==================================================================== */
|
||||
|
||||
/* ==================================================================== */
|
||||
//! @{ \name Miscellaneous
|
||||
//! @{ \name Miscellaneous
|
||||
/* ==================================================================== */
|
||||
|
||||
/**
|
||||
|
@ -320,11 +320,11 @@ public:
|
|||
inline Spectrum getPrefixSuffixWeight(int l, int m) const {
|
||||
Spectrum weight(1.0f);
|
||||
|
||||
for (int s=0; s<l; ++s)
|
||||
weight *= m_vertices[s]->weight[EImportance]
|
||||
for (int s=0; s<l; ++s)
|
||||
weight *= m_vertices[s]->weight[EImportance]
|
||||
* m_edges[s]->weight[EImportance];
|
||||
|
||||
for (int t=length(); t>m; --t)
|
||||
for (int t=length(); t>m; --t)
|
||||
weight *= m_vertices[t]->weight[ERadiance]
|
||||
* m_edges[t-1]->weight[ERadiance];
|
||||
|
||||
|
@ -344,7 +344,7 @@ public:
|
|||
return false;
|
||||
|
||||
for (size_t i=0; i<m_vertices.size(); ++i) {
|
||||
if (m_vertices[i]->type != p.vertex(i)->type ||
|
||||
if (m_vertices[i]->type != p.vertex(i)->type ||
|
||||
m_vertices[i]->isConnectable() != p.vertex(i)->isConnectable())
|
||||
return false;
|
||||
}
|
||||
|
@ -365,11 +365,11 @@ public:
|
|||
Spectrum weight(1.0f);
|
||||
int k = length();
|
||||
|
||||
for (int s=0; s<k-1; ++s)
|
||||
weight *= m_vertices[s]->weight[EImportance]
|
||||
for (int s=0; s<k-1; ++s)
|
||||
weight *= m_vertices[s]->weight[EImportance]
|
||||
* m_edges[s]->weight[EImportance];
|
||||
|
||||
weight = weight
|
||||
weight = weight
|
||||
* m_vertices[k]->weight[ERadiance]
|
||||
* m_vertices[k-1]->weight[ERadiance]
|
||||
* m_edges[k-1]->weight[ERadiance];
|
||||
|
@ -379,15 +379,15 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Compute the multiple importance sampling weight of the <tt>(s,t)</tt>
|
||||
* \brief Compute the multiple importance sampling weight of the <tt>(s,t)</tt>
|
||||
* sampling strategy in BDPT.
|
||||
*
|
||||
* This implementation uses the power heuristic with exponent 2 and
|
||||
* repeatedly evaluates equation (10.9) from Eric Veach's PhD thesis to
|
||||
* compute the weight in an efficient and numerically stable manner.
|
||||
* This implementation uses the power heuristic with exponent 2 and
|
||||
* repeatedly evaluates equation (10.9) from Eric Veach's PhD thesis to
|
||||
* compute the weight in an efficient and numerically stable manner.
|
||||
*
|
||||
* The function completely ignores the effects of russian roulette, since
|
||||
* this allows for a more efficient implementation. The resulting estimator
|
||||
* this allows for a more efficient implementation. The resulting estimator
|
||||
* is still unbiased despite this apparent inaccuracy.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -396,7 +396,7 @@ public:
|
|||
* Reference to the emitter subpath
|
||||
* \param connectionEdge
|
||||
* Pointer to an edge data structure associated with the
|
||||
* transport between <tt>emitterSubpath[s]</tt> and
|
||||
* transport between <tt>emitterSubpath[s]</tt> and
|
||||
* <tt>sensorSubpath[t]</tt>.
|
||||
* \param sensorSubpath
|
||||
* Reference to the sensor subpath
|
||||
|
@ -404,19 +404,19 @@ public:
|
|||
* Number of steps to take along the emitter subpath
|
||||
* \param t
|
||||
* Number of steps to take along the sensor subpath
|
||||
* \param direct
|
||||
* \param direct
|
||||
* When the parameter \c direct is set to \c true, the implementation
|
||||
* accounts for the fact that specialized direct sampling strategies
|
||||
* are used for paths with <tt>s==1</tt> and <tt>t==1</tt>.
|
||||
* \param lightImage
|
||||
* Denotes whether or not rendering strategies that require a 'light image'
|
||||
* (specifically, those with <tt>t==0</tt> or <tt>t==1</tt>) are included
|
||||
* (specifically, those with <tt>t==0</tt> or <tt>t==1</tt>) are included
|
||||
* in the rendering process.
|
||||
*/
|
||||
static Float miWeight(const Scene *scene,
|
||||
const Path &emitterSubpath,
|
||||
static Float miWeight(const Scene *scene,
|
||||
const Path &emitterSubpath,
|
||||
const PathEdge *connectionEdge,
|
||||
const Path &sensorSubpath, int s, int t,
|
||||
const Path &sensorSubpath, int s, int t,
|
||||
bool direct, bool lightImage);
|
||||
|
||||
/**
|
||||
|
@ -494,7 +494,7 @@ public:
|
|||
|
||||
/// Compare this path against another path
|
||||
bool operator==(const Path &path) const;
|
||||
|
||||
|
||||
/// Compare this path against another path
|
||||
inline bool operator!=(const Path &path) const {
|
||||
return !operator==(path);
|
||||
|
@ -503,10 +503,10 @@ public:
|
|||
/// Create a deep copy of this path
|
||||
void clone(Path &target, MemoryPool &pool) const;
|
||||
|
||||
/// Return a string representation of the path
|
||||
/// Return a string representation of the path
|
||||
std::string toString() const;
|
||||
|
||||
/// Return a basic string summary of the path
|
||||
|
||||
/// Return a basic string summary of the path
|
||||
std::string summarize() const;
|
||||
|
||||
//! @}
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief Implements a sampling strategy that is able to produce paths using
|
||||
* \brief Implements a sampling strategy that is able to produce paths using
|
||||
* bidirectional path tracing or unidirectional volumetric path tracing.
|
||||
*
|
||||
* This versatile class does the heavy lifting under the hood of Mitsuba's
|
||||
* PSSMLT implementation. It is also used to provide the Veach-MLT
|
||||
* This versatile class does the heavy lifting under the hood of Mitsuba's
|
||||
* PSSMLT implementation. It is also used to provide the Veach-MLT
|
||||
* implementation with a luminance estimate and seed paths.
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
*/
|
||||
typedef boost::function<void (int, int, Float, Path &)> PathCallback;
|
||||
|
||||
/// Specifies the sampling algorithm that is internally used
|
||||
/// Specifies the sampling algorithm that is internally used
|
||||
enum ETechnique {
|
||||
/// Bidirectional path tracing
|
||||
EBidirectional,
|
||||
|
@ -92,15 +92,15 @@ public:
|
|||
*
|
||||
* \param sampleDirect
|
||||
* When this parameter is set to true, specialized direct
|
||||
* sampling strategies are used for s=1 and t=1 paths.
|
||||
*
|
||||
* sampling strategies are used for s=1 and t=1 paths.
|
||||
*
|
||||
* \param lightImage
|
||||
* Denotes whether or not rendering strategies that require a 'light image'
|
||||
* (specifically, those with <tt>t==0</tt> or <tt>t==1</tt>) are included
|
||||
* (specifically, those with <tt>t==0</tt> or <tt>t==1</tt>) are included
|
||||
* in the rendering process.
|
||||
*/
|
||||
PathSampler(ETechnique technique, const Scene *scene, Sampler *emitterSampler,
|
||||
Sampler *sensorSampler, Sampler *directSampler, int maxDepth, int rrDepth,
|
||||
PathSampler(ETechnique technique, const Scene *scene, Sampler *emitterSampler,
|
||||
Sampler *sensorSampler, Sampler *directSampler, int maxDepth, int rrDepth,
|
||||
bool excludeDirectIllum, bool sampleDirect, bool lightImage = true);
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ public:
|
|||
*
|
||||
* This function is similar to \ref sampleSplats(), but instead of
|
||||
* returning only the contribution of the samples paths in the form of
|
||||
* screen-space "splats", it returns the actual paths by invoking a
|
||||
* screen-space "splats", it returns the actual paths by invoking a
|
||||
* specified callback function multiple times.
|
||||
*
|
||||
* This function is currently only implemented for the bidirectional
|
||||
|
@ -138,7 +138,7 @@ public:
|
|||
* value <tt>Point2i(-1)</tt> results in uniform sampling in screen space.
|
||||
*
|
||||
* \param pathCallback
|
||||
* A callback function that will be invoked once for each
|
||||
* A callback function that will be invoked once for each
|
||||
* path generated by the BDPT sampling strategy. The first argument
|
||||
* specifies the path importance weight.
|
||||
*/
|
||||
|
@ -164,7 +164,7 @@ public:
|
|||
* A vector of resulting MLT seeds
|
||||
* \return The average luminance over the image plane
|
||||
*/
|
||||
Float generateSeeds(size_t sampleCount, size_t seedCount,
|
||||
Float generateSeeds(size_t sampleCount, size_t seedCount,
|
||||
bool fineGrained, std::vector<PathSeed> &seeds);
|
||||
|
||||
/**
|
||||
|
@ -211,7 +211,7 @@ protected:
|
|||
/**
|
||||
* \brief Stores information required to re-create a seed path (e.g. for MLT)
|
||||
*
|
||||
* This class makes it possible to transmit a path over the network or store
|
||||
* This class makes it possible to transmit a path over the network or store
|
||||
* it locally, while requiring very little storage to do so. This is done by
|
||||
* describing a path using an index into a random number stream, which allows
|
||||
* to generate it cheaply when needed.
|
||||
|
@ -355,7 +355,7 @@ struct MTS_EXPORT_BIDIR SplatList {
|
|||
* This function divides all splats so that they have unit
|
||||
* luminance (though it leaves the \c luminance field untouched).
|
||||
* When given an optional importance map in 2-stage MLT approaches,
|
||||
* it divides the splat values by the associated importance
|
||||
* it divides the splat values by the associated importance
|
||||
* map values
|
||||
*/
|
||||
void normalize(const Bitmap *importanceMap = NULL);
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief Specialized sampler implementation used to seed MLT-style algorithm.
|
||||
* \brief Specialized sampler implementation used to seed MLT-style algorithm.
|
||||
*
|
||||
* Allows to query for the current sample index, which can later be used to rewind
|
||||
* back to this state. In the case of MLT, this makes it possible to sample paths
|
||||
* back to this state. In the case of MLT, this makes it possible to sample paths
|
||||
* approximately proportional to their contribution without actually having
|
||||
* to store millions of path. Note that `rewinding' is naive -- it just
|
||||
* to store millions of path. Note that `rewinding' is naive -- it just
|
||||
* resets & regenerates the whole random number sequence, which might be slow.
|
||||
*
|
||||
* \ingroup libbidir
|
||||
|
|
|
@ -34,17 +34,17 @@ public:
|
|||
/**
|
||||
* \brief Render the direct illumination component of a scene
|
||||
*
|
||||
* The function is made available here, since it is used
|
||||
* The function is made available here, since it is used
|
||||
* by both Keleman-style and Veach-style MLT.
|
||||
*/
|
||||
static ref<Bitmap> renderDirectComponent(Scene *scene, int sceneResID,
|
||||
int sensorResID, RenderQueue *queue, const RenderJob *job,
|
||||
static ref<Bitmap> renderDirectComponent(Scene *scene, int sceneResID,
|
||||
int sensorResID, RenderQueue *queue, const RenderJob *job,
|
||||
size_t directSamples);
|
||||
|
||||
/**
|
||||
* \brief Execute the first pass of a 2-pass MLT scheme.
|
||||
* \brief Execute the first pass of a 2-pass MLT scheme.
|
||||
*
|
||||
* The function is made available here, since it is used
|
||||
* The function is made available here, since it is used
|
||||
* by both Keleman-style and Veach-style MLT.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
* Pointer to the render queue associated with the original job
|
||||
*
|
||||
* \param sizeFactor
|
||||
* Size reduction factor to use when rendering the
|
||||
* Size reduction factor to use when rendering the
|
||||
* luminance image
|
||||
*
|
||||
* \param nestedJob
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
|
||||
/// Restores the measure of a path vertex after going out of scope
|
||||
struct RestoreMeasureHelper {
|
||||
RestoreMeasureHelper(PathVertex *vertex)
|
||||
RestoreMeasureHelper(PathVertex *vertex)
|
||||
: vertex(vertex), measure(vertex->measure) { }
|
||||
~RestoreMeasureHelper() { vertex->measure = measure; }
|
||||
PathVertex *vertex;
|
||||
|
|
|
@ -34,12 +34,12 @@ MTS_NAMESPACE_BEGIN
|
|||
* or Veach-style Metropolis Light Transport.
|
||||
*
|
||||
* This data structure can describe a several different types of interactions,
|
||||
* including surface and medium scattering events, as well as emission events
|
||||
* by a light source or a sensor (in the bidirectional framework, the response
|
||||
* including surface and medium scattering events, as well as emission events
|
||||
* by a light source or a sensor (in the bidirectional framework, the response
|
||||
* of a sensor is treated as an emitted quantity)
|
||||
*
|
||||
* A path vertex only describes what happens at the location of a scattering
|
||||
* or emission event -- what happens <em>in between</em> such interactions is
|
||||
* or emission event -- what happens <em>in between</em> such interactions is
|
||||
* captured in a separate data structure named \ref PathEdge.
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
|
@ -47,12 +47,12 @@ MTS_NAMESPACE_BEGIN
|
|||
*/
|
||||
struct MTS_EXPORT_BIDIR PathVertex {
|
||||
/* ==================================================================== */
|
||||
//! @{ \name Enumerations and Fields
|
||||
//! @{ \name Enumerations and Fields
|
||||
/* ==================================================================== */
|
||||
|
||||
/// Denotes the size of the auxiliary data section associated with each node
|
||||
enum {
|
||||
EDataSize = MAX(MAX(sizeof(Intersection),
|
||||
EDataSize = MAX(MAX(sizeof(Intersection),
|
||||
sizeof(MediumSamplingRecord)), MAX(
|
||||
sizeof(PositionSamplingRecord), sizeof(EndpointRecord)))
|
||||
};
|
||||
|
@ -60,7 +60,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/**
|
||||
* \brief What kind of vertex is this (e.g. medium, surface, emitter)?
|
||||
*
|
||||
* The two special 'supernode' types are used as path endpoints, which greatly
|
||||
* The two special 'supernode' types are used as path endpoints, which greatly
|
||||
* simplifies the control flow of various functions in this data structure and the
|
||||
* MLT/BDPT implementations.
|
||||
*/
|
||||
|
@ -71,7 +71,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
ESensorSupernode = 1,
|
||||
/// Special emitter 'supernode' -- just before the emitter sample
|
||||
EEmitterSupernode = 2,
|
||||
/// Sampled position on the surface of a sensor
|
||||
/// Sampled position on the surface of a sensor
|
||||
ESensorSample = 4,
|
||||
/// Sampled position on the surface of an emitter
|
||||
EEmitterSample = 8,
|
||||
|
@ -94,14 +94,14 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
uint8_t type : 7;
|
||||
|
||||
/**
|
||||
* \brief Denotes whether this vertex \a only supports
|
||||
* \brief Denotes whether this vertex \a only supports
|
||||
* sampling from degenerate distributions.
|
||||
*
|
||||
* It's useful to cache this information, since it allows
|
||||
* to quickly determine when certain pairs of vertices
|
||||
* to quickly determine when certain pairs of vertices
|
||||
* cannot be deterministically connected.
|
||||
*
|
||||
* Examples of degenerate vertices are surface interactions with
|
||||
* Examples of degenerate vertices are surface interactions with
|
||||
* dielectric boundaries and certain special cases. For instance, the
|
||||
* sensor supernode can be degenerate when the used sensor does not
|
||||
* cover any area (e.g. because it is a point camera).
|
||||
|
@ -113,15 +113,15 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* probability densities stored in \ref pdf.
|
||||
*
|
||||
* Certain vertices use sampling methods, whose probability
|
||||
* mass lies on domains that have different associated
|
||||
* measures. An example would be a surface interaction with
|
||||
* mass lies on domains that have different associated
|
||||
* measures. An example would be a surface interaction with
|
||||
* a smooth plastic material, where the specular reflection
|
||||
* component is degenerate and the glossy reflection component
|
||||
* component is degenerate and the glossy reflection component
|
||||
* is non-degenerate.
|
||||
*
|
||||
* This attribute stores the actual measure (an enumeration
|
||||
* item of type \ref EMeasure) and therefore clarifies whether
|
||||
* or not a degenerate component was sampled. When no sampling
|
||||
* item of type \ref EMeasure) and therefore clarifies whether
|
||||
* or not a degenerate component was sampled. When no sampling
|
||||
* event was generated yet, it is undefined.
|
||||
*
|
||||
* Currently, only three values are permissible:
|
||||
|
@ -134,7 +134,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/**
|
||||
* \brief When the current vertex supports sampling
|
||||
* from several components (this currently only applies
|
||||
* to %BSDF lobes), this attribute records the type
|
||||
* to %BSDF lobes), this attribute records the type
|
||||
* sampled component.
|
||||
*
|
||||
* Otherwise, it will be set to zero.
|
||||
|
@ -145,8 +145,8 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \brief Measurement contribution weight
|
||||
*
|
||||
* This field stores the terms of the path-space measurement contribution
|
||||
* function that are coupled to this specific vertex, divided by the
|
||||
* density of the adjacent vertices in the radiance and importance transport
|
||||
* function that are coupled to this specific vertex, divided by the
|
||||
* density of the adjacent vertices in the radiance and importance transport
|
||||
* directions (hence, it is an array with two entries).
|
||||
*
|
||||
* More precisely, it stores
|
||||
|
@ -163,9 +163,9 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* G(\mathbf{x}_i\leftrightarrow\mathbf{x}_{i-1})\,p_A(\mathbf{x}_{i+1}\to
|
||||
* \mathbf{x}_i\to\mathbf{x}_{i-1})^{-1}
|
||||
* \f]
|
||||
*
|
||||
*
|
||||
* Where \f$G\f$ is the geometric term, \f$p_A\f$ is an area density, and
|
||||
* increasing indices are closer to the sensor. Generally much cancellation
|
||||
* increasing indices are closer to the sensor. Generally much cancellation
|
||||
* will occur in the above expressions. For instance, for a surface
|
||||
* iteractions, this is equal to the BRDF times a cosine foreshortening
|
||||
* factor divided by the solid angle density of the default sampling
|
||||
|
@ -179,13 +179,13 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/**
|
||||
* \brief Area density of the two adjacent vertices
|
||||
*
|
||||
* This field stores the density of the predecessor and sucessor nodes
|
||||
* with respect of the sampling technique implemented by \ref sampleNext().
|
||||
* This field stores the density of the predecessor and sucessor nodes
|
||||
* with respect of the sampling technique implemented by \ref sampleNext().
|
||||
* The measure of this value is specified by the \ref measure field
|
||||
* (generally, it is the density per unit area).
|
||||
* (generally, it is the density per unit area).
|
||||
*
|
||||
* When one of the adjacent vertices is a medium interaction (i.e. it is
|
||||
* not located on a surface), the stored probability will specify the density
|
||||
* When one of the adjacent vertices is a medium interaction (i.e. it is
|
||||
* not located on a surface), the stored probability will specify the density
|
||||
* on a hypothetical surface oriented perpendicularly to the transport
|
||||
* direction.
|
||||
*
|
||||
|
@ -207,7 +207,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* which wreaks havoc with strict aliasing (and hence it is disabled
|
||||
* for all bidirectional code).
|
||||
*
|
||||
* Once C++11 is widely supported across all target platforms, this
|
||||
* Once C++11 is widely supported across all target platforms, this
|
||||
* should be replaced by an unrestricted union.
|
||||
*/
|
||||
uint8_t data[EDataSize];
|
||||
|
@ -220,13 +220,13 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/* ==================================================================== */
|
||||
|
||||
/**
|
||||
* \brief Generate a path endpoint that can be used to start
|
||||
* \brief Generate a path endpoint that can be used to start
|
||||
* a random walk
|
||||
*
|
||||
* \param scene
|
||||
* Pointer to the underlying scene
|
||||
* \param mode
|
||||
* Specifies the desired mode of transport, i.e. radiance or
|
||||
* Specifies the desired mode of transport, i.e. radiance or
|
||||
* importance transport
|
||||
* \param time
|
||||
* Denotes the time value that will be associated with this
|
||||
|
@ -235,7 +235,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
void makeEndpoint(const Scene *scene, Float time, ETransportMode mode);
|
||||
|
||||
/**
|
||||
* \brief Sample the next vertex in a random walk using the default
|
||||
* \brief Sample the next vertex in a random walk using the default
|
||||
* sampling technique implemented by the current vertex.
|
||||
*
|
||||
* Given a vertex, its predecessor, as well as the edge in between them,
|
||||
|
@ -250,12 +250,12 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \param predEdge
|
||||
* Edge to the preceding edge (if any) and \c NULL otherwise
|
||||
* \param succEdge
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* with information about the edge between the current vertex and
|
||||
* the newly sampled successor.
|
||||
* \param succ
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \param russianRoulette
|
||||
|
@ -270,21 +270,21 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \return \c true on success
|
||||
*/
|
||||
bool sampleNext(const Scene *scene, Sampler *sampler,
|
||||
const PathVertex *pred, const PathEdge *predEdge,
|
||||
PathEdge *succEdge, PathVertex *succ,
|
||||
const PathVertex *pred, const PathEdge *predEdge,
|
||||
PathEdge *succEdge, PathVertex *succ,
|
||||
ETransportMode mode, bool russianRoulette = false,
|
||||
Spectrum *throughput = NULL);
|
||||
|
||||
/**
|
||||
* \brief \a Direct sampling: given the current vertex as a reference
|
||||
* sample an emitter (or sensor) position that has a nonzero emission
|
||||
* sample an emitter (or sensor) position that has a nonzero emission
|
||||
* (or response) towards it.
|
||||
*
|
||||
* This can be seen as a generalization of direct illumination sampling
|
||||
* that can be used for both emitter and sensor endpoints.
|
||||
*
|
||||
* Ideally, the implementation should importance sample the product of
|
||||
* the emission or response profile and the geometry term between the
|
||||
* the emission or response profile and the geometry term between the
|
||||
* reference point and the sampled position. In practice, one of these
|
||||
* usually has to be sacrificed.
|
||||
*
|
||||
|
@ -303,11 +303,11 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* sampled sensor or emitter position
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \return The emitted radiance or importance divided by the
|
||||
* \return The emitted radiance or importance divided by the
|
||||
* sample probability per unit area per unit solid angle.
|
||||
*/
|
||||
Spectrum sampleDirect(const Scene *scene, Sampler *sampler,
|
||||
PathVertex *endpoint, PathEdge *edge, PathVertex *sample,
|
||||
Spectrum sampleDirect(const Scene *scene, Sampler *sampler,
|
||||
PathVertex *endpoint, PathEdge *edge, PathVertex *sample,
|
||||
ETransportMode mode) const;
|
||||
|
||||
/**
|
||||
|
@ -316,8 +316,8 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
*
|
||||
* This function samples the spatial and directional components of the sensor
|
||||
* and is similar to calling \ref sampleNext() two times in sequence starting
|
||||
* from a sensor supernode. The main difference is that the resulting subpath
|
||||
* passes through a specified pixel position, which is important to implement
|
||||
* from a sensor supernode. The main difference is that the resulting subpath
|
||||
* passes through a specified pixel position, which is important to implement
|
||||
* algorithms that parallelize rendering of images by processing it in separate
|
||||
* blocks. If this function is called once for every pixel in the output
|
||||
* image, the resulting path distribution is identical to what would have
|
||||
|
@ -332,17 +332,17 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* Pointer to a sample generator
|
||||
* \param pixelPosition
|
||||
* Specifies the desired pixel position
|
||||
* \param e0
|
||||
* \param e0
|
||||
* Pointer to the first edge on the sensor subpath
|
||||
* \param e0
|
||||
* \param e0
|
||||
* Pointer to the first edge on the sensor subpath
|
||||
* \param v1
|
||||
* \param v1
|
||||
* Pointer to the second vertex on the sensor subpath
|
||||
* \param v2
|
||||
* \param v2
|
||||
* Pointer to the third vertex on the sensor subpath
|
||||
* \return The number of successful sampling operations (i.e.
|
||||
* \c 0 if sensor sampling failed, \c 1 if no surface/medium
|
||||
* interaction was encountered, or \c 2 if all data structures
|
||||
* \return The number of successful sampling operations (i.e.
|
||||
* \c 0 if sensor sampling failed, \c 1 if no surface/medium
|
||||
* interaction was encountered, or \c 2 if all data structures
|
||||
* were successfully filled)
|
||||
*/
|
||||
int sampleSensor(const Scene *scene, Sampler *sampler, const Point2i &pixelPosition,
|
||||
|
@ -351,11 +351,11 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/**
|
||||
* \brief Create a perturbed successor vertex and edge
|
||||
*
|
||||
* This function behaves similar to \ref sampleNext() in that it
|
||||
* generates a successor edge and vertex.
|
||||
* This function behaves similar to \ref sampleNext() in that it
|
||||
* generates a successor edge and vertex.
|
||||
*
|
||||
* The main difference is that the desired direction, distance, and
|
||||
* type of the successor vertex are all specified, which makes the
|
||||
* The main difference is that the desired direction, distance, and
|
||||
* type of the successor vertex are all specified, which makes the
|
||||
* sampling process completely deterministic. This is useful for
|
||||
* implementing path-space perturbation strategies.
|
||||
*
|
||||
|
@ -368,25 +368,25 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \param predEdge
|
||||
* Edge to the preceding edge (if any) and \c NULL otherwise
|
||||
* \param succEdge
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* with information about the edge between the current vertex and
|
||||
* the new successor.
|
||||
* \param succ
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* \param d
|
||||
* Specifies the desired outgoing direction at the current vertex
|
||||
* \param dist
|
||||
* Specifies the desired distance between the current vertex and \c succ
|
||||
* (this only applies when <tt>desiredType=EMediumInteraction</tt>)
|
||||
* \param desiredType
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \return \c true on success
|
||||
*/
|
||||
bool perturbDirection(const Scene *scene, const PathVertex *pred,
|
||||
const PathEdge *predEdge, PathEdge *succEdge, PathVertex *succ,
|
||||
bool perturbDirection(const Scene *scene, const PathVertex *pred,
|
||||
const PathEdge *predEdge, PathEdge *succEdge, PathVertex *succ,
|
||||
const Vector &d, Float dist, EVertexType desiredType, ETransportMode mode);
|
||||
|
||||
/**
|
||||
|
@ -399,12 +399,12 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \brief Propagate a perturbation through an ideally specular interaction
|
||||
*
|
||||
* This function behaves similar to \ref sampleNext() and \ref
|
||||
* perturbDirection() in that it generates a successor edge and vertex.
|
||||
* perturbDirection() in that it generates a successor edge and vertex.
|
||||
*
|
||||
* The main difference is that it only works for specular interactions,
|
||||
* where the requested type of interaction (reflection/refraction) is
|
||||
* additionally specified, which makese the sampling process completely
|
||||
* deterministic. This is useful for implementing path-space
|
||||
* deterministic. This is useful for implementing path-space
|
||||
* perturbation strategies. For now, it is only used by the perturbations
|
||||
* of Veach and Guibas.
|
||||
*
|
||||
|
@ -417,29 +417,29 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \param predEdge
|
||||
* Edge to the preceding edge (if any) and \c NULL otherwise
|
||||
* \param succEdge
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* Pointer to an unused edge data structure, which will be filled
|
||||
* with information about the edge between the current vertex and
|
||||
* the new successor.
|
||||
* \param dist
|
||||
* Specifies the desired distance between the current vertex and \c succ
|
||||
* (this only applies when <tt>desiredType=EMediumInteraction</tt>)
|
||||
* \param desiredType
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* Specifies the desired vertex type of \c succ.
|
||||
* \param componentType
|
||||
* Specifies the desired type of scattering interaction (equivalent
|
||||
* to \ref BSDF::typeMask)
|
||||
* \param succ
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* Pointer to an unused vertex data structure, which will be filled
|
||||
* with information about the successor vertex
|
||||
* \param dist
|
||||
* Specifies the desired distance between the current vertex and
|
||||
* Specifies the desired distance between the current vertex and
|
||||
* \c succ (this only applies to medium interactions)
|
||||
* \param mode
|
||||
* Specifies whether radiance or importance is being transported
|
||||
* \return \c true on success
|
||||
*/
|
||||
bool propagatePerturbation(const Scene *scene, const PathVertex *pred,
|
||||
const PathEdge *predEdge, PathEdge *succEdge, PathVertex *succ,
|
||||
bool propagatePerturbation(const Scene *scene, const PathVertex *pred,
|
||||
const PathEdge *predEdge, PathEdge *succEdge, PathVertex *succ,
|
||||
unsigned int componentType, Float dist, EVertexType desiredType,
|
||||
ETransportMode mode);
|
||||
|
||||
|
@ -455,12 +455,12 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* that are associated with this vertex.
|
||||
*
|
||||
* Compute a single term of the contribution weighting function associated
|
||||
* with the current node given a predecessor and successor node.
|
||||
* with the current node given a predecessor and successor node.
|
||||
*
|
||||
* Note: this function only accounts for the factor associated with this
|
||||
* specific vertex -- to account for an adjacent edge, refer to
|
||||
* \ref PathEdge::eval.
|
||||
*
|
||||
*
|
||||
* \param scene
|
||||
* Pointer to the underlying scene
|
||||
* \param pred
|
||||
|
@ -471,23 +471,23 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* Specifies whether radiance or importance is being transported
|
||||
* \param measure
|
||||
* Specifies the measure of the queried component. This is necessary
|
||||
* to handle mixture scattering functions, whose components are
|
||||
* to handle mixture scattering functions, whose components are
|
||||
* defined on spaces with different measures.
|
||||
* \return The contribution weighting factor
|
||||
*/
|
||||
Spectrum eval(const Scene *scene, const PathVertex *pred,
|
||||
Spectrum eval(const Scene *scene, const PathVertex *pred,
|
||||
const PathVertex *succ, ETransportMode mode, EMeasure measure = EArea) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the density of a successor node
|
||||
*
|
||||
* This function computes the hypothetical scattering-related sampling density
|
||||
* of a given successor node when using the sampling technique implemented by
|
||||
* \ref sampleNext(). Since this technique conditions on a predecessor vertex,
|
||||
* This function computes the hypothetical scattering-related sampling density
|
||||
* of a given successor node when using the sampling technique implemented by
|
||||
* \ref sampleNext(). Since this technique conditions on a predecessor vertex,
|
||||
* it must also be provided here. The desired measure (e.g. area/solid angle/discrete)
|
||||
* can be provided as an extra parameter.
|
||||
*
|
||||
* Note: this function only computes probability associated with the
|
||||
*
|
||||
* Note: this function only computes probability associated with the
|
||||
* vertices -- to account for edges, refer to \ref PathEdge::evalPdf.
|
||||
*
|
||||
* \param scene
|
||||
|
@ -500,11 +500,11 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* Specifies whether radiance or importance is being transported
|
||||
* \param measure
|
||||
* Specifies the measure of the queried component. This is necessary
|
||||
* to handle mixture scattering functions, whose components are
|
||||
* to handle mixture scattering functions, whose components are
|
||||
* defined on spaces with different measures.
|
||||
* \return The computed probability density
|
||||
*/
|
||||
Float evalPdf(const Scene *scene, const PathVertex *pred,
|
||||
Float evalPdf(const Scene *scene, const PathVertex *pred,
|
||||
const PathVertex *succ, ETransportMode mode, EMeasure measure = EArea) const;
|
||||
|
||||
/**
|
||||
|
@ -523,11 +523,11 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* An emitter or sensor sample
|
||||
* \param measure
|
||||
* Specifies the measure of the queried component. This is necessary
|
||||
* to handle scattering functions, whose components are
|
||||
* to handle scattering functions, whose components are
|
||||
* defined on spaces with different measures.
|
||||
* \return The density of \c sample conditioned on this vertex.
|
||||
*/
|
||||
Float evalPdfDirect(const Scene *scene, const PathVertex *sample,
|
||||
Float evalPdfDirect(const Scene *scene, const PathVertex *sample,
|
||||
ETransportMode mode, EMeasure measure = EArea) const;
|
||||
|
||||
/**
|
||||
|
@ -545,7 +545,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \return
|
||||
* The medium between \c this and \c succ
|
||||
*/
|
||||
const Medium *getTargetMedium(const PathEdge *predEdge,
|
||||
const Medium *getTargetMedium(const PathEdge *predEdge,
|
||||
const PathVertex *succ) const;
|
||||
|
||||
/**
|
||||
|
@ -558,7 +558,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \return
|
||||
* The medium containing the ray <tt>(this->getPosition(), d)</tt>
|
||||
*/
|
||||
const Medium *getTargetMedium(const PathEdge *predEdge,
|
||||
const Medium *getTargetMedium(const PathEdge *predEdge,
|
||||
const Vector &d) const;
|
||||
|
||||
//! @}
|
||||
|
@ -572,7 +572,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
inline EVertexType getType() const { return (EVertexType) type; }
|
||||
|
||||
/**
|
||||
* \brief Return the position associated with this vertex
|
||||
* \brief Return the position associated with this vertex
|
||||
*
|
||||
* Throws an exception when called on a supernode
|
||||
*/
|
||||
|
@ -580,34 +580,34 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
|
||||
/// Check if the vertex lies on a surface
|
||||
inline bool isOnSurface() const {
|
||||
return (type == ESurfaceInteraction) || ((type == EEmitterSample ||
|
||||
return (type == ESurfaceInteraction) || ((type == EEmitterSample ||
|
||||
type == ESensorSample) && static_cast<const AbstractEmitter *>(
|
||||
getPositionSamplingRecord().object)->getType() & AbstractEmitter::EOnSurface);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns whether or not this vertex describes a "null" scattering interaction.
|
||||
*
|
||||
* A null interaction is a degenerate scattering event with a Dirac delta peak in the
|
||||
* forward direction. Apart from a potential influence on their weight, particles
|
||||
*
|
||||
* A null interaction is a degenerate scattering event with a Dirac delta peak in the
|
||||
* forward direction. Apart from a potential influence on their weight, particles
|
||||
* will pass through such an interface unchanged.
|
||||
*/
|
||||
inline bool isNullInteraction() const {
|
||||
inline bool isNullInteraction() const {
|
||||
return type == ESurfaceInteraction && componentType == BSDF::ENull;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns whether or not this vertex describes a diffuse surface
|
||||
* \brief Returns whether or not this vertex describes a diffuse surface
|
||||
* scattering interaction.
|
||||
*/
|
||||
inline bool isDiffuseInteraction() const {
|
||||
return type == ESurfaceInteraction &&
|
||||
inline bool isDiffuseInteraction() const {
|
||||
return type == ESurfaceInteraction &&
|
||||
(componentType == BSDF::EDiffuseReflection || componentType == BSDF::EDiffuseTransmission);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns whether or not this vertex describes a 100% absorbing surface
|
||||
*
|
||||
*
|
||||
* Such is the case on emitters/sensors that don't have an explicit BSDF assigned
|
||||
* to them. It is useful to be able to query this to avoid some useless connection
|
||||
* attempts involving these vertices.
|
||||
|
@ -731,7 +731,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
inline bool isDegenerate() const { return degenerate; }
|
||||
|
||||
/**
|
||||
* \brief Returns whether or not this vertex can be deterministically
|
||||
* \brief Returns whether or not this vertex can be deterministically
|
||||
* connected to other vertices.
|
||||
*
|
||||
* This is the case when <tt>\ref degenerate == false</tt> and
|
||||
|
@ -746,7 +746,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \param v
|
||||
* Pointer to the target vertex
|
||||
*
|
||||
* \return \c true upon success (i.e. when the point is in the
|
||||
* \return \c true upon success (i.e. when the point is in the
|
||||
* sensor's field of view)
|
||||
*/
|
||||
bool updateSamplePosition(const PathVertex *succ);
|
||||
|
@ -762,7 +762,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* Reference to a 2D point that will be set to the fractional
|
||||
* pixel coordinates associated with \c succ.
|
||||
*
|
||||
* \return \c true upon success (i.e. when the point is in the
|
||||
* \return \c true upon success (i.e. when the point is in the
|
||||
* sensor's field of view)
|
||||
*/
|
||||
bool getSamplePosition(const PathVertex *succ, Point2 &result) const;
|
||||
|
@ -771,7 +771,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
/* ==================================================================== */
|
||||
|
||||
/* ==================================================================== */
|
||||
//! @{ \name Miscellaneous
|
||||
//! @{ \name Miscellaneous
|
||||
/* ==================================================================== */
|
||||
|
||||
/**
|
||||
|
@ -779,8 +779,8 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
*
|
||||
* Sometimes it is necessary to cast a vertex into a different type.
|
||||
* An example when this occurs is when a surface interaction vertex
|
||||
* lies on the surface of an emitter or a sensor. In such a situation,
|
||||
* it may be useful to retroactively turn it into an emitter or sensor
|
||||
* lies on the surface of an emitter or a sensor. In such a situation,
|
||||
* it may be useful to retroactively turn it into an emitter or sensor
|
||||
* sample vertex located at the same position. This function allows
|
||||
* to do precisely that.
|
||||
*
|
||||
|
@ -788,7 +788,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* A pointer to the underlying scene
|
||||
* \param desired
|
||||
* Desired type after the cast
|
||||
* \return \c true on success. When returning \c false, the
|
||||
* \return \c true on success. When returning \c false, the
|
||||
* function did not make any changes.
|
||||
*/
|
||||
bool cast(const Scene *scene, EVertexType desired);
|
||||
|
@ -814,39 +814,39 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \param os
|
||||
* Target output stream for error messages
|
||||
*/
|
||||
bool verify(const Scene *scene, const PathVertex *adjL,
|
||||
bool verify(const Scene *scene, const PathVertex *adjL,
|
||||
const PathVertex *adjE, ETransportMode mode, std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* \brief Given the specified predecessor and successor, update
|
||||
* the cached values stored in this vertex
|
||||
*
|
||||
*
|
||||
* \param pred
|
||||
* Pointer to the predecessor vertex (if any) and \c NULL otherwise
|
||||
* \param succ
|
||||
* Pointer to the successor vertex (if any) and \c NULL otherwise
|
||||
* \param mode
|
||||
* Specifies the direction of light transport
|
||||
* Specifies the direction of light transport
|
||||
* \return \c false when there is no throughput
|
||||
*/
|
||||
bool update(const Scene *scene, const PathVertex *pred,
|
||||
bool update(const Scene *scene, const PathVertex *pred,
|
||||
const PathVertex *succ, ETransportMode mode, EMeasure measure = EArea);
|
||||
|
||||
/**
|
||||
* \brief Create a connection between two disconnected subpaths
|
||||
*
|
||||
* This function can be used to connect two seperately created emitter
|
||||
* and sensor subpaths so that they can be merged into a \ref Path data
|
||||
* structure. The function checks that the vertices \c vs and \c vt are
|
||||
* mutually visible, and that there is a nonzero throughput between them.
|
||||
* If that is the case, it updates the cached values stored in \c vs,
|
||||
* and sensor subpaths so that they can be merged into a \ref Path data
|
||||
* structure. The function checks that the vertices \c vs and \c vt are
|
||||
* mutually visible, and that there is a nonzero throughput between them.
|
||||
* If that is the case, it updates the cached values stored in \c vs,
|
||||
* \c edge, and \c vt.
|
||||
*
|
||||
* The expected order of the parameters in path-space is
|
||||
* <pre>
|
||||
* (pred) -> predEdge -> (vs) -> edge -> (vt) -> succEdge -> (succ)
|
||||
* </pre>
|
||||
* where entries in parentheses denote vertices,
|
||||
* where entries in parentheses denote vertices,
|
||||
* \c pred is the closer to the light source, and \c succ
|
||||
* is the closer to the sensor.
|
||||
*
|
||||
|
@ -875,15 +875,15 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
* \return \c true upon success, \c false when there is no
|
||||
* throughput or an inconsistency has been detected.
|
||||
*/
|
||||
static bool connect(const Scene *scene,
|
||||
static bool connect(const Scene *scene,
|
||||
const PathVertex *pred, const PathEdge *predEdge,
|
||||
PathVertex *vs, PathEdge *edge, PathVertex *vt,
|
||||
PathVertex *vs, PathEdge *edge, PathVertex *vt,
|
||||
const PathEdge *succEdge, const PathVertex *succ);
|
||||
|
||||
/// Like the above, but can be used to connect delta endpoints
|
||||
static bool connect(const Scene *scene,
|
||||
static bool connect(const Scene *scene,
|
||||
const PathVertex *pred, const PathEdge *predEdge,
|
||||
PathVertex *vs, PathEdge *edge, PathVertex *vt,
|
||||
PathVertex *vs, PathEdge *edge, PathVertex *vt,
|
||||
const PathEdge *succEdge, const PathVertex *succ,
|
||||
EMeasure vsMeasure, EMeasure vtMeasure);
|
||||
|
||||
|
@ -895,7 +895,7 @@ struct MTS_EXPORT_BIDIR PathVertex {
|
|||
|
||||
/// Compare this vertex against another vertex
|
||||
bool operator==(const PathVertex &vertex) const;
|
||||
|
||||
|
||||
/// Compare this vertex against another vertex
|
||||
inline bool operator!=(const PathVertex &vertex) const {
|
||||
return !operator==(vertex);
|
||||
|
|
|
@ -39,10 +39,10 @@ template <typename T> struct TAABB {
|
|||
typedef typename T::VectorType VectorType;
|
||||
typedef TRay<PointType, VectorType> RayType;
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Create a new invalid bounding box
|
||||
*
|
||||
* Initializes the components of the minimum
|
||||
*
|
||||
* Initializes the components of the minimum
|
||||
* and maximum position to \f$\infty\f$ and \f$-\infty\f$,
|
||||
* respectively.
|
||||
*/
|
||||
|
@ -57,14 +57,14 @@ template <typename T> struct TAABB {
|
|||
}
|
||||
|
||||
/// Create a collapsed AABB from a single point
|
||||
inline TAABB(const PointType &p)
|
||||
inline TAABB(const PointType &p)
|
||||
: min(p), max(p) { }
|
||||
|
||||
/// Create a bounding box from two positions
|
||||
inline TAABB(const PointType &min, const PointType &max)
|
||||
: min(min), max(max) {
|
||||
#if defined(MTS_DEBUG)
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
SAssert(min[i] <= max[i]);
|
||||
#endif
|
||||
}
|
||||
|
@ -87,10 +87,10 @@ template <typename T> struct TAABB {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Mark the bounding box as invalid.
|
||||
*
|
||||
* This operation sets the components of the minimum
|
||||
*
|
||||
* This operation sets the components of the minimum
|
||||
* and maximum position to \f$\infty\f$ and \f$-\infty\f$,
|
||||
* respectively.
|
||||
*/
|
||||
|
@ -149,7 +149,7 @@ template <typename T> struct TAABB {
|
|||
|
||||
/// Axis-aligned bounding box overlap test
|
||||
inline bool overlaps(const TAABB &aabb) const {
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
if (max[i] < aabb.min[i] || min[i] > aabb.max[i])
|
||||
return false;
|
||||
return true;
|
||||
|
@ -212,14 +212,14 @@ template <typename T> struct TAABB {
|
|||
|
||||
/// Return whether this bounding box is valid
|
||||
inline bool isValid() const {
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
for (int i=0; i<PointType::dim; ++i)
|
||||
if (max[i] < min[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return whether or not this bounding box
|
||||
* \brief Return whether or not this bounding box
|
||||
* covers anything at all.
|
||||
*
|
||||
* A bounding box which only covers a single point
|
||||
|
@ -325,14 +325,14 @@ template <typename T> struct TAABB {
|
|||
return oss.str();
|
||||
}
|
||||
|
||||
PointType min; ///< Component-wise minimum
|
||||
PointType max; ///< Component-wise maximum
|
||||
PointType min; ///< Component-wise minimum
|
||||
PointType max; ///< Component-wise maximum
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Axis-aligned bounding box data structure in three dimensions
|
||||
*
|
||||
*
|
||||
* Maintains a component-wise minimum and maximum position and provides
|
||||
* various convenience functions to query or change them.
|
||||
*
|
||||
|
@ -341,10 +341,10 @@ template <typename T> struct TAABB {
|
|||
*/
|
||||
struct AABB : public TAABB<Point> {
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* \brief Create a new invalid bounding box
|
||||
*
|
||||
* Initializes the components of the minimum
|
||||
*
|
||||
* Initializes the components of the minimum
|
||||
* and maximum position to \f$\infty\f$ and \f$-\infty\f$,
|
||||
* respectively.
|
||||
*/
|
||||
|
@ -357,12 +357,12 @@ public:
|
|||
inline AABB(const Point &p) : TAABB<Point>(p) { }
|
||||
|
||||
/// Create a bounding box from two positions
|
||||
inline AABB(const PointType &min, const PointType &max)
|
||||
inline AABB(const PointType &min, const PointType &max)
|
||||
: TAABB<Point>(min, max) {
|
||||
}
|
||||
|
||||
/// Construct from a TAABB<Point>
|
||||
inline AABB(const TAABB<Point> &aabb)
|
||||
inline AABB(const TAABB<Point> &aabb)
|
||||
: TAABB<Point>(aabb) { }
|
||||
|
||||
/// Calculate the surface area of the bounding box
|
||||
|
@ -388,7 +388,7 @@ public:
|
|||
|
||||
#ifdef MTS_SSE
|
||||
/**
|
||||
* \brief Intersect against a packet of four rays.
|
||||
* \brief Intersect against a packet of four rays.
|
||||
* \return \c false if none of the rays intersect.
|
||||
*/
|
||||
FINLINE bool rayIntersectPacket(const RayPacket4 &ray, RayInterval4 &interval) const;
|
||||
|
|
|
@ -28,16 +28,16 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* NaN-aware slab test using SSE by Thierry Berger-Perrin (Intersects
|
||||
* against 4 rays simultaneously). Returns false if none of the rays
|
||||
* NaN-aware slab test using SSE by Thierry Berger-Perrin (Intersects
|
||||
* against 4 rays simultaneously). Returns false if none of the rays
|
||||
* intersect.
|
||||
*/
|
||||
FINLINE bool AABB::rayIntersectPacket(const RayPacket4 &ray,
|
||||
FINLINE bool AABB::rayIntersectPacket(const RayPacket4 &ray,
|
||||
RayInterval4 &interval) const {
|
||||
const __m128
|
||||
xl1 = _mm_mul_ps(ray.dRcp[0].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(min.x), ray.o[0].ps)),
|
||||
xl2 = _mm_mul_ps(ray.dRcp[0].ps,
|
||||
xl2 = _mm_mul_ps(ray.dRcp[0].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(max.x), ray.o[0].ps)),
|
||||
xl1a = _mm_min_ps(xl1, SSEConstants::p_inf.ps),
|
||||
xl2a = _mm_min_ps(xl2, SSEConstants::p_inf.ps),
|
||||
|
@ -49,9 +49,9 @@ FINLINE bool AABB::rayIntersectPacket(const RayPacket4 &ray,
|
|||
lmin = _mm_min_ps(xl1b, xl2b);
|
||||
|
||||
const __m128
|
||||
yl1 = _mm_mul_ps(ray.dRcp[1].ps,
|
||||
yl1 = _mm_mul_ps(ray.dRcp[1].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(min.y), ray.o[1].ps)),
|
||||
yl2 = _mm_mul_ps(ray.dRcp[1].ps,
|
||||
yl2 = _mm_mul_ps(ray.dRcp[1].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(max.y), ray.o[1].ps)),
|
||||
yl1a = _mm_min_ps(yl1, SSEConstants::p_inf.ps),
|
||||
yl2a = _mm_min_ps(yl2, SSEConstants::p_inf.ps),
|
||||
|
@ -62,11 +62,11 @@ FINLINE bool AABB::rayIntersectPacket(const RayPacket4 &ray,
|
|||
lmin = _mm_max_ps(_mm_min_ps(yl1b,yl2b), lmin);
|
||||
|
||||
const __m128
|
||||
zl1 = _mm_mul_ps(ray.dRcp[2].ps,
|
||||
zl1 = _mm_mul_ps(ray.dRcp[2].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(min.z), ray.o[2].ps)),
|
||||
zl2 = _mm_mul_ps(ray.dRcp[2].ps,
|
||||
zl2 = _mm_mul_ps(ray.dRcp[2].ps,
|
||||
_mm_sub_ps(_mm_set1_ps(max.z), ray.o[2].ps)),
|
||||
zl1a = _mm_min_ps(zl1, SSEConstants::p_inf.ps),
|
||||
zl1a = _mm_min_ps(zl1, SSEConstants::p_inf.ps),
|
||||
zl2a = _mm_min_ps(zl2, SSEConstants::p_inf.ps),
|
||||
zl1b = _mm_max_ps(zl1, SSEConstants::n_inf.ps),
|
||||
zl2b = _mm_max_ps(zl2, SSEConstants::n_inf.ps);
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
* \remark The \c ptr argument is missing in the Python bindings
|
||||
*/
|
||||
virtual void logProgress(Float progress, const std::string &name,
|
||||
const std::string &formatted, const std::string &eta,
|
||||
const std::string &formatted, const std::string &eta,
|
||||
const void *ptr) = 0;
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
@ -97,7 +97,7 @@ private:
|
|||
bool m_lastMessageWasProgress;
|
||||
};
|
||||
|
||||
/** \brief %Appender implementation, which writes directly
|
||||
/** \brief %Appender implementation, which writes directly
|
||||
* to an UNIX-style unbuffered file descriptor.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
|
|
@ -40,7 +40,7 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/**
|
||||
* \brief Atomically attempt to exchange a pointer with another value
|
||||
*
|
||||
*
|
||||
* \param v Pointer to the pointer in question
|
||||
* \param oldValue Last known value of the destination \a v
|
||||
* \param newValue Replacement value for the destination \a v
|
||||
|
@ -55,7 +55,7 @@ template <typename T> inline bool atomicCompareAndExchangePtr(T **v, T *newValue
|
|||
reinterpret_cast<void * volatile *>(v), newValue, oldValue) == oldValue;
|
||||
#else
|
||||
return _InterlockedCompareExchange(
|
||||
reinterpret_cast<long volatile *>(v),
|
||||
reinterpret_cast<long volatile *>(v),
|
||||
reinterpret_cast<long>(newValue), reinterpret_cast<long>(oldValue)) == reinterpret_cast<long>(oldValue);
|
||||
#endif
|
||||
#else
|
||||
|
@ -65,11 +65,11 @@ template <typename T> inline bool atomicCompareAndExchangePtr(T **v, T *newValue
|
|||
/* Use the following workaround for clang and icl (Linux/Mac OS) */
|
||||
#if __SIZEOF_POINTER__ == 8 || defined(__LP64__)
|
||||
return __sync_bool_compare_and_swap(
|
||||
reinterpret_cast<long long volatile *>(v), reinterpret_cast<long long>(oldValue),
|
||||
reinterpret_cast<long long volatile *>(v), reinterpret_cast<long long>(oldValue),
|
||||
reinterpret_cast<long long>(newValue));
|
||||
#else
|
||||
return __sync_bool_compare_and_swap(
|
||||
reinterpret_cast<long volatile *>(v), reinterpret_cast<long>(oldValue),
|
||||
reinterpret_cast<long volatile *>(v), reinterpret_cast<long>(oldValue),
|
||||
reinterpret_cast<long>(newValue));
|
||||
#endif
|
||||
#endif
|
||||
|
@ -78,7 +78,7 @@ template <typename T> inline bool atomicCompareAndExchangePtr(T **v, T *newValue
|
|||
|
||||
/**
|
||||
* \brief Atomically attempt to exchange a 32-bit integer with another value
|
||||
*
|
||||
*
|
||||
* \param v Pointer to the memory region in question
|
||||
* \param oldValue Last known value of the destination \a v
|
||||
* \param newValue Replacement value for the destination \a v
|
||||
|
@ -97,7 +97,7 @@ inline bool atomicCompareAndExchange(volatile int32_t *v, int32_t newValue, int3
|
|||
|
||||
/**
|
||||
* \brief Atomically attempt to exchange a 64-bit integer with another value
|
||||
*
|
||||
*
|
||||
* \param v Pointer to the memory region in question
|
||||
* \param oldValue Last known value of the destination \a v
|
||||
* \param newValue Replacement value for the destination \a v
|
||||
|
|
|
@ -27,8 +27,8 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Blocked generic 2D array data type
|
||||
*
|
||||
* This class implements a blocked 2D array for cache-efficient
|
||||
* access to two-dimensional data.
|
||||
* This class implements a blocked 2D array for cache-efficient
|
||||
* access to two-dimensional data.
|
||||
*/
|
||||
template <typename Value, size_t logblockSize = 2> class BlockedArray {
|
||||
public:
|
||||
|
@ -38,20 +38,20 @@ public:
|
|||
BlockedArray() : m_data(NULL), m_size(-1), m_owner(false) { }
|
||||
|
||||
/**
|
||||
* \brief Allocate memory for a new blocked array of
|
||||
* \brief Allocate memory for a new blocked array of
|
||||
* the specified width and height
|
||||
*/
|
||||
BlockedArray(const Vector2i &size) : m_data(NULL),
|
||||
BlockedArray(const Vector2i &size) : m_data(NULL),
|
||||
m_size(-1), m_owner(false) {
|
||||
alloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocate memory for a blocked array of
|
||||
* \brief Allocate memory for a blocked array of
|
||||
* the specified width and height
|
||||
*/
|
||||
void alloc(const Vector2i &size) {
|
||||
if (m_data && m_owner)
|
||||
if (m_data && m_owner)
|
||||
delete[] m_data;
|
||||
|
||||
m_xBlocks = (size.x + blockSize - 1) / blockSize;
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
m_data = (Value *) allocAligned(m_xBlocks * m_yBlocks
|
||||
* blockSize * blockSize * sizeof(Value));
|
||||
m_owner = true; /* We own this pointer */
|
||||
m_size = size;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,7 +76,7 @@ public:
|
|||
m_yBlocks = (size.y + blockSize - 1) / blockSize;
|
||||
m_data = (Value *) ptr;
|
||||
m_owner = false; /* We do not own this pointer */
|
||||
m_size = size;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,13 +94,13 @@ public:
|
|||
/**
|
||||
* \brief Initialize the contents of the blocked array with values
|
||||
* from a non-blocked source in row-major order and collect component-wise
|
||||
* minimum, maximum, and average information.
|
||||
* minimum, maximum, and average information.
|
||||
*
|
||||
* Assumes that \c AltValue is some kind of \c TVector or \c TSpectrum instance.
|
||||
*
|
||||
* \remark This function performs type casts when <tt>Value != AltValue</tt>
|
||||
*/
|
||||
template <typename AltValue> void init(const AltValue *data,
|
||||
template <typename AltValue> void init(const AltValue *data,
|
||||
AltValue &min_, AltValue &max_, AltValue &avg_) {
|
||||
typedef typename AltValue::Scalar Scalar;
|
||||
|
||||
|
@ -128,7 +128,7 @@ public:
|
|||
/**
|
||||
* \brief Copy the contents of the blocked array to a non-blocked
|
||||
* destination buffer in row-major order.
|
||||
*
|
||||
*
|
||||
* This is effectively the opposite of \ref init().
|
||||
*
|
||||
* \remark This function performs type casts when <tt>Value != AltValue</tt>
|
||||
|
@ -143,9 +143,9 @@ public:
|
|||
/**
|
||||
* \brief Zero out unused memory portions
|
||||
*
|
||||
* This is useful in case we want to write the internal representation to
|
||||
* disk and avoid accessing uninitialized memory (otherwise, valgrind
|
||||
* or other similar tools will complain..)
|
||||
* This is useful in case we want to write the internal representation to
|
||||
* disk and avoid accessing uninitialized memory (otherwise, valgrind
|
||||
* or other similar tools will complain..)
|
||||
*/
|
||||
void cleanup() {
|
||||
size_t unusedColsRight = m_xBlocks * blockSize - m_size.x,
|
||||
|
@ -194,7 +194,7 @@ public:
|
|||
inline Value &operator()(int x, int y) {
|
||||
size_t xb = getBlock(x), yb = getBlock(y),
|
||||
xo = getOffset(x), yo = getOffset(y);
|
||||
|
||||
|
||||
return m_data[
|
||||
// Offset to block
|
||||
blockSize * blockSize * (xb + yb * m_xBlocks) +
|
||||
|
@ -224,7 +224,7 @@ public:
|
|||
protected:
|
||||
/// Determine the index of the block which contains the given global index
|
||||
inline size_t getBlock(int a) const { return (size_t) (a >> logblockSize); }
|
||||
|
||||
|
||||
/// Determine the offset within the block that contains the given global index
|
||||
inline size_t getOffset(int a) const { return (size_t) (a & (blockSize - 1)); }
|
||||
private:
|
||||
|
@ -247,25 +247,25 @@ public:
|
|||
LinearArray() : m_data(NULL), m_size(-1), m_owner(false) { }
|
||||
|
||||
/**
|
||||
* \brief Allocate memory for a new linear array of
|
||||
* \brief Allocate memory for a new linear array of
|
||||
* the specified width and height
|
||||
*/
|
||||
LinearArray(const Vector2i &size) : m_data(NULL),
|
||||
LinearArray(const Vector2i &size) : m_data(NULL),
|
||||
m_size(-1), m_owner(false) {
|
||||
alloc(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Allocate memory for a linear array of
|
||||
* \brief Allocate memory for a linear array of
|
||||
* the specified width and height
|
||||
*/
|
||||
void alloc(const Vector2i &size) {
|
||||
if (m_data && m_owner)
|
||||
if (m_data && m_owner)
|
||||
delete[] m_data;
|
||||
|
||||
size_t arraySize = (size_t) size.x * (size_t) size.y * sizeof(Value);
|
||||
m_data = (Value *) allocAligned(arraySize);
|
||||
m_size = size;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -280,7 +280,7 @@ public:
|
|||
|
||||
m_data = (Value *) ptr;
|
||||
m_owner = false; /* We do not own this pointer */
|
||||
m_size = size;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,13 +299,13 @@ public:
|
|||
/**
|
||||
* \brief Initialize the contents of the linear array with values
|
||||
* from a non-blocked source in row-major order and collect component-wise
|
||||
* minimum, maximum, and average information.
|
||||
* minimum, maximum, and average information.
|
||||
*
|
||||
* Assumes that \c AltValue is some kind of \c TVector or \c TSpectrum instance.
|
||||
*
|
||||
* \remark This function performs type casts when <tt>Value != AltValue</tt>
|
||||
*/
|
||||
template <typename AltValue> void init(const AltValue *data,
|
||||
template <typename AltValue> void init(const AltValue *data,
|
||||
AltValue &min_, AltValue &max_, AltValue &avg_) {
|
||||
typedef typename AltValue::Scalar Scalar;
|
||||
|
||||
|
@ -313,7 +313,7 @@ public:
|
|||
min(+std::numeric_limits<Scalar>::infinity()),
|
||||
max(-std::numeric_limits<Scalar>::infinity()),
|
||||
avg((Scalar) 0);
|
||||
|
||||
|
||||
Value *ptr = m_data;
|
||||
|
||||
for (int y=0; y<m_size.y; ++y) {
|
||||
|
@ -335,7 +335,7 @@ public:
|
|||
/**
|
||||
* \brief Copy the contents of the linear array to a non-blocked
|
||||
* destination buffer in row-major order.
|
||||
*
|
||||
*
|
||||
* This is effectively the opposite of \ref init().
|
||||
*
|
||||
* \remark This function performs type casts when <tt>Value != AltValue</tt>
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief General-purpose bitmap class with read and write support
|
||||
* \brief General-purpose bitmap class with read and write support
|
||||
* for several common file formats.
|
||||
*
|
||||
* This class handles loading of PNG, JPEG, BMP, TGA, as well as
|
||||
* This class handles loading of PNG, JPEG, BMP, TGA, as well as
|
||||
* OpenEXR files, and it supports writing of PNG, JPEG and OpenEXR files.
|
||||
*
|
||||
* PNG and OpenEXR files are optionally annotated with string-valued
|
||||
|
@ -92,14 +92,14 @@ public:
|
|||
* Note that you can use this class to load, save, and access bitmasks -- however,
|
||||
* many of the manipulation operations (i.e. \ref crop(), \ref accumulate(), etc.)
|
||||
* do not currently handle them.
|
||||
*
|
||||
*
|
||||
* Default gamma value: linear (1.0)
|
||||
*/
|
||||
EBitmask = 0,
|
||||
|
||||
/**
|
||||
* \brief 8-bit unsigned integer (\c uint8_t) component encoding
|
||||
*
|
||||
*
|
||||
* Default gamma value: sRGB (approx. 2.2)
|
||||
*/
|
||||
EUInt8,
|
||||
|
@ -124,7 +124,7 @@ public:
|
|||
* Default gamma value: linear (1.0)
|
||||
*/
|
||||
EFloat16,
|
||||
|
||||
|
||||
/**
|
||||
* \brief 32-bit floating point (\c float) HDR component encoding
|
||||
*
|
||||
|
@ -145,7 +145,7 @@ public:
|
|||
EInvalid,
|
||||
|
||||
/**
|
||||
* \brief Floating point (\c float or \c double depending on the
|
||||
* \brief Floating point (\c float or \c double depending on the
|
||||
* compilation settings) HDR component encoding
|
||||
*
|
||||
* Default gamma value: linear (1.0)
|
||||
|
@ -178,13 +178,13 @@ public:
|
|||
*
|
||||
* The following is supported:
|
||||
* <ul>
|
||||
* <li>Loading and saving of \ref Eloat16 / \ref EFloat32/ \ref
|
||||
* <li>Loading and saving of \ref Eloat16 / \ref EFloat32/ \ref
|
||||
* EUInt32 bitmaps with all supported RGB/Luminance/Alpha combinations</li>
|
||||
* <li>Loading and saving of spectral bitmaps</tt>
|
||||
* <li>Loading and saving of XYZ tristimulus bitmaps</tt>
|
||||
* <li>Loading and saving of string-valued metadata fields</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* The following is <em>not</em> supported:
|
||||
* <ul>
|
||||
* <li>Saving of tiled images, tile-based read access</li>
|
||||
|
@ -251,7 +251,7 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Create a bitmap of the specified type and allocate
|
||||
* \brief Create a bitmap of the specified type and allocate
|
||||
* the necessary amount of memory
|
||||
*
|
||||
* \param pFmt
|
||||
|
@ -296,10 +296,10 @@ public:
|
|||
/// Return the bitmap component format for a specified type
|
||||
template <typename T> inline static EComponentFormat componentFormat();
|
||||
|
||||
/// Return the pixel format of this bitmap
|
||||
/// Return the pixel format of this bitmap
|
||||
inline EPixelFormat getPixelFormat() const { return m_pixelFormat; }
|
||||
|
||||
/// Return the component format of this bitmap
|
||||
/// Return the component format of this bitmap
|
||||
inline EComponentFormat getComponentFormat() const { return m_componentFormat; }
|
||||
|
||||
/// Return the bitmap's resolution in pixels
|
||||
|
@ -335,35 +335,35 @@ public:
|
|||
* this function throws an exception.
|
||||
*/
|
||||
int getBytesPerComponent() const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the number of bytes per pixel
|
||||
*
|
||||
* When the component format is set to \c EBitmask,
|
||||
* this function throws an exception.
|
||||
*/
|
||||
inline int getBytesPerPixel() const {
|
||||
inline int getBytesPerPixel() const {
|
||||
return getBytesPerComponent() * getChannelCount(); }
|
||||
|
||||
/// Return the bitmap size in bytes
|
||||
size_t getBufferSize() const;
|
||||
|
||||
/**
|
||||
* \brief Return the spectral color value associated with
|
||||
* \brief Return the spectral color value associated with
|
||||
* a given pixel.
|
||||
*
|
||||
*
|
||||
* When this is not a spectrum image, conversions are applied
|
||||
* as appropriate.
|
||||
*
|
||||
* \remark This function is provided here for convenience and
|
||||
* debugging purposes. Its use is discouraged, particularly for
|
||||
* performance critical code (direct buffer access will be
|
||||
* performance critical code (direct buffer access will be
|
||||
* faster by at least an order of magnitude)
|
||||
*/
|
||||
Spectrum getPixel(const Point2i &pos) const;
|
||||
|
||||
/**
|
||||
* \brief Set the spectral color value associated with
|
||||
* \brief Set the spectral color value associated with
|
||||
* a given pixel.
|
||||
*
|
||||
* When this is not a spectrum image, conversions are applied
|
||||
|
@ -371,7 +371,7 @@ public:
|
|||
*
|
||||
* \remark This function is provided here for convenience and
|
||||
* debugging purposes. Its use is discouraged, particularly for
|
||||
* performance critical code (direct buffer access will be
|
||||
* performance critical code (direct buffer access will be
|
||||
* faster by at least order of magnitude)
|
||||
*/
|
||||
void setPixel(const Point2i &pos, const Spectrum &value);
|
||||
|
@ -394,10 +394,10 @@ public:
|
|||
void drawRect(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
||||
|
||||
/**
|
||||
* \brief Color balancing: apply the given scale factors to the
|
||||
* \brief Color balancing: apply the given scale factors to the
|
||||
* red, green, and blue channels of the image
|
||||
*
|
||||
* When the image is not an \c EFloat16, \c EFloat32, or
|
||||
* When the image is not an \c EFloat16, \c EFloat32, or
|
||||
* \c EFloat64-based RGB/RGBA image, the function throws an exception
|
||||
*/
|
||||
void colorBalance(Float r, Float g, Float b);
|
||||
|
@ -414,7 +414,7 @@ public:
|
|||
|
||||
/// Create an identical copy
|
||||
ref<Bitmap> clone() const;
|
||||
|
||||
|
||||
/// Clear the bitmap to zero
|
||||
void clear();
|
||||
|
||||
|
@ -433,7 +433,7 @@ public:
|
|||
* the lowest and 9 denoting the highest compression). Note that
|
||||
* saving files with the highest compression will be very slow.
|
||||
* For JPEG files, this denotes the desired quality (between 0 and 100,
|
||||
* the latter being best). The default argument (-1) uses compression
|
||||
* the latter being best). The default argument (-1) uses compression
|
||||
* 5 for PNG and 100 for JPEG files.
|
||||
*
|
||||
* \param channelNames
|
||||
|
@ -456,7 +456,7 @@ public:
|
|||
/**
|
||||
* \brief Convert the bitmap into another pixel and/or component format
|
||||
*
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* between different underlying representations. For instance, it can
|
||||
* translate a 24-bit sRGB bitmap to a linear spectrum-valued representation
|
||||
* based on half-, single- or double-precision floating point-backed storage.
|
||||
|
@ -473,12 +473,12 @@ public:
|
|||
* of the desired component format.</li>
|
||||
* <li>The clamped gamma-corrected value is then written to
|
||||
* the new bitmap</li>
|
||||
*
|
||||
*
|
||||
* If the pixel formats differ, this function will also perform basic
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* values, etc.)
|
||||
*
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* the source and target bitmap, hence it won't be affected by
|
||||
* any gamma-related transformations.
|
||||
*
|
||||
|
@ -498,13 +498,13 @@ public:
|
|||
* specifies how ambiguities in this highly under-constrained problem
|
||||
* should be resolved.
|
||||
*/
|
||||
void convert(Bitmap *target, Float multiplier = 1.0f,
|
||||
void convert(Bitmap *target, Float multiplier = 1.0f,
|
||||
Spectrum::EConversionIntent intent = Spectrum::EReflectance) const;
|
||||
|
||||
/**
|
||||
* \brief Convert the bitmap into another pixel and/or component format
|
||||
*
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* between different underlying representations. For instance, it can
|
||||
* translate a 24-bit sRGB bitmap to a linear spectrum-valued representation
|
||||
* based on half-, single- or double-precision floating point-backed storage.
|
||||
|
@ -521,19 +521,19 @@ public:
|
|||
* of the desired component format.</li>
|
||||
* <li>The clamped gamma-corrected value is then written to
|
||||
* the new bitmap</li>
|
||||
*
|
||||
*
|
||||
* If the pixel formats differ, this function will also perform basic
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* values, etc.)
|
||||
*
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* the source and target bitmap, hence it won't be affected by
|
||||
* any gamma-related transformations.
|
||||
*
|
||||
* \remark This <tt>convert()</tt> variant usually returns a new
|
||||
* bitmap instance. When the conversion would just involve copying
|
||||
* the original bitmap, the function becomes a no-op and returns
|
||||
* the current instance.
|
||||
*
|
||||
* \remark This <tt>convert()</tt> variant usually returns a new
|
||||
* bitmap instance. When the conversion would just involve copying
|
||||
* the original bitmap, the function becomes a no-op and returns
|
||||
* the current instance.
|
||||
*
|
||||
* \ref pixelFormat
|
||||
* Specifies the desired pixel format
|
||||
|
@ -552,14 +552,14 @@ public:
|
|||
* specifies how ambiguities in this highly under-constrained problem
|
||||
* should be resolved.
|
||||
*/
|
||||
ref<Bitmap> convert(EPixelFormat pixelFormat, EComponentFormat componentFormat,
|
||||
Float gamma = 1.0f, Float multiplier = 1.0f,
|
||||
ref<Bitmap> convert(EPixelFormat pixelFormat, EComponentFormat componentFormat,
|
||||
Float gamma = 1.0f, Float multiplier = 1.0f,
|
||||
Spectrum::EConversionIntent intent = Spectrum::EReflectance);
|
||||
|
||||
/**
|
||||
* \brief Convert the bitmap into another pixel and/or component format
|
||||
*
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* This helper function can be used to efficiently convert a bitmap
|
||||
* between different underlying representations. For instance, it can
|
||||
* translate a 24-bit sRGB bitmap to a linear spectrum-valued representation
|
||||
* based on half-, single- or double-precision floating point-backed storage.
|
||||
|
@ -576,12 +576,12 @@ public:
|
|||
* of the desired component format.</li>
|
||||
* <li>The clamped gamma-corrected value is then written to
|
||||
* the new bitmap</li>
|
||||
*
|
||||
*
|
||||
* If the pixel formats differ, this function will also perform basic
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* conversions (e.g. spectrum to rgb, luminance to uniform spectrum
|
||||
* values, etc.)
|
||||
*
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* the source and target bitmap, hence it won't be affected by
|
||||
* any gamma-related transformations.
|
||||
*
|
||||
|
@ -608,8 +608,8 @@ public:
|
|||
* should be resolved.
|
||||
*/
|
||||
void convert(void *target,
|
||||
EPixelFormat pixelFormat, EComponentFormat componentFormat,
|
||||
Float gamma = 1.0f, Float multiplier = 1.0f,
|
||||
EPixelFormat pixelFormat, EComponentFormat componentFormat,
|
||||
Float gamma = 1.0f, Float multiplier = 1.0f,
|
||||
Spectrum::EConversionIntent intent = Spectrum::EReflectance) const;
|
||||
|
||||
/**
|
||||
|
@ -617,25 +617,25 @@ public:
|
|||
*
|
||||
* This function
|
||||
* <ol>
|
||||
* <li>Computes and stores the maximum and log-average luminance of the image
|
||||
* If the \c logAvgLuminace and \c maxLuminance parameters are nonzero, it is
|
||||
* assumed that these have already been computed, and this step is omitted.
|
||||
* Explicitly specifying them can be useful to prevent flickering when tonemapping
|
||||
* <li>Computes and stores the maximum and log-average luminance of the image
|
||||
* If the \c logAvgLuminace and \c maxLuminance parameters are nonzero, it is
|
||||
* assumed that these have already been computed, and this step is omitted.
|
||||
* Explicitly specifying them can be useful to prevent flickering when tonemapping
|
||||
* multiple frames of an animation.</li>
|
||||
*
|
||||
* <li>Converts the image to xyY, applies Reinhard's photographic tonemapper in this
|
||||
* <li>Converts the image to xyY, applies Reinhard's photographic tonemapper in this
|
||||
* space, and then transforms the result back to its original
|
||||
* representation (i.e. RGB or XYZ). The global version of the
|
||||
* tonemapping algorithm is used (i.e. the one without automatic
|
||||
* tonemapping algorithm is used (i.e. the one without automatic
|
||||
* dodging and burning).</li>
|
||||
* </ol>
|
||||
*
|
||||
* The <tt>key</tt> parameter specifies whether a low-key or high-key image is
|
||||
* desired. The value must be in the interval <tt>[0,1]</tt>. A good starting
|
||||
* desired. The value must be in the interval <tt>[0,1]</tt>. A good starting
|
||||
* point is a middle-grey, i.e. <tt>key=0.18</tt>.
|
||||
*
|
||||
* When <tt>burn=0</tt>, the entire image is re-mapped into the displayable range. This
|
||||
* may not always be desireable -- for instance, one might choose to let a highlight
|
||||
* may not always be desireable -- for instance, one might choose to let a highlight
|
||||
* burn out, and this is achieved by choosing burn in (0, 1].
|
||||
*
|
||||
* For reference, see
|
||||
|
@ -643,8 +643,8 @@ public:
|
|||
* Peter Shirley, and James Fewerda, in ACM Transactions on Graphics 2002, Vol. 21, 3
|
||||
*
|
||||
* \remark The implementation assumes that the image has a RGB(A), XYZ(A), or Luminance(Alpha)
|
||||
* pixel format, that <tt>gamma=1</tt>, and that it uses a EFloat16/EFloat32/EFloat64
|
||||
* component format. The conversion process is destructive in the sense that it overwrites
|
||||
* pixel format, that <tt>gamma=1</tt>, and that it uses a EFloat16/EFloat32/EFloat64
|
||||
* component format. The conversion process is destructive in the sense that it overwrites
|
||||
* the original image.
|
||||
*/
|
||||
void tonemapReinhard(Float &logAvgLuminance, Float &maxLuminance,
|
||||
|
@ -663,13 +663,13 @@ public:
|
|||
* \brief Separate out one of the color channels in the
|
||||
* bitmap and return it as a separate luminance bitmap
|
||||
*
|
||||
* When this is already a single-channel bitmap, the function
|
||||
* When this is already a single-channel bitmap, the function
|
||||
* returns a pointer to the current instance.
|
||||
*/
|
||||
ref<Bitmap> separateChannel(int channelIndex);
|
||||
|
||||
/**
|
||||
* \brief Merges multiple luminance-valued bitmaps into
|
||||
* \brief Merges multiple luminance-valued bitmaps into
|
||||
* a proper multi-channel bitmap.
|
||||
*
|
||||
* \param fmt The desired pixel format of the combined bitmap
|
||||
|
@ -696,7 +696,7 @@ public:
|
|||
* <tt>bitmap != this</tt>.
|
||||
*
|
||||
* \remark This function throws an exception when the bitmaps
|
||||
* use different component formats or channels, or when the
|
||||
* use different component formats or channels, or when the
|
||||
* component format is \ref EBitmask.
|
||||
*/
|
||||
void accumulate(const Bitmap *bitmap, const Point2i &offset);
|
||||
|
@ -705,15 +705,15 @@ public:
|
|||
* \brief Up- or down-sample this image to a different resolution
|
||||
*
|
||||
* Uses the provided reconstruction filter and observes the specified
|
||||
* horizontal and vertical boundary conditions when looking up data
|
||||
* horizontal and vertical boundary conditions when looking up data
|
||||
* outside of the input domain.
|
||||
*
|
||||
* A maximum and maximum image value can be specified to prevent to prevent
|
||||
* out-of-range values that are created by the resampling process.
|
||||
*/
|
||||
void resample(const ReconstructionFilter *rfilter,
|
||||
ReconstructionFilter::EBoundaryCondition bch,
|
||||
ReconstructionFilter::EBoundaryCondition bcv,
|
||||
void resample(const ReconstructionFilter *rfilter,
|
||||
ReconstructionFilter::EBoundaryCondition bch,
|
||||
ReconstructionFilter::EBoundaryCondition bcv,
|
||||
Bitmap *target, Float minValue = 0.0f,
|
||||
Float maxValue = 1.0f) const;
|
||||
|
||||
|
@ -721,13 +721,13 @@ public:
|
|||
* \brief Up- or down-sample this image to a different resolution
|
||||
*
|
||||
* Uses the provided reconstruction filter and observes the specified
|
||||
* horizontal and vertical boundary conditions when looking up data
|
||||
* horizontal and vertical boundary conditions when looking up data
|
||||
* outside of the input domain.
|
||||
*
|
||||
* A maximum and maximum image value can be specified to prevent to prevent
|
||||
* out-of-range values that are created by the resampling process.
|
||||
*/
|
||||
ref<Bitmap> resample(const ReconstructionFilter *rfilter,
|
||||
ref<Bitmap> resample(const ReconstructionFilter *rfilter,
|
||||
ReconstructionFilter::EBoundaryCondition bch,
|
||||
ReconstructionFilter::EBoundaryCondition bcv,
|
||||
const Vector2i &size, Float minValue = 0.0f,
|
||||
|
@ -748,7 +748,7 @@ public:
|
|||
|
||||
/// Set a string-valued metadata field
|
||||
void setString(const std::string &key, const std::string &value);
|
||||
|
||||
|
||||
/// Return a string-valued metadata field
|
||||
std::string getString(const std::string &key) const;
|
||||
|
||||
|
@ -769,20 +769,20 @@ public:
|
|||
|
||||
//! @}
|
||||
// ======================================================================
|
||||
|
||||
|
||||
// ======================================================================
|
||||
//! @{ \name Bitmap raster data accessors
|
||||
// ======================================================================
|
||||
|
||||
/// Access the underlying raster
|
||||
inline void *getData() { return m_data; }
|
||||
|
||||
|
||||
/// Access the underlying bit raster (const version)
|
||||
inline const void *getData() const { return m_data; }
|
||||
|
||||
/// Access the underlying raster (for uint8 bitmaps)
|
||||
inline uint8_t *getUInt8Data() { return m_data; }
|
||||
|
||||
|
||||
/// Access the underlying bit raster (for uint8 bitmaps, const version)
|
||||
inline const uint8_t *getUInt8Data() const { return m_data; }
|
||||
|
||||
|
@ -844,7 +844,7 @@ protected:
|
|||
|
||||
/// Write a file using the PNG file format
|
||||
void writePNG(Stream *stream, int compression) const;
|
||||
|
||||
|
||||
/// Read a file stored using the JPEG file format
|
||||
void readJPEG(Stream *stream);
|
||||
|
||||
|
@ -872,7 +872,7 @@ protected:
|
|||
|
||||
/// Read a file stored using the TGA file format
|
||||
void readTGA(Stream *stream);
|
||||
|
||||
|
||||
/// Read a file stored using the BMP file format
|
||||
void readBMP(Stream *stream);
|
||||
|
||||
|
@ -909,7 +909,7 @@ protected:
|
|||
* \remark This is not a color management system. Depending on the
|
||||
* target type, out-of-gamut values may be clipped component-wise.
|
||||
* If a luminance scale factor is applied, that is also done component-wise
|
||||
* (instead of scaling in a space that is based on human perception, such
|
||||
* (instead of scaling in a space that is based on human perception, such
|
||||
* as xyY or CIELab). If this and smarter gamut remapping are needed,
|
||||
* a library such as lcms2 will be more appropriate.
|
||||
*
|
||||
|
@ -927,7 +927,7 @@ public:
|
|||
* \brief Transform pixels based on the conversion implemented
|
||||
* by this class
|
||||
*
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* Note that the alpha channel is assumed to be linear in both
|
||||
* the source and target bitmap, hence it won't be affected by
|
||||
* Gamma-related transformations.
|
||||
*
|
||||
|
@ -941,8 +941,8 @@ public:
|
|||
* Pointer to the first pixel of the source bitmap
|
||||
* \param destFormat
|
||||
* Pixel format of the destination bitmap
|
||||
* \param destGamma
|
||||
* Gamma value associated with pixels from the destination
|
||||
* \param destGamma
|
||||
* Gamma value associated with pixels from the destination
|
||||
* bitmap. Special values: 1.0 denotes a linear space, and -1.0
|
||||
* corresponds to sRGB.
|
||||
* \param dest
|
||||
|
@ -950,7 +950,7 @@ public:
|
|||
* \param count
|
||||
* How many pixels should be transformed?
|
||||
* \ref multiplier
|
||||
* An optional multiplicative factor that will be applied to all
|
||||
* An optional multiplicative factor that will be applied to all
|
||||
* color/luminance/spectrum values in linear space (alpha and weight
|
||||
* values will not be affected).
|
||||
* \ref intent
|
||||
|
@ -960,9 +960,9 @@ public:
|
|||
* \sa getConversion()
|
||||
*/
|
||||
virtual void convert(
|
||||
Bitmap::EPixelFormat sourceFormat, Float sourceGamma, const void *_source,
|
||||
Bitmap::EPixelFormat destFormat, Float destGamma, void *_dest,
|
||||
size_t count, Float multiplier = 1.0f,
|
||||
Bitmap::EPixelFormat sourceFormat, Float sourceGamma, const void *_source,
|
||||
Bitmap::EPixelFormat destFormat, Float destGamma, void *_dest,
|
||||
size_t count, Float multiplier = 1.0f,
|
||||
Spectrum::EConversionIntent intent = Spectrum::EReflectance) const= 0;
|
||||
|
||||
/**
|
||||
|
@ -1003,7 +1003,7 @@ namespace detail {
|
|||
template <> inline Bitmap::EComponentFormat cfmt<double>() { return Bitmap::EFloat64; }
|
||||
};
|
||||
|
||||
template <typename T> inline Bitmap::EComponentFormat Bitmap::componentFormat() {
|
||||
template <typename T> inline Bitmap::EComponentFormat Bitmap::componentFormat() {
|
||||
return detail::cfmt<T>();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Brent's method nonlinear zero finder
|
||||
*
|
||||
* The implementation is transcribed from the Apache Commons
|
||||
* The implementation is transcribed from the Apache Commons
|
||||
* Java implementation. The supplied function is required to be
|
||||
* continuous, but not necessarily smooth.
|
||||
*
|
||||
|
@ -60,7 +60,7 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Create a new Brent-style solver with the
|
||||
* \brief Create a new Brent-style solver with the
|
||||
* specified accuracy requirements
|
||||
*
|
||||
* \param maxIterations
|
||||
|
@ -69,16 +69,16 @@ public:
|
|||
* Absolute accuracy requirement -- the iterations will stop
|
||||
* when |f(x)| < absAccuracy.
|
||||
* \param absAccuracyPos
|
||||
* Absolute accuracy requirement of the position -- the
|
||||
* Absolute accuracy requirement of the position -- the
|
||||
* iterations will stop when |minX-maxX| < absAccuracyPos.
|
||||
* \param absAccuracyPos
|
||||
* Absolute accuracy requirement of the position -- the
|
||||
* iterations will stop when |minX-maxX|/minX < relAccuracyPos.
|
||||
*/
|
||||
inline BrentSolver(size_t maxIterations = 100,
|
||||
inline BrentSolver(size_t maxIterations = 100,
|
||||
Float absAccuracy = 1e-6f,
|
||||
Float absAccuracyPos = 1e-6f,
|
||||
Float relAccuracyPos = 1e-6f)
|
||||
Float relAccuracyPos = 1e-6f)
|
||||
: m_maxIterations(maxIterations),
|
||||
m_absAccuracy(absAccuracy),
|
||||
m_absAccuracyPos(absAccuracyPos),
|
||||
|
@ -87,8 +87,8 @@ public:
|
|||
/**
|
||||
* \brief Find a zero in the given interval.
|
||||
*
|
||||
* Requires that the values of the function at the endpoints
|
||||
* have opposite signs.
|
||||
* Requires that the values of the function at the endpoints
|
||||
* have opposite signs.
|
||||
*
|
||||
* \param min the lower bound for the interval.
|
||||
* \param max the upper bound for the interval.
|
||||
|
@ -100,14 +100,14 @@ public:
|
|||
/**
|
||||
* \brief Find a zero in the given interval with an initial guess
|
||||
*
|
||||
* Requires that the values of the function at the endpoints
|
||||
* have opposite signs (note that it is allowed to have endpoints
|
||||
* with the same sign if the initial point has opposite sign
|
||||
* Requires that the values of the function at the endpoints
|
||||
* have opposite signs (note that it is allowed to have endpoints
|
||||
* with the same sign if the initial point has opposite sign
|
||||
* function-wise).
|
||||
*
|
||||
* \param min the lower bound for the interval.
|
||||
* \param max the upper bound for the interval.
|
||||
* \param initial the start value to use (must be set to min
|
||||
* \param initial the start value to use (must be set to min
|
||||
* if no initial point is known)
|
||||
* \return the value where the function is zero
|
||||
*/
|
||||
|
@ -136,7 +136,7 @@ protected:
|
|||
Float m_absAccuracy;
|
||||
Float m_absAccuracyPos;
|
||||
Float m_relAccuracyPos;
|
||||
};
|
||||
};
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ struct BSphere {
|
|||
}
|
||||
|
||||
/// Copy constructor
|
||||
inline BSphere(const BSphere &boundingSphere)
|
||||
inline BSphere(const BSphere &boundingSphere)
|
||||
: center(boundingSphere.center), radius(boundingSphere.radius) {
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ struct BSphere {
|
|||
inline void expandBy(const Point p) {
|
||||
radius = std::max(radius, (p-center).length());
|
||||
}
|
||||
|
||||
|
||||
/// Check whether the specified point is inside or on the sphere
|
||||
inline bool contains(const Point p) const {
|
||||
return (p - center).length() <= radius;
|
||||
|
|
|
@ -59,7 +59,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \endcode
|
||||
*
|
||||
* the code in this class might be used as follows
|
||||
*
|
||||
*
|
||||
* \code
|
||||
* MyDistribution myDistrInstance;
|
||||
* ChiSquare chiSqr;
|
||||
|
@ -109,9 +109,9 @@ public:
|
|||
* Number of samples to be used when computing the bin
|
||||
* values. The default is \c thetaBins*phiBins*5000
|
||||
*/
|
||||
ChiSquare(int thetaBins = 10, int phiBins = 0,
|
||||
ChiSquare(int thetaBins = 10, int phiBins = 0,
|
||||
int numTests = 1, size_t sampleCount = 0);
|
||||
|
||||
|
||||
/// Get the log level
|
||||
inline ELogLevel getLogLevel() const { return m_logLevel; }
|
||||
|
||||
|
@ -119,17 +119,17 @@ public:
|
|||
inline void setLogLevel(ELogLevel logLevel) { m_logLevel = logLevel; }
|
||||
|
||||
/**
|
||||
* \brief Set the tolerance threshold for bins with very low
|
||||
* \brief Set the tolerance threshold for bins with very low
|
||||
* aggregate probabilities
|
||||
*
|
||||
* When the Chi-square test integrates the supplied probability
|
||||
* When the Chi-square test integrates the supplied probability
|
||||
* density function over the support of a bin and determines that
|
||||
* the aggregate bin probability is zero, the test would ordinarily
|
||||
* fail if as much as one sample is placed in that bin in the
|
||||
* subsequent sampling step. However, due to various numerical
|
||||
* errors in a system based on finite-precision arithmetic, it
|
||||
* may be a good idea to tolerate at least a few samples without
|
||||
* immediately rejecting the null hypothesis. This parameter
|
||||
* the aggregate bin probability is zero, the test would ordinarily
|
||||
* fail if as much as one sample is placed in that bin in the
|
||||
* subsequent sampling step. However, due to various numerical
|
||||
* errors in a system based on finite-precision arithmetic, it
|
||||
* may be a good idea to tolerate at least a few samples without
|
||||
* immediately rejecting the null hypothesis. This parameter
|
||||
* sets this threshold. The default value is \c number-of-samples*1e-4f
|
||||
*/
|
||||
inline void setTolerance(Float tolerance) { m_tolerance = tolerance; }
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
* \param instPtr Pointer to an instantiation function
|
||||
* \param unSerPtr Pointer to an unserialization function
|
||||
*/
|
||||
Class(const std::string &name, bool abstract, const std::string &superClassName,
|
||||
Class(const std::string &name, bool abstract, const std::string &superClassName,
|
||||
void *instPtr = NULL, void *unSerPtr = NULL);
|
||||
|
||||
/// Return the name of the represented class
|
||||
|
@ -134,7 +134,7 @@ private:
|
|||
#define MTS_CLASS(x) x::m_theClass
|
||||
|
||||
/**
|
||||
* \brief This macro must be used in the initial definition in
|
||||
* \brief This macro must be used in the initial definition in
|
||||
* classes that derive from \ref Object.
|
||||
*
|
||||
* This is needed for the basic RTTI support provided by Mitsuba objects.
|
||||
|
@ -158,7 +158,7 @@ private:
|
|||
#define MTS_DECLARE_CLASS() \
|
||||
virtual const Class *getClass() const; \
|
||||
public: \
|
||||
static Class *m_theClass;
|
||||
static Class *m_theClass;
|
||||
|
||||
/**
|
||||
* \brief Creates basic RTTI support for a class
|
||||
|
@ -227,7 +227,7 @@ public: \
|
|||
|
||||
/**
|
||||
* \brief Creates basic RTTI support for a class. To be used when the class
|
||||
* can be unserialized from a binary data stream as well as instantiated
|
||||
* can be unserialized from a binary data stream as well as instantiated
|
||||
* by a constructor that does not take any arguments.
|
||||
*
|
||||
* This macro or one of its variants should be invoked in the main
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/** \brief Generic serializable object, which supports construction
|
||||
/** \brief Generic serializable object, which supports construction
|
||||
* from a Properties instance.
|
||||
*
|
||||
* All plugins in Mitsuba derive from ConfigurableObject. This mechanism
|
||||
|
@ -40,7 +40,7 @@ MTS_NAMESPACE_BEGIN
|
|||
class MTS_EXPORT_CORE ConfigurableObject : public SerializableObject {
|
||||
public:
|
||||
/**
|
||||
* \brief Notify the \ref ConfigurableObject instance about
|
||||
* \brief Notify the \ref ConfigurableObject instance about
|
||||
* its parent object
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
inline void setID(const std::string &name) { m_properties.setID(name); }
|
||||
|
||||
/**
|
||||
* \brief Return the properties object that was originally used to
|
||||
* \brief Return the properties object that was originally used to
|
||||
* create this instance
|
||||
*
|
||||
* This feature mainly of use for editors and other graphical
|
||||
|
@ -80,18 +80,18 @@ public:
|
|||
protected:
|
||||
/// Virtual destructor
|
||||
virtual ~ConfigurableObject() { }
|
||||
|
||||
|
||||
/// Construct a configurable object
|
||||
inline ConfigurableObject(const Properties &props)
|
||||
inline ConfigurableObject(const Properties &props)
|
||||
: SerializableObject(), m_properties(props) { }
|
||||
|
||||
|
||||
/// Unserialize a configurable object
|
||||
ConfigurableObject(Stream *stream, InstanceManager *manager);
|
||||
protected:
|
||||
Properties m_properties;
|
||||
};
|
||||
|
||||
/** \brief This macro creates the binary interface, which Mitsuba
|
||||
/** \brief This macro creates the binary interface, which Mitsuba
|
||||
* requires to load a plugin.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
|
|
@ -33,7 +33,7 @@ enum ELogLevel {
|
|||
EError = 400 ///< Error message, causes an exception to be thrown
|
||||
};
|
||||
|
||||
/** \brief Abstract interface for converting log information into
|
||||
/** \brief Abstract interface for converting log information into
|
||||
* a human-readable format
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
*/
|
||||
|
||||
virtual std::string format(ELogLevel logLevel, const Class *theClass,
|
||||
const Thread *thread, const std::string &text,
|
||||
const Thread *thread, const std::string &text,
|
||||
const char *file, int line) = 0;
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
@ -69,7 +69,7 @@ public:
|
|||
DefaultFormatter();
|
||||
|
||||
std::string format(ELogLevel logLevel, const Class *theClass,
|
||||
const Thread *thread, const std::string &text,
|
||||
const Thread *thread, const std::string &text,
|
||||
const char *file, int line);
|
||||
|
||||
/// Should date information be included? The default is yes.
|
||||
|
|
|
@ -62,7 +62,7 @@ struct Frame {
|
|||
t = Vector(stream);
|
||||
n = Normal(stream);
|
||||
}
|
||||
|
||||
|
||||
/// Serialize to a binary data stream
|
||||
inline void serialize(Stream *stream) const {
|
||||
s.serialize(stream);
|
||||
|
@ -84,7 +84,7 @@ struct Frame {
|
|||
return s * v.x + t * v.y + n * v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the cosine of the angle between the normal and v */
|
||||
inline static Float cosTheta(const Vector &v) {
|
||||
return v.z;
|
||||
|
@ -114,7 +114,7 @@ struct Frame {
|
|||
return 1.0f - v.z * v.z;
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the sine of the phi parameter in spherical coordinates */
|
||||
inline static Float sinPhi(const Vector &v) {
|
||||
Float sinTheta = Frame::sinTheta(v);
|
||||
|
@ -123,7 +123,7 @@ struct Frame {
|
|||
return clamp(v.y / sinTheta, (Float) -1.0f, (Float) 1.0f);
|
||||
}
|
||||
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
/** \brief Assuming that the given direction is in the local coordinate
|
||||
* system, return the cosine of the phi parameter in spherical coordinates */
|
||||
inline static Float cosPhi(const Vector &v) {
|
||||
Float sinTheta = Frame::sinTheta(v);
|
||||
|
|
|
@ -29,10 +29,10 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/**
|
||||
* \brief File resolution helper
|
||||
*
|
||||
* FileResolver is a convenience class that allows searching for files
|
||||
*
|
||||
* FileResolver is a convenience class that allows searching for files
|
||||
* within a set of specifiable search paths in a cross-platform
|
||||
* compatible manner (similar to the $PATH variable on various
|
||||
* compatible manner (similar to the $PATH variable on various
|
||||
* operating systems).
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -43,15 +43,15 @@ public:
|
|||
/**
|
||||
* \brief Create a new file resolver with the default settings
|
||||
*
|
||||
* Create a new file resolver containing the current working
|
||||
* Create a new file resolver containing the current working
|
||||
* directory as the initial search path.
|
||||
*/
|
||||
FileResolver();
|
||||
|
||||
/**
|
||||
* \brief Resolve a file using the stored list of search paths
|
||||
*
|
||||
* Go through the list of search paths and try to resolve the
|
||||
*
|
||||
* Go through the list of search paths and try to resolve the
|
||||
* supplied path with respect to each one. If everything fails,
|
||||
* the path is returned as-is.
|
||||
*/
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Resolve a file using the stored list of search paths
|
||||
*
|
||||
*
|
||||
* In comparison to \ref resolve(), this funtion returns all
|
||||
* matches instead of only the first one.
|
||||
*
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
//
|
||||
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
|
||||
// Digital Ltd. LLC
|
||||
//
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
|
@ -22,8 +22,8 @@
|
|||
// distribution.
|
||||
// * Neither the name of Industrial Light & Magic nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
|
@ -311,9 +311,9 @@ MTS_EXPORT_CORE void printBits (char c[35], float f);
|
|||
// floating point number, whose bits are arranged as follows:
|
||||
//
|
||||
// 31 (msb)
|
||||
// |
|
||||
// |
|
||||
// | 30 23
|
||||
// | | |
|
||||
// | | |
|
||||
// | | | 22 0 (lsb)
|
||||
// | | | | |
|
||||
// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
@ -357,7 +357,7 @@ MTS_EXPORT_CORE void printBits (char c[35], float f);
|
|||
// Here is the bit-layout for a half number, h:
|
||||
//
|
||||
// 15 (msb)
|
||||
// |
|
||||
// |
|
||||
// | 14 10
|
||||
// | | |
|
||||
// | | | 9 0 (lsb)
|
||||
|
@ -562,7 +562,7 @@ half::round (unsigned int n) const
|
|||
// Other inline functions
|
||||
//-----------------------
|
||||
|
||||
inline half
|
||||
inline half
|
||||
half::operator - () const
|
||||
{
|
||||
half h;
|
||||
|
@ -651,7 +651,7 @@ half::operator /= (float f)
|
|||
}
|
||||
|
||||
|
||||
inline bool
|
||||
inline bool
|
||||
half::isFinite () const
|
||||
{
|
||||
unsigned short e = (_h >> 10) & 0x001f;
|
||||
|
@ -701,7 +701,7 @@ half::isInfinity () const
|
|||
}
|
||||
|
||||
|
||||
inline bool
|
||||
inline bool
|
||||
half::isNegative () const
|
||||
{
|
||||
return (_h & 0x8000) != 0;
|
||||
|
|
|
@ -28,13 +28,13 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Simple kd-tree node for use with \ref PointKDTree.
|
||||
*
|
||||
* This class is an example of how one might write a space-efficient kd-tree
|
||||
* node that is compatible with the \ref PointKDTree class. The implementation
|
||||
* supports associating a custom data record with each node and works up to
|
||||
* This class is an example of how one might write a space-efficient kd-tree
|
||||
* node that is compatible with the \ref PointKDTree class. The implementation
|
||||
* supports associating a custom data record with each node and works up to
|
||||
* 16 dimensions.
|
||||
*
|
||||
* \tparam _PointType Underlying point data type (e.g. \ref TPoint3<float>)
|
||||
* \tparam _DataRecord Custom storage that should be associated with each
|
||||
* \tparam _DataRecord Custom storage that should be associated with each
|
||||
* tree node
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -51,7 +51,7 @@ template <typename _PointType, typename _DataRecord> struct SimpleKDNode {
|
|||
ELeafFlag = 0x10,
|
||||
EAxisMask = 0x0F
|
||||
};
|
||||
|
||||
|
||||
static const bool leftBalancedLayout = false;
|
||||
|
||||
PointType position;
|
||||
|
@ -60,18 +60,18 @@ template <typename _PointType, typename _DataRecord> struct SimpleKDNode {
|
|||
uint8_t flags;
|
||||
|
||||
/// Initialize a KD-tree node
|
||||
inline SimpleKDNode() : position((Scalar) 0),
|
||||
inline SimpleKDNode() : position((Scalar) 0),
|
||||
right(0), data(), flags(0) { }
|
||||
/// Initialize a KD-tree node with the given data record
|
||||
inline SimpleKDNode(const DataRecord &data) : position((Scalar) 0),
|
||||
inline SimpleKDNode(const DataRecord &data) : position((Scalar) 0),
|
||||
right(0), data(data), flags(0) { }
|
||||
|
||||
/// Given the current node's index, return the index of the right child
|
||||
/// Given the current node's index, return the index of the right child
|
||||
inline IndexType getRightIndex(IndexType self) const { return right; }
|
||||
/// Given the current node's index, set the right child index
|
||||
inline void setRightIndex(IndexType self, IndexType value) { right = value; }
|
||||
|
||||
/// Given the current node's index, return the index of the left child
|
||||
/// Given the current node's index, return the index of the left child
|
||||
inline IndexType getLeftIndex(IndexType self) const { return self + 1; }
|
||||
/// Given the current node's index, set the left child index
|
||||
inline void setLeftIndex(IndexType self, IndexType value) {
|
||||
|
@ -84,10 +84,10 @@ template <typename _PointType, typename _DataRecord> struct SimpleKDNode {
|
|||
/// Check whether this is a leaf node
|
||||
inline bool isLeaf() const { return flags & (uint8_t) ELeafFlag; }
|
||||
/// Specify whether this is a leaf node
|
||||
inline void setLeaf(bool value) {
|
||||
if (value)
|
||||
flags |= (uint8_t) ELeafFlag;
|
||||
else
|
||||
inline void setLeaf(bool value) {
|
||||
if (value)
|
||||
flags |= (uint8_t) ELeafFlag;
|
||||
else
|
||||
flags &= (uint8_t) ~ELeafFlag;
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ template <typename _PointType, typename _DataRecord> struct SimpleKDNode {
|
|||
* that there is no need to store node pointers within nodes.
|
||||
*
|
||||
* \tparam _PointType Underlying point data type (e.g. \ref TPoint3<float>)
|
||||
* \tparam _DataRecord Custom storage that should be associated with each
|
||||
* \tparam _DataRecord Custom storage that should be associated with each
|
||||
* tree node
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -145,10 +145,10 @@ template <typename _PointType, typename _DataRecord> struct LeftBalancedKDNode {
|
|||
/// Initialize a KD-tree node
|
||||
inline LeftBalancedKDNode() : position((Scalar) 0), data(), flags(0) { }
|
||||
/// Initialize a KD-tree node with the given data record
|
||||
inline LeftBalancedKDNode(const DataRecord &data) : position((Scalar) 0),
|
||||
inline LeftBalancedKDNode(const DataRecord &data) : position((Scalar) 0),
|
||||
data(data), flags(0) { }
|
||||
|
||||
/// Given the current node's index, return the index of the left child
|
||||
/// Given the current node's index, return the index of the left child
|
||||
inline IndexType getLeftIndex(IndexType self) const { return 2 * self + 1; }
|
||||
/// Given the current node's index, set the left child index
|
||||
inline void setLeftIndex(IndexType self, IndexType value) {
|
||||
|
@ -158,7 +158,7 @@ template <typename _PointType, typename _DataRecord> struct LeftBalancedKDNode {
|
|||
#endif
|
||||
}
|
||||
|
||||
/// Given the current node's index, return the index of the right child
|
||||
/// Given the current node's index, return the index of the right child
|
||||
inline IndexType getRightIndex(IndexType self) const { return 2 * self + 2; }
|
||||
/// Given the current node's index, set the right child index
|
||||
inline void setRightIndex(IndexType self, IndexType value) {
|
||||
|
@ -171,10 +171,10 @@ template <typename _PointType, typename _DataRecord> struct LeftBalancedKDNode {
|
|||
/// Check whether this is a leaf node
|
||||
inline bool isLeaf() const { return flags & (uint8_t) ELeafFlag; }
|
||||
/// Specify whether this is a leaf node
|
||||
inline void setLeaf(bool value) {
|
||||
if (value)
|
||||
flags |= (uint8_t) ELeafFlag;
|
||||
else
|
||||
inline void setLeaf(bool value) {
|
||||
if (value)
|
||||
flags |= (uint8_t) ELeafFlag;
|
||||
else
|
||||
flags &= (uint8_t) ~ELeafFlag;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ template <typename _PointType, typename _DataRecord> struct LeftBalancedKDNode {
|
|||
* data layout of the nodes themselves.
|
||||
*
|
||||
* Note that this class is meant for point data only --- for things that
|
||||
* have some kind of spatial extent, the classes \ref GenericKDTree and
|
||||
* have some kind of spatial extent, the classes \ref GenericKDTree and
|
||||
* \ref ShapeKDTree will be more appropriate.
|
||||
*
|
||||
* \tparam _NodeType Underlying node data structure. See \ref SimpleKDNode as
|
||||
|
@ -227,22 +227,22 @@ public:
|
|||
enum EHeuristic {
|
||||
/// Create a balanced tree by splitting along the median
|
||||
EBalanced = 0,
|
||||
|
||||
|
||||
/// Create a left-balanced tree
|
||||
ELeftBalanced,
|
||||
|
||||
/**
|
||||
* \brief Use the sliding midpoint tree construction rule. This
|
||||
* \brief Use the sliding midpoint tree construction rule. This
|
||||
* ensures that cells do not become overly elongated.
|
||||
*/
|
||||
ESlidingMidpoint,
|
||||
|
||||
/**
|
||||
* \brief Choose the split plane by optimizing a cost heuristic
|
||||
* based on the ratio of voxel volumes.
|
||||
* based on the ratio of voxel volumes.
|
||||
*
|
||||
* Note that Mitsuba's implementation of this heuristic is not
|
||||
* particularly optimized --- the tree construction construction
|
||||
* Note that Mitsuba's implementation of this heuristic is not
|
||||
* particularly optimized --- the tree construction construction
|
||||
* runs time O(n (log n)^2) instead of O(n log n).
|
||||
*/
|
||||
EVoxelVolume
|
||||
|
@ -260,7 +260,7 @@ public:
|
|||
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "SearchResult[distance=" << std::sqrt(distSquared)
|
||||
oss << "SearchResult[distance=" << std::sqrt(distSquared)
|
||||
<< ", index=" << index << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ public:
|
|||
};
|
||||
|
||||
/// Comparison functor for nearest-neighbor search queries
|
||||
struct SearchResultComparator : public
|
||||
struct SearchResultComparator : public
|
||||
std::binary_function<SearchResult, SearchResult, bool> {
|
||||
public:
|
||||
inline bool operator()(const SearchResult &a, const SearchResult &b) const {
|
||||
|
@ -281,7 +281,7 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
/**
|
||||
* \brief Create an empty KD-tree that can hold the specified
|
||||
* number of points
|
||||
*/
|
||||
|
@ -344,8 +344,8 @@ public:
|
|||
timer->reset();
|
||||
|
||||
/* Instead of shuffling around the node data itself, only modify
|
||||
an indirection table initially. Once the tree construction
|
||||
is done, this table will contain a indirection that can then
|
||||
an indirection table initially. Once the tree construction
|
||||
is done, this table will contain a indirection that can then
|
||||
be applied to the data in one pass */
|
||||
std::vector<IndexType> indirection(m_nodes.size());
|
||||
for (size_t i=0; i<m_nodes.size(); ++i)
|
||||
|
@ -355,7 +355,7 @@ public:
|
|||
int constructionTime;
|
||||
if (NodeType::leftBalancedLayout) {
|
||||
std::vector<IndexType> permutation(m_nodes.size());
|
||||
buildLB(0, 1, indirection.begin(), indirection.begin(),
|
||||
buildLB(0, 1, indirection.begin(), indirection.begin(),
|
||||
indirection.end(), permutation);
|
||||
constructionTime = timer->getMilliseconds();
|
||||
timer->reset();
|
||||
|
@ -381,16 +381,16 @@ public:
|
|||
* \brief Run a k-nearest-neighbor search query
|
||||
*
|
||||
* \param p Search position
|
||||
* \param sqrSearchRadius
|
||||
* Specifies the squared maximum search radius. This parameter can be used
|
||||
* \param sqrSearchRadius
|
||||
* Specifies the squared maximum search radius. This parameter can be used
|
||||
* to restrict the k-nn query to a subset of the data -- it that is not
|
||||
* desired, simply set it to positive infinity. After the query
|
||||
* finishes, the parameter value will correspond to the (potentially lower)
|
||||
* maximum query radius that was necessary to ensure that the number of
|
||||
* finishes, the parameter value will correspond to the (potentially lower)
|
||||
* maximum query radius that was necessary to ensure that the number of
|
||||
* results did not exceed \c k.
|
||||
* \param k Maximum number of search results
|
||||
* \param results Target array for search results. Must
|
||||
* contain storage for at least \c k+1 entries!
|
||||
* \param results Target array for search results. Must
|
||||
* contain storage for at least \c k+1 entries!
|
||||
* (one extra entry is needed for shuffling data around)
|
||||
* \return The number of search results (equal to \c k or less)
|
||||
*/
|
||||
|
@ -409,15 +409,15 @@ public:
|
|||
while (stackPos > 0) {
|
||||
const NodeType &node = m_nodes[index];
|
||||
IndexType nextIndex;
|
||||
|
||||
|
||||
/* Recurse on inner nodes */
|
||||
if (!node.isLeaf()) {
|
||||
Float distToPlane = p[node.getAxis()] - node.getPosition()[node.getAxis()];
|
||||
|
||||
|
||||
bool searchBoth = distToPlane*distToPlane <= sqrSearchRadius;
|
||||
|
||||
if (distToPlane > 0) {
|
||||
/* The search query is located on the right side of the split.
|
||||
/* The search query is located on the right side of the split.
|
||||
Search this side first. */
|
||||
if (hasRightChild(index)) {
|
||||
if (searchBoth)
|
||||
|
@ -429,7 +429,7 @@ public:
|
|||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
} else {
|
||||
/* The search query is located on the left side of the split.
|
||||
/* The search query is located on the left side of the split.
|
||||
Search this side first. */
|
||||
if (searchBoth && hasRightChild(index))
|
||||
stack[stackPos++] = node.getRightIndex(index);
|
||||
|
@ -439,12 +439,12 @@ public:
|
|||
} else {
|
||||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
|
||||
|
||||
/* Check if the current point is within the query's search radius */
|
||||
const Float pointDistSquared = (node.getPosition() - p).lengthSquared();
|
||||
|
||||
|
||||
if (pointDistSquared < sqrSearchRadius) {
|
||||
/* Switch to a max-heap when the available search
|
||||
/* Switch to a max-heap when the available search
|
||||
result space is exhausted */
|
||||
if (resultCount < k) {
|
||||
/* There is still room, just add the point to
|
||||
|
@ -453,17 +453,17 @@ public:
|
|||
} else {
|
||||
if (!isHeap) {
|
||||
/* Establish the max-heap property */
|
||||
std::make_heap(results, results + resultCount,
|
||||
std::make_heap(results, results + resultCount,
|
||||
SearchResultComparator());
|
||||
isHeap = true;
|
||||
}
|
||||
SearchResult *end = results + resultCount + 1;
|
||||
|
||||
|
||||
/* Add the new point, remove the one that is farthest away */
|
||||
results[resultCount] = SearchResult(pointDistSquared, index);
|
||||
std::push_heap(results, end, SearchResultComparator());
|
||||
std::pop_heap(results, end, SearchResultComparator());
|
||||
|
||||
|
||||
/* Reduce the search radius accordingly */
|
||||
sqrSearchRadius = results[0].distSquared;
|
||||
}
|
||||
|
@ -478,17 +478,17 @@ public:
|
|||
* \brief Run a k-nearest-neighbor search query and record statistics
|
||||
*
|
||||
* \param p Search position
|
||||
* \param sqrSearchRadius
|
||||
* Specifies the squared maximum search radius. This parameter can be used
|
||||
* \param sqrSearchRadius
|
||||
* Specifies the squared maximum search radius. This parameter can be used
|
||||
* to restrict the k-nn query to a subset of the data -- it that is not
|
||||
* desired, simply set it to positive infinity. After the query
|
||||
* finishes, the parameter value will correspond to the (potentially lower)
|
||||
* maximum query radius that was necessary to ensure that the number of
|
||||
* finishes, the parameter value will correspond to the (potentially lower)
|
||||
* maximum query radius that was necessary to ensure that the number of
|
||||
* results did not exceed \c k.
|
||||
* \param k Maximum number of search results
|
||||
* \param results
|
||||
* Target array for search results. Must contain
|
||||
* storage for at least \c k+1 entries! (one
|
||||
* Target array for search results. Must contain
|
||||
* storage for at least \c k+1 entries! (one
|
||||
* extra entry is needed for shuffling data around)
|
||||
* \return The number of used traversal steps
|
||||
*/
|
||||
|
@ -509,15 +509,15 @@ public:
|
|||
const NodeType &node = m_nodes[index];
|
||||
++traversalSteps;
|
||||
IndexType nextIndex;
|
||||
|
||||
|
||||
/* Recurse on inner nodes */
|
||||
if (!node.isLeaf()) {
|
||||
Float distToPlane = p[node.getAxis()] - node.getPosition()[node.getAxis()];
|
||||
|
||||
|
||||
bool searchBoth = distToPlane*distToPlane <= sqrSearchRadius;
|
||||
|
||||
if (distToPlane > 0) {
|
||||
/* The search query is located on the right side of the split.
|
||||
/* The search query is located on the right side of the split.
|
||||
Search this side first. */
|
||||
if (hasRightChild(index)) {
|
||||
if (searchBoth)
|
||||
|
@ -529,7 +529,7 @@ public:
|
|||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
} else {
|
||||
/* The search query is located on the left side of the split.
|
||||
/* The search query is located on the left side of the split.
|
||||
Search this side first. */
|
||||
if (searchBoth && hasRightChild(index))
|
||||
stack[stackPos++] = node.getRightIndex(index);
|
||||
|
@ -539,12 +539,12 @@ public:
|
|||
} else {
|
||||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
|
||||
|
||||
/* Check if the current point is within the query's search radius */
|
||||
const Float pointDistSquared = (node.getPosition() - p).lengthSquared();
|
||||
|
||||
|
||||
if (pointDistSquared < sqrSearchRadius) {
|
||||
/* Switch to a max-heap when the available search
|
||||
/* Switch to a max-heap when the available search
|
||||
result space is exhausted */
|
||||
if (resultCount < k) {
|
||||
/* There is still room, just add the point to
|
||||
|
@ -553,16 +553,16 @@ public:
|
|||
} else {
|
||||
if (!isHeap) {
|
||||
/* Establish the max-heap property */
|
||||
std::make_heap(results, results + resultCount,
|
||||
std::make_heap(results, results + resultCount,
|
||||
SearchResultComparator());
|
||||
isHeap = true;
|
||||
}
|
||||
|
||||
|
||||
/* Add the new point, remove the one that is farthest away */
|
||||
results[resultCount] = SearchResult(pointDistSquared, index);
|
||||
std::push_heap(results, results + resultCount + 1, SearchResultComparator());
|
||||
std::pop_heap(results, results + resultCount + 1, SearchResultComparator());
|
||||
|
||||
|
||||
/* Reduce the search radius accordingly */
|
||||
sqrSearchRadius = results[0].distSquared;
|
||||
}
|
||||
|
@ -579,13 +579,13 @@ public:
|
|||
* \param p Search position
|
||||
* \param k Maximum number of search results
|
||||
* \param results
|
||||
* Target array for search results. Must contain
|
||||
* storage for at least \c k+1 entries! (one
|
||||
* Target array for search results. Must contain
|
||||
* storage for at least \c k+1 entries! (one
|
||||
* extra entry is needed for shuffling data around)
|
||||
* \return The number of used traversal steps
|
||||
*/
|
||||
|
||||
inline size_t nnSearch(const PointType &p, size_t k,
|
||||
inline size_t nnSearch(const PointType &p, size_t k,
|
||||
SearchResult *results) const {
|
||||
Float searchRadiusSqr = std::numeric_limits<Float>::infinity();
|
||||
return nnSearch(p, searchRadiusSqr, k, results);
|
||||
|
@ -600,7 +600,7 @@ public:
|
|||
*
|
||||
* \param p Search position
|
||||
* \param functor Functor to be called on each search result
|
||||
* \param searchRadius Search radius
|
||||
* \param searchRadius Search radius
|
||||
* \return The number of functor invocations
|
||||
*/
|
||||
template <typename Functor> size_t executeModifier(const PointType &p,
|
||||
|
@ -616,16 +616,16 @@ public:
|
|||
while (stackPos > 0) {
|
||||
NodeType &node = m_nodes[index];
|
||||
IndexType nextIndex;
|
||||
|
||||
|
||||
/* Recurse on inner nodes */
|
||||
if (!node.isLeaf()) {
|
||||
Float distToPlane = p[node.getAxis()]
|
||||
Float distToPlane = p[node.getAxis()]
|
||||
- node.getPosition()[node.getAxis()];
|
||||
|
||||
|
||||
bool searchBoth = distToPlane*distToPlane <= distSquared;
|
||||
|
||||
if (distToPlane > 0) {
|
||||
/* The search query is located on the right side of the split.
|
||||
/* The search query is located on the right side of the split.
|
||||
Search this side first. */
|
||||
if (hasRightChild(index)) {
|
||||
if (searchBoth)
|
||||
|
@ -637,7 +637,7 @@ public:
|
|||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
} else {
|
||||
/* The search query is located on the left side of the split.
|
||||
/* The search query is located on the left side of the split.
|
||||
Search this side first. */
|
||||
if (searchBoth && hasRightChild(index))
|
||||
stack[stackPos++] = node.getRightIndex(index);
|
||||
|
@ -647,10 +647,10 @@ public:
|
|||
} else {
|
||||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
|
||||
|
||||
/* Check if the current point is within the query's search radius */
|
||||
const Float pointDistSquared = (node.getPosition() - p).lengthSquared();
|
||||
|
||||
|
||||
if (pointDistSquared < distSquared) {
|
||||
functor(node);
|
||||
++found;
|
||||
|
@ -669,7 +669,7 @@ public:
|
|||
*
|
||||
* \param p Search position
|
||||
* \param functor Functor to be called on each search result
|
||||
* \param searchRadius Search radius
|
||||
* \param searchRadius Search radius
|
||||
* \return The number of functor invocations
|
||||
*/
|
||||
template <typename Functor> size_t executeQuery(const PointType &p,
|
||||
|
@ -685,16 +685,16 @@ public:
|
|||
while (stackPos > 0) {
|
||||
const NodeType &node = m_nodes[index];
|
||||
IndexType nextIndex;
|
||||
|
||||
|
||||
/* Recurse on inner nodes */
|
||||
if (!node.isLeaf()) {
|
||||
Float distToPlane = p[node.getAxis()]
|
||||
Float distToPlane = p[node.getAxis()]
|
||||
- node.getPosition()[node.getAxis()];
|
||||
|
||||
|
||||
bool searchBoth = distToPlane*distToPlane <= distSquared;
|
||||
|
||||
if (distToPlane > 0) {
|
||||
/* The search query is located on the right side of the split.
|
||||
/* The search query is located on the right side of the split.
|
||||
Search this side first. */
|
||||
if (hasRightChild(index)) {
|
||||
if (searchBoth)
|
||||
|
@ -706,7 +706,7 @@ public:
|
|||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
} else {
|
||||
/* The search query is located on the left side of the split.
|
||||
/* The search query is located on the left side of the split.
|
||||
Search this side first. */
|
||||
if (searchBoth && hasRightChild(index))
|
||||
stack[stackPos++] = node.getRightIndex(index);
|
||||
|
@ -719,7 +719,7 @@ public:
|
|||
|
||||
/* Check if the current point is within the query's search radius */
|
||||
const Float pointDistSquared = (node.getPosition() - p).lengthSquared();
|
||||
|
||||
|
||||
if (pointDistSquared < distSquared) {
|
||||
++found;
|
||||
functor(node);
|
||||
|
@ -736,7 +736,7 @@ public:
|
|||
*
|
||||
* \param p Search position
|
||||
* \param results Index list of search results
|
||||
* \param searchRadius Search radius
|
||||
* \param searchRadius Search radius
|
||||
* \return The number of functor invocations
|
||||
*/
|
||||
size_t search(const PointType &p, Float searchRadius, std::vector<IndexType> &results) const {
|
||||
|
@ -751,16 +751,16 @@ public:
|
|||
while (stackPos > 0) {
|
||||
const NodeType &node = m_nodes[index];
|
||||
IndexType nextIndex;
|
||||
|
||||
|
||||
/* Recurse on inner nodes */
|
||||
if (!node.isLeaf()) {
|
||||
Float distToPlane = p[node.getAxis()]
|
||||
- node.getPosition()[node.getAxis()];
|
||||
|
||||
|
||||
bool searchBoth = distToPlane*distToPlane <= distSquared;
|
||||
|
||||
if (distToPlane > 0) {
|
||||
/* The search query is located on the right side of the split.
|
||||
/* The search query is located on the right side of the split.
|
||||
Search this side first. */
|
||||
if (hasRightChild(index)) {
|
||||
if (searchBoth)
|
||||
|
@ -772,7 +772,7 @@ public:
|
|||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
} else {
|
||||
/* The search query is located on the left side of the split.
|
||||
/* The search query is located on the left side of the split.
|
||||
Search this side first. */
|
||||
if (searchBoth && hasRightChild(index))
|
||||
stack[stackPos++] = node.getRightIndex(index);
|
||||
|
@ -782,11 +782,11 @@ public:
|
|||
} else {
|
||||
nextIndex = stack[--stackPos];
|
||||
}
|
||||
|
||||
|
||||
/* Check if the current point is within the query's search radius */
|
||||
const Float pointDistSquared = (node.getPosition() - p).lengthSquared();
|
||||
|
||||
if (pointDistSquared < distSquared) {
|
||||
|
||||
if (pointDistSquared < distSquared) {
|
||||
++found;
|
||||
results.push_back(index);
|
||||
}
|
||||
|
@ -797,10 +797,10 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Return whether or not the inner node of the
|
||||
* \brief Return whether or not the inner node of the
|
||||
* specified index has a right child node.
|
||||
*
|
||||
* This function is available for convenience and abstracts away some
|
||||
* This function is available for convenience and abstracts away some
|
||||
* details about the underlying node representation.
|
||||
*/
|
||||
inline bool hasRightChild(IndexType index) const {
|
||||
|
@ -813,7 +813,7 @@ public:
|
|||
protected:
|
||||
struct CoordinateOrdering : public std::binary_function<IndexType, IndexType, bool> {
|
||||
public:
|
||||
inline CoordinateOrdering(const std::vector<NodeType> &nodes, int axis)
|
||||
inline CoordinateOrdering(const std::vector<NodeType> &nodes, int axis)
|
||||
: m_nodes(nodes), m_axis(axis) { }
|
||||
inline bool operator()(const IndexType &i1, const IndexType &i2) const {
|
||||
return m_nodes[i1].getPosition()[m_axis] < m_nodes[i2].getPosition()[m_axis];
|
||||
|
@ -825,7 +825,7 @@ protected:
|
|||
|
||||
struct LessThanOrEqual : public std::unary_function<IndexType, bool> {
|
||||
public:
|
||||
inline LessThanOrEqual(const std::vector<NodeType> &nodes, int axis, Scalar value)
|
||||
inline LessThanOrEqual(const std::vector<NodeType> &nodes, int axis, Scalar value)
|
||||
: m_nodes(nodes), m_axis(axis), m_value(value) { }
|
||||
inline bool operator()(const IndexType &i) const {
|
||||
return m_nodes[i].getPosition()[m_axis] <= m_value;
|
||||
|
@ -838,9 +838,9 @@ protected:
|
|||
|
||||
/**
|
||||
* Given a number of entries, this method calculates the number of nodes
|
||||
* nodes on the left subtree of a left-balanced tree. There are two main
|
||||
* nodes on the left subtree of a left-balanced tree. There are two main
|
||||
* cases here:
|
||||
*
|
||||
*
|
||||
* 1) It is possible to completely fill the left subtree
|
||||
* 2) It doesn't work - the last level contains too few nodes, e.g :
|
||||
* O
|
||||
|
@ -848,21 +848,21 @@ protected:
|
|||
* O O
|
||||
* /
|
||||
* O
|
||||
*
|
||||
*
|
||||
* The function assumes that "count" > 1.
|
||||
*/
|
||||
inline IndexType leftSubtreeSize(IndexType count) const {
|
||||
/* Layer 0 contains one node */
|
||||
IndexType p = 1;
|
||||
|
||||
|
||||
/* Traverse downwards until the first incompletely
|
||||
filled tree level is encountered */
|
||||
while (2*p <= count)
|
||||
p *= 2;
|
||||
|
||||
|
||||
/* Calculate the number of filled slots in the last level */
|
||||
IndexType remaining = count - p + 1;
|
||||
|
||||
|
||||
if (2*remaining < p) {
|
||||
/* Case 2: The last level contains too few nodes. Remove
|
||||
overestimate from the left subtree node count and add
|
||||
|
@ -876,7 +876,7 @@ protected:
|
|||
/// Left-balanced tree construction routine
|
||||
void buildLB(IndexType idx, size_t depth,
|
||||
typename std::vector<IndexType>::iterator base,
|
||||
typename std::vector<IndexType>::iterator rangeStart,
|
||||
typename std::vector<IndexType>::iterator rangeStart,
|
||||
typename std::vector<IndexType>::iterator rangeEnd,
|
||||
typename std::vector<IndexType> &permutation) {
|
||||
m_depth = std::max(depth, m_depth);
|
||||
|
@ -920,10 +920,10 @@ protected:
|
|||
/// Default tree construction routine
|
||||
void build(size_t depth,
|
||||
typename std::vector<IndexType>::iterator base,
|
||||
typename std::vector<IndexType>::iterator rangeStart,
|
||||
typename std::vector<IndexType>::iterator rangeStart,
|
||||
typename std::vector<IndexType>::iterator rangeEnd) {
|
||||
m_depth = std::max(depth, m_depth);
|
||||
|
||||
|
||||
IndexType count = (IndexType) (rangeEnd-rangeStart);
|
||||
SAssert(count > 0);
|
||||
|
||||
|
@ -940,7 +940,7 @@ protected:
|
|||
case EBalanced: {
|
||||
split = rangeStart + count/2;
|
||||
axis = m_aabb.getLargestAxis();
|
||||
std::nth_element(rangeStart, split, rangeEnd,
|
||||
std::nth_element(rangeStart, split, rangeEnd,
|
||||
CoordinateOrdering(m_nodes, axis));
|
||||
};
|
||||
break;
|
||||
|
@ -957,7 +957,7 @@ protected:
|
|||
/* Sliding midpoint rule: find a split that is close to the spatial median */
|
||||
axis = m_aabb.getLargestAxis();
|
||||
|
||||
Scalar midpoint = (Scalar) 0.5f
|
||||
Scalar midpoint = (Scalar) 0.5f
|
||||
* (m_aabb.max[axis]+m_aabb.min[axis]);
|
||||
|
||||
size_t nLT = std::count_if(rangeStart, rangeEnd,
|
||||
|
@ -975,18 +975,18 @@ protected:
|
|||
CoordinateOrdering(m_nodes, axis));
|
||||
};
|
||||
break;
|
||||
|
||||
|
||||
case EVoxelVolume: {
|
||||
Float bestCost = std::numeric_limits<Float>::infinity();
|
||||
|
||||
for (int dim=0; dim<PointType::dim; ++dim) {
|
||||
std::sort(rangeStart, rangeEnd,
|
||||
std::sort(rangeStart, rangeEnd,
|
||||
CoordinateOrdering(m_nodes, dim));
|
||||
|
||||
size_t numLeft = 1, numRight = count-2;
|
||||
AABBType leftAABB(m_aabb), rightAABB(m_aabb);
|
||||
Float invVolume = 1.0f / m_aabb.getVolume();
|
||||
for (typename std::vector<IndexType>::iterator it = rangeStart+1;
|
||||
for (typename std::vector<IndexType>::iterator it = rangeStart+1;
|
||||
it != rangeEnd; ++it) {
|
||||
++numLeft; --numRight;
|
||||
Float pos = m_nodes[*it].getPosition()[dim];
|
||||
|
@ -1011,10 +1011,10 @@ protected:
|
|||
splitNode.setAxis(axis);
|
||||
splitNode.setLeaf(false);
|
||||
|
||||
if (split+1 != rangeEnd)
|
||||
if (split+1 != rangeEnd)
|
||||
splitNode.setRightIndex((IndexType) (rangeStart - base),
|
||||
(IndexType) (split + 1 - base));
|
||||
else
|
||||
else
|
||||
splitNode.setRightIndex((IndexType) (rangeStart - base), 0);
|
||||
|
||||
splitNode.setLeftIndex((IndexType) (rangeStart - base),
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Temporarily wait for the flag to be set to true
|
||||
*
|
||||
*
|
||||
* Similar to \ref wait(), but also uses a time value given
|
||||
* in milliseconds. A return value of \c false signals
|
||||
* that a timeout has occurred.
|
||||
|
@ -106,31 +106,31 @@ private:
|
|||
class MTS_EXPORT_CORE ConditionVariable : public Object {
|
||||
public:
|
||||
/**
|
||||
* \brief Create a new condition variable. Also takes a
|
||||
* \brief Create a new condition variable. Also takes a
|
||||
* mutex, which is later used by wait(). If none is specified,
|
||||
* a new mutex instance will be created.
|
||||
*/
|
||||
ConditionVariable(Mutex *mutex = NULL);
|
||||
|
||||
/**
|
||||
* \brief Send a signal, which wakes up at least one of
|
||||
* the waiting threads.
|
||||
*
|
||||
* The calling thread does not have to hold the lock,
|
||||
* but more predictable scheduling will occur if this is the
|
||||
* \brief Send a signal, which wakes up at least one of
|
||||
* the waiting threads.
|
||||
*
|
||||
* The calling thread does not have to hold the lock,
|
||||
* but more predictable scheduling will occur if this is the
|
||||
* case.
|
||||
*/
|
||||
void signal();
|
||||
|
||||
/**
|
||||
* \brief Send a signal, which wakes up any waiting threads.
|
||||
* \brief Send a signal, which wakes up any waiting threads.
|
||||
*
|
||||
* The calling thread does not have to hold the lock, but more
|
||||
* predictable scheduling will occur if this is the case.
|
||||
*/
|
||||
void broadcast();
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Wait for a signal and release the lock in the meanwhile.
|
||||
*
|
||||
* Assumes that the lock specified in the constructor has
|
||||
|
@ -224,7 +224,7 @@ public:
|
|||
inline bool operator!() const {
|
||||
return !ownsLock();
|
||||
}
|
||||
|
||||
|
||||
inline bool ownsLock() const {
|
||||
return is_locked;
|
||||
}
|
||||
|
|
|
@ -63,13 +63,13 @@ MTS_NAMESPACE_BEGIN
|
|||
/*! \addtogroup libcore */
|
||||
/*! @{ */
|
||||
|
||||
/// Assert that a condition is true (to be used \a inside of classes that derive from \ref Object)
|
||||
/// Assert that a condition is true (to be used \a inside of classes that derive from \ref Object)
|
||||
#define Assert(cond) do { \
|
||||
if (!(cond)) Log(EError, "Assertion \"%s\" failed in %s:%i", \
|
||||
#cond, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
/// ``Static'' assertion (to be used \a outside of classes that derive from \ref Object)
|
||||
/// ``Static'' assertion (to be used \a outside of classes that derive from \ref Object)
|
||||
#define SAssert(cond) do { \
|
||||
if (!(cond)) SLog(EError, "Assertion \"%s\" failed in %s:%i", \
|
||||
#cond, __FILE__, __LINE__); \
|
||||
|
@ -95,13 +95,13 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/*! @} */
|
||||
|
||||
/**
|
||||
/**
|
||||
* \headerfile mitsuba/core/logger.h mitsuba/mitsuba.h
|
||||
* \brief Responsible for processing log messages
|
||||
*
|
||||
* Upon receiving a log message, the Logger class invokes
|
||||
*
|
||||
* Upon receiving a log message, the Logger class invokes
|
||||
* a Formatter to convert it into a human-readable form.
|
||||
* Following that, it sends this information to every
|
||||
* Following that, it sends this information to every
|
||||
* registered Appender.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -122,8 +122,8 @@ public:
|
|||
* \note This function is not exposed in the Python bindings.
|
||||
* Instead, please use \cc mitsuba.core.Log
|
||||
*/
|
||||
void log(ELogLevel level, const Class *theClass,
|
||||
const char *fileName, int lineNumber,
|
||||
void log(ELogLevel level, const Class *theClass,
|
||||
const char *fileName, int lineNumber,
|
||||
const char *fmt, ...);
|
||||
|
||||
/**
|
||||
|
@ -145,7 +145,7 @@ public:
|
|||
void setLogLevel(ELogLevel level);
|
||||
|
||||
/**
|
||||
* \brief Set the error log level (this level and anything
|
||||
* \brief Set the error log level (this level and anything
|
||||
* above will throw exceptions).
|
||||
*
|
||||
* The value provided here can be used for instance to turn
|
||||
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
/// Return the current log level
|
||||
inline ELogLevel getLogLevel() const { return m_logLevel; }
|
||||
|
||||
|
||||
/// Return the current error level
|
||||
inline ELogLevel getErrorLevel() const { return m_errorLevel; }
|
||||
|
||||
|
@ -175,7 +175,7 @@ public:
|
|||
|
||||
/// Return one of the appenders
|
||||
inline Appender *getAppender(size_t index) { return m_appenders[index]; }
|
||||
|
||||
|
||||
/// Return one of the appenders
|
||||
inline const Appender *getAppender(size_t index) const { return m_appenders[index]; }
|
||||
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
|
||||
/// Return the logger's formatter implementation
|
||||
inline Formatter *getFormatter() { return m_formatter; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the contents of the log file as a string (if it exists)
|
||||
*
|
||||
|
@ -197,7 +197,7 @@ public:
|
|||
|
||||
/// Initialize logging
|
||||
static void staticInitialization();
|
||||
|
||||
|
||||
/// Shutdown logging
|
||||
static void staticShutdown();
|
||||
|
||||
|
@ -213,7 +213,7 @@ private:
|
|||
std::vector<Appender *> m_appenders;
|
||||
size_t m_warningCount;
|
||||
};
|
||||
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __MITSUBA_CORE_LOGGER_H_ */
|
||||
|
|
|
@ -39,17 +39,17 @@ MTS_NAMESPACE_BEGIN
|
|||
* The original code is under the following license:
|
||||
*
|
||||
* <pre>
|
||||
* Copyright (c) 2010, Tim Day <timday@timday.com>
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* Copyright (c) 2010, Tim Day <timday@timday.com>
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* </pre>
|
||||
*
|
||||
|
@ -85,11 +85,11 @@ public:
|
|||
typename cache_type::right_iterator
|
||||
src = m_cache.right.begin();
|
||||
if (m_cleanupFunction) {
|
||||
while (src != m_cache.right.end())
|
||||
while (src != m_cache.right.end())
|
||||
m_cleanupFunction((*src++).info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool isFull() const {
|
||||
return m_cache.size() == m_capacity;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
// Obtain value of the cached function for k
|
||||
V get(const K& k, bool &hit) {
|
||||
// Attempt to find existing record
|
||||
const typename cache_type::left_iterator it
|
||||
const typename cache_type::left_iterator it
|
||||
= m_cache.left.find(k);
|
||||
|
||||
if (it == m_cache.left.end()) {
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
template <typename IT> void get_keys(IT dst) const {
|
||||
typename cache_type::right_const_reverse_iterator
|
||||
src = m_cache.right.rbegin();
|
||||
while (src != m_cache.right.rend())
|
||||
while (src != m_cache.right.rend())
|
||||
*dst++=(*src++).second;
|
||||
}
|
||||
protected:
|
||||
|
|
|
@ -34,9 +34,9 @@ template <int M, int N, typename T> struct Matrix {
|
|||
public:
|
||||
T m[M][N];
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Construct a new MxN matrix without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the matrix will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -328,7 +328,7 @@ public:
|
|||
*
|
||||
* Based on the implementation in JAMA.
|
||||
*/
|
||||
template <int K> void cholSolve(const Matrix<M, K, T> &B,
|
||||
template <int K> void cholSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X) const;
|
||||
|
||||
/**
|
||||
|
@ -340,11 +340,11 @@ public:
|
|||
*
|
||||
* Based on the implementation in JAMA.
|
||||
*/
|
||||
template <int K> void luSolve(const Matrix<M, K, T> &B,
|
||||
template <int K> void luSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X, int piv[M]) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the determinant of a decomposed matrix
|
||||
* \brief Compute the determinant of a decomposed matrix
|
||||
* created by \ref lu()
|
||||
*
|
||||
* \param pivsign The sign of the pivoting permutation returned
|
||||
|
@ -355,7 +355,7 @@ public:
|
|||
T luDet(int pivsign) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the determinant of a decomposed matrix
|
||||
* \brief Compute the determinant of a decomposed matrix
|
||||
* created by \ref chol()
|
||||
*/
|
||||
|
||||
|
@ -397,7 +397,7 @@ public:
|
|||
bool invert(Matrix &target) const;
|
||||
|
||||
/**
|
||||
* \brief Perform a symmetric eigendecomposition of a square matrix
|
||||
* \brief Perform a symmetric eigendecomposition of a square matrix
|
||||
* into Q and D.
|
||||
*
|
||||
* Based on the implementation in JAMA.
|
||||
|
@ -468,7 +468,7 @@ public:
|
|||
/// Initialize the matrix from two 2D column vectors
|
||||
explicit inline Matrix2x2(const Vector2 &v1, const Vector2 &v2) {
|
||||
m[0][0] = v1.x; m[0][1] = v2.x;
|
||||
m[1][0] = v1.y; m[1][1] = v2.y;
|
||||
m[1][0] = v1.y; m[1][1] = v2.y;
|
||||
}
|
||||
|
||||
/// Unserialize a matrix from a stream
|
||||
|
@ -480,7 +480,7 @@ public:
|
|||
/// Initialize with the given values
|
||||
inline Matrix2x2(Float a00, Float a01, Float a10, Float a11) {
|
||||
m[0][0] = a00; m[0][1] = a01;
|
||||
m[1][0] = a10; m[1][1] = a11;
|
||||
m[1][0] = a10; m[1][1] = a11;
|
||||
}
|
||||
|
||||
/// Return the determinant (Faster than Matrix::det)
|
||||
|
@ -563,7 +563,7 @@ public:
|
|||
|
||||
/// Unserialize a matrix from a stream
|
||||
explicit inline Matrix3x3(Stream *stream) : Matrix<3, 3, Float>(stream) { }
|
||||
|
||||
|
||||
/// Copy constructor
|
||||
inline Matrix3x3(const Matrix<3, 3, Float> &mtx) : Matrix<3, 3, Float>(mtx) { }
|
||||
|
||||
|
@ -717,7 +717,7 @@ struct MTS_EXPORT_CORE Matrix4x4 : public Matrix<4, 4, Float> {
|
|||
};
|
||||
|
||||
/// Matrix multiplication (creates a temporary)
|
||||
template <typename T, int M1, int N1, int M2, int N2> inline Matrix<M1, N2, T>
|
||||
template <typename T, int M1, int N1, int M2, int N2> inline Matrix<M1, N2, T>
|
||||
operator*(const Matrix<M1, N1, T> &mat1, const Matrix<M2, N2, T> &mat2) {
|
||||
BOOST_STATIC_ASSERT(N1 == M2);
|
||||
Matrix<M1, N2, T> result;
|
||||
|
@ -750,7 +750,7 @@ extern MTS_EXPORT_CORE bool eig3(Matrix3x3 &m, Float lambda[3]);
|
|||
|
||||
/**
|
||||
* \brief Fast non-iterative 3x3 eigenvalue decomposition
|
||||
*
|
||||
*
|
||||
* \param m
|
||||
* Matrix in question -- will be replaced with the eigenvectors
|
||||
* \param lambda
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/* Implementations are based on the public domain JAMA library */
|
||||
|
||||
|
||||
template <int M, int N, typename T> bool Matrix<M, N, T>::chol(Matrix &L) const {
|
||||
BOOST_STATIC_ASSERT(M == N);
|
||||
|
||||
|
@ -21,15 +21,15 @@ template <int M, int N, typename T> bool Matrix<M, N, T>::chol(Matrix &L) const
|
|||
if (d <= 0)
|
||||
return false;
|
||||
L.m[j][j] = std::sqrt(std::max(d, (T) 0));
|
||||
for (int k = j+1; k < N; k++)
|
||||
for (int k = j+1; k < N; k++)
|
||||
L.m[j][k] = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <int M, int N, typename T> template <int K> void Matrix<M, N, T>::cholSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X) const {
|
||||
template <int M, int N, typename T> template <int K> void Matrix<M, N, T>::cholSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X) const {
|
||||
BOOST_STATIC_ASSERT(M == N);
|
||||
|
||||
memcpy(X.m, B.m, sizeof(T)*M*K);
|
||||
|
@ -67,12 +67,12 @@ template <int M, int N, typename T> bool Matrix<M, N, T>::lu(Matrix &LU,
|
|||
// Find pivot.
|
||||
int p = k;
|
||||
for (int i = k+1; i < M; i++)
|
||||
if (std::abs(LU.m[i][k]) > std::abs(LU.m[p][k]))
|
||||
if (std::abs(LU.m[i][k]) > std::abs(LU.m[p][k]))
|
||||
p = i;
|
||||
|
||||
// Exchange if necessary.
|
||||
if (p != k) {
|
||||
for (int j = 0; j < N; j++)
|
||||
for (int j = 0; j < N; j++)
|
||||
std::swap(LU.m[p][j], LU.m[k][j]);
|
||||
std::swap(piv[p], piv[k]);
|
||||
pivsign = -pivsign;
|
||||
|
@ -93,19 +93,19 @@ template <int M, int N, typename T> bool Matrix<M, N, T>::lu(Matrix &LU,
|
|||
return true;
|
||||
}
|
||||
|
||||
template <int M, int N, typename T> template <int K> void Matrix<M, N, T>::luSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X, int piv[M]) const {
|
||||
template <int M, int N, typename T> template <int K> void Matrix<M, N, T>::luSolve(const Matrix<M, K, T> &B,
|
||||
Matrix<M, K, T> &X, int piv[M]) const {
|
||||
BOOST_STATIC_ASSERT(M == N);
|
||||
|
||||
// Copy right hand side with pivoting
|
||||
for (int i=0; i<M; ++i)
|
||||
for (int j=0; j<K; ++j)
|
||||
for (int j=0; j<K; ++j)
|
||||
X.m[i][j] = B.m[piv[i]][j];
|
||||
|
||||
// Solve L*Y = B(piv,:)
|
||||
for (int k = 0; k < N; k++)
|
||||
for (int i = k+1; i < N; i++)
|
||||
for (int j = 0; j < K; j++)
|
||||
for (int j = 0; j < K; j++)
|
||||
X.m[i][j] -= X.m[k][j]*m[i][k];
|
||||
|
||||
// Solve U*X = Y;
|
||||
|
@ -193,7 +193,7 @@ template <int M, int N, typename T> bool Matrix<M, N, T>::invert(Matrix &target)
|
|||
}
|
||||
|
||||
// Symmetric Householder reduction to tridiagonal form.
|
||||
template <int M, int N, typename T> void
|
||||
template <int M, int N, typename T> void
|
||||
Matrix<M, N, T>::tred2(T V[M][N], T d[N], T e[N]) {
|
||||
// This is derived from the Algol procedures tred2 by
|
||||
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||
|
@ -202,7 +202,7 @@ template <int M, int N, typename T> void
|
|||
|
||||
for (int j = 0; j < N; j++)
|
||||
d[j] = V[N - 1][j];
|
||||
|
||||
|
||||
// Householder reduction to tridiagonal form.
|
||||
for (int i = N - 1; i > 0; i--) {
|
||||
// Scale to avoid under/overflow.
|
||||
|
@ -225,7 +225,7 @@ template <int M, int N, typename T> void
|
|||
d[k] /= scale;
|
||||
h += d[k] * d[k];
|
||||
}
|
||||
T f = d[i - 1],
|
||||
T f = d[i - 1],
|
||||
g = std::sqrt(h);
|
||||
|
||||
if (f > 0)
|
||||
|
@ -300,7 +300,7 @@ template <int M, int N, typename T> void
|
|||
}
|
||||
|
||||
// Symmetric tridiagonal QL algorithm.
|
||||
template <int M, int N, typename T> void
|
||||
template <int M, int N, typename T> void
|
||||
Matrix<M, N, T>::tql2(T V[M][N], T d[N], T e[N]) {
|
||||
// This is derived from the Algol procedures tql2, by
|
||||
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <mitsuba/mitsuba.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
/// Create a new memory pool with an initial set of 128 entries
|
||||
#define MTS_MEMPOOL_GRANULARITY 128
|
||||
|
||||
|
@ -31,12 +31,12 @@ MTS_NAMESPACE_BEGIN
|
|||
#define MTS_DEBUG_MEMPOOL 0
|
||||
|
||||
/**
|
||||
* \brief Basic memory pool for efficient allocation and deallocation
|
||||
* \brief Basic memory pool for efficient allocation and deallocation
|
||||
* of objects of the same type.
|
||||
*
|
||||
* This class attempts to keep most instances contiguous in memory, while
|
||||
* having only minimal interaction with the underlying allocator.
|
||||
*
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
template <typename T> class BasicMemoryPool {
|
||||
|
@ -82,12 +82,12 @@ public:
|
|||
inline size_t size() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
|
||||
/// Check if every entry has been released
|
||||
bool unused() const {
|
||||
return m_free.size() == m_size;
|
||||
}
|
||||
|
||||
|
||||
/// Return a human-readable description
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/** \brief Simple memory buffer-based stream with automatic memory management
|
||||
*
|
||||
* The underlying memory storage of this implementation dynamically expands
|
||||
/** \brief Simple memory buffer-based stream with automatic memory management
|
||||
*
|
||||
* The underlying memory storage of this implementation dynamically expands
|
||||
* as data is written to the stream.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Create a memory stream, which operates on a
|
||||
* pre-allocated buffer.
|
||||
* pre-allocated buffer.
|
||||
*
|
||||
* A memory stream created in this way will never resize the
|
||||
* underlying buffer. An exception is thrown e.g. when attempting
|
||||
|
@ -59,13 +59,13 @@ public:
|
|||
|
||||
/// Return the underlying data
|
||||
inline uint8_t *getData() { return m_data; }
|
||||
|
||||
|
||||
/// Return the underlying data (const version)
|
||||
inline const uint8_t *getData() const { return m_data; }
|
||||
|
||||
/// Return the underlying data at the current position
|
||||
inline uint8_t *getCurrentData() { return m_data + m_pos; }
|
||||
|
||||
|
||||
/// Return the underlying data at the current position (const version)
|
||||
inline const uint8_t *getCurrentData() const { return m_data + m_pos; }
|
||||
|
||||
|
|
|
@ -24,15 +24,15 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/** \brief Abstract interface for objects that reference shared network
|
||||
/** \brief Abstract interface for objects that reference shared network
|
||||
* resources.
|
||||
*
|
||||
* When a networked object is serialized as part of a parallel process
|
||||
* executed on multiple machines, the object is first given the
|
||||
* opportunity to bind named resources to the process (by a call to
|
||||
* \ref bindUsedResources()). These will then be distributed to all
|
||||
* participating compute servers. Once unserialized on the remote side,
|
||||
* \ref wakeup() is called to let the object re-associate with the
|
||||
*
|
||||
* When a networked object is serialized as part of a parallel process
|
||||
* executed on multiple machines, the object is first given the
|
||||
* opportunity to bind named resources to the process (by a call to
|
||||
* \ref bindUsedResources()). These will then be distributed to all
|
||||
* participating compute servers. Once unserialized on the remote side,
|
||||
* \ref wakeup() is called to let the object re-associate with the
|
||||
* shared resources.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -58,7 +58,7 @@ protected:
|
|||
inline NetworkedObject(const Properties &props) : ConfigurableObject(props) { }
|
||||
|
||||
/// Unserialize a configurable object
|
||||
inline NetworkedObject(Stream *stream, InstanceManager *manager)
|
||||
inline NetworkedObject(Stream *stream, InstanceManager *manager)
|
||||
: ConfigurableObject(stream, manager) {
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,9 +28,9 @@ MTS_NAMESPACE_BEGIN
|
|||
* \headerfile mitsuba/core/normal.h mitsuba/mitsuba.h
|
||||
* \brief Three-dimensional normal data structure
|
||||
*
|
||||
* Internally represented using floating point numbers of the chosen
|
||||
* Internally represented using floating point numbers of the chosen
|
||||
* compile-time precision. The main difference of this data structure
|
||||
* when compared to \ref TVector3<Float> is in how instances of
|
||||
* when compared to \ref TVector3<Float> is in how instances of
|
||||
* \ref Normal are treated by linear transformations.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -38,7 +38,7 @@ MTS_NAMESPACE_BEGIN
|
|||
*/
|
||||
struct Normal : public TVector3<Float> {
|
||||
/** \brief Construct a new normal without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the normal will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
|
|
@ -28,7 +28,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \headerfile mitsuba/core/object.h mitsuba/mitsuba.h
|
||||
* \brief Parent of all Mitsuba classes.
|
||||
*
|
||||
* Contains functions relevant to every object such as reference counting,
|
||||
* Contains functions relevant to every object such as reference counting,
|
||||
* limited type introspection and lifetime management.
|
||||
*
|
||||
* \sa ref, Class
|
||||
|
@ -37,7 +37,7 @@ MTS_NAMESPACE_BEGIN
|
|||
*/
|
||||
class MTS_EXPORT_CORE Object {
|
||||
public:
|
||||
/// Construct a new object
|
||||
/// Construct a new object
|
||||
Object();
|
||||
|
||||
/// Return the current reference count
|
||||
|
@ -48,10 +48,10 @@ public:
|
|||
*/
|
||||
void incRef() const;
|
||||
|
||||
/** \brief Decrease the reference count of
|
||||
* the object and possibly deallocate it.
|
||||
/** \brief Decrease the reference count of
|
||||
* the object and possibly deallocate it.
|
||||
*
|
||||
* The object will automatically be deallocated once
|
||||
* The object will automatically be deallocated once
|
||||
* the reference count reaches zero.
|
||||
*/
|
||||
void decRef() const;
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
*/
|
||||
virtual std::string toString() const;
|
||||
|
||||
/** \brief Initializes the built-in reference count
|
||||
/** \brief Initializes the built-in reference count
|
||||
* debugger (if enabled)
|
||||
*/
|
||||
static void staticInitialization();
|
||||
|
|
|
@ -30,9 +30,9 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Lock-free linked list data structure
|
||||
*
|
||||
* This class provides a very basic linked list data structure whose primary
|
||||
* This class provides a very basic linked list data structure whose primary
|
||||
* purpose it is to efficiently service append operations from multiple parallel
|
||||
* threads. These are internally realized via atomic compare and exchange
|
||||
* threads. These are internally realized via atomic compare and exchange
|
||||
* operations, meaning that no lock must be acquired.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -79,7 +79,7 @@ private:
|
|||
* This class is currently used to implement BSSRDF evaluation
|
||||
* with irradiance point clouds.
|
||||
*
|
||||
* The \c Item template parameter must implement a function
|
||||
* The \c Item template parameter must implement a function
|
||||
* named <tt>getPosition()</tt> that returns a \ref Point.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
*
|
||||
* By default, the maximum tree depth is set to 16
|
||||
*/
|
||||
inline StaticOctree(const AABB &aabb, uint32_t maxDepth = 24, uint32_t maxItems = 8) :
|
||||
inline StaticOctree(const AABB &aabb, uint32_t maxDepth = 24, uint32_t maxItems = 8) :
|
||||
m_aabb(aabb), m_maxDepth(maxDepth), m_maxItems(maxItems), m_root(NULL) { }
|
||||
|
||||
/// Release all memory
|
||||
|
@ -220,7 +220,7 @@ protected:
|
|||
OctreeNode *result = new OctreeNode();
|
||||
for (int i=0; i<8; i++) {
|
||||
AABB bounds = childBounds(i, aabb, center);
|
||||
|
||||
|
||||
uint32_t *it = start + nestedCounts[i];
|
||||
result->children[i] = build(bounds, depth+1, base, temp, start, it);
|
||||
start = it;
|
||||
|
@ -243,7 +243,7 @@ protected:
|
|||
/**
|
||||
* \brief Generic multiple-reference octree with support for parallel dynamic updates
|
||||
*
|
||||
* Based on the excellent implementation in PBRT. Modifications are
|
||||
* Based on the excellent implementation in PBRT. Modifications are
|
||||
* the addition of a bounding sphere query and support for multithreading.
|
||||
*
|
||||
* This class is currently used to implement irradiance caching.
|
||||
|
@ -257,11 +257,11 @@ public:
|
|||
*
|
||||
* By default, the maximum tree depth is set to 24
|
||||
*/
|
||||
inline DynamicOctree(const AABB &aabb, uint32_t maxDepth = 24)
|
||||
inline DynamicOctree(const AABB &aabb, uint32_t maxDepth = 24)
|
||||
: m_aabb(aabb), m_maxDepth(maxDepth) {
|
||||
}
|
||||
|
||||
/// Insert an item with the specified cell coverage
|
||||
/// Insert an item with the specified cell coverage
|
||||
inline void insert(const Item &value, const AABB &coverage) {
|
||||
insert(&m_root, m_aabb, value, coverage,
|
||||
coverage.getExtents().lengthSquared(), 0);
|
||||
|
@ -280,7 +280,7 @@ public:
|
|||
return;
|
||||
searchSphere(&m_root, m_aabb, sphere, functor);
|
||||
}
|
||||
|
||||
|
||||
inline const AABB &getAABB() const { return m_aabb; }
|
||||
private:
|
||||
struct OctreeNode {
|
||||
|
@ -313,12 +313,12 @@ private:
|
|||
return childAABB;
|
||||
}
|
||||
|
||||
void insert(OctreeNode *node, const AABB &nodeAABB, const Item &value,
|
||||
void insert(OctreeNode *node, const AABB &nodeAABB, const Item &value,
|
||||
const AABB &coverage, Float diag2, uint32_t depth) {
|
||||
/* Add the data item to the current octree node if the max. tree
|
||||
depth is reached or the data item's coverage area is smaller
|
||||
than the current node size */
|
||||
if (depth == m_maxDepth ||
|
||||
if (depth == m_maxDepth ||
|
||||
(nodeAABB.getExtents().lengthSquared() < diag2)) {
|
||||
node->data.append(value);
|
||||
return;
|
||||
|
@ -352,7 +352,7 @@ private:
|
|||
}
|
||||
|
||||
/// Internal lookup procedure - const version
|
||||
template <typename Functor> inline void lookup(const OctreeNode *node,
|
||||
template <typename Functor> inline void lookup(const OctreeNode *node,
|
||||
const AABB &nodeAABB, const Point &p, Functor &functor) const {
|
||||
const Point center = nodeAABB.getCenter();
|
||||
|
||||
|
@ -363,7 +363,7 @@ private:
|
|||
}
|
||||
|
||||
int child = (p.x > center.x ? 4 : 0)
|
||||
+ (p.y > center.y ? 2 : 0)
|
||||
+ (p.y > center.y ? 2 : 0)
|
||||
+ (p.z > center.z ? 1 : 0);
|
||||
|
||||
OctreeNode *childNode = node->children[child];
|
||||
|
@ -374,8 +374,8 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Functor> inline void searchSphere(OctreeNode *node,
|
||||
const AABB &nodeAABB, const BSphere &sphere,
|
||||
template <typename Functor> inline void searchSphere(OctreeNode *node,
|
||||
const AABB &nodeAABB, const BSphere &sphere,
|
||||
Functor &functor) {
|
||||
const Point center = nodeAABB.getCenter();
|
||||
|
||||
|
@ -386,7 +386,7 @@ private:
|
|||
}
|
||||
|
||||
// Potential for much optimization..
|
||||
for (int child=0; child<8; ++child) {
|
||||
for (int child=0; child<8; ++child) {
|
||||
if (node->children[child]) {
|
||||
const AABB childAABB(childBounds(child, nodeAABB, center));
|
||||
if (childAABB.overlaps(sphere))
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
#ifdef __MSVC__
|
||||
#define MTS_DONT_EXPORT // not supported on MSVC
|
||||
#define SIZE_T_FMT "%Iu"
|
||||
#define BOOST_FILESYSTEM_NO_LIB
|
||||
#define BOOST_SYSTEM_NO_LIB
|
||||
#define BOOST_FILESYSTEM_NO_LIB
|
||||
#define BOOST_SYSTEM_NO_LIB
|
||||
#define MTS_EXPORT __declspec(dllexport)
|
||||
#define MTS_IMPORT __declspec(dllimport)
|
||||
#define MTS_MAY_ALIAS // not supported on Windows
|
||||
|
@ -159,7 +159,7 @@
|
|||
#endif
|
||||
|
||||
/* Compile with Boost::Filesystem v3 */
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -186,8 +186,8 @@ extern MTS_EXPORT_CORE void __mts_set_appdefaults();
|
|||
#define MTS_AUTORELEASE_END() __mts_autorelease_end();
|
||||
#define MTS_AMBIGUOUS_SIZE_T 1
|
||||
#else
|
||||
#define MTS_AUTORELEASE_BEGIN()
|
||||
#define MTS_AUTORELEASE_END()
|
||||
#define MTS_AUTORELEASE_BEGIN()
|
||||
#define MTS_AUTORELEASE_END()
|
||||
#endif
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Abstract plugin class -- represents loadable configurable objects
|
||||
* and utilities.
|
||||
*
|
||||
*
|
||||
* Please see the \ref ConfigurableObject and \ref Utility classes for
|
||||
* details.
|
||||
*
|
||||
|
@ -42,11 +42,11 @@ public:
|
|||
|
||||
/// Virtual destructor
|
||||
virtual ~Plugin();
|
||||
|
||||
|
||||
/// Is this a configurable object plugin or an utility plugin?
|
||||
bool isUtility() const;
|
||||
|
||||
/// Return an instance of the class implemented by this plugin
|
||||
/// Return an instance of the class implemented by this plugin
|
||||
ConfigurableObject *createInstance(const Properties &props) const;
|
||||
|
||||
/// Return an utility instance (if this is an utility plugin)
|
||||
|
@ -54,10 +54,10 @@ public:
|
|||
|
||||
/// Return a description of this plugin
|
||||
std::string getDescription() const;
|
||||
|
||||
|
||||
/// Return the path of this plugin
|
||||
const fs::path &getPath() const;
|
||||
|
||||
|
||||
/// Return a short name of this plugin
|
||||
const std::string &getShortName() const;
|
||||
protected:
|
||||
|
@ -74,13 +74,13 @@ private:
|
|||
* \brief The plugin manager is responsible for resolving and
|
||||
* loading external plugins.
|
||||
*
|
||||
* Ordinarily, this class will be used by making repeated calls to
|
||||
* Ordinarily, this class will be used by making repeated calls to
|
||||
* the \ref createObject() methods. The generated instances are then
|
||||
* assembled into a final object graph, such as a scene. One such
|
||||
* examples is the \ref SceneHandler class, which parses an XML
|
||||
* scene file by esentially translating the XML elements into calls
|
||||
* scene file by esentially translating the XML elements into calls
|
||||
* to \ref createObject().
|
||||
*
|
||||
*
|
||||
* Since this kind of construction method can be tiresome when
|
||||
* dynamically building scenes from Python, this class has an
|
||||
* additional Python-only method \c create(), which works as follows:
|
||||
|
@ -130,13 +130,13 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Instantiate a plugin, verify its type,
|
||||
* and return the newly created instance.
|
||||
*
|
||||
* and return the newly created instance.
|
||||
*
|
||||
* \param classType Expected type of the plugin. An
|
||||
* exception will be thrown if it turns out not
|
||||
* to derive from this class.
|
||||
* \param props A \ref Properties instance containing
|
||||
* all information required to find and construct
|
||||
* all information required to find and construct
|
||||
* the plugin.
|
||||
*/
|
||||
ConfigurableObject *createObject(
|
||||
|
@ -146,10 +146,10 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Instantiate a plugin and return the new
|
||||
* instance (without verifying its type).
|
||||
*
|
||||
* instance (without verifying its type).
|
||||
*
|
||||
* \param props A \ref Properties instance containing
|
||||
* all information required to find and construct
|
||||
* all information required to find and construct
|
||||
* the plugin.
|
||||
*/
|
||||
ConfigurableObject *createObject(
|
||||
|
@ -165,7 +165,7 @@ public:
|
|||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
PluginManager();
|
||||
|
||||
|
||||
/// Destruct and unload all plugins
|
||||
~PluginManager();
|
||||
private:
|
||||
|
|
|
@ -26,10 +26,10 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/**
|
||||
* \brief Discrete probability distribution
|
||||
*
|
||||
*
|
||||
* This data structure can be used to transform uniformly distributed
|
||||
* samples to a stored discrete probability distribution.
|
||||
*
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
struct DiscreteDistribution {
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
m_sum = m_cdf[m_cdf.size()-1];
|
||||
if (m_sum > 0) {
|
||||
m_normalization = 1.0f / m_sum;
|
||||
for (size_t i=1; i<m_cdf.size(); ++i)
|
||||
for (size_t i=1; i<m_cdf.size(); ++i)
|
||||
m_cdf[i] *= m_normalization;
|
||||
m_cdf[m_cdf.size()-1] = 1.0f;
|
||||
m_normalized = true;
|
||||
|
@ -115,14 +115,14 @@ public:
|
|||
|
||||
/**
|
||||
* \brief %Transform a uniformly distributed sample to the stored distribution
|
||||
*
|
||||
*
|
||||
* \param[in] sampleValue
|
||||
* An uniformly distributed sample on [0,1]
|
||||
* \return
|
||||
* The discrete index associated with the sample
|
||||
*/
|
||||
inline size_t sample(Float sampleValue) const {
|
||||
std::vector<Float>::const_iterator entry =
|
||||
std::vector<Float>::const_iterator entry =
|
||||
std::lower_bound(m_cdf.begin(), m_cdf.end(), sampleValue);
|
||||
size_t index = std::min(m_cdf.size()-2,
|
||||
(size_t) std::max((ptrdiff_t) 0, entry - m_cdf.begin() - 1));
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief %Transform a uniformly distributed sample to the stored distribution
|
||||
*
|
||||
*
|
||||
* \param[in] sampleValue
|
||||
* An uniformly distributed sample on [0,1]
|
||||
* \param[out] pdf
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief %Transform a uniformly distributed sample to the stored distribution
|
||||
*
|
||||
*
|
||||
* The original sample is value adjusted so that it can be "reused".
|
||||
*
|
||||
* \param[in, out] sampleValue
|
||||
|
@ -169,8 +169,8 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief %Transform a uniformly distributed sample.
|
||||
*
|
||||
* \brief %Transform a uniformly distributed sample.
|
||||
*
|
||||
* The original sample is value adjusted so that it can be "reused".
|
||||
*
|
||||
* \param[in,out]
|
||||
|
@ -193,7 +193,7 @@ public:
|
|||
*/
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "DiscreteDistribution[sum=" << m_sum << ", normalized="
|
||||
oss << "DiscreteDistribution[sum=" << m_sum << ", normalized="
|
||||
<< (int) m_normalized << ", cdf={";
|
||||
for (size_t i=0; i<m_cdf.size(); ++i) {
|
||||
oss << m_cdf[i];
|
||||
|
@ -217,23 +217,23 @@ namespace math {
|
|||
/// Index of the alias entry
|
||||
Index index;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create the lookup table needed for Walker's alias sampling
|
||||
* method implemented in \ref sampleAlias(). Runs in linear time.
|
||||
*
|
||||
* The basic idea of this method is that one can "redistribute" the
|
||||
* The basic idea of this method is that one can "redistribute" the
|
||||
* probability mass of a distribution to make it uniform. This
|
||||
* this can be done in a way such that the probability of each entry in
|
||||
* the "flattened" PMF consists of probability mass from at most *two*
|
||||
* entries in the original PMF. That then leads to an efficient O(1)
|
||||
* sampling algorithm with a O(n) preprocessing step to set up this
|
||||
* the "flattened" PMF consists of probability mass from at most *two*
|
||||
* entries in the original PMF. That then leads to an efficient O(1)
|
||||
* sampling algorithm with a O(n) preprocessing step to set up this
|
||||
* special decomposition.
|
||||
*
|
||||
* The downside of this method is that it generally does not preserve
|
||||
* the nice stratification properties of QMC number sequences.
|
||||
*
|
||||
* \return The original (un-normalized) sum of all probabilities
|
||||
* \return The original (un-normalized) sum of all probabilities
|
||||
* in \c pmf.
|
||||
*/
|
||||
template <typename Scalar, typename QuantizedScalar, typename Index> float makeAliasTable(
|
||||
|
@ -241,15 +241,15 @@ namespace math {
|
|||
/* Allocate temporary storage for classification purposes */
|
||||
Index *c = new Index[size],
|
||||
*c_short = c - 1, *c_long = c + size;
|
||||
|
||||
|
||||
/* Begin by computing the normalization constant */
|
||||
Scalar sum = 0;
|
||||
for (size_t i=0; i<size; ++i)
|
||||
sum += pmf[i];
|
||||
|
||||
|
||||
Scalar normalization = (Scalar) 1 / sum;
|
||||
for (Index i=0; i<size; ++i) {
|
||||
/* For each entry, determine whether there is
|
||||
/* For each entry, determine whether there is
|
||||
"too little" or "too much" probability mass */
|
||||
Scalar value = size * normalization * pmf[i];
|
||||
if (value < 1)
|
||||
|
@ -259,52 +259,52 @@ namespace math {
|
|||
tbl[i].prob = value;
|
||||
tbl[i].index = i;
|
||||
}
|
||||
|
||||
/* Perform pairwise exchanges while there are entries
|
||||
|
||||
/* Perform pairwise exchanges while there are entries
|
||||
with too much probability mass */
|
||||
for (Index i=0; i < size-1 && c_long - c < size; ++i) {
|
||||
Index short_index = c[i],
|
||||
long_index = *c_long;
|
||||
|
||||
|
||||
tbl[short_index].index = long_index;
|
||||
tbl[long_index].prob -= (Scalar) 1 - tbl[short_index].prob;
|
||||
|
||||
|
||||
if (tbl[long_index].prob <= 1)
|
||||
++c_long;
|
||||
}
|
||||
|
||||
|
||||
delete[] c;
|
||||
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
/// Generate a sample in constant time using the alias method
|
||||
template <typename Scalar, typename QuantizedScalar, typename Index> Index sampleAlias(
|
||||
const AliasTableEntry<QuantizedScalar, Index> *tbl, Index size, Scalar sample) {
|
||||
Index l = std::min((Index) (sample * size), (Index) (size - 1));
|
||||
Scalar prob = (Scalar) tbl[l].prob;
|
||||
|
||||
|
||||
sample = sample * size - l;
|
||||
|
||||
|
||||
if (prob == 1 || (prob != 0 && sample < prob))
|
||||
return l;
|
||||
else
|
||||
return tbl[l].index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate a sample in constant time using the alias method
|
||||
*
|
||||
* This variation shifts and scales the uniform random sample so
|
||||
* This variation shifts and scales the uniform random sample so
|
||||
* that it can be reused for another sampling operation
|
||||
*/
|
||||
template <typename Scalar, typename QuantizedScalar, typename Index> Index sampleAliasReuse(
|
||||
const AliasTableEntry<QuantizedScalar, Index> *tbl, Index size, Scalar &sample) {
|
||||
Index l = std::min((Index) (sample * size), (Index) (size - 1));
|
||||
Scalar prob = (Scalar) tbl[l].prob;
|
||||
|
||||
|
||||
sample = sample * size - l;
|
||||
|
||||
|
||||
if (prob == 1 || (prob != 0 && sample < prob)) {
|
||||
sample /= prob;
|
||||
return l;
|
||||
|
@ -314,7 +314,7 @@ namespace math {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
MTS_NAMESPACE_END
|
||||
|
||||
#endif /* __MITSUBA_CORE_PMF_H_ */
|
||||
|
|
|
@ -40,7 +40,7 @@ template <typename T> struct TPoint1 {
|
|||
const static int dim = 1;
|
||||
|
||||
/** \brief Construct a new point without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the point will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -56,13 +56,13 @@ template <typename T> struct TPoint1 {
|
|||
|
||||
/// Initialize the point with the specified value
|
||||
TPoint1(T x) : x(x) { }
|
||||
|
||||
|
||||
/// Initialize the point with the components of another point
|
||||
template <typename T1> explicit TPoint1(const TPoint1<T1> &p)
|
||||
template <typename T1> explicit TPoint1(const TPoint1<T1> &p)
|
||||
: x((T) p.x) { }
|
||||
|
||||
/// Initialize the point with the components of a vector data structure
|
||||
template <typename T1> explicit TPoint1(const TVector1<T1> &v)
|
||||
template <typename T1> explicit TPoint1(const TVector1<T1> &v)
|
||||
: x((T) v.x) { }
|
||||
|
||||
/// Unserialize a point from a binary data stream
|
||||
|
@ -82,13 +82,13 @@ template <typename T> struct TPoint1 {
|
|||
|
||||
/// Add a vector to this one (e.g. to compute a weighted position)
|
||||
TPoint1& operator+=(const TVector1<T> &v) {
|
||||
x += v.x;
|
||||
x += v.x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a point to this one (e.g. to compute a weighted position)
|
||||
TPoint1& operator+=(const TPoint1 &p) {
|
||||
x += p.x;
|
||||
x += p.x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ template <typename T> struct TPoint1 {
|
|||
|
||||
/// Subtract a vector from this point
|
||||
TPoint1& operator-=(const TVector1<T> &v) {
|
||||
x -= v.x;
|
||||
x -= v.x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ template <typename T> struct TPoint1 {
|
|||
|
||||
/// Scale the point's coordinates by the given scalar
|
||||
TPoint1 &operator*=(T f) {
|
||||
x *= f;
|
||||
x *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ template <typename T> struct TPoint1 {
|
|||
/// Divide the point's coordinates by the given scalar and return the result
|
||||
TPoint1 operator/(T f) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point1: Division by zero!");
|
||||
#endif
|
||||
return TPoint1(x / f);
|
||||
|
@ -136,10 +136,10 @@ template <typename T> struct TPoint1 {
|
|||
/// Divide the point's coordinates by the given scalar
|
||||
TPoint1 &operator/=(T f) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point1: Division by zero!");
|
||||
#endif
|
||||
x /= f;
|
||||
x /= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ template <typename T> inline T distanceSquared(const TPoint1<T> &p1, const TPoin
|
|||
|
||||
template <> inline TPoint1<int> TPoint1<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point1i: Division by zero!");
|
||||
#endif
|
||||
return TPoint1(x/s);
|
||||
|
@ -203,7 +203,7 @@ template <> inline TPoint1<int> TPoint1<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TPoint1<int> &TPoint1<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point1i: Division by zero!");
|
||||
#endif
|
||||
x /= s;
|
||||
|
@ -226,7 +226,7 @@ template <typename T> struct TPoint2 {
|
|||
const static int dim = 2;
|
||||
|
||||
/** \brief Construct a new point without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the point will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -242,13 +242,13 @@ template <typename T> struct TPoint2 {
|
|||
|
||||
/// Initialize the point with the specified X, Y and Z components
|
||||
TPoint2(T x, T y) : x(x), y(y) { }
|
||||
|
||||
|
||||
/// Initialize the point with the components of another point
|
||||
template <typename T2> explicit TPoint2(const TPoint2<T2> &p)
|
||||
template <typename T2> explicit TPoint2(const TPoint2<T2> &p)
|
||||
: x((T) p.x), y((T) p.y) { }
|
||||
|
||||
/// Initialize the point with the components of a vector data structure
|
||||
template <typename T2> explicit TPoint2(const TVector2<T2> &v)
|
||||
template <typename T2> explicit TPoint2(const TVector2<T2> &v)
|
||||
: x((T) v.x), y((T) v.y) { }
|
||||
|
||||
/// Initialize all components of the the point with the specified value
|
||||
|
@ -272,7 +272,7 @@ template <typename T> struct TPoint2 {
|
|||
|
||||
/// Add a vector to this one (e.g. to compute a weighted position)
|
||||
TPoint2& operator+=(const TVector2<T> &v) {
|
||||
x += v.x; y += v.y;
|
||||
x += v.x; y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ template <typename T> struct TPoint2 {
|
|||
/// Divide the point's coordinates by the given scalar and return the result
|
||||
TPoint2 operator/(T f) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point2: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
|
@ -327,7 +327,7 @@ template <typename T> struct TPoint2 {
|
|||
/// Divide the point's coordinates by the given scalar
|
||||
TPoint2 &operator/=(T f) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point2: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
|
@ -388,7 +388,7 @@ template <typename T> inline T distanceSquared(const TPoint2<T> &p1, const TPoin
|
|||
|
||||
template <> inline TPoint2<int> TPoint2<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point2i: Division by zero!");
|
||||
#endif
|
||||
return TPoint2(x/s, y/s);
|
||||
|
@ -396,7 +396,7 @@ template <> inline TPoint2<int> TPoint2<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TPoint2<int> &TPoint2<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point2i: Division by zero!");
|
||||
#endif
|
||||
x /= s;
|
||||
|
@ -419,7 +419,7 @@ template <typename T> struct TPoint3 {
|
|||
const static int dim = 3;
|
||||
|
||||
/** \brief Construct a new point without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the point will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -435,13 +435,13 @@ template <typename T> struct TPoint3 {
|
|||
|
||||
/// Initialize the point with the specified X, Y and Z components
|
||||
TPoint3(T x, T y, T z) : x(x), y(y), z(z) { }
|
||||
|
||||
|
||||
/// Initialize the point with the components of another point
|
||||
template <typename T2> explicit TPoint3(const TPoint3<T2> &p)
|
||||
template <typename T2> explicit TPoint3(const TPoint3<T2> &p)
|
||||
: x((T) p.x), y((T) p.y), z((T) p.z) { }
|
||||
|
||||
/// Initialize the point with the components of a vector data structure
|
||||
template <typename T2> explicit TPoint3(const TVector3<T2> &v)
|
||||
template <typename T2> explicit TPoint3(const TVector3<T2> &v)
|
||||
: x((T) v.x), y((T) v.y), z((T) v.z) { }
|
||||
|
||||
/// Initialize all components of the the point with the specified value
|
||||
|
@ -472,7 +472,7 @@ template <typename T> struct TPoint3 {
|
|||
|
||||
/// Add a point to this one (e.g. to compute a weighted position)
|
||||
TPoint3& operator+=(const TPoint3 &p) {
|
||||
x += p.x; y += p.y; z += p.z;
|
||||
x += p.x; y += p.y; z += p.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,7 @@ template <typename T> struct TPoint3 {
|
|||
|
||||
/// Subtract a vector from this point
|
||||
TPoint3& operator-=(const TVector3<T> &v) {
|
||||
x -= v.x; y -= v.y; z -= v.z;
|
||||
x -= v.x; y -= v.y; z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ template <typename T> struct TPoint3 {
|
|||
|
||||
/// Scale the point's coordinates by the given scalar
|
||||
TPoint3 &operator*=(T f) {
|
||||
x *= f; y *= f; z *= f;
|
||||
x *= f; y *= f; z *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -511,7 +511,7 @@ template <typename T> struct TPoint3 {
|
|||
/// Divide the point's coordinates by the given scalar and return the result
|
||||
TPoint3 operator/(T f) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point3: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
|
@ -521,11 +521,11 @@ template <typename T> struct TPoint3 {
|
|||
/// Divide the point's coordinates by the given scalar
|
||||
TPoint3 &operator/=(T f) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point3: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
x *= recip; y *= recip; z *= recip;
|
||||
x *= recip; y *= recip; z *= recip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -584,7 +584,7 @@ template <typename T> inline T distanceSquared(const TPoint3<T> &p1, const TPoin
|
|||
|
||||
template <> inline TPoint3<int> TPoint3<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point3i: Division by zero!");
|
||||
#endif
|
||||
return TPoint3(x/s, y/s, z/s);
|
||||
|
@ -592,7 +592,7 @@ template <> inline TPoint3<int> TPoint3<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TPoint3<int> &TPoint3<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point3i: Division by zero!");
|
||||
#endif
|
||||
x /= s;
|
||||
|
@ -611,12 +611,12 @@ template <typename T> struct TPoint4 {
|
|||
typedef TVector4<T> VectorType;
|
||||
|
||||
T x, y, z, w;
|
||||
|
||||
|
||||
/// Number of dimensions
|
||||
const static int dim = 4;
|
||||
|
||||
/** \brief Construct a new point without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the point will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -634,11 +634,11 @@ template <typename T> struct TPoint4 {
|
|||
TPoint4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) { }
|
||||
|
||||
/// Initialize the point with the components of another point
|
||||
template <typename T2> explicit TPoint4(const TPoint4<T2> &p)
|
||||
template <typename T2> explicit TPoint4(const TPoint4<T2> &p)
|
||||
: x((T) p.x), y((T) p.y), z((T) p.z), w((T) p.w) { }
|
||||
|
||||
/// Initialize the point with the components of a vector data structure
|
||||
template <typename T2> explicit TPoint4(const TVector4<T2> &v)
|
||||
template <typename T2> explicit TPoint4(const TVector4<T2> &v)
|
||||
: x((T) v.x), y((T) v.y), z((T) v.z), w((T) v.w) { }
|
||||
|
||||
/// Initialize all components of the the point with the specified value
|
||||
|
@ -709,7 +709,7 @@ template <typename T> struct TPoint4 {
|
|||
/// Divide the point's coordinates by the given scalar and return the result
|
||||
TPoint4 operator/(T f) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point4: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
|
@ -719,7 +719,7 @@ template <typename T> struct TPoint4 {
|
|||
/// Divide the point's coordinates by the given scalar
|
||||
TPoint4 &operator/=(T f) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (f == 0)
|
||||
if (f == 0)
|
||||
SLog(EWarn, "Point4: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
|
@ -759,7 +759,7 @@ template <typename T> struct TPoint4 {
|
|||
stream->writeElement<T>(z);
|
||||
stream->writeElement<T>(w);
|
||||
}
|
||||
|
||||
|
||||
/// Return a readable string representation of this point
|
||||
std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
|
@ -782,7 +782,7 @@ template <typename T> inline T distanceSquared(const TPoint4<T> &p1, const TPoin
|
|||
|
||||
template <> inline TPoint4<int> TPoint4<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point4i: Division by zero!");
|
||||
#endif
|
||||
return TPoint4(x/s, y/s, z/s, w/s);
|
||||
|
@ -790,7 +790,7 @@ template <> inline TPoint4<int> TPoint4<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TPoint4<int> &TPoint4<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Point4i: Division by zero!");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,10 +27,10 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
struct PropertyElement;
|
||||
|
||||
/** \brief Associative parameter map for constructing
|
||||
/** \brief Associative parameter map for constructing
|
||||
* subclasses of \ref ConfigurableObject.
|
||||
*
|
||||
* Note that the Python bindings for this class do not implement
|
||||
* Note that the Python bindings for this class do not implement
|
||||
* the various type-dependent getters and setters. Instead, they
|
||||
* are accessed just like a normal Python map, e.g:
|
||||
*
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
/// Construct an empty property container
|
||||
Properties();
|
||||
|
||||
|
||||
/// Construct an empty property container and set the plugin name
|
||||
Properties(const std::string &pluginName);
|
||||
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
inline void setPluginName(const std::string &name) { m_pluginName = name; }
|
||||
/// Get the associated plugin name
|
||||
inline const std::string &getPluginName() const { return m_pluginName; }
|
||||
|
||||
|
||||
/// Returns the associated identifier (or the string "unnamed")
|
||||
inline const std::string &getID() const { return m_id; }
|
||||
/// Set the associated identifier
|
||||
|
@ -150,7 +150,7 @@ public:
|
|||
Spectrum getSpectrum(const std::string &name) const;
|
||||
/// Get a spectral power distribution (with default)
|
||||
Spectrum getSpectrum(const std::string &name, const Spectrum &defVal) const;
|
||||
|
||||
|
||||
/// Set a 3d point
|
||||
void setPoint(const std::string &name, const Point &value, bool warnDuplicates = true);
|
||||
/// Get a 3d point
|
||||
|
@ -160,7 +160,7 @@ public:
|
|||
|
||||
/// Set a 3d vector
|
||||
void setVector(const std::string &name, const Vector &value, bool warnDuplicates = true);
|
||||
/// Get a 3d vector
|
||||
/// Get a 3d vector
|
||||
Vector getVector(const std::string &name) const;
|
||||
/// Get a 3d vector (with default)
|
||||
Vector getVector(const std::string &name, const Vector &defVal) const;
|
||||
|
@ -174,7 +174,7 @@ public:
|
|||
|
||||
/// Store an array containing the names of all stored properties
|
||||
void putPropertyNames(std::vector<std::string> &results) const;
|
||||
|
||||
|
||||
/// Return an array containing the names of all stored properties
|
||||
inline std::vector<std::string> getPropertyNames() const {
|
||||
std::vector<std::string> results;
|
||||
|
@ -190,7 +190,7 @@ public:
|
|||
|
||||
/// Verify if a value with the specified name exists
|
||||
bool hasProperty(const std::string &name) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Remove a property with the specified name
|
||||
* \return \c true upon success
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <mitsuba/mitsuba.h>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
/*! \addtogroup libcore */
|
||||
/*! @{ */
|
||||
|
||||
|
@ -40,7 +40,7 @@ extern const int MTS_EXPORT_CORE primeTable[primeTableSize];
|
|||
/// Van der Corput radical inverse in base 2 with single precision
|
||||
inline float radicalInverse2Single(uint32_t n, uint32_t scramble = 0U) {
|
||||
/* Efficiently reverse the bits in 'n' using binary operations */
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
n = __builtin_bswap32(n);
|
||||
#else
|
||||
n = (n << 16) | (n >> 16);
|
||||
|
@ -59,7 +59,7 @@ inline float radicalInverse2Single(uint32_t n, uint32_t scramble = 0U) {
|
|||
/// Van der Corput radical inverse in base 2 with double precision
|
||||
inline double radicalInverse2Double(uint64_t n, uint64_t scramble = 0ULL) {
|
||||
/* Efficiently reverse the bits in 'n' using binary operations */
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
|
||||
n = __builtin_bswap64(n);
|
||||
#else
|
||||
n = (n << 32) | (n >> 32);
|
||||
|
@ -125,7 +125,7 @@ inline Point2 sample02(size_t n) {
|
|||
}
|
||||
|
||||
/**
|
||||
* \ref Generate fast and reasonably good pseudorandom numbers using the
|
||||
* \ref Generate fast and reasonably good pseudorandom numbers using the
|
||||
* Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham.
|
||||
*
|
||||
* For details, refer to "GPU Random Numbers via the Tiny Encryption Algorithm"
|
||||
|
@ -146,7 +146,7 @@ inline uint64_t sampleTEA(uint32_t v0, uint32_t v1, int rounds = 4) {
|
|||
|
||||
for (int i=0; i<rounds; ++i) {
|
||||
sum += 0x9e3779b9;
|
||||
v0 += ((v1 << 4) + 0xA341316C) ^ (v1 + sum) ^ ((v1 >> 5) + 0xC8013EA4);
|
||||
v0 += ((v1 << 4) + 0xA341316C) ^ (v1 + sum) ^ ((v1 >> 5) + 0xC8013EA4);
|
||||
v1 += ((v0 << 4) + 0xAD90777D) ^ (v0 + sum) ^ ((v0 >> 5) + 0x7E95761E);
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ inline uint64_t sampleTEA(uint32_t v0, uint32_t v1, int rounds = 4) {
|
|||
|
||||
#if defined(DOUBLE_PRECISION)
|
||||
inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
|
||||
/* Trick from MTGP: generate an uniformly distributed
|
||||
/* Trick from MTGP: generate an uniformly distributed
|
||||
single precision number in [1,2) and subtract 1. */
|
||||
union {
|
||||
uint64_t u;
|
||||
|
@ -167,7 +167,7 @@ inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
|
|||
|
||||
#else
|
||||
inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
|
||||
/* Trick from MTGP: generate an uniformly distributed
|
||||
/* Trick from MTGP: generate an uniformly distributed
|
||||
single precision number in [1,2) and subtract 1. */
|
||||
union {
|
||||
uint32_t u;
|
||||
|
@ -183,7 +183,7 @@ inline Float sampleTEAFloat(uint32_t v0, uint32_t v1, int rounds = 4) {
|
|||
*
|
||||
* This function is used as a building block to construct Halton and
|
||||
* Hammersley sequences. Roughly, it computes a b-ary representation
|
||||
* of the input value \c index, mirrors it along the decimal
|
||||
* of the input value \c index, mirrors it along the decimal
|
||||
* point, and returns the resulting fractional value.
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float radicalInverse(int base, uint64_t index);
|
||||
|
@ -191,13 +191,13 @@ extern MTS_EXPORT_CORE Float radicalInverse(int base, uint64_t index);
|
|||
/**
|
||||
* \brief Calculate a scrambled radical inverse function
|
||||
*
|
||||
* This function is used as a building block to construct permuted
|
||||
* This function is used as a building block to construct permuted
|
||||
* Halton and Hammersley sequence variants. It works like the normal
|
||||
* radical inverse function \ref radicalInverse(), except that every digit
|
||||
* is run through an extra scrambling permutation specified as array
|
||||
* radical inverse function \ref radicalInverse(), except that every digit
|
||||
* is run through an extra scrambling permutation specified as array
|
||||
* of size \c base.
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float scrambledRadicalInverse(int base,
|
||||
extern MTS_EXPORT_CORE Float scrambledRadicalInverse(int base,
|
||||
uint64_t index, uint16_t *perm);
|
||||
|
||||
/**
|
||||
|
@ -211,13 +211,13 @@ extern MTS_EXPORT_CORE Float radicalInverseIncremental(int base, Float x);
|
|||
/**
|
||||
* \brief Calculate a radical inverse function (fast version)
|
||||
*
|
||||
* This function works similarly to \ref radicalInverse, but is potentially much
|
||||
* This function works similarly to \ref radicalInverse, but is potentially much
|
||||
* faster. Internally, it relies on optimized implementations of the radical inverse
|
||||
* functions for the first 1024 prime number bases. For that reason, only works for
|
||||
* functions for the first 1024 prime number bases. For that reason, only works for
|
||||
* such bases.
|
||||
*
|
||||
* \ref baseIndex
|
||||
* Prime number index starting at 0 (i.e. 3 would cause 7 to be
|
||||
* Prime number index starting at 0 (i.e. 3 would cause 7 to be
|
||||
* used as the basis)
|
||||
* \ref perm
|
||||
* Sequence index
|
||||
|
@ -227,12 +227,12 @@ extern MTS_EXPORT_CORE Float radicalInverseFast(uint16_t baseIndex, uint64_t ind
|
|||
/**
|
||||
* \brief Calculate a scrambled radical inverse function (fast version)
|
||||
*
|
||||
* This function is used as a building block to construct permuted
|
||||
* This function is used as a building block to construct permuted
|
||||
* Halton and Hammersley sequence variants. It works like the fast
|
||||
* radical inverse function \ref radicalInverseFast(), except that every
|
||||
* radical inverse function \ref radicalInverseFast(), except that every
|
||||
* digit is run through an extra scrambling permutation.
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float scrambledRadicalInverseFast(uint16_t baseIndex,
|
||||
extern MTS_EXPORT_CORE Float scrambledRadicalInverseFast(uint16_t baseIndex,
|
||||
uint64_t index, uint16_t *perm);
|
||||
|
||||
//! @}
|
||||
|
|
|
@ -45,12 +45,12 @@ extern MTS_EXPORT_CORE std::pair<double, double> legendrePD(int l, double x);
|
|||
* \brief Computes the nodes and weights of a Gauss-Legendre quadrature
|
||||
* (aka "Gaussian quadrature") rule with the given number of evaluations.
|
||||
*
|
||||
* Integration is over the interval \f$[-1, 1]\f$. Gauss-Legendre quadrature
|
||||
* maximizes the order of exactly integrable polynomials achieves this up to
|
||||
* Integration is over the interval \f$[-1, 1]\f$. Gauss-Legendre quadrature
|
||||
* maximizes the order of exactly integrable polynomials achieves this up to
|
||||
* degree \f$2n-1\f$ (where \f$n\f$ is the number of function evaluations).
|
||||
*
|
||||
* This method is numerically well-behaved until about \f$n=200\f$
|
||||
* and then becomes progressively less accurate. It is generally not a
|
||||
* and then becomes progressively less accurate. It is generally not a
|
||||
* good idea to go much higher---in any case, a composite or
|
||||
* adaptive integration scheme will be superior for large \f$n\f$.
|
||||
*
|
||||
|
@ -68,15 +68,15 @@ extern MTS_EXPORT_CORE void gaussLegendre(int n, Float *nodes, Float *weights);
|
|||
* \brief Computes the nodes and weights of a Gauss-Lobatto quadrature
|
||||
* rule with the given number of evaluations.
|
||||
*
|
||||
* Integration is over the interval \f$[-1, 1]\f$. Gauss-Lobatto quadrature
|
||||
* is preferable to Gauss-Legendre quadrature whenever the endpoints of the
|
||||
* integration domain should explicitly be included. It maximizes the order
|
||||
* of exactly integrable polynomials subject to this constraint and achieves
|
||||
* this up to degree \f$2n-3\f$ (where \f$n\f$ is the number of function
|
||||
* Integration is over the interval \f$[-1, 1]\f$. Gauss-Lobatto quadrature
|
||||
* is preferable to Gauss-Legendre quadrature whenever the endpoints of the
|
||||
* integration domain should explicitly be included. It maximizes the order
|
||||
* of exactly integrable polynomials subject to this constraint and achieves
|
||||
* this up to degree \f$2n-3\f$ (where \f$n\f$ is the number of function
|
||||
* evaluations).
|
||||
*
|
||||
* This method is numerically well-behaved until about \f$n=200\f$
|
||||
* and then becomes progressively less accurate. It is generally not a
|
||||
* and then becomes progressively less accurate. It is generally not a
|
||||
* good idea to go much higher---in any case, a composite or
|
||||
* adaptive integration scheme will be superior for large \f$n\f$.
|
||||
*
|
||||
|
@ -113,11 +113,11 @@ extern MTS_EXPORT_CORE void gaussLobatto(int n, Float *nodes, Float *weights);
|
|||
*
|
||||
* The original MATLAB version can be downloaded here
|
||||
* http://www.inf.ethz.ch/personal/gander/adaptlob.m
|
||||
*
|
||||
* This particular implementation is based on code in QuantLib,
|
||||
*
|
||||
* This particular implementation is based on code in QuantLib,
|
||||
* a free-software/open-source library for financial quantitative
|
||||
* analysts and developers - http://quantlib.org/
|
||||
*
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
class MTS_EXPORT_CORE GaussLobattoIntegrator {
|
||||
|
@ -173,7 +173,7 @@ protected:
|
|||
Float a, Float b, Float fa, Float fb, Float is, size_t &evals) const;
|
||||
|
||||
/**
|
||||
* Compute the absolute error tolerance using a 13-point
|
||||
* Compute the absolute error tolerance using a 13-point
|
||||
* Gauss-Lobatto rule.
|
||||
*/
|
||||
Float calculateAbsTolerance(const boost::function<Float (Float)>& f,
|
||||
|
@ -191,7 +191,7 @@ protected:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Adaptively computes the integral of a multidimensional function using
|
||||
* \brief Adaptively computes the integral of a multidimensional function using
|
||||
* either a Gauss-Kronod (1D) or a Genz-Malik (>1D) cubature rule.
|
||||
*
|
||||
* This class is a C++ wrapper around the \c cubature code by Steven G. Johnson
|
||||
|
@ -227,9 +227,9 @@ public:
|
|||
* \param fDim Number of integrands (i.e. dimensions of the image space)
|
||||
* \param nDim Number of integration dimensions (i.e. dimensions of the
|
||||
* function domain)
|
||||
* \param maxEvals Maximum number of function evaluations (0 means no
|
||||
* \param maxEvals Maximum number of function evaluations (0 means no
|
||||
* limit). The error bounds will likely be exceeded when the
|
||||
* integration is forced to stop prematurely. Note: the actual
|
||||
* integration is forced to stop prematurely. Note: the actual
|
||||
* number of evaluations may somewhat exceed this value.
|
||||
* \param absError Absolute error requirement (0 to disable)
|
||||
* \param relError Relative error requirement (0 to disable)
|
||||
|
@ -238,7 +238,7 @@ public:
|
|||
size_t maxEvals, Float absError = 0, Float relError = 0);
|
||||
|
||||
/**
|
||||
* \brief Integrate the function \c f over the rectangular domain
|
||||
* \brief Integrate the function \c f over the rectangular domain
|
||||
* bounded by \c min and \c max.
|
||||
*
|
||||
* The supplied function should have the interface
|
||||
|
@ -255,12 +255,12 @@ public:
|
|||
Float *result, Float *error, size_t *evals = NULL) const;
|
||||
|
||||
/**
|
||||
* \brief Integrate the function \c f over the rectangular domain
|
||||
* \brief Integrate the function \c f over the rectangular domain
|
||||
* bounded by \c min and \c max.
|
||||
*
|
||||
* This function implements a vectorized version of the above
|
||||
* integration function, which is more efficient by evaluating
|
||||
* the integrant in `batches'. The supplied function should
|
||||
* the integrant in `batches'. The supplied function should
|
||||
* have the interface
|
||||
*
|
||||
* <code>
|
||||
|
@ -269,7 +269,7 @@ public:
|
|||
*
|
||||
* Note that \c in in is not a single point, but an array of \c numPoints points
|
||||
* (length \c numPoints x \c dim), and upon return the values of all \c fDim
|
||||
* integrands at all \c numPoints points should be stored in \c out
|
||||
* integrands at all \c numPoints points should be stored in \c out
|
||||
* (length \c fDim x \c numPoints). In particular, out[i*dim + j] is the j-th
|
||||
* coordinate of the i-th point, and the k-th function evaluation (k<fDim)
|
||||
* for the i-th point is returned in out[k*npt + i].
|
||||
|
@ -281,7 +281,7 @@ public:
|
|||
* up requiring several thousand points in total, \c numPoints may grow to
|
||||
* several hundred.
|
||||
*/
|
||||
EResult integrateVectorized(const VectorizedIntegrand &f, const Float *min,
|
||||
EResult integrateVectorized(const VectorizedIntegrand &f, const Float *min,
|
||||
const Float *max, Float *result, Float *error, size_t *evals = NULL) const;
|
||||
protected:
|
||||
size_t m_fdim, m_dim, m_maxEvals;
|
||||
|
|
|
@ -51,7 +51,7 @@ template <typename T> struct TQuaternion {
|
|||
TQuaternion() : v(0.0f), w(1) { }
|
||||
|
||||
/**
|
||||
* Initialize the quaternion with the specified
|
||||
* Initialize the quaternion with the specified
|
||||
* real and imaginary components
|
||||
*/
|
||||
TQuaternion(const TVector3<T> &v, T w) : v(v), w(w) { }
|
||||
|
@ -74,7 +74,7 @@ template <typename T> struct TQuaternion {
|
|||
|
||||
/// Add another quaternions to the current one
|
||||
TQuaternion& operator+=(const TQuaternion &q) {
|
||||
v += q.v; w += q.w;
|
||||
v += q.v; w += q.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ template <typename T> struct TQuaternion {
|
|||
|
||||
/// Multiply the quaternion by the given scalar
|
||||
TQuaternion &operator*=(T f) {
|
||||
v *= f; w *= f;
|
||||
v *= f; w *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ template <typename T> struct TQuaternion {
|
|||
SLog(EWarn, "Quaternion: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
v *= recip; w *= recip;
|
||||
v *= recip; w *= recip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ template <typename T> struct TQuaternion {
|
|||
|
||||
/**
|
||||
* \brief Compute the exponential of a quaternion with
|
||||
* scalar part w = 0.
|
||||
* scalar part w = 0.
|
||||
*
|
||||
* Based on code the appendix of
|
||||
* "Quaternion Calculus for Computer Graphics" by Ken Shoemake
|
||||
|
@ -157,7 +157,7 @@ template <typename T> struct TQuaternion {
|
|||
T theta = v.length();
|
||||
T c = std::cos(theta);
|
||||
|
||||
if (theta > Epsilon)
|
||||
if (theta > Epsilon)
|
||||
return TQuaternion(v * (std::sin(theta) / theta), c);
|
||||
else
|
||||
return TQuaternion(v, c);
|
||||
|
@ -189,7 +189,7 @@ template <typename T> struct TQuaternion {
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Construct an unit quaternion, which rotates unit direction
|
||||
* \brief Construct an unit quaternion, which rotates unit direction
|
||||
* \a from onto \a to.
|
||||
*/
|
||||
static TQuaternion fromDirectionPair(const Vector &from, const Vector &to) {
|
||||
|
@ -255,7 +255,7 @@ template <typename T> struct TQuaternion {
|
|||
}
|
||||
return TQuaternion(v, w);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Construct an unit quaternion matching the supplied
|
||||
* rotation expressed in Euler angles (in radians)
|
||||
|
@ -279,7 +279,7 @@ template <typename T> struct TQuaternion {
|
|||
return qy * qx * qz;
|
||||
case EEulerZYX:
|
||||
return qx * qy * qz;
|
||||
default:
|
||||
default:
|
||||
SLog(EError, "Internal error!");
|
||||
return TQuaternion();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <mitsuba/mitsuba.h>
|
||||
#include <mitsuba/core/cobject.h>
|
||||
|
||||
/*
|
||||
/*
|
||||
SIMD oriented Fast Mersenne Twister (SFMT) pseudorandom number generator
|
||||
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
|
||||
|
||||
|
@ -65,12 +65,12 @@
|
|||
Springer (2008) 607--622.
|
||||
DOI: 10.1007/978-3-540-74496-2_36
|
||||
T. Nishimura, ``Tables of 64-bit Mersenne Twisters''
|
||||
ACM Transactions on Modeling and
|
||||
ACM Transactions on Modeling and
|
||||
Computer Simulation 10. (2000) 348--357.
|
||||
M. Matsumoto and T. Nishimura,
|
||||
``Mersenne Twister: a 623-dimensionally equidistributed
|
||||
uniform pseudorandom number generator''
|
||||
ACM Transactions on Modeling and
|
||||
ACM Transactions on Modeling and
|
||||
Computer Simulation 8. (Jan. 1998) 3--30.
|
||||
* \ingroup libcore
|
||||
*/
|
||||
|
@ -79,7 +79,7 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/**
|
||||
* \brief %Random number generator based on SIMD-oriented Fast Mersenne Twister
|
||||
*
|
||||
*
|
||||
* \author Mutsuo Saito and Makoto Matsumoto at Hiroshima University.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -90,7 +90,7 @@ public:
|
|||
/**
|
||||
* \brief Construct a new seeded random generator.
|
||||
*
|
||||
* Uses the default seed on Windows and '/dev/urandom'
|
||||
* Uses the default seed on Windows and '/dev/urandom'
|
||||
* on OSX and Linux.
|
||||
*/
|
||||
Random();
|
||||
|
@ -117,18 +117,18 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Seed the random generator from an array
|
||||
* \remark This function is currently not exposed
|
||||
* \remark This function is currently not exposed
|
||||
* by the Python bindings
|
||||
*/
|
||||
void seed(uint64_t *values, uint64_t length);
|
||||
|
||||
/// Return an integer on the [0, 2^63-1]-interval
|
||||
/// Return an integer on the [0, 2^63-1]-interval
|
||||
uint64_t nextULong();
|
||||
|
||||
/// Return an integer on the [0, n)-interval
|
||||
/// Return an integer on the [0, n)-interval
|
||||
uint32_t nextUInt(uint32_t n);
|
||||
|
||||
/// Return an integer on the [0, n)-interval
|
||||
/// Return an integer on the [0, n)-interval
|
||||
size_t nextSize(size_t n);
|
||||
|
||||
/// Return a floating point value on the [0, 1) interval
|
||||
|
@ -138,16 +138,16 @@ public:
|
|||
Float nextStandardNormal();
|
||||
|
||||
/**
|
||||
* \brief Draw a uniformly distributed permutation and permute the
|
||||
* \brief Draw a uniformly distributed permutation and permute the
|
||||
* given STL container.
|
||||
*
|
||||
* See Knuth, TAoCP Vol. 2 (3rd 3d), Section 3.4.2.
|
||||
*
|
||||
* \remark This function is currently not exposed
|
||||
* \remark This function is currently not exposed
|
||||
* by the Python bindings
|
||||
*/
|
||||
template <typename Iterator> void shuffle(Iterator it1, Iterator it2) {
|
||||
for (Iterator it = it2 - 1; it > it1; --it)
|
||||
for (Iterator it = it2 - 1; it > it1; --it)
|
||||
std::iter_swap(it, it1 + nextSize((size_t) (it-it1)));
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ template <typename _PointType, typename _VectorType> struct TRay {
|
|||
typedef _VectorType VectorType;
|
||||
typedef typename PointType::Scalar Scalar;
|
||||
|
||||
/* The somewhat peculiar ordering of the attributes is for
|
||||
/* The somewhat peculiar ordering of the attributes is for
|
||||
alignment purposes in the 3D case and should not be changed. */
|
||||
|
||||
PointType o; ///< Ray origin
|
||||
|
@ -49,28 +49,28 @@ template <typename _PointType, typename _VectorType> struct TRay {
|
|||
Float time; ///< Time value associated with this ray
|
||||
|
||||
/// Construct a new ray
|
||||
inline TRay() : mint(Epsilon),
|
||||
inline TRay() : mint(Epsilon),
|
||||
maxt(std::numeric_limits<Scalar>::infinity()), time(0) {
|
||||
}
|
||||
|
||||
/// Copy constructor (1)
|
||||
inline TRay(const TRay &ray)
|
||||
: o(ray.o), mint(ray.mint), d(ray.d), maxt(ray.maxt),
|
||||
inline TRay(const TRay &ray)
|
||||
: o(ray.o), mint(ray.mint), d(ray.d), maxt(ray.maxt),
|
||||
dRcp(ray.dRcp), time(ray.time) {
|
||||
}
|
||||
|
||||
/// Copy constructor (2)
|
||||
inline TRay(const TRay &ray, Scalar mint, Scalar maxt)
|
||||
: o(ray.o), mint(mint), d(ray.d), maxt(maxt),
|
||||
inline TRay(const TRay &ray, Scalar mint, Scalar maxt)
|
||||
: o(ray.o), mint(mint), d(ray.d), maxt(maxt),
|
||||
dRcp(ray.dRcp), time(ray.time) { }
|
||||
|
||||
/// Construct a new ray, while not specifying a direction yet
|
||||
inline TRay(const PointType &o, Scalar time) : o(o), mint(Epsilon),
|
||||
inline TRay(const PointType &o, Scalar time) : o(o), mint(Epsilon),
|
||||
maxt(std::numeric_limits<Scalar>::infinity()), time(time) { }
|
||||
|
||||
/// Construct a new ray
|
||||
inline TRay(const PointType &o, const VectorType &d, Scalar time)
|
||||
: o(o), mint(Epsilon), d(d),
|
||||
: o(o), mint(Epsilon), d(d),
|
||||
maxt(std::numeric_limits<Scalar>::infinity()), time(time) {
|
||||
#ifdef MTS_DEBUG_FP
|
||||
bool state = disableFPExceptions();
|
||||
|
@ -100,7 +100,7 @@ template <typename _PointType, typename _VectorType> struct TRay {
|
|||
|
||||
/// Set the origin
|
||||
inline void setTime(Scalar tval) { time = tval; }
|
||||
|
||||
|
||||
/// Set the direction and update the reciprocal
|
||||
inline void setDirection(const VectorType &dir) {
|
||||
d = dir;
|
||||
|
@ -117,8 +117,8 @@ template <typename _PointType, typename _VectorType> struct TRay {
|
|||
/**
|
||||
* \brief Return the position of a point along the ray
|
||||
*
|
||||
* \remark In the Python bindings, this operator is
|
||||
* exposed as a function named \c eval -- i.e.
|
||||
* \remark In the Python bindings, this operator is
|
||||
* exposed as a function named \c eval -- i.e.
|
||||
* position lookups should be written as \c ray.eval(t)
|
||||
*/
|
||||
inline PointType operator() (Scalar t) const { return o + t * d; }
|
||||
|
@ -126,14 +126,14 @@ template <typename _PointType, typename _VectorType> struct TRay {
|
|||
/// Return a string representation of this ray
|
||||
inline std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "Ray[origin=" << o.toString() << ", direction="
|
||||
<< d.toString() << ", mint=" << mint
|
||||
oss << "Ray[origin=" << o.toString() << ", direction="
|
||||
<< d.toString() << ", mint=" << mint
|
||||
<< ", maxt=" << maxt << ", time=" << time << "]";
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
/** \brief %Ray differential -- enhances the basic ray class with
|
||||
/** \brief %Ray differential -- enhances the basic ray class with
|
||||
information about the rays of adjacent pixels on the view plane
|
||||
\ingroup libcore
|
||||
*/
|
||||
|
@ -142,24 +142,24 @@ struct RayDifferential : public Ray {
|
|||
Vector rxDirection, ryDirection;
|
||||
bool hasDifferentials;
|
||||
|
||||
inline RayDifferential()
|
||||
inline RayDifferential()
|
||||
: hasDifferentials(false) {
|
||||
}
|
||||
|
||||
inline RayDifferential(const Point &p, const Vector &d, Float time)
|
||||
inline RayDifferential(const Point &p, const Vector &d, Float time)
|
||||
: Ray(p, d, time), hasDifferentials(false) {
|
||||
}
|
||||
|
||||
inline explicit RayDifferential(const Ray &ray)
|
||||
inline explicit RayDifferential(const Ray &ray)
|
||||
: Ray(ray), hasDifferentials(false) {
|
||||
}
|
||||
|
||||
inline RayDifferential(const RayDifferential &ray)
|
||||
inline RayDifferential(const RayDifferential &ray)
|
||||
: Ray(ray), rxOrigin(ray.rxOrigin), ryOrigin(ray.ryOrigin),
|
||||
rxDirection(ray.rxDirection), ryDirection(ray.ryDirection),
|
||||
hasDifferentials(ray.hasDifferentials) {
|
||||
}
|
||||
|
||||
|
||||
void scaleDifferential(Float amount) {
|
||||
rxOrigin = o + (rxOrigin - o) * amount;
|
||||
ryOrigin = o + (ryOrigin - o) * amount;
|
||||
|
|
|
@ -27,12 +27,12 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \headerfile mitsuba/core/ref.h mitsuba/mitsuba.h
|
||||
* \brief Reference counting helper
|
||||
*
|
||||
* The \a ref refeference template is a simple wrapper to store a
|
||||
*
|
||||
* The \a ref refeference template is a simple wrapper to store a
|
||||
* pointer to an object. It takes care of increasing and decreasing
|
||||
* the reference count of the object. When the last reference goes
|
||||
* out of scope, the associated object will be deallocated.
|
||||
*
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
* \ingroup libcore
|
||||
*/
|
||||
|
@ -61,7 +61,7 @@ public:
|
|||
((Object *) m_ptr)->incRef();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Overwrite this reference with a pointer to another object
|
||||
inline ref& operator= (T *ptr) {
|
||||
if (m_ptr == ptr)
|
||||
|
@ -76,13 +76,13 @@ public:
|
|||
|
||||
/// Compare this reference with another reference
|
||||
inline bool operator== (const ref &pref) const { return (m_ptr == pref.m_ptr); }
|
||||
|
||||
|
||||
/// Compare this reference with another reference
|
||||
inline bool operator!= (const ref &pref) const { return (m_ptr != pref.m_ptr); }
|
||||
|
||||
|
||||
/// Compare this reference with a pointer
|
||||
inline bool operator== (const T* ptr) const { return (m_ptr == ptr); }
|
||||
|
||||
|
||||
/// Compare this reference with a pointer
|
||||
inline bool operator!= (const T* ptr) const { return (m_ptr != ptr); }
|
||||
|
||||
|
@ -91,13 +91,13 @@ public:
|
|||
|
||||
/// Access the object referenced by this reference
|
||||
inline T* operator-> () { return m_ptr; }
|
||||
|
||||
|
||||
/// Access the object referenced by this reference
|
||||
inline const T* operator-> () const { return m_ptr; }
|
||||
|
||||
/// Return a C++ reference to the referenced object
|
||||
inline T& operator*() { return *m_ptr; }
|
||||
|
||||
|
||||
/// Return a C++ reference to the referenced object
|
||||
inline const T& operator*() const { return *m_ptr; }
|
||||
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
|
||||
/// Return a pointer to the referenced object
|
||||
inline T* get() { return m_ptr; }
|
||||
|
||||
|
||||
/// Return a pointer to the referenced object
|
||||
inline const T* get() const { return m_ptr; }
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \brief Generic interface to separable image reconstruction filters
|
||||
*
|
||||
* When resampling bitmaps or adding radiance-valued samples to a rendering in
|
||||
* progress, Mitsuba first convolves them with a so-called image reconstruction
|
||||
* progress, Mitsuba first convolves them with a so-called image reconstruction
|
||||
* filter. Various kinds are implemented as subclasses of this interface.
|
||||
*
|
||||
* Because image filters are generally too expensive to evaluate for
|
||||
|
@ -45,7 +45,7 @@ class MTS_EXPORT_CORE ReconstructionFilter : public ConfigurableObject {
|
|||
public:
|
||||
/**
|
||||
* \brief When resampling data to a different resolution using
|
||||
* \ref Resample, this enumeration specifies how lookups
|
||||
* \ref Resample, this enumeration specifies how lookups
|
||||
* <em>outside</em> of the input domain are handled.
|
||||
*
|
||||
* \see Resampler
|
||||
|
@ -114,13 +114,13 @@ template <typename Scalar> struct Resampler {
|
|||
*
|
||||
* \param sourceRes
|
||||
* Source resolution
|
||||
* \param targetRes
|
||||
* Desired target resolution
|
||||
* \param targetRes
|
||||
* Desired target resolution
|
||||
* \param bc
|
||||
* Boundary conditions that should be observed when looking up samples
|
||||
* outside of the defined input domain.
|
||||
*/
|
||||
Resampler(const ReconstructionFilter *rfilter, ReconstructionFilter::EBoundaryCondition bc,
|
||||
Resampler(const ReconstructionFilter *rfilter, ReconstructionFilter::EBoundaryCondition bc,
|
||||
int sourceRes, int targetRes) : m_bc(bc), m_sourceRes(sourceRes), m_targetRes(targetRes) {
|
||||
SAssert(sourceRes > 0 && targetRes > 0);
|
||||
Float filterRadius = rfilter->getRadius(), scale = 1.0f, invScale = 1.0f;
|
||||
|
@ -153,7 +153,7 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
Float sum = 0;
|
||||
for (int j=0; j<m_taps; j++) {
|
||||
/* Compute the the position where the filter should be evaluated */
|
||||
/* Compute the the position where the filter should be evaluated */
|
||||
Float pos = m_start[i] + j + (Float) 0.5f - center;
|
||||
|
||||
/* Perform the evaluation and record the weight */
|
||||
|
@ -206,9 +206,9 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += lookup(source, start + j, sourceStride, ch) * m_weights[i * taps + j];
|
||||
*target++ = result;
|
||||
*target++ = result;
|
||||
}
|
||||
|
||||
target += targetStride;
|
||||
|
@ -220,9 +220,9 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += source[sourceStride * (start + j) + ch] * m_weights[i * taps + j];
|
||||
*target++ = result;
|
||||
*target++ = result;
|
||||
}
|
||||
|
||||
target += targetStride;
|
||||
|
@ -234,9 +234,9 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += lookup(source, start + j, sourceStride, ch) * m_weights[i * taps + j];
|
||||
*target++ = result;
|
||||
*target++ = result;
|
||||
}
|
||||
|
||||
target += targetStride;
|
||||
|
@ -244,7 +244,7 @@ template <typename Scalar> struct Resampler {
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Resample a multi-channel array and clamp the results
|
||||
* \brief Resample a multi-channel array and clamp the results
|
||||
* to a specified valid range
|
||||
*
|
||||
* This function is preferred if too large positive/negative values
|
||||
|
@ -268,7 +268,7 @@ template <typename Scalar> struct Resampler {
|
|||
* Maximum sample value after resampling
|
||||
*/
|
||||
void resampleAndClamp(const Scalar *source, size_t sourceStride,
|
||||
Scalar *target, size_t targetStride, int channels,
|
||||
Scalar *target, size_t targetStride, int channels,
|
||||
Scalar min = (Scalar) 0, Scalar max = (Scalar) 1) {
|
||||
const int taps = m_taps;
|
||||
targetStride = channels * (targetStride - 1);
|
||||
|
@ -280,7 +280,7 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += lookup(source, start + j, sourceStride, ch) * m_weights[i * taps + j];
|
||||
*target++ = std::min(max, std::max(min, result));
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += source[sourceStride * (start + j) + ch] * m_weights[i * taps + j];
|
||||
*target++ = std::min(max, std::max(min, result));
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ template <typename Scalar> struct Resampler {
|
|||
|
||||
for (int ch=0; ch<channels; ++ch) {
|
||||
Scalar result = 0;
|
||||
for (int j=0; j<taps; ++j)
|
||||
for (int j=0; j<taps; ++j)
|
||||
result += lookup(source, start + j, sourceStride, ch) * m_weights[i * taps + j];
|
||||
*target++ = std::min(max, std::max(min, result));
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief Abstract work unit -- represents a small amount of information
|
||||
* \brief Abstract work unit -- represents a small amount of information
|
||||
* that encodes part of a larger processing task.
|
||||
*
|
||||
* Instead of the usual serialization function and unserialization
|
||||
* constructor, implementations of this class supply \ref load()
|
||||
* constructor, implementations of this class supply \ref load()
|
||||
* and \ref save() methods that can be used for essentially the
|
||||
* same purpose, but without requiring any memory allocations.
|
||||
*
|
||||
|
@ -65,11 +65,11 @@ protected:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Abstract work result -- represents the result of a
|
||||
* \brief Abstract work result -- represents the result of a
|
||||
* processed \ref WorkUnit instance.
|
||||
*
|
||||
* Instead of the usual serialization function and unserialization
|
||||
* constructor, implementations of this class supply \ref load()
|
||||
* constructor, implementations of this class supply \ref load()
|
||||
* and \ref save() methods that can be used for essentially the
|
||||
* same purpose, but without requiring any memory allocations.
|
||||
*
|
||||
|
@ -95,23 +95,23 @@ protected:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Abstract work processor -- takes work units and turns them into
|
||||
* \brief Abstract work processor -- takes work units and turns them into
|
||||
*\ref WorkResult instances.
|
||||
*
|
||||
*
|
||||
* When executing a parallel task using Mitsuba's scheduling system, the
|
||||
* actual work is done in an implementation of this interface.
|
||||
*
|
||||
* The class is serializable so that it can be sent over the network if
|
||||
* The class is serializable so that it can be sent over the network if
|
||||
* required. It is possible to keep local state in \ref WorkProcessor
|
||||
* instances (e.g. scratch space for computations), though anything not
|
||||
* returned in the form of a \ref WorkResult will eventually be lost.
|
||||
* Each \ref Worker (both locally and remotely) has its own \ref WorkProcessor,
|
||||
* instances (e.g. scratch space for computations), though anything not
|
||||
* returned in the form of a \ref WorkResult will eventually be lost.
|
||||
* Each \ref Worker (both locally and remotely) has its own \ref WorkProcessor,
|
||||
* and therefore no form of locking is required within instances of this class.
|
||||
*
|
||||
* \sa WorkUnit
|
||||
* \sa WorkResult
|
||||
* \sa ParallelProcess
|
||||
* \sa Scheduler
|
||||
* \sa Scheduler
|
||||
* \ingroup libcore
|
||||
* \ingroup libpython
|
||||
*/
|
||||
|
@ -125,9 +125,9 @@ public:
|
|||
virtual ref<WorkResult> createWorkResult() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a copy of this work processor instance.
|
||||
*
|
||||
* \remark In practice, before the cloned work processor
|
||||
* \brief Create a copy of this work processor instance.
|
||||
*
|
||||
* \remark In practice, before the cloned work processor
|
||||
* is actually used, its \ref prepare() method will be called.
|
||||
* Therefore, any state that is initialized in \ref prepeare()
|
||||
* does not have to be copied.
|
||||
|
@ -135,25 +135,25 @@ public:
|
|||
virtual ref<WorkProcessor> clone() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Called once before processing starts.
|
||||
*
|
||||
* This is useful for allocating scratch space or resolving references
|
||||
* to resource objects. Lengthy computations should be performed in
|
||||
* \brief Called once before processing starts.
|
||||
*
|
||||
* This is useful for allocating scratch space or resolving references
|
||||
* to resource objects. Lengthy computations should be performed in
|
||||
* process() instead of here, since this this method will be called
|
||||
* while the central scheduler lock is held. A thrown exception will
|
||||
* while the central scheduler lock is held. A thrown exception will
|
||||
* lead to the termination of the parallel process.
|
||||
*/
|
||||
virtual void prepare() = 0;
|
||||
|
||||
/**
|
||||
* \brief Process a work unit and store the computed results.
|
||||
*
|
||||
* The <tt>active</tt> parameter can be used to signal a premature
|
||||
* stop of the execution flow. In this case, the work result is allowed
|
||||
*
|
||||
* The <tt>active</tt> parameter can be used to signal a premature
|
||||
* stop of the execution flow. In this case, the work result is allowed
|
||||
* to be undefined (it will simply be ignored). A thrown exception will
|
||||
* lead to the termination of the parallel process.
|
||||
*/
|
||||
virtual void process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||
virtual void process(const WorkUnit *workUnit, WorkResult *workResult,
|
||||
const bool &stop) = 0;
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
@ -162,11 +162,11 @@ protected:
|
|||
virtual ~WorkProcessor() { }
|
||||
/// Protected constructors
|
||||
inline WorkProcessor() { }
|
||||
inline WorkProcessor(Stream *stream, InstanceManager *manager)
|
||||
inline WorkProcessor(Stream *stream, InstanceManager *manager)
|
||||
: SerializableObject(stream, manager) { }
|
||||
|
||||
/**
|
||||
* \brief Look up a named resource, which has been bound to
|
||||
* \brief Look up a named resource, which has been bound to
|
||||
* the associated parallel process.
|
||||
*
|
||||
* Throws an exception if the resource is not known / bound.
|
||||
|
@ -177,18 +177,18 @@ protected:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Abstract parallelizable task.
|
||||
* \brief Abstract parallelizable task.
|
||||
*
|
||||
* Instances of this class model a larger piece of work that can be split
|
||||
* into independent `units' and subsequently farmed out over a cluster or
|
||||
* processed locally. After the work units have been completed, the results
|
||||
* are pieced back together to a solution of the original large-scale problem.
|
||||
* Instances of this class model a larger piece of work that can be split
|
||||
* into independent `units' and subsequently farmed out over a cluster or
|
||||
* processed locally. After the work units have been completed, the results
|
||||
* are pieced back together to a solution of the original large-scale problem.
|
||||
*
|
||||
* This class implements the core logic running on the central scheduling
|
||||
* server, i.e. the part that is responsible for generating work units and
|
||||
* accepting their results. The module that performs the actual computation
|
||||
* This class implements the core logic running on the central scheduling
|
||||
* server, i.e. the part that is responsible for generating work units and
|
||||
* accepting their results. The module that performs the actual computation
|
||||
* is an instance of \ref WorkProcessor, which is also specified here.
|
||||
* Finally, the this class references `resources', which denote
|
||||
* Finally, the this class references `resources', which denote
|
||||
* chunks of globally shared read-only data required during execution.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -211,22 +211,22 @@ public:
|
|||
/**
|
||||
* \brief Generate a piece of work.
|
||||
*
|
||||
* Takes a pre-allocated \ref WorkUnit instance of
|
||||
* the appropriate sub-type and size (as specified by
|
||||
* \ref ParallelProcess::getWorkUnitName()) and
|
||||
* Takes a pre-allocated \ref WorkUnit instance of
|
||||
* the appropriate sub-type and size (as specified by
|
||||
* \ref ParallelProcess::getWorkUnitName()) and
|
||||
* fills it with the appropriate content. Returns ESuccess
|
||||
* on success and EFailure or EPause when no more work is
|
||||
* left -- in that case, the work unit will be ignored and
|
||||
* the process completed (\ref EFailure) or temporarily
|
||||
* paused (\ref EPause). When \ref EPause was used,
|
||||
* resubmission via \ref Scheduler::schedule() will
|
||||
* be required once more work is available. In some cases, it
|
||||
* left -- in that case, the work unit will be ignored and
|
||||
* the process completed (\ref EFailure) or temporarily
|
||||
* paused (\ref EPause). When \ref EPause was used,
|
||||
* resubmission via \ref Scheduler::schedule() will
|
||||
* be required once more work is available. In some cases, it
|
||||
* is useful to distribute 'nearby' pieces of work to the same
|
||||
* processor -- the \c worker parameter can be used to
|
||||
* processor -- the \c worker parameter can be used to
|
||||
* implement this.
|
||||
* This function should run as quickly as possible, since it
|
||||
* will be executed while the scheduler mutex is held. A
|
||||
* thrown exception will lead to the termination of the
|
||||
* This function should run as quickly as possible, since it
|
||||
* will be executed while the scheduler mutex is held. A
|
||||
* thrown exception will lead to the termination of the
|
||||
* parallel process.
|
||||
*
|
||||
* \param unit Work unit data structure to be filled
|
||||
|
@ -237,7 +237,7 @@ public:
|
|||
/**
|
||||
* \brief Called whenever a work unit has been completed.
|
||||
*
|
||||
* Note that this function may concurrently be executed by
|
||||
* Note that this function may concurrently be executed by
|
||||
* multiple threads. Also, processing of work results will
|
||||
* generally be out of order with respect to the creation
|
||||
* in \ref generateWork().
|
||||
|
@ -245,17 +245,17 @@ public:
|
|||
* When a work unit is only partially completed due to
|
||||
* a call to \ref Scheduler::cancel(), the second
|
||||
* parameter is set to true.
|
||||
* A thrown exception will lead to the termination of
|
||||
* A thrown exception will lead to the termination of
|
||||
* the parallel process.
|
||||
*
|
||||
* \param result Work result to be processed
|
||||
* \param cancelled Was the associated work unit not fully completed
|
||||
*/
|
||||
virtual void processResult(const WorkResult *result,
|
||||
virtual void processResult(const WorkResult *result,
|
||||
bool cancelled) = 0;
|
||||
|
||||
/**
|
||||
* \brief Called when the parallel process is canceled by
|
||||
* \brief Called when the parallel process is canceled by
|
||||
* \ref Scheduler::cancel().
|
||||
*
|
||||
* The default implementation does nothing.
|
||||
|
@ -265,9 +265,9 @@ public:
|
|||
/**
|
||||
* \brief Query the return status of a process after its
|
||||
* execution has finished.
|
||||
*
|
||||
*
|
||||
* Returns one of \ref Success, \ref Failure or \ref Unknown.
|
||||
* (\ref EUnknown means that the process is either still running
|
||||
* (\ref EUnknown means that the process is either still running
|
||||
* or has never been scheduled).
|
||||
*/
|
||||
inline EStatus getReturnStatus() const { return m_returnStatus; }
|
||||
|
@ -281,10 +281,10 @@ public:
|
|||
/**
|
||||
* \brief Bind a resource to this parallel process.
|
||||
*
|
||||
* Takes a resource ID as given by the scheduler and associates it
|
||||
* with a name. This name can later be used by the work processor
|
||||
* Takes a resource ID as given by the scheduler and associates it
|
||||
* with a name. This name can later be used by the work processor
|
||||
* to access the resource data.
|
||||
*
|
||||
*
|
||||
* \param name Process-specific name of the resource
|
||||
* \param id Resource ID as returned by \ref Scheduler::registerResource()
|
||||
* \sa WorkProcessor::getResource
|
||||
|
@ -294,8 +294,8 @@ public:
|
|||
/**
|
||||
* \brief Is this process strictly local?
|
||||
*
|
||||
* If a process is marked as local, it shouldn't be distributed
|
||||
* to remote processing nodes. The default implementation
|
||||
* If a process is marked as local, it shouldn't be distributed
|
||||
* to remote processing nodes. The default implementation
|
||||
* returns false.
|
||||
*/
|
||||
virtual bool isLocal() const;
|
||||
|
@ -313,10 +313,10 @@ public:
|
|||
inline const ResourceBindings &getResourceBindings() const { return m_bindings; }
|
||||
|
||||
/**
|
||||
* \brief Return a list of plugins required by this parallel process.
|
||||
* \brief Return a list of plugins required by this parallel process.
|
||||
*
|
||||
* This is required so that remote machines can load the plugins before
|
||||
* they accept work from this process. The default implementation just
|
||||
* they accept work from this process. The default implementation just
|
||||
* returns all plugins that are loaded in the current application.
|
||||
*/
|
||||
virtual std::vector<std::string> getRequiredPlugins();
|
||||
|
@ -324,7 +324,7 @@ public:
|
|||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
/// Protected constructor
|
||||
inline ParallelProcess() : m_returnStatus(EUnknown),
|
||||
inline ParallelProcess() : m_returnStatus(EUnknown),
|
||||
m_logLevel(EDebug) { }
|
||||
/// Virtual destructor
|
||||
virtual ~ParallelProcess() { }
|
||||
|
@ -339,10 +339,10 @@ class Worker;
|
|||
/**
|
||||
* \brief Centralized task scheduler implementation.
|
||||
*
|
||||
* Accepts parallelizable jobs and distributes their computational load
|
||||
* both locally and remotely. This is done by associating different types
|
||||
* of \ref Worker instances with the scheduler. These try to acquire work
|
||||
* units from the scheduler, which are then executed on the current machine
|
||||
* Accepts parallelizable jobs and distributes their computational load
|
||||
* both locally and remotely. This is done by associating different types
|
||||
* of \ref Worker instances with the scheduler. These try to acquire work
|
||||
* units from the scheduler, which are then executed on the current machine
|
||||
* or sent to remote nodes over a network connection.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -354,7 +354,7 @@ public:
|
|||
/**
|
||||
* \brief Schedule a parallelizable process for execution.
|
||||
*
|
||||
* If the scheduler is currently running and idle, its execution
|
||||
* If the scheduler is currently running and idle, its execution
|
||||
* will begin immediately. Returns \c false if the process
|
||||
* is already scheduled and has not yet terminated and \c true
|
||||
* in any other case.
|
||||
|
@ -363,15 +363,15 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Block until the process has successfully been completed
|
||||
* or canceled prematurely.
|
||||
* or canceled prematurely.
|
||||
*
|
||||
* Returns false if the process does not exist or has already
|
||||
* Returns false if the process does not exist or has already
|
||||
* finished by the time \ref wait() is invoked.
|
||||
*/
|
||||
bool wait(const ParallelProcess *process);
|
||||
|
||||
/**
|
||||
* \brief Cancel the execution of a parallelizable process.
|
||||
* \brief Cancel the execution of a parallelizable process.
|
||||
*
|
||||
* Upon return, no more work from this process is running.
|
||||
* Returns false if the process does not exist (anymore).
|
||||
|
@ -383,21 +383,21 @@ public:
|
|||
/**
|
||||
* \brief Register a serializable resource with the scheduler.
|
||||
*
|
||||
* A resource should be thought of as a constant state that is shared
|
||||
* amongst all processing nodes. Resources can be reused by
|
||||
* subsequent parallel processes, and consequently do not have to be
|
||||
* re-transmitted over the network. Returns a resource ID, which can be
|
||||
* A resource should be thought of as a constant state that is shared
|
||||
* amongst all processing nodes. Resources can be reused by
|
||||
* subsequent parallel processes, and consequently do not have to be
|
||||
* re-transmitted over the network. Returns a resource ID, which can be
|
||||
* used to reference the associated data.
|
||||
*/
|
||||
int registerResource(SerializableObject *resource);
|
||||
|
||||
/**
|
||||
* \brief Register a \a multiple resource with the scheduler.
|
||||
* \brief Register a \a multiple resource with the scheduler.
|
||||
*
|
||||
* \a Multi means that in comparison to the previous method, a separate
|
||||
* instance is provided for every core. An example where this is useful
|
||||
* is to distribute random generator state when performing parallel
|
||||
* Monte Carlo simulations. \c resources must be a vector whose
|
||||
* \a Multi means that in comparison to the previous method, a separate
|
||||
* instance is provided for every core. An example where this is useful
|
||||
* is to distribute random generator state when performing parallel
|
||||
* Monte Carlo simulations. \c resources must be a vector whose
|
||||
* length is equal to \ref getCoreCount().
|
||||
*/
|
||||
int registerMultiResource(std::vector<SerializableObject *> &resources);
|
||||
|
@ -412,10 +412,10 @@ public:
|
|||
*/
|
||||
void retainResource(int resourceID);
|
||||
|
||||
/**
|
||||
* \brief Unregister a resource from the scheduler
|
||||
*
|
||||
* Note that the resource's won't be removed until all processes using
|
||||
/**
|
||||
* \brief Unregister a resource from the scheduler
|
||||
*
|
||||
* Note that the resource's won't be removed until all processes using
|
||||
* it have terminated)
|
||||
*/
|
||||
void unregisterResource(int id);
|
||||
|
@ -446,7 +446,7 @@ public:
|
|||
void start();
|
||||
|
||||
/**
|
||||
* \brief Pause the distribution of work units and shut down all
|
||||
* \brief Pause the distribution of work units and shut down all
|
||||
* running workers.
|
||||
*
|
||||
* Any currently scheduled work units are still completed.
|
||||
|
@ -512,8 +512,8 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* Data structure, which contains a piece of work
|
||||
* as well as the information required to either execute
|
||||
* Data structure, which contains a piece of work
|
||||
* as well as the information required to either execute
|
||||
* it locally or submit it to a processing node over the
|
||||
* network.
|
||||
*/
|
||||
|
@ -528,7 +528,7 @@ public:
|
|||
ref<WorkResult> workResult;
|
||||
bool stop;
|
||||
|
||||
inline Item() : id(-1), workerIndex(-1), coreOffset(-1),
|
||||
inline Item() : id(-1), workerIndex(-1), coreOffset(-1),
|
||||
proc(NULL), rec(NULL), stop(false) {
|
||||
}
|
||||
|
||||
|
@ -541,12 +541,12 @@ public:
|
|||
int refCount;
|
||||
bool multi;
|
||||
|
||||
inline ResourceRecord(SerializableObject *resource)
|
||||
inline ResourceRecord(SerializableObject *resource)
|
||||
: resources(1), refCount(1), multi(false) {
|
||||
resources[0] = resource;
|
||||
}
|
||||
|
||||
inline ResourceRecord(std::vector<SerializableObject *> resources)
|
||||
inline ResourceRecord(std::vector<SerializableObject *> resources)
|
||||
: resources(resources), refCount(1), multi(true) {
|
||||
}
|
||||
};
|
||||
|
@ -569,7 +569,7 @@ public:
|
|||
const MemoryStream *getResourceStream(int id);
|
||||
|
||||
/**
|
||||
* \brief Test whether this is a multi-resource,
|
||||
* \brief Test whether this is a multi-resource,
|
||||
* i.e. different for every core.
|
||||
*/
|
||||
bool isMultiResource(int id) const;
|
||||
|
@ -615,7 +615,7 @@ protected:
|
|||
bool cancel(ParallelProcess *proc, bool reduceInflight);
|
||||
|
||||
/**
|
||||
* Internally used to prepare a Scheduler::Item structure
|
||||
* Internally used to prepare a Scheduler::Item structure
|
||||
* when only the process ID is known.
|
||||
*/
|
||||
inline void setProcessByID(Item &item, int id) {
|
||||
|
@ -683,12 +683,12 @@ protected:
|
|||
|
||||
/// Protected constructor
|
||||
Worker(const std::string &name);
|
||||
|
||||
|
||||
/* Decrement reference counts to any referenced objects */
|
||||
virtual void clear();
|
||||
|
||||
/// Used internally by the scheduler
|
||||
virtual void start(Scheduler *scheduler,
|
||||
virtual void start(Scheduler *scheduler,
|
||||
int workerIndex, int coreOffset);
|
||||
|
||||
/**
|
||||
|
@ -702,7 +702,7 @@ protected:
|
|||
/**
|
||||
* \brief Called to inform a worker that a process has been cancelled
|
||||
*
|
||||
* Guaranteed to be called while the Scheduler's main lock is held.
|
||||
* Guaranteed to be called while the Scheduler's main lock is held.
|
||||
*/
|
||||
virtual void signalProcessCancellation(int id) = 0;
|
||||
|
||||
|
@ -731,9 +731,9 @@ protected:
|
|||
void setProcessByID(Scheduler::Item &item, int id) {
|
||||
return m_scheduler->setProcessByID(item, id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancel the currently scheduled parallel process and possibly
|
||||
* Cancel the currently scheduled parallel process and possibly
|
||||
* reduce the number of in-flight work units
|
||||
* Returns false if the process does not exist (anymore).
|
||||
*/
|
||||
|
@ -748,7 +748,7 @@ protected:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Acquires work from the scheduler and executes
|
||||
* \brief Acquires work from the scheduler and executes
|
||||
* it locally.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
|
|
@ -51,7 +51,7 @@ class MTS_EXPORT_CORE RemoteWorker : public Worker {
|
|||
friend class RemoteWorkerReader;
|
||||
public:
|
||||
/**
|
||||
* \brief Construct a new remote worker with the given name and
|
||||
* \brief Construct a new remote worker with the given name and
|
||||
* communication stream
|
||||
*/
|
||||
RemoteWorker(const std::string &name, Stream *stream);
|
||||
|
@ -68,7 +68,7 @@ protected:
|
|||
virtual void clear();
|
||||
virtual void signalResourceExpiration(int id);
|
||||
virtual void signalProcessCancellation(int id);
|
||||
virtual void signalProcessTermination(int id);
|
||||
virtual void signalProcessTermination(int id);
|
||||
virtual void start(Scheduler *scheduler, int workerIndex, int coreOffset);
|
||||
void flush();
|
||||
|
||||
|
@ -95,7 +95,7 @@ protected:
|
|||
|
||||
/**
|
||||
* \brief Communication helper thread required by \ref RemoteWorker.
|
||||
*
|
||||
*
|
||||
* Constantly waits for finished work units sent by the processing node.
|
||||
*/
|
||||
class MTS_EXPORT_CORE RemoteWorkerReader : public Thread {
|
||||
|
@ -136,12 +136,12 @@ public:
|
|||
* \param backend The responsible server-side communication backend
|
||||
* \param proc Work processor instance for use with this process
|
||||
*/
|
||||
RemoteProcess(int id, ELogLevel logLevel,
|
||||
RemoteProcess(int id, ELogLevel logLevel,
|
||||
StreamBackend *backend, WorkProcessor *proc);
|
||||
|
||||
/* ParallelProcess interface implementation */
|
||||
EStatus generateWork(WorkUnit *unit, int worker);
|
||||
void processResult(const WorkResult *result,
|
||||
void processResult(const WorkResult *result,
|
||||
bool cancelled);
|
||||
ref<WorkProcessor> createWorkProcessor() const;
|
||||
void handleCancellation();
|
||||
|
@ -189,7 +189,7 @@ private:
|
|||
/**
|
||||
* \brief Network processing communication backend
|
||||
*
|
||||
* Attaches to the end of a stream, accepts work units and forwards
|
||||
* Attaches to the end of a stream, accepts work units and forwards
|
||||
* them to the local scheduler. Can be used to create network processing nodes.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -229,7 +229,7 @@ public:
|
|||
* \param detach
|
||||
* Should the associated thread be joinable or detach instead?
|
||||
*/
|
||||
StreamBackend(const std::string &name, Scheduler *scheduler,
|
||||
StreamBackend(const std::string &name, Scheduler *scheduler,
|
||||
const std::string &nodeName, Stream *stream, bool detach);
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
|
|
@ -87,7 +87,7 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void generate(int order,
|
||||
void generate(int order,
|
||||
EDirection front, EDirection right,
|
||||
EDirection back, EDirection left) {
|
||||
if (order == 0) {
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/* Precompute normalization coefficients for the first 10 bands */
|
||||
#define SH_NORMTBL_SIZE 10
|
||||
#define SH_NORMTBL_SIZE 10
|
||||
|
||||
namespace ublas = boost::numeric::ublas;
|
||||
|
||||
struct SHVector;
|
||||
|
||||
/**
|
||||
* \brief Stores the diagonal blocks of a spherical harmonic
|
||||
* \brief Stores the diagonal blocks of a spherical harmonic
|
||||
* rotation matrix
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -52,7 +52,7 @@ struct MTS_EXPORT_CORE SHRotation {
|
|||
|
||||
/**
|
||||
* \brief Transform a coefficient vector and store the result into
|
||||
* the given target vector.
|
||||
* the given target vector.
|
||||
*
|
||||
* The source and target must have the same number of bands.
|
||||
*/
|
||||
|
@ -63,9 +63,9 @@ struct MTS_EXPORT_CORE SHRotation {
|
|||
* \brief Stores a truncated real spherical harmonics representation of
|
||||
* an L2-integrable function.
|
||||
*
|
||||
* Also provides some other useful functionality, such as evaluation,
|
||||
* Also provides some other useful functionality, such as evaluation,
|
||||
* projection and rotation.
|
||||
*
|
||||
*
|
||||
* The Mathematica equivalent of the basis functions implemented here is:
|
||||
*
|
||||
* \code
|
||||
|
@ -231,8 +231,8 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Convolve the SH representation with the supplied kernel.
|
||||
*
|
||||
* Based on the Funk-Hecke theorem -- the kernel must be rotationally
|
||||
*
|
||||
* Based on the Funk-Hecke theorem -- the kernel must be rotationally
|
||||
* symmetric around the Z-axis.
|
||||
*/
|
||||
void convolve(const SHVector &kernel);
|
||||
|
@ -282,7 +282,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int l=0; l<m_bands; ++l)
|
||||
for (int m=-l; m<=l; ++m)
|
||||
operator()(l,m) *= hExt*hInt/9;
|
||||
|
@ -329,18 +329,18 @@ public:
|
|||
if (l < SH_NORMTBL_SIZE)
|
||||
return m_normalization[l*(l+1)/2 + m];
|
||||
else
|
||||
return computeNormalization(l, m);
|
||||
return computeNormalization(l, m);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Recursively computes rotation matrices for each band of SH coefficients.
|
||||
*
|
||||
* Based on 'Rotation Matrices for Real Spherical Harmonics. Direct Determination by Recursion'
|
||||
* by Ivanic and Ruedenberg. The implemented tables follow the notation in
|
||||
* Based on 'Rotation Matrices for Real Spherical Harmonics. Direct Determination by Recursion'
|
||||
* by Ivanic and Ruedenberg. The implemented tables follow the notation in
|
||||
* 'Spherical Harmonic Lighting: The Gritty Details' by Robin Green.
|
||||
*/
|
||||
static void rotation(const Transform &t, SHRotation &rot);
|
||||
|
||||
|
||||
/// Precomputes normalization coefficients for the first few bands
|
||||
static void staticInitialization();
|
||||
|
||||
|
@ -366,7 +366,7 @@ class MTS_EXPORT_CORE SHSampler : public Object {
|
|||
public:
|
||||
/**
|
||||
* \brief Precompute a spherical harmonics sampler object
|
||||
*
|
||||
*
|
||||
* \param bands Number of SH coefficient bands to support
|
||||
* \param depth Number of recursive sample warping steps.
|
||||
*/
|
||||
|
@ -376,7 +376,7 @@ public:
|
|||
* \brief Warp a uniform sample in [0,1]^2 to one that is
|
||||
* approximately proportional to the specified function.
|
||||
*
|
||||
* The resulting sample will have spherical coordinates
|
||||
* The resulting sample will have spherical coordinates
|
||||
* [0,pi]x[0,2pi] and its actual PDF (which might be
|
||||
* slightly different from the function evaluated at the
|
||||
* sample, even if $f$ is a distribution) will be returned.
|
||||
|
|
|
@ -30,14 +30,14 @@ MTS_NAMESPACE_BEGIN
|
|||
*
|
||||
* This class implements a simple and efficient one-entry storage for caching
|
||||
* the result of a call to an expensive-to-evaluate function that has no side
|
||||
* effects.
|
||||
* effects.
|
||||
*
|
||||
* The target application is a situation where multiple threads are causing
|
||||
* calls to such a function and each individual thread may invoke it a few
|
||||
* The target application is a situation where multiple threads are causing
|
||||
* calls to such a function and each individual thread may invoke it a few
|
||||
* times in a row using the same input argument.
|
||||
*
|
||||
* This storage class provides the means to avoid re-evaluating the function
|
||||
* in this case. By isolating threads from one another, it does not suffer
|
||||
*
|
||||
* This storage class provides the means to avoid re-evaluating the function
|
||||
* in this case. By isolating threads from one another, it does not suffer
|
||||
* heavy costs for inter-thread synchronizations.
|
||||
*
|
||||
* Here is an example snippet:
|
||||
|
@ -68,7 +68,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \tparam ReturnType
|
||||
* Return type of the function whose return values should be cached
|
||||
*/
|
||||
template <typename ArgType, typename ReturnType> class SimpleCache
|
||||
template <typename ArgType, typename ReturnType> class SimpleCache
|
||||
: protected PrimitiveThreadLocal< std::pair<ArgType, ReturnType> > {
|
||||
protected:
|
||||
typedef std::pair<ArgType, ReturnType> ValueType;
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
* \brief Integrate the spectral power distribution
|
||||
* over a given interval and return the average value
|
||||
*
|
||||
* Unless overridden in a subclass, the integration is done
|
||||
* Unless overridden in a subclass, the integration is done
|
||||
* using adaptive Gauss-Lobatto quadrature.
|
||||
*
|
||||
* \param lambdaMin
|
||||
|
@ -73,7 +73,7 @@ public:
|
|||
* implementation will return zero.
|
||||
*/
|
||||
virtual Float average(Float lambdaMin, Float lambdaMax) const;
|
||||
|
||||
|
||||
/// \brief Return a string representation
|
||||
virtual std::string toString() const = 0;
|
||||
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
/**
|
||||
* \brief Spectral power distribution based on Planck's black body law
|
||||
*
|
||||
* Computes the spectral power distribution of a black body of the
|
||||
* Computes the spectral power distribution of a black body of the
|
||||
* specified temperature.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -104,11 +104,11 @@ public:
|
|||
/** \brief Return the value of the spectral power distribution
|
||||
* at the given wavelength.
|
||||
*
|
||||
* The units are Watts per unit surface area (m^-2)
|
||||
* The units are Watts per unit surface area (m^-2)
|
||||
* per unit wavelength (nm^-1) per steradian (sr^-1)
|
||||
*/
|
||||
virtual Float eval(Float lambda) const;
|
||||
|
||||
|
||||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
private:
|
||||
|
@ -119,7 +119,7 @@ private:
|
|||
* \brief Spectral distribution for rendering participating media
|
||||
* with Rayleigh scattering.
|
||||
*
|
||||
* This distribution captures the 1/lambda^4 wavelength dependence
|
||||
* This distribution captures the 1/lambda^4 wavelength dependence
|
||||
* of Rayleigh scattering. It can provide both the scattering and
|
||||
* extinction coefficient needed for simulating planetary
|
||||
* atmospheres with participating media.
|
||||
|
@ -138,7 +138,7 @@ public:
|
|||
/**
|
||||
* \brief Create a Rayleigh spectrum instance
|
||||
*
|
||||
* \param mode Specifies the requested type of spectrum
|
||||
* \param mode Specifies the requested type of spectrum
|
||||
* \param eta Refractive index of the medium (e.g. air)
|
||||
* \param height Height above sea level (in meters)
|
||||
*/
|
||||
|
@ -147,12 +147,12 @@ public:
|
|||
virtual ~RayleighSpectrum() { }
|
||||
|
||||
/** \brief Evaluate the extinction/scattering coefficient for
|
||||
* a specified wavelength.
|
||||
* a specified wavelength.
|
||||
*
|
||||
* The returned value is in units of 1/meter.
|
||||
*/
|
||||
virtual Float eval(Float lambda) const;
|
||||
|
||||
|
||||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
private:
|
||||
|
@ -168,7 +168,7 @@ public:
|
|||
/** \brief Return the value of the spectral power distribution
|
||||
* at the given wavelength.
|
||||
*/
|
||||
ProductSpectrum(const ContinuousSpectrum &s1,
|
||||
ProductSpectrum(const ContinuousSpectrum &s1,
|
||||
const ContinuousSpectrum &s2) : m_spec1(s1),
|
||||
m_spec2(s2) { }
|
||||
|
||||
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
/// Virtual destructor
|
||||
virtual ~ProductSpectrum() { }
|
||||
|
||||
|
||||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
private:
|
||||
|
@ -191,19 +191,19 @@ private:
|
|||
* \brief Linearly interpolated spectral power distribution
|
||||
*
|
||||
* This class implements a linearly interpolated spectral
|
||||
* power distribution that is defined over a discrete set of
|
||||
* power distribution that is defined over a discrete set of
|
||||
* measurements at different wavelengths. Outside of the
|
||||
* specified range, the spectrum is assumed to be zero. Hence,
|
||||
* at least two entries are required to produce a nonzero
|
||||
* at least two entries are required to produce a nonzero
|
||||
* spectrum.
|
||||
*
|
||||
* \ingroup libcore
|
||||
* \ingroup libpython
|
||||
* \ingroup libpython
|
||||
*/
|
||||
class MTS_EXPORT_CORE InterpolatedSpectrum : public ContinuousSpectrum {
|
||||
public:
|
||||
/**
|
||||
* \brief Create a new interpolated spectrum with space
|
||||
* \brief Create a new interpolated spectrum with space
|
||||
* for the specified number of samples
|
||||
*/
|
||||
InterpolatedSpectrum(size_t size = 0);
|
||||
|
@ -235,7 +235,7 @@ public:
|
|||
void append(Float lambda, Float value);
|
||||
|
||||
/**
|
||||
* \brief This function adds a zero entry before and after
|
||||
* \brief This function adds a zero entry before and after
|
||||
* the stored wavelength range.
|
||||
*
|
||||
* This is useful when handling datasets that don't fall
|
||||
|
@ -258,7 +258,7 @@ public:
|
|||
* \brief Integrate the spectral power distribution
|
||||
* over a given interval and return the average value
|
||||
*
|
||||
* This method overrides the implementation in
|
||||
* This method overrides the implementation in
|
||||
* \ref ContinousSpectrum, since the integral can be
|
||||
* analytically computed for linearly interpolated spectra.
|
||||
*
|
||||
|
@ -285,7 +285,7 @@ protected:
|
|||
/**
|
||||
* \brief Abstract spectral power distribution data type
|
||||
*
|
||||
* This class defines a vector-like data type that can be used for
|
||||
* This class defines a vector-like data type that can be used for
|
||||
* computations involving radiance. A concrete instantiation for the
|
||||
* precision and spectral discretization chosen at compile time is
|
||||
* given by the \ref Spectrum data type.
|
||||
|
@ -402,7 +402,7 @@ public:
|
|||
s[i] /= spec.s[i];
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Perform a component-wise division by another spectrum
|
||||
inline TSpectrum operator/(const TSpectrum &spec) const {
|
||||
TSpectrum value = *this;
|
||||
|
@ -554,7 +554,7 @@ public:
|
|||
for (int i=0; i<N; i++) {
|
||||
if (s[i] != 0.0f)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -574,7 +574,7 @@ public:
|
|||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
Scalar s[N];
|
||||
};
|
||||
|
@ -611,15 +611,15 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/** \brief Discrete spectral power distribution based on a number
|
||||
* of wavelength bins over the 360-830 nm range.
|
||||
/** \brief Discrete spectral power distribution based on a number
|
||||
* of wavelength bins over the 360-830 nm range.
|
||||
*
|
||||
* This class defines a vector-like data type that can be used for
|
||||
* This class defines a vector-like data type that can be used for
|
||||
* computations involving radiance.
|
||||
*
|
||||
* When configured for spectral rendering (i.e. when the compile-time flag
|
||||
* \c SPECTRUM_SAMPLES is set to a value != 3), the implementation discretizes
|
||||
* the visible spectrum of light into a set of intervals, where the
|
||||
* \c SPECTRUM_SAMPLES is set to a value != 3), the implementation discretizes
|
||||
* the visible spectrum of light into a set of intervals, where the
|
||||
* distribution within each bin is modeled as being uniform.
|
||||
*
|
||||
* When SPECTRUM_SAMPLES == 3, the class reverts to a simple linear
|
||||
|
@ -628,7 +628,7 @@ public:
|
|||
* The implementation of this class is based on PBRT.
|
||||
*
|
||||
* \ingroup libcore
|
||||
* \ingroup libpython
|
||||
* \ingroup libpython
|
||||
*/
|
||||
struct MTS_EXPORT_CORE Spectrum : public TSpectrum<Float, SPECTRUM_SAMPLES> {
|
||||
public:
|
||||
|
@ -700,7 +700,7 @@ public:
|
|||
#endif
|
||||
|
||||
/**
|
||||
* \brief Convert from a spectral power distribution to XYZ
|
||||
* \brief Convert from a spectral power distribution to XYZ
|
||||
* tristimulus values
|
||||
*
|
||||
* In the Python API, this function returns a 3-tuple
|
||||
|
@ -712,11 +712,11 @@ public:
|
|||
* \brief Convert XYZ tristimulus into a plausible spectral
|
||||
* power distribution
|
||||
*
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* information on how to solve this highly under-constrained problem.
|
||||
* The default is \ref EReflectance.
|
||||
*/
|
||||
void fromXYZ(Float x, Float y, Float z,
|
||||
void fromXYZ(Float x, Float y, Float z,
|
||||
EConversionIntent intent = EReflectance);
|
||||
|
||||
#if SPECTRUM_SAMPLES == 3
|
||||
|
@ -750,12 +750,12 @@ public:
|
|||
* \brief Convert linear RGB colors into a plausible
|
||||
* spectral power distribution
|
||||
*
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* information on how to solve this highly under-constrained problem.
|
||||
* The default is \ref EReflectance.
|
||||
*/
|
||||
void fromLinearRGB(Float r, Float g, Float b,
|
||||
EConversionIntent intent = EReflectance);
|
||||
void fromLinearRGB(Float r, Float g, Float b,
|
||||
EConversionIntent intent = EReflectance);
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -771,7 +771,7 @@ public:
|
|||
* power distribution
|
||||
*
|
||||
* Note that compared to \ref fromLinearRGB, no \c intent parameter
|
||||
* is available. For sRGB colors, it is assumed that the intent is
|
||||
* is available. For sRGB colors, it is assumed that the intent is
|
||||
* always \ref EReflectance.
|
||||
*/
|
||||
void fromSRGB(Float r, Float g, Float b);
|
||||
|
@ -782,13 +782,13 @@ public:
|
|||
*
|
||||
* Based on code by Bruce Walter and Greg ward.
|
||||
*
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* The \ref EConversionIntent parameter can be used to provide more
|
||||
* information on how to solve this highly under-constrained problem.
|
||||
* For RGBE values, the default is \ref EIlluminant.
|
||||
*/
|
||||
void fromRGBE(const uint8_t rgbe[4], EConversionIntent intent = EIlluminant);
|
||||
|
||||
/// Linear RGBE conversion based on Bruce Walter's and Greg Ward's code
|
||||
/// Linear RGBE conversion based on Bruce Walter's and Greg Ward's code
|
||||
void toRGBE(uint8_t rgbe[4]) const;
|
||||
|
||||
/// Initialize with spectral values from a smooth spectrum representation
|
||||
|
@ -811,10 +811,10 @@ public:
|
|||
/// Return a string representation
|
||||
std::string toString() const;
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Static initialization (should be called once during the
|
||||
* application's initialization phase)
|
||||
*
|
||||
*
|
||||
* This function is responsible for choosing the wavelengths
|
||||
* that will be used during rendering. It also pre-integrates
|
||||
* the CIE matching curves so that sampled spectra can
|
||||
|
@ -828,8 +828,8 @@ protected:
|
|||
#if SPECTRUM_SAMPLES != 3
|
||||
/// Configured wavelengths bins in nanometers
|
||||
static Float m_wavelengths[SPECTRUM_SAMPLES+1];
|
||||
|
||||
/// @{ \name Pre-integrated CIE 1931 XYZ color matching functions.
|
||||
|
||||
/// @{ \name Pre-integrated CIE 1931 XYZ color matching functions.
|
||||
static Spectrum CIE_X;
|
||||
static Spectrum CIE_Y;
|
||||
static Spectrum CIE_Z;
|
||||
|
|
|
@ -88,19 +88,19 @@ union SSEVector {
|
|||
: ps(ps) {
|
||||
}
|
||||
|
||||
explicit SSEVector(float f0, float f1, float f2, float f3)
|
||||
explicit SSEVector(float f0, float f1, float f2, float f3)
|
||||
: f0(f0), f1(f1), f2(f2), f3(f3) {
|
||||
}
|
||||
|
||||
explicit SSEVector(float f) : f0(f), f1(f), f2(f), f3(f) {}
|
||||
|
||||
explicit SSEVector(int32_t i0, int32_t i1, int32_t i2, int32_t i3)
|
||||
|
||||
explicit SSEVector(int32_t i0, int32_t i1, int32_t i2, int32_t i3)
|
||||
: i0(i0), i1(i1), i2(i2), i3(i3) {
|
||||
}
|
||||
|
||||
explicit SSEVector(int32_t i) : i0(i), i1(i), i2(i), i3(i) {}
|
||||
|
||||
explicit SSEVector(uint32_t ui0, uint32_t ui1, uint32_t ui2, uint32_t ui3)
|
||||
explicit SSEVector(uint32_t ui0, uint32_t ui1, uint32_t ui2, uint32_t ui3)
|
||||
: ui0(ui0), ui1(ui1), ui2(ui2), ui3(ui3) {
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace math {
|
|||
extern MTS_EXPORT_CORE __m128 cos_ps(__m128 x);
|
||||
|
||||
/**
|
||||
* \brief SIMD (SSE2) implementation which simultaneously
|
||||
* \brief SIMD (SSE2) implementation which simultaneously
|
||||
* computes the sine and cosine of a given value
|
||||
* \author Julien Pommier
|
||||
*/
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
-----------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------
|
||||
Primary author:
|
||||
Edgar Velazquez-Armendariz <cs#cornell#edu - eva5>
|
||||
============================================================================*/
|
||||
|
|
|
@ -27,17 +27,17 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
|
||||
/** \brief Stream implementation based on an encrypted SSH tunnel
|
||||
*
|
||||
* This class remotely starts a program and exposes its stdin/stdout
|
||||
* streams through an instance of \ref Stream. To make all
|
||||
* of this work, passwordless authentication must be enabled (for
|
||||
* example by using public key authentication in addition to a
|
||||
*
|
||||
* This class remotely starts a program and exposes its stdin/stdout
|
||||
* streams through an instance of \ref Stream. To make all
|
||||
* of this work, passwordless authentication must be enabled (for
|
||||
* example by using public key authentication in addition to a
|
||||
* running ssh-agent, which stores the decrypted private key).
|
||||
*
|
||||
* On Windows, things are implemented a bit differently: Instead
|
||||
* of OpenSSH, plink.exe (from PUTTY) is used and must be available
|
||||
* in $PATH. For passwordless authentication, convert your private
|
||||
* key to PuTTY's format (with the help of puttygen.exe). Afterwards,
|
||||
* key to PuTTY's format (with the help of puttygen.exe). Afterwards,
|
||||
* pageant.exe is required to load and authenticate the key.
|
||||
*
|
||||
* Note: SSH streams are set to use network byte order by default.
|
||||
|
@ -52,19 +52,19 @@ public:
|
|||
// =============================================================
|
||||
|
||||
/**
|
||||
* \brief Create a new SSH stream.
|
||||
* \brief Create a new SSH stream.
|
||||
*
|
||||
* The timeout parameter specifies specifies the maximum amount of
|
||||
* time that can be spent before failing to create the initial
|
||||
* The timeout parameter specifies specifies the maximum amount of
|
||||
* time that can be spent before failing to create the initial
|
||||
* connection. This feature is unsupported (and ignored) on Windows.
|
||||
*
|
||||
*
|
||||
* \param userName Username to use for the authentication
|
||||
* \param hostName Destination host name
|
||||
* \param cmdLine Command (with arguments) to be executed on the remote side
|
||||
* \param port Destination port
|
||||
* \param timeout Maximum time to use for the connection attempt (in seconds)
|
||||
*/
|
||||
SSHStream(const std::string &userName,
|
||||
SSHStream(const std::string &userName,
|
||||
const std::string &hostName,
|
||||
const std::vector<std::string> &cmdLine,
|
||||
int port = 22, int timeout = 10
|
||||
|
@ -79,13 +79,13 @@ public:
|
|||
|
||||
/// Return the destination machine's host name
|
||||
const std::string &getHostName() const;
|
||||
|
||||
|
||||
/// Return the user name used for authentication
|
||||
const std::string &getUserName() const;
|
||||
|
||||
|
||||
/// Return the number of received bytes
|
||||
size_t getReceivedBytes() const;
|
||||
|
||||
|
||||
/// Return the number of sent bytes
|
||||
size_t getSentBytes() const;
|
||||
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
void flush();
|
||||
bool canWrite() const;
|
||||
bool canRead() const;
|
||||
|
||||
|
||||
//! @}
|
||||
// =============================================================
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/** \brief Portable %Stream implementation, which encapsulates a socket
|
||||
* for IPv4/IPv6 network communications.
|
||||
/** \brief Portable %Stream implementation, which encapsulates a socket
|
||||
* for IPv4/IPv6 network communications.
|
||||
*
|
||||
* By default, this type of stream is configured to use network byte
|
||||
* order (= big endian).
|
||||
|
@ -67,10 +67,10 @@ public:
|
|||
|
||||
/// Return the peer's name
|
||||
inline const std::string &getPeer() const { return m_peer; }
|
||||
|
||||
|
||||
/// Return the number of received bytes
|
||||
inline size_t getReceivedBytes() const { return m_received; }
|
||||
|
||||
|
||||
/// Return the number of sent bytes
|
||||
inline size_t getSentBytes() const { return m_sent; }
|
||||
|
||||
|
|
|
@ -37,10 +37,10 @@ MTS_NAMESPACE_BEGIN
|
|||
#define PROGRESS_MSG_SIZE 56
|
||||
|
||||
/**
|
||||
* Specifies the number of internal counters associated with each
|
||||
* Specifies the number of internal counters associated with each
|
||||
* \ref StatsCounter instance.
|
||||
*
|
||||
* This is needed for SMP/ccNUMA systems where different processors might
|
||||
* This is needed for SMP/ccNUMA systems where different processors might
|
||||
* be contending for a cache line containing a counter. The solution used
|
||||
* here tries to ensure that every processor has its own local counter.
|
||||
*/
|
||||
|
@ -68,7 +68,7 @@ enum EStatsType {
|
|||
*
|
||||
* This counter takes up at least one cache line to reduce false sharing.
|
||||
*/
|
||||
struct CacheLineCounter {
|
||||
struct CacheLineCounter {
|
||||
#if MTS_32BIT_COUNTERS == 1
|
||||
// WIN32 & Darwin (PPC/32) don't support atomic 64 bit increment operations
|
||||
// -> restrict counters to 32bit :(
|
||||
|
@ -81,19 +81,19 @@ struct CacheLineCounter {
|
|||
};
|
||||
|
||||
/** \brief General-purpose statistics counter
|
||||
*
|
||||
*
|
||||
* This class implements a simple counter, which can be used to track various
|
||||
* quantities within Mitsuba. At various points during the execution, it is
|
||||
* possible to then call \ref Statistics::printStats() to get a human-readable
|
||||
* possible to then call \ref Statistics::printStats() to get a human-readable
|
||||
* report of their values.
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
class MTS_EXPORT_CORE StatsCounter {
|
||||
public:
|
||||
/**
|
||||
* \brief Create a new statistics counter
|
||||
*
|
||||
/**
|
||||
* \brief Create a new statistics counter
|
||||
*
|
||||
* \param category Category of the counter when shown in the statistics summary
|
||||
* \param name Name of the counter when shown in the statistics summary
|
||||
* \param type Characterization of the quantity that will be measured
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
__sync_fetch_and_add(&m_value[Thread::getID() & NUM_COUNTERS_MASK].value, amount);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Increment the base counter by the specified amount (only for use with EPercentage/EAverage)
|
||||
inline void incrementBase(size_t amount = 1) {
|
||||
#ifdef MTS_NO_STATISTICS
|
||||
|
@ -158,12 +158,12 @@ public:
|
|||
inline void recordMinimum(size_t value) {
|
||||
int id = Thread::getID() & NUM_COUNTERS_MASK;
|
||||
#if MTS_32BIT_COUNTERS == 1
|
||||
volatile int32_t *ptr =
|
||||
volatile int32_t *ptr =
|
||||
(volatile int32_t *) &m_value[id].value;
|
||||
int32_t curMinimum;
|
||||
int32_t newMinimum = (int32_t) value;
|
||||
#else
|
||||
volatile int64_t *ptr =
|
||||
volatile int64_t *ptr =
|
||||
(volatile int64_t *) &m_value[id].value;
|
||||
int64_t curMinimum;
|
||||
int64_t newMinimum = (int64_t) value;
|
||||
|
@ -186,12 +186,12 @@ public:
|
|||
inline void recordMaximum(size_t value) {
|
||||
int id = Thread::getID() & NUM_COUNTERS_MASK;
|
||||
#if MTS_32BIT_COUNTERS == 1
|
||||
volatile int32_t *ptr =
|
||||
volatile int32_t *ptr =
|
||||
(volatile int32_t *) &m_value[id].value;
|
||||
int32_t curMaximum;
|
||||
int32_t newMaximum = (int32_t) value;
|
||||
#else
|
||||
volatile int64_t *ptr =
|
||||
volatile int64_t *ptr =
|
||||
(volatile int64_t *) &m_value[id].value;
|
||||
int64_t curMaximum;
|
||||
int64_t newMaximum = (int64_t) value;
|
||||
|
@ -284,7 +284,7 @@ private:
|
|||
class MTS_EXPORT_CORE ProgressReporter {
|
||||
public:
|
||||
/**
|
||||
* Construct a new progress reporter.
|
||||
* Construct a new progress reporter.
|
||||
* 'ptr' is a custom pointer payload to be submitted with progress messages
|
||||
*/
|
||||
ProgressReporter(const std::string &title, long long total, const void *ptr);
|
||||
|
@ -299,7 +299,7 @@ public:
|
|||
inline long long getValue() const { return m_value; }
|
||||
|
||||
/// Finish
|
||||
inline void finish() {
|
||||
inline void finish() {
|
||||
if (m_value < m_total)
|
||||
update(m_total);
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ private:
|
|||
/** \brief Collects various rendering statistics and presents them
|
||||
* in a human-readable form.
|
||||
*
|
||||
* \remark Only the \ref getInstance(), \ref getStats(), and
|
||||
* \remark Only the \ref getInstance(), \ref getStats(), and
|
||||
* \ref printStats() functions are implemented in the Python bindings.
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -370,7 +370,7 @@ private:
|
|||
return c1->getCategory() < c2->getCategory();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static ref<Statistics> m_instance;
|
||||
std::vector<const StatsCounter *> m_counters;
|
||||
std::vector<std::pair<std::string, std::string> > m_plugins;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#pragma once
|
||||
#if !defined(__MITSUBA_CORE_STL_H_)
|
||||
#define __MITSUBA_CORE_STL_H_
|
||||
|
||||
|
||||
/* Include some SGI STL extensions, which might be missing */
|
||||
#ifdef __GNUC__
|
||||
#include <ext/functional>
|
||||
|
@ -36,7 +36,7 @@ namespace std {
|
|||
return __x.first;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> {
|
||||
const typename _Pair::second_type& operator()(const _Pair& __x) const {
|
||||
return __x.second;
|
||||
|
@ -66,7 +66,7 @@ namespace std {
|
|||
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
|
||||
|
||||
inline char tolower(char c) {
|
||||
return ::tolower(c);
|
||||
}
|
||||
|
|
|
@ -41,16 +41,16 @@ private:
|
|||
|
||||
/** \brief Abstract seekable stream class
|
||||
*
|
||||
* Specifies all functions to be implemented by stream
|
||||
* Specifies all functions to be implemented by stream
|
||||
* subclasses and provides various convenience functions
|
||||
* layered on top of on them.
|
||||
*
|
||||
* All read<b>X</b>() and write<b>X</b>() methods support transparent
|
||||
* conversion based on the endianness of the underlying system and the
|
||||
* conversion based on the endianness of the underlying system and the
|
||||
* value passed to \ref setByteOrder(). Whenever \ref getHostByteOrder()
|
||||
* and \ref getByteOrder() disagree, the endianness is swapped.
|
||||
*
|
||||
* \sa FileStream, MemoryStream, SocketStream,
|
||||
* \sa FileStream, MemoryStream, SocketStream,
|
||||
* ConsoleStream, SSHStream, ZStream
|
||||
* \ingroup libcore
|
||||
* \ingroup libpython
|
||||
|
@ -65,21 +65,21 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* \brief Create a new stream.
|
||||
*
|
||||
* By default, it assumes the byte order of the
|
||||
* underlying system, i.e. no endianness conversion
|
||||
* \brief Create a new stream.
|
||||
*
|
||||
* By default, it assumes the byte order of the
|
||||
* underlying system, i.e. no endianness conversion
|
||||
* is performed.
|
||||
*/
|
||||
Stream();
|
||||
|
||||
|
||||
/// Return a string representation
|
||||
virtual std::string toString() const;
|
||||
|
||||
// ======================================================================
|
||||
/// @{ \name Endianness-related
|
||||
// ======================================================================
|
||||
|
||||
|
||||
/// Set the stream byte order
|
||||
void setByteOrder(EByteOrder byteOrder);
|
||||
|
||||
|
@ -88,7 +88,7 @@ public:
|
|||
|
||||
/// Return the byte order of the underlying machine
|
||||
inline static EByteOrder getHostByteOrder() { return m_hostByteOrder; }
|
||||
|
||||
|
||||
/// @}
|
||||
// ======================================================================
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Read a specified amount of data from the stream
|
||||
*
|
||||
*
|
||||
* Throws an exception when the stream ended prematurely
|
||||
*/
|
||||
virtual void read(void *ptr, size_t size) = 0;
|
||||
|
@ -133,7 +133,7 @@ public:
|
|||
|
||||
//! @}
|
||||
// ======================================================================
|
||||
|
||||
|
||||
// ======================================================================
|
||||
//! @{ \name Convenience functions with automatic endianness conversion
|
||||
// ======================================================================
|
||||
|
@ -149,7 +149,7 @@ public:
|
|||
|
||||
/// Write a signed short (16 bit) to the stream
|
||||
void writeShort(short value);
|
||||
|
||||
|
||||
/// Write an array of signed shorts (16 bit) to the stream
|
||||
void writeShortArray(const short *values, size_t size);
|
||||
|
||||
|
@ -161,13 +161,13 @@ public:
|
|||
|
||||
/// Write a signed int (32 bit) to the stream
|
||||
void writeInt(int value);
|
||||
|
||||
|
||||
/// Write an array of signed ints (32 bit) to the stream
|
||||
void writeIntArray(const int *values, size_t size);
|
||||
|
||||
/// Write an unsigned int (32 bit) to the stream
|
||||
void writeUInt(unsigned int value);
|
||||
|
||||
|
||||
/// Write an array of unsigned ints (32 bit) to the stream
|
||||
void writeUIntArray(const unsigned int *values, size_t size);
|
||||
|
||||
|
@ -203,13 +203,13 @@ public:
|
|||
|
||||
/// Write a single-precision floating point number (32 bit) to the stream
|
||||
void writeSingle(float value);
|
||||
|
||||
|
||||
/// Write a single-precision floating point array (32 bit) to the stream
|
||||
void writeSingleArray(const float *data, size_t size);
|
||||
|
||||
/// Write a double-precision floating point number (64 bit) to the stream
|
||||
void writeDouble(double value);
|
||||
|
||||
|
||||
/// Write a double-precision floating point array (64 bit) to the stream
|
||||
void writeDoubleArray(const double *data, size_t size);
|
||||
|
||||
|
@ -242,25 +242,25 @@ public:
|
|||
|
||||
/// Read a signed short (16 bit) from the stream
|
||||
short readShort();
|
||||
|
||||
|
||||
/// Read an array of signed shorts (16 bit) from the stream
|
||||
void readShortArray(short *dest, size_t size);
|
||||
|
||||
/// Read an unsigned short (16 bit) from the stream
|
||||
unsigned short readUShort();
|
||||
|
||||
|
||||
/// Read an array of unsigned shorts (16 bit) from the stream
|
||||
void readUShortArray(unsigned short *dest, size_t size);
|
||||
|
||||
/// Read a signed int (32 bit) from the stream
|
||||
int readInt();
|
||||
|
||||
|
||||
/// Read an array of signed ints (32 bit) from the stream
|
||||
void readIntArray(int *dst, size_t size);
|
||||
|
||||
/// Read an unsigned int (32 bit) from the stream
|
||||
unsigned int readUInt();
|
||||
|
||||
|
||||
/// Read an array of unsigned ints (32 bit) from the stream
|
||||
void readUIntArray(unsigned int *dest, size_t size);
|
||||
|
||||
|
@ -272,7 +272,7 @@ public:
|
|||
|
||||
/// Read an unsigned int (64 bit) from the stream
|
||||
uint64_t readULong();
|
||||
|
||||
|
||||
/// Read a size value from the stream
|
||||
size_t readSize() { return (size_t) readULong(); }
|
||||
|
||||
|
@ -327,32 +327,32 @@ public:
|
|||
/**
|
||||
* \brief Copy content from this stream into another stream
|
||||
* \param stream Destination stream
|
||||
* \param numBytes
|
||||
* \param numBytes
|
||||
* The number of bytes to copy. When -1 is specified,
|
||||
* copying proceeds until the end of the source stream.
|
||||
*/
|
||||
void copyTo(Stream *stream, int64_t numBytes = -1);
|
||||
|
||||
/**
|
||||
* \brief Read an element from the stream (uses partial template
|
||||
* \brief Read an element from the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T> T readElement();
|
||||
|
||||
/**
|
||||
* \brief Write an element to the stream (uses partial template
|
||||
* \brief Write an element to the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T> void writeElement(T value);
|
||||
|
||||
/**
|
||||
* \brief Read an array from the stream (uses partial template
|
||||
* \brief Read an array from the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T> void readArray(T *array, size_t count);
|
||||
|
||||
/**
|
||||
* \brief Write an array to the stream (uses partial template
|
||||
* \brief Write an array to the stream (uses partial template
|
||||
* specialization to select a method appropriate to the data type)
|
||||
*/
|
||||
template <typename T> void writeArray(const T *array, size_t count);
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Create a new thread object
|
||||
* \param name An identifying name of this thread
|
||||
* \param name An identifying name of this thread
|
||||
* (will be shown in debug messages)
|
||||
* \remark Note that it is currently not possible to
|
||||
* construct Thread instances from Python
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
/**
|
||||
* \brief Set the thread priority
|
||||
*
|
||||
* This does not always work -- for instance, Linux
|
||||
* This does not always work -- for instance, Linux
|
||||
* requires root privileges for this operation.
|
||||
*
|
||||
* \return \c true upon success.
|
||||
|
@ -68,9 +68,9 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Specify whether or not this thread is critical
|
||||
*
|
||||
* When an thread marked critical crashes from an uncaught
|
||||
* exception, the whole process is brought down.
|
||||
*
|
||||
* When an thread marked critical crashes from an uncaught
|
||||
* exception, the whole process is brought down.
|
||||
* The default is \c false.
|
||||
*/
|
||||
void setCritical(bool critical);
|
||||
|
@ -116,7 +116,7 @@ public:
|
|||
|
||||
/**
|
||||
* \brief Detach the thread and release resources
|
||||
*
|
||||
*
|
||||
* After a call to this function, \ref join()
|
||||
* cannot be used anymore. This releases resources, which
|
||||
* would otherwise be held until a call to \ref join().
|
||||
|
@ -142,7 +142,7 @@ public:
|
|||
static void initializeOpenMP(size_t threadCount);
|
||||
|
||||
/**
|
||||
* \brief Register an unmanaged thread with Mitsuba (i.e. one that
|
||||
* \brief Register an unmanaged thread with Mitsuba (i.e. one that
|
||||
* doesn't derive from \c mitsuba::Thread)
|
||||
*
|
||||
* Should be called from the thread in question. The function returns
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
void start();
|
||||
|
||||
/**
|
||||
* \brief Reset the timer, including the total elapsed time across
|
||||
* \brief Reset the timer, including the total elapsed time across
|
||||
* all intervals (and restart it by default)
|
||||
*/
|
||||
void reset(bool restart = true);
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
/**
|
||||
* \brief "Lap"-style interface
|
||||
*
|
||||
* This function is the atomic equivalent to stopping the
|
||||
* This function is the atomic equivalent to stopping the
|
||||
* timer, recording the time passed since it was started,
|
||||
* and restarting it. The resulting time value in seconds
|
||||
* is returned.
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace detail {
|
|||
/// Functor to release memory of a TLS object
|
||||
typedef void (*DestructFunctor)(void *);
|
||||
/// Construct a new thread local storage object
|
||||
ThreadLocalBase(const ConstructFunctor &constructFunctor,
|
||||
ThreadLocalBase(const ConstructFunctor &constructFunctor,
|
||||
const DestructFunctor &destructFfunctor);
|
||||
/// Destroy the thread local storage object
|
||||
~ThreadLocalBase();
|
||||
|
@ -62,14 +62,14 @@ namespace detail {
|
|||
|
||||
/**
|
||||
* \headerfile mitsuba/core/tls.h mitsuba/mitsuba.h
|
||||
* \brief Thin wrapper around boost thread local storage.
|
||||
* \brief Thin wrapper around boost thread local storage.
|
||||
* Stores references to Object instances.
|
||||
* \sa PrimitiveThreadLocal
|
||||
* \ingroup libcore
|
||||
*
|
||||
* This class implements a reference counting thread local storage object which captures
|
||||
* This class implements a reference counting thread local storage object which captures
|
||||
* references to subclasses of \ref Object. In comparison to an API like <tt>boost::thread_specific_ptr</tt>
|
||||
* it has a much nicer cleanup mechanism. Held references are destroyed when the owning thread dies \a or
|
||||
* it has a much nicer cleanup mechanism. Held references are destroyed when the owning thread dies \a or
|
||||
* when the \c ThreadLocal instance is freed, whichever occurs first.
|
||||
*/
|
||||
template <typename ValueType> class ThreadLocal {
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
inline ValueType *get() { return ((ref<ValueType> *) m_base.get())->get(); }
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the data associated with the
|
||||
* \brief Return a reference to the data associated with the
|
||||
* current thread (const version)
|
||||
*/
|
||||
inline const ValueType *get() const { return ((const ref<ValueType> *) m_base.get())->get(); }
|
||||
|
@ -102,14 +102,14 @@ protected:
|
|||
|
||||
/**
|
||||
* \headerfile mitsuba/core/tls.h mitsuba/mitsuba.h
|
||||
* \brief Thin wrapper around posix thread local storage.
|
||||
* \brief Thin wrapper around posix thread local storage.
|
||||
* Stores heap-allocated data other than Object instances.
|
||||
* \sa ThreadLocal
|
||||
* \ingroup libcore
|
||||
*
|
||||
*
|
||||
* This class implements a thread local storage object for POD-style data structures.
|
||||
* In comparison to an API like <tt>boost::thread_specific_ptr</tt> it has a much nicer
|
||||
* cleanup mechanism. Held references are destroyed when the owning thread dies \a or
|
||||
* In comparison to an API like <tt>boost::thread_specific_ptr</tt> it has a much nicer
|
||||
* cleanup mechanism. Held references are destroyed when the owning thread dies \a or
|
||||
* when the \c PrimitiveThreadLocal instance is freed, whichever occurs first.
|
||||
*/
|
||||
template <typename ValueType> class PrimitiveThreadLocal {
|
||||
|
@ -129,7 +129,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the data associated with the
|
||||
* \brief Return a reference to the data associated with the
|
||||
* current thread (const version)
|
||||
*/
|
||||
inline const ValueType &get() const {
|
||||
|
|
|
@ -37,9 +37,9 @@ public:
|
|||
m_transform.setIdentity();
|
||||
m_invTransform.setIdentity();
|
||||
}
|
||||
|
||||
|
||||
/// Unserialize a transformation from a stream
|
||||
inline Transform(Stream *stream) {
|
||||
inline Transform(Stream *stream) {
|
||||
m_transform = Matrix4x4(stream);
|
||||
m_invTransform = Matrix4x4(stream);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ public:
|
|||
return Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Matrix-vector multiplication for vectors in 3d space (no temporaries)
|
||||
* \remark This function is not available in the Python bindings
|
||||
*/
|
||||
|
@ -196,7 +196,7 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Matrix-normal multiplication
|
||||
* \brief Matrix-normal multiplication
|
||||
* \remark In the Python bindings, this is function implemented as
|
||||
* the multiplication operator (\c __mul__).
|
||||
*/
|
||||
|
@ -222,7 +222,7 @@ public:
|
|||
dest.z = m_invTransform.m[0][2] * v.x + m_invTransform.m[1][2] * v.y
|
||||
+ m_invTransform.m[2][2] * v.z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief 4D matrix-vector multiplication
|
||||
* \remark In the Python bindings, this is function implemented as
|
||||
|
@ -327,7 +327,7 @@ public:
|
|||
|
||||
/// Create a scale transformation
|
||||
static Transform scale(const Vector &v);
|
||||
|
||||
|
||||
/** \brief Create a perspective transformation.
|
||||
* (Maps [near, far] to [0, 1])
|
||||
* \param fov Field of view in degrees
|
||||
|
@ -335,7 +335,7 @@ public:
|
|||
* \param clipFar Far clipping plane
|
||||
*/
|
||||
static Transform perspective(Float fov, Float clipNear, Float clipFar);
|
||||
|
||||
|
||||
/** \brief Create a perspective transformation for OpenGL.
|
||||
* (Maps [-near, -far] to [-1, 1])
|
||||
* \param fov Field of view in degrees
|
||||
|
@ -360,7 +360,7 @@ public:
|
|||
* \param clipFar Far clipping plane
|
||||
*/
|
||||
static Transform orthographic(Float clipNear, Float clipFar);
|
||||
|
||||
|
||||
/** \brief Create an orthographic transformation for OpenGL
|
||||
* \param clipNear Near clipping plane
|
||||
* \param clipFar Far clipping plane
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \brief Simple triangle class including a collection of routines
|
||||
* for analysis and transformation.
|
||||
/**
|
||||
* \brief Simple triangle class including a collection of routines
|
||||
* for analysis and transformation.
|
||||
*
|
||||
* Triangles are stored as indices into a vertex array
|
||||
* \ingroup libcore
|
||||
|
@ -45,15 +45,15 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the axis-aligned bounding box of a triangle after it has
|
||||
* clipped to the extends of another given AABB.
|
||||
* \brief Returns the axis-aligned bounding box of a triangle after it has
|
||||
* clipped to the extends of another given AABB.
|
||||
*
|
||||
* This function uses the Sutherland-Hodgman algorithm to calculate the
|
||||
* convex polygon that is created when applying all 6 AABB splitting
|
||||
* planes to the triangle. Afterwards, the AABB of the newly created
|
||||
* convex polygon is returned. This function is an important component
|
||||
* for efficiently creating 'Perfect Split' KD-trees. For more detail,
|
||||
* see "On building fast kd-Trees for Ray Tracing, and on doing
|
||||
* This function uses the Sutherland-Hodgman algorithm to calculate the
|
||||
* convex polygon that is created when applying all 6 AABB splitting
|
||||
* planes to the triangle. Afterwards, the AABB of the newly created
|
||||
* convex polygon is returned. This function is an important component
|
||||
* for efficiently creating 'Perfect Split' KD-trees. For more detail,
|
||||
* see "On building fast kd-Trees for Ray Tracing, and on doing
|
||||
* that in O(N log N)" by Ingo Wald and Vlastimil Havran
|
||||
*/
|
||||
AABB getClippedAABB(const Point *positions, const AABB &aabb) const;
|
||||
|
@ -66,7 +66,7 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
Float surfaceArea(const Point *positions) const;
|
||||
|
||||
/** \brief Ray-triangle intersection test
|
||||
*
|
||||
*
|
||||
* Uses the algorithm by Moeller and Trumbore discussed at
|
||||
* <tt>http://www.acm.org/jgt/papers/MollerTrumbore97/code.html</tt>.
|
||||
*
|
||||
|
@ -90,7 +90,7 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
* \return
|
||||
* \c true if an intersection has been detected
|
||||
*/
|
||||
FINLINE static bool rayIntersect(const Point &p0, const Point &p1, const Point &p2,
|
||||
FINLINE static bool rayIntersect(const Point &p0, const Point &p1, const Point &p2,
|
||||
const Ray &ray, Float &u, Float &v, Float &t) {
|
||||
/* Find vectors for two edges sharing */
|
||||
Vector edge1 = p1 - p0, edge2 = p2 - p0;
|
||||
|
@ -127,9 +127,9 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Ray-triangle intersection test
|
||||
*
|
||||
*
|
||||
* Uses the algorithm by Moeller and Trumbore discussed at
|
||||
* <tt>http://www.acm.org/jgt/papers/MollerTrumbore97/code.html</tt>.
|
||||
*
|
||||
|
@ -151,7 +151,7 @@ struct MTS_EXPORT_CORE Triangle {
|
|||
* \return
|
||||
* \c true if an intersection has been detected
|
||||
*/
|
||||
FINLINE bool rayIntersect(const Point *positions, const Ray &ray, Float &u,
|
||||
FINLINE bool rayIntersect(const Point *positions, const Ray &ray, Float &u,
|
||||
Float &v, Float &t) const {
|
||||
return rayIntersect(
|
||||
positions[idx[0]], positions[idx[1]],
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <boost/static_assert.hpp>
|
||||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
/*! \addtogroup libcore */
|
||||
/*! @{ */
|
||||
|
||||
|
@ -68,7 +68,7 @@ template<class Iterator> std::string containerToString(const Iterator &start, co
|
|||
while (it != end) {
|
||||
oss << " " << indent((*it)->toString());
|
||||
++it;
|
||||
if (it != end)
|
||||
if (it != end)
|
||||
oss << "," << std::endl;
|
||||
else
|
||||
oss << std::endl;
|
||||
|
@ -110,12 +110,12 @@ extern MTS_EXPORT_CORE int getCoreCount();
|
|||
/// Return the host name of this machine
|
||||
extern MTS_EXPORT_CORE std::string getHostName();
|
||||
|
||||
/// Return the fully qualified domain name of this machine
|
||||
/// Return the fully qualified domain name of this machine
|
||||
extern MTS_EXPORT_CORE std::string getFQDN();
|
||||
|
||||
/**
|
||||
* \brief Enable floating point exceptions (to catch NaNs, overflows,
|
||||
* arithmetic with infinity).
|
||||
* \brief Enable floating point exceptions (to catch NaNs, overflows,
|
||||
* arithmetic with infinity).
|
||||
*
|
||||
* On Intel processors, this applies to both x87 and SSE2 math
|
||||
*
|
||||
|
@ -183,7 +183,7 @@ static FINLINE __int64 rdtsc(void) {
|
|||
|
||||
/**
|
||||
* \brief Apply an arbitrary permutation to an array in linear time
|
||||
*
|
||||
*
|
||||
* This algorithm is based on Donald Knuth's book
|
||||
* "The Art of Computer Programming, Volume 3: Sorting and Searching"
|
||||
* (1st edition, section 5.2, page 595)
|
||||
|
@ -197,7 +197,7 @@ static FINLINE __int64 rdtsc(void) {
|
|||
* Pointer to the data that should be permuted
|
||||
* \param perm
|
||||
* Input permutation vector having the same size as \c data. After
|
||||
* the function terminates, this vector will be set to the
|
||||
* the function terminates, this vector will be set to the
|
||||
* identity permutation.
|
||||
*/
|
||||
template <typename DataType, typename IndexType> void permute_inplace(
|
||||
|
@ -223,7 +223,7 @@ template <typename DataType, typename IndexType> void permute_inplace(
|
|||
} while (perm[j] != i);
|
||||
|
||||
/* Fix the final position with the saved value */
|
||||
data[j] = curval;
|
||||
data[j] = curval;
|
||||
perm[j] = j;
|
||||
}
|
||||
}
|
||||
|
@ -329,94 +329,94 @@ inline size_t roundToPowerOfTwo(size_t value) {
|
|||
* \brief Solve a quadratic equation of the form a*x^2 + b*x + c = 0.
|
||||
* \return \c true if a solution could be found
|
||||
*/
|
||||
extern MTS_EXPORT_CORE bool solveQuadratic(Float a, Float b,
|
||||
extern MTS_EXPORT_CORE bool solveQuadratic(Float a, Float b,
|
||||
Float c, Float &x0, Float &x1);
|
||||
|
||||
/**
|
||||
* \brief Solve a double-precision quadratic equation of the
|
||||
* \brief Solve a double-precision quadratic equation of the
|
||||
* form a*x^2 + b*x + c = 0.
|
||||
* \return \c true if a solution could be found
|
||||
*/
|
||||
extern MTS_EXPORT_CORE bool solveQuadraticDouble(double a, double b,
|
||||
extern MTS_EXPORT_CORE bool solveQuadraticDouble(double a, double b,
|
||||
double c, double &x0, double &x1);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 1D function
|
||||
*
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* Evaluation point
|
||||
* \param data
|
||||
* Floating point array containing \c size regularly spaced evaluations
|
||||
* in the range [\c min,\c max] of the function to be approximated.
|
||||
* \param min
|
||||
* \param min
|
||||
* Position of the first knot
|
||||
* \param max
|
||||
* Position of the last knot
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array
|
||||
* \return
|
||||
* The interpolated value or zero when \c x lies outside of [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic1D(Float x, const Float *data,
|
||||
extern MTS_EXPORT_CORE Float interpCubic1D(Float x, const Float *data,
|
||||
Float min, Float max, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 1D function
|
||||
*
|
||||
*
|
||||
* This implementation relies on Catmull-Rom splines, i.e. it uses finite
|
||||
* differences to approximate the derivatives at the endpoints of each spline
|
||||
* segment.
|
||||
*
|
||||
* \param x
|
||||
* Evaluation point
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Floating point array containing \c size irregularly spaced values
|
||||
* denoting positions the where the function to be interpolated was evaluated.
|
||||
* They must be provided in \a increasing order.
|
||||
* \param data
|
||||
* Floating point array containing interpolant values matched to
|
||||
* Floating point array containing interpolant values matched to
|
||||
* the entries of \c nodes.
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array
|
||||
* \return
|
||||
* The interpolated value or zero when \c x lies outside of \a [\c min, \c max]
|
||||
*/
|
||||
extern MTS_EXPORT Float interpCubic1DIrregular(Float x, const Float *nodes,
|
||||
extern MTS_EXPORT Float interpCubic1DIrregular(Float x, const Float *nodes,
|
||||
const Float *data, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* patch.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* Evaluation point
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic2D(const Point2 &p, const Float *data,
|
||||
extern MTS_EXPORT_CORE Float interpCubic2D(const Point2 &p, const Float *data,
|
||||
const Point2 &min, const Point2 &max, const Size2 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 2D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
|
@ -424,27 +424,27 @@ extern MTS_EXPORT_CORE Float interpCubic2D(const Point2 &p, const Float *data,
|
|||
* should be preferred, since data lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing irregularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate.
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic2DIrregular(const Point2 &p, const Float **nodes,
|
||||
extern MTS_EXPORT_CORE Float interpCubic2DIrregular(const Point2 &p, const Float **nodes,
|
||||
const Float *data, const Size2 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of a regularly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
|
@ -452,25 +452,25 @@ extern MTS_EXPORT_CORE Float interpCubic2DIrregular(const Point2 &p, const Float
|
|||
* Evaluation point of the interpolant
|
||||
* \param data
|
||||
* A 3D floating point array of <tt>size.x*size.y*size.z</tt> cells containing regularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param min
|
||||
* Position of the first knot on each dimension
|
||||
* \param max
|
||||
* Position of the last knot on each dimension
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic3D(const Point3 &p, const Float *data,
|
||||
extern MTS_EXPORT_CORE Float interpCubic3D(const Point3 &p, const Float *data,
|
||||
const Point3 &min, const Point3 &max, const Size3 &size);
|
||||
|
||||
/**
|
||||
* \brief Evaluate a cubic spline interpolant of an \a irregularly sampled 3D function
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
*
|
||||
* This implementation relies on a tensor product of Catmull-Rom splines, i.e. it uses
|
||||
* finite differences to approximate the derivatives at the endpoints of each spline
|
||||
* region.
|
||||
*
|
||||
|
@ -478,22 +478,22 @@ extern MTS_EXPORT_CORE Float interpCubic3D(const Point3 &p, const Float *data,
|
|||
* should be preferred, since data lookups will be considerably faster.
|
||||
*
|
||||
* \param p
|
||||
* Evaluation point
|
||||
* Evaluation point
|
||||
* \param nodes
|
||||
* Pointer to a list for each dimension denoting the positions where the function
|
||||
* to be interpolated was evaluated. The <tt>i</tt>-th array must have
|
||||
* size <tt>size[i]</tt> and contain position values in \a increasing order.
|
||||
* \param data
|
||||
* A 2D floating point array of <tt>size.x*size.y</tt> cells containing irregularly
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* spaced evaluations of the function to be interpolated on the domain <tt>[min, max]</tt>.
|
||||
* Consecutive entries of this array correspond to increments in the 'x' coordinate,
|
||||
* then 'y', and finally 'z' increments.
|
||||
* \param size
|
||||
* \param size
|
||||
* Denotes the size of the \c data array (along each dimension)
|
||||
* \return
|
||||
* The interpolated value or zero when \c p lies outside of the knot range
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float interpCubic3DIrregular(const Point3 &p, const Float **nodes,
|
||||
extern MTS_EXPORT_CORE Float interpCubic3DIrregular(const Point3 &p, const Float **nodes,
|
||||
const Float *data, const Size3 &size);
|
||||
|
||||
//// Convert radians to degrees
|
||||
|
@ -519,7 +519,7 @@ inline Float smoothStep(Float min, Float max, Float value) {
|
|||
}
|
||||
|
||||
/**
|
||||
* \brief Numerically well-behaved routine for computing the angle
|
||||
* \brief Numerically well-behaved routine for computing the angle
|
||||
* between two unit direction vectors
|
||||
*
|
||||
* This should be used wherever one is tempted to compute the
|
||||
|
@ -549,7 +549,7 @@ extern MTS_EXPORT_CORE bool solveLinearSystem2x2(const Float a[2][2], const Floa
|
|||
|
||||
/**
|
||||
* \brief Complete the set {a} to an orthonormal base
|
||||
* \remark In Python, this function is used as
|
||||
* \remark In Python, this function is used as
|
||||
* follows: <tt>s, t = coordinateSystem(n)</tt>
|
||||
* \ingroup libpython
|
||||
*/
|
||||
|
@ -563,18 +563,18 @@ extern MTS_EXPORT_CORE void coordinateSystem(const Vector &a, Vector &b, Vector
|
|||
* \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,
|
||||
extern MTS_EXPORT_CORE void stratifiedSample1D(Random *random, Float *dest,
|
||||
int count, bool jitter);
|
||||
|
||||
/**
|
||||
* \brief Generate (optionally jittered) stratified 2D samples
|
||||
* \param random Source of random numbers
|
||||
* \param dest A pointer to a floating point array
|
||||
* \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,
|
||||
extern MTS_EXPORT_CORE void stratifiedSample2D(Random *random, Point2 *dest,
|
||||
int countX, int countY, bool jitter);
|
||||
|
||||
/// Generate latin hypercube samples
|
||||
|
@ -616,19 +616,19 @@ extern MTS_EXPORT_CORE Point2 toSphericalCoordinates(const Vector &v);
|
|||
* Relative refractive index to the transmitted direction
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float fresnelDielectric(Float cosThetaI,
|
||||
extern MTS_EXPORT_CORE Float fresnelDielectric(Float cosThetaI,
|
||||
Float cosThetaT, Float eta);
|
||||
|
||||
/**
|
||||
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||
* at a planar interface between two dielectrics (extended version)
|
||||
*
|
||||
* In comparison to \ref fresnelDielectric(), this function internally
|
||||
* computes the transmitted direction and returns it using the \c cosThetaT
|
||||
* argument. When encountering total internal reflection, it sets
|
||||
* In comparison to \ref fresnelDielectric(), this function internally
|
||||
* computes the transmitted direction and returns it using the \c cosThetaT
|
||||
* argument. When encountering total internal reflection, it sets
|
||||
* <tt>cosThetaT=0</tt> and returns the value 1.
|
||||
*
|
||||
* When <tt>cosThetaI < 0</tt>, the function computes the Fresnel reflectance
|
||||
* When <tt>cosThetaI < 0</tt>, the function computes the Fresnel reflectance
|
||||
* from the \a internal boundary, which is equivalent to calling the function
|
||||
* with arguments <tt>fresnelDielectric(abs(cosThetaI), cosThetaT, 1/eta)</tt>.
|
||||
*
|
||||
|
@ -639,13 +639,13 @@ extern MTS_EXPORT_CORE Float fresnelDielectric(Float cosThetaI,
|
|||
* Cosine of the angle between the normal and the incident ray
|
||||
* (may be negative)
|
||||
* \param cosThetaT
|
||||
* Argument used to return the cosine of the angle between the normal
|
||||
* Argument used to return the cosine of the angle between the normal
|
||||
* and the transmitted ray, will have the opposite sign of \c cosThetaI
|
||||
* \param eta
|
||||
* Relative refractive index
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Float fresnelDielectricExt(Float cosThetaI,
|
||||
extern MTS_EXPORT_CORE Float fresnelDielectricExt(Float cosThetaI,
|
||||
Float &cosThetaT, Float eta);
|
||||
|
||||
/**
|
||||
|
@ -663,7 +663,7 @@ inline Float fresnelDielectricExt(Float cosThetaI, Float eta) { Float cosThetaT;
|
|||
return fresnelDielectricExt(cosThetaI, cosThetaT, eta); }
|
||||
|
||||
/**
|
||||
* \brief Calculates the unpolarized fresnel reflection coefficient
|
||||
* \brief Calculates the unpolarized fresnel reflection coefficient
|
||||
* at a planar interface between vacuum and a conductor.
|
||||
*
|
||||
* \param cosThetaI
|
||||
|
@ -674,12 +674,12 @@ inline Float fresnelDielectricExt(Float cosThetaI, Float eta) { Float cosThetaT;
|
|||
* Imaginary refractive index (wavelength-dependent)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosThetaI,
|
||||
extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosThetaI,
|
||||
const Spectrum &eta, const Spectrum &k);
|
||||
|
||||
/**
|
||||
* \brief Calculates the diffuse unpolarized fresnel reflectance of
|
||||
* a dielectric material (sometimes referred to as "Fdr").
|
||||
* a dielectric material (sometimes referred to as "Fdr").
|
||||
*
|
||||
* This value quantifies what fraction of diffuse incident illumination
|
||||
* will, on average, be reflected at a dielectric material boundary
|
||||
|
@ -687,10 +687,10 @@ extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosThetaI,
|
|||
* \param eta
|
||||
* Relative refraction coefficient
|
||||
* \param fast
|
||||
* Compute an approximate value? If set to \c true, the
|
||||
* Compute an approximate value? If set to \c true, the
|
||||
* implementation will use a polynomial approximation with
|
||||
* a max relative error of ~0.5% on the interval 0.5 < \c eta < 2.
|
||||
* When \c fast=false, the code will use Gauss-Lobatto quadrature
|
||||
* When \c fast=false, the code will use Gauss-Lobatto quadrature
|
||||
* to compute the diffuse reflectance more accurately, and for
|
||||
* a wider range of refraction coefficients, but at a cost
|
||||
* in terms of performance.
|
||||
|
@ -712,11 +712,11 @@ extern MTS_EXPORT_CORE Float fresnelDiffuseReflectance(
|
|||
extern MTS_EXPORT_CORE Vector reflect(const Vector &wi, const Normal &n);
|
||||
|
||||
/**
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* the given surface normal and index of refraction.
|
||||
*
|
||||
* This variant internally computes the transmitted direction cosine by
|
||||
* calling \ref fresnelDielectricExt. As a side result, the cosine and
|
||||
* calling \ref fresnelDielectricExt. As a side result, the cosine and
|
||||
* Fresnel reflectance are computed and returned via the reference arguments
|
||||
* \c cosThetaT and \c F.
|
||||
*
|
||||
|
@ -730,8 +730,8 @@ extern MTS_EXPORT_CORE Vector reflect(const Vector &wi, const Normal &n);
|
|||
* \param eta
|
||||
* Relative index of refraction at the interface
|
||||
* \param cosThetaT
|
||||
* Parameter used to return the signed cosine of the angle between the transmitted
|
||||
* direction and the surface normal
|
||||
* Parameter used to return the signed cosine of the angle between the transmitted
|
||||
* direction and the surface normal
|
||||
* \param F
|
||||
* Parameter used to return the Fresnel reflectance
|
||||
* \return
|
||||
|
@ -739,11 +739,11 @@ extern MTS_EXPORT_CORE Vector reflect(const Vector &wi, const Normal &n);
|
|||
* the case of total internal reflection)
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Vector refract(const Vector &wi, const Normal &n,
|
||||
extern MTS_EXPORT_CORE Vector refract(const Vector &wi, const Normal &n,
|
||||
Float eta, Float &cosThetaT, Float &F);
|
||||
|
||||
/**
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* the given surface normal and index of refraction.
|
||||
*
|
||||
* This variant assumes that the transmitted direction cosine has
|
||||
|
@ -762,11 +762,11 @@ extern MTS_EXPORT_CORE Vector refract(const Vector &wi, const Normal &n,
|
|||
* Specularly transmitted direction
|
||||
* \ingroup libpython
|
||||
*/
|
||||
extern MTS_EXPORT_CORE Vector refract(const Vector &wi, const Normal &n,
|
||||
extern MTS_EXPORT_CORE Vector refract(const Vector &wi, const Normal &n,
|
||||
Float eta, Float cosThetaT);
|
||||
|
||||
/**
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* \brief Specularly refract the direction \c wi into a planar dielectric with
|
||||
* the given surface normal and index of refraction.
|
||||
*
|
||||
* This function is a simple convenience function that only returns the refracted
|
||||
|
|
|
@ -38,7 +38,7 @@ template <typename T> struct TVector1 {
|
|||
const static int dim = 1;
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the vector will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -52,15 +52,15 @@ template <typename T> struct TVector1 {
|
|||
TVector1() { x = std::numeric_limits<T>::quiet_NaN(); }
|
||||
#endif
|
||||
|
||||
/// Initialize the vector with the specified value
|
||||
/// Initialize the vector with the specified value
|
||||
TVector1(T x) : x(x) { }
|
||||
|
||||
/// Initialize the vector with the components of another vector data structure
|
||||
template <typename T1> explicit TVector1(const TVector1<T1> &v)
|
||||
template <typename T1> explicit TVector1(const TVector1<T1> &v)
|
||||
: x((T) v.x) { }
|
||||
|
||||
/// Initialize the vector with the components of a point data structure
|
||||
template <typename T1> explicit TVector1(const TPoint1<T1> &p)
|
||||
template <typename T1> explicit TVector1(const TPoint1<T1> &p)
|
||||
: x((T) p.x) { }
|
||||
|
||||
/// Unserialize a vector from a binary data stream
|
||||
|
@ -80,7 +80,7 @@ template <typename T> struct TVector1 {
|
|||
|
||||
/// Add another vector to the current one
|
||||
TVector1& operator+=(const TVector1 &v) {
|
||||
x += v.x;
|
||||
x += v.x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ template <typename T> struct TVector1 {
|
|||
|
||||
/// Multiply the vector by the given scalar
|
||||
TVector1 &operator*=(T f) {
|
||||
x *= f;
|
||||
x *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ template <typename T> inline TVector1<T> normalize(const TVector1<T> &v) {
|
|||
|
||||
template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector1i: Division by zero!");
|
||||
#endif
|
||||
return TVector1(x/s);
|
||||
|
@ -199,7 +199,7 @@ template <> inline TVector1<int> TVector1<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TVector1<int> &TVector1<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector1i: Division by zero!");
|
||||
#endif
|
||||
|
||||
|
@ -222,7 +222,7 @@ template <typename T> struct TVector2 {
|
|||
const static int dim = 2;
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the vector will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -243,11 +243,11 @@ template <typename T> struct TVector2 {
|
|||
explicit TVector2(T val) : x(val), y(val) { }
|
||||
|
||||
/// Initialize the vector with the components of another vector data structure
|
||||
template <typename T2> explicit TVector2(const TVector2<T2> &v)
|
||||
template <typename T2> explicit TVector2(const TVector2<T2> &v)
|
||||
: x((T) v.x), y((T) v.y) { }
|
||||
|
||||
/// Initialize the vector with the components of a point data structure
|
||||
template <typename T2> explicit TVector2(const TPoint2<T2> &p)
|
||||
template <typename T2> explicit TVector2(const TPoint2<T2> &p)
|
||||
: x((T) p.x), y((T) p.y) { }
|
||||
|
||||
/// Unserialize a vector from a binary data stream
|
||||
|
@ -268,7 +268,7 @@ template <typename T> struct TVector2 {
|
|||
|
||||
/// Add another vector to the current one
|
||||
TVector2& operator+=(const TVector2 &v) {
|
||||
x += v.x; y += v.y;
|
||||
x += v.x; y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ template <typename T> struct TVector2 {
|
|||
|
||||
/// Multiply the vector by the given scalar
|
||||
TVector2 &operator*=(T f) {
|
||||
x *= f; y *= f;
|
||||
x *= f; y *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ template <typename T> struct TVector2 {
|
|||
SLog(EWarn, "Vector2: Division by zero!");
|
||||
#endif
|
||||
T recip = (T) 1 / f;
|
||||
x *= recip; y *= recip;
|
||||
x *= recip; y *= recip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -382,7 +382,7 @@ template <typename T> inline TVector2<T> normalize(const TVector2<T> &v) {
|
|||
|
||||
template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector2i: Division by zero!");
|
||||
#endif
|
||||
return TVector2(x/s, y/s);
|
||||
|
@ -390,7 +390,7 @@ template <> inline TVector2<int> TVector2<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TVector2<int> &TVector2<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector2i: Division by zero!");
|
||||
#endif
|
||||
|
||||
|
@ -409,12 +409,12 @@ template <typename T> struct TVector3 {
|
|||
typedef TPoint3<T> PointType;
|
||||
|
||||
T x, y, z;
|
||||
|
||||
|
||||
/// Number of dimensions
|
||||
const static int dim = 3;
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the vector will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -435,11 +435,11 @@ template <typename T> struct TVector3 {
|
|||
explicit TVector3(T val) : x(val), y(val), z(val) { }
|
||||
|
||||
/// Initialize the vector with the components of another vector data structure
|
||||
template <typename T2> explicit TVector3(const TVector3<T2> &v)
|
||||
template <typename T2> explicit TVector3(const TVector3<T2> &v)
|
||||
: x((T) v.x), y((T) v.y), z((T) v.z) { }
|
||||
|
||||
/// Initialize the vector with the components of a point data structure
|
||||
template <typename T2> explicit TVector3(const TPoint3<T2> &p)
|
||||
template <typename T2> explicit TVector3(const TPoint3<T2> &p)
|
||||
: x((T) p.x), y((T) p.y), z((T) p.z) { }
|
||||
|
||||
/// Unserialize a vector from a binary data stream
|
||||
|
@ -572,7 +572,7 @@ template <typename T> inline T absDot(const TVector3<T> &v1, const TVector3<T> &
|
|||
|
||||
template <typename T> inline TVector3<T> cross(const TVector3<T> &v1, const TVector3<T> &v2) {
|
||||
return TVector3<T>(
|
||||
(v1.y * v2.z) - (v1.z * v2.y),
|
||||
(v1.y * v2.z) - (v1.z * v2.y),
|
||||
(v1.z * v2.x) - (v1.x * v2.z),
|
||||
(v1.x * v2.y) - (v1.y * v2.x)
|
||||
);
|
||||
|
@ -584,7 +584,7 @@ template <typename T> inline TVector3<T> normalize(const TVector3<T> &v) {
|
|||
|
||||
template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector3i: Division by zero!");
|
||||
#endif
|
||||
return TVector3(x/s, y/s, z/s);
|
||||
|
@ -592,7 +592,7 @@ template <> inline TVector3<int> TVector3<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TVector3<int> &TVector3<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector3i: Division by zero!");
|
||||
#endif
|
||||
|
||||
|
@ -613,13 +613,13 @@ template <typename T> struct TVector4 {
|
|||
typedef TPoint4<T> PointType;
|
||||
|
||||
T x, y, z, w;
|
||||
|
||||
|
||||
/// Number of dimensions
|
||||
const static int dim = 3;
|
||||
|
||||
|
||||
/** \brief Construct a new vector without initializing it.
|
||||
*
|
||||
*
|
||||
* This construtor is useful when the vector will either not
|
||||
* be used at all (it might be part of a larger data structure)
|
||||
* or initialized at a later point in time. Always make sure
|
||||
|
@ -640,11 +640,11 @@ template <typename T> struct TVector4 {
|
|||
explicit TVector4(T val) : x(val), y(val), z(val), w(val) { }
|
||||
|
||||
/// Initialize the vector with the components of another vector data structure
|
||||
template <typename T2> explicit TVector4(const TVector4<T2> &v)
|
||||
template <typename T2> explicit TVector4(const TVector4<T2> &v)
|
||||
: x((T) v.x), y((T) v.y), z((T) v.z), w((T) v.w) { }
|
||||
|
||||
/// Initialize the vector with the components of a point data structure
|
||||
template <typename T2> explicit TVector4(const TPoint4<T2> &p)
|
||||
template <typename T2> explicit TVector4(const TPoint4<T2> &p)
|
||||
: x((T) p.x), y((T) p.y), z((T) p.z), w((T) p.w) { }
|
||||
|
||||
/// Unserialize a vector from a binary data stream
|
||||
|
@ -783,7 +783,7 @@ template <typename T> inline TVector4<T> normalize(const TVector4<T> &v) {
|
|||
|
||||
template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector4i: Division by zero!");
|
||||
#endif
|
||||
return TVector4(x/s, y/s, z/s, w/s);
|
||||
|
@ -791,7 +791,7 @@ template <> inline TVector4<int> TVector4<int>::operator/(int s) const {
|
|||
|
||||
template <> inline TVector4<int> &TVector4<int>::operator/=(int s) {
|
||||
#ifdef MTS_DEBUG
|
||||
if (s == 0)
|
||||
if (s == 0)
|
||||
SLog(EWarn, "Vector4i: Division by zero!");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ MTS_NAMESPACE_BEGIN
|
|||
#define MTS_YEAR "2012"
|
||||
|
||||
/**
|
||||
* \brief A simple data structure for representing and
|
||||
* \brief A simple data structure for representing and
|
||||
* comparing Mitsuba version strings
|
||||
*
|
||||
* \ingroup libcore
|
||||
|
@ -44,17 +44,17 @@ struct MTS_EXPORT_CORE Version {
|
|||
public:
|
||||
/// Default constructor: initialize to an invalid version (0.0.0)
|
||||
inline Version() : m_major(0), m_minor(0), m_release(0) { }
|
||||
|
||||
|
||||
/// Initialize with the specified version number
|
||||
inline Version(int major, int minor, int release)
|
||||
: m_major(major), m_minor(minor), m_release(release) { }
|
||||
|
||||
/**
|
||||
* \brief Parse a version string of the form "major.minor.release"
|
||||
* \brief Parse a version string of the form "major.minor.release"
|
||||
* and turn it into a \ref Version structure
|
||||
*/
|
||||
Version(const std::string &versionString);
|
||||
|
||||
|
||||
/// Check if this program version is \a older than \c other
|
||||
inline bool operator<(const Version &other) const {
|
||||
if (m_major < other.m_major)
|
||||
|
@ -78,8 +78,8 @@ public:
|
|||
|
||||
/// Check if two program versions match
|
||||
inline bool operator==(const Version &other) const {
|
||||
return m_major == other.m_major
|
||||
&& m_minor == other.m_minor
|
||||
return m_major == other.m_major
|
||||
&& m_minor == other.m_minor
|
||||
&& m_release == other.m_release;
|
||||
}
|
||||
|
||||
|
@ -102,11 +102,11 @@ public:
|
|||
|
||||
/// Return the major version
|
||||
inline int getMajorVersion() const { return m_major; }
|
||||
|
||||
|
||||
/// Return the minor version
|
||||
inline int getMinorVersion() const { return m_minor; }
|
||||
|
||||
/// Return the release
|
||||
/// Return the release
|
||||
inline int getRelease() const { return m_release; }
|
||||
private:
|
||||
int m_major;
|
||||
|
|
|
@ -27,7 +27,7 @@ MTS_NAMESPACE_BEGIN
|
|||
/**
|
||||
* \brief Von Mises-Fisher distribution on the 2-sphere
|
||||
*
|
||||
* This is a basic implementation, which assumes that the
|
||||
* This is a basic implementation, which assumes that the
|
||||
* distribution is centered around the Z-axis.
|
||||
*
|
||||
* \author Wenzel Jakob
|
||||
|
@ -36,7 +36,7 @@ MTS_NAMESPACE_BEGIN
|
|||
struct MTS_EXPORT_CORE VonMisesFisherDistr {
|
||||
public:
|
||||
/**
|
||||
* \brief Create a new von Mises-Fisher distribution
|
||||
* \brief Create a new von Mises-Fisher distribution
|
||||
* with the given concentration parameter
|
||||
*/
|
||||
VonMisesFisherDistr(Float kappa = 0);
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
/// Evaluate the distribution for a given value of cos(theta)
|
||||
Float eval(Float cosTheta) const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Generate a sample from this distribution
|
||||
*
|
||||
|
@ -64,9 +64,9 @@ public:
|
|||
static Float forPeakValue(Float x);
|
||||
|
||||
/**
|
||||
* \brief Compute an concentration parameter that approximately
|
||||
* \brief Compute an concentration parameter that approximately
|
||||
* corresponds to the spherical convolution of two vMF distributions.
|
||||
*
|
||||
*
|
||||
* For details, see "Directional Statistics" by Mardia and Jupp, p.44
|
||||
*/
|
||||
static Float convolve(Float kappa1, Float kappa2);
|
||||
|
|
|
@ -28,7 +28,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \brief Implements common warping techniques that map from the unit
|
||||
* square to other domains, such as spheres, hemispheres, etc.
|
||||
*
|
||||
* The main application of this class is to generate uniformly
|
||||
* The main application of this class is to generate uniformly
|
||||
* distributed or weighted point sets in certain common target domains.
|
||||
*/
|
||||
class MTS_EXPORT_CORE Warp {
|
||||
|
@ -53,11 +53,11 @@ public:
|
|||
static Vector squareToCosineHemisphere(const Point2 &sample);
|
||||
|
||||
/// Density of \ref squareToCosineHemiphere with respect to solid angles
|
||||
static inline Float squareToCosineHemispherePdf(const Vector &d)
|
||||
static inline Float squareToCosineHemispherePdf(const Vector &d)
|
||||
{ return INV_PI * Frame::cosTheta(d); }
|
||||
|
||||
/**
|
||||
* \brief Uniformly sample a vector that lies within a given
|
||||
* \brief Uniformly sample a vector that lies within a given
|
||||
* cone of angles around the Z axis
|
||||
*
|
||||
* \param cosCutoff Cosine of the cutoff angle
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
static Vector squareToUniformCone(Float cosCutoff, const Point2 &sample);
|
||||
|
||||
/**
|
||||
* \brief Uniformly sample a vector that lies within a given
|
||||
* \brief Uniformly sample a vector that lies within a given
|
||||
* cone of angles around the Z axis
|
||||
*
|
||||
* \param cosCutoff Cosine of the cutoff angle
|
||||
|
@ -102,7 +102,7 @@ public:
|
|||
static Point2 squareToUniformTriangle(const Point2 &sample);
|
||||
|
||||
/**
|
||||
* \brief Sample a point on a 2D standard normal distribution
|
||||
* \brief Sample a point on a 2D standard normal distribution
|
||||
*
|
||||
* Internally uses the Box-Muller transformation
|
||||
*/
|
||||
|
|
|
@ -32,7 +32,7 @@ MTS_NAMESPACE_BEGIN
|
|||
* \brief Transparent compression/decompression stream based on \c zlib.
|
||||
*
|
||||
* This class transparently decompresses and compresses reads and writes
|
||||
* to a nested stream, respectively.
|
||||
* to a nested stream, respectively.
|
||||
*
|
||||
* \ingroup libcore
|
||||
*/
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
inline Spectrum getAverage() const {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
||||
inline Spectrum getMaximum() const {
|
||||
return m_value;
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
inline Spectrum getAverage() const {
|
||||
return Spectrum(m_value);
|
||||
}
|
||||
|
||||
|
||||
inline Spectrum getMaximum() const {
|
||||
return Spectrum(m_value);
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public:
|
|||
|
||||
/// Get the interpreted keypress data
|
||||
inline const char* getKeyboardInterpreted() const { return m_keyboard.interpreted; }
|
||||
|
||||
|
||||
/// Get the interpreted keypress data
|
||||
inline char* getKeyboardInterpreted() { return m_keyboard.interpreted; }
|
||||
|
||||
|
@ -261,7 +261,7 @@ public:
|
|||
|
||||
/// Return the FSAA sample count
|
||||
inline int getFSAA() const { return m_fsaa; }
|
||||
|
||||
|
||||
/// Only applies to devices, which are UI windows
|
||||
virtual void setVisible(bool visible) = 0;
|
||||
|
||||
|
@ -357,7 +357,7 @@ public:
|
|||
inline Session *getSession() { return m_session; }
|
||||
|
||||
/**
|
||||
* Initialize the renderer. Optionally, an existing device instance
|
||||
* Initialize the renderer. Optionally, an existing device instance
|
||||
* can be provided as a second argument -- this is primarily meant
|
||||
* to create a device that will be able to support a shared context
|
||||
* with another device.
|
||||
|
@ -387,7 +387,7 @@ protected:
|
|||
/// Create a new device
|
||||
Device(Session *session);
|
||||
|
||||
/** \brief Send a device event using
|
||||
/** \brief Send a device event using
|
||||
* the registered callbacks
|
||||
*/
|
||||
void fireDeviceEvent(const DeviceEvent &event);
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
*/
|
||||
int32_t verticalBearing;
|
||||
|
||||
/** \brief Horizontal advance value of this glyph
|
||||
/** \brief Horizontal advance value of this glyph
|
||||
*
|
||||
* (# of pixels the pen must be advanced
|
||||
* after rendering a glyph)
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
/// Determine the ID number of a named parameter
|
||||
int getParameterID(const std::string &name, bool failIfMissing = true) const;
|
||||
|
||||
|
||||
/// Set a boolean parameter
|
||||
void setParameter(int id, bool value);
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
|
||||
/// Set a integer parameter
|
||||
void setParameter(int id, int value);
|
||||
|
||||
|
||||
/// Set a unsigned integer parameter
|
||||
void setParameter(int id, uint32_t value);
|
||||
|
||||
|
@ -108,7 +108,7 @@ public:
|
|||
|
||||
/** Set a GPUTexture parameter. Must be executed after
|
||||
binding the texture to a texture unit */
|
||||
void setParameter(int id, const GPUTexture *value);
|
||||
void setParameter(int id, const GPUTexture *value);
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
protected:
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
/// Clear the viewport
|
||||
void clear();
|
||||
|
||||
/// Configure the camera
|
||||
/// Configure the camera
|
||||
void setCamera(const ProjectiveCamera *pCamera,
|
||||
const Point2 &apertureSample = Point2(0.5f),
|
||||
const Point2 &aaSample = Point2(0.5f),
|
||||
|
@ -89,19 +89,19 @@ public:
|
|||
Matrix4x4 getMatrix(EMatrixType type) const;
|
||||
|
||||
/// Set up the renderer for drawing triangle geometry
|
||||
void beginDrawingMeshes(bool transmitOnlyPositions = false);
|
||||
void beginDrawingMeshes(bool transmitOnlyPositions = false);
|
||||
|
||||
/// Send a triangle mesh to the renderer
|
||||
void drawMesh(const TriMesh *geo);
|
||||
void drawMesh(const TriMesh *geo);
|
||||
|
||||
/// Send a triangle mesh to the renderer
|
||||
void drawMesh(const GPUGeometry *geo);
|
||||
void drawMesh(const GPUGeometry *geo);
|
||||
|
||||
/// Clean up the renderer after drawing triangle geometry
|
||||
void endDrawingMeshes();
|
||||
void endDrawingMeshes();
|
||||
|
||||
/**
|
||||
* \brief Quickly draw all geometry that has been registered
|
||||
* \brief Quickly draw all geometry that has been registered
|
||||
* with the renderer.
|
||||
*
|
||||
* Only transmits positions, hence this is mainly useful for
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
|
||||
/// Draw a quad using the given texture
|
||||
void blitTexture(const GPUTexture *texture,
|
||||
bool flipVertically = false,
|
||||
bool flipVertically = false,
|
||||
bool centerHoriz = true, bool centerVert = true,
|
||||
const Vector2i &offset = Vector2i(0, 0));
|
||||
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
* Draw a line of text on the screen. The coordinates are specified
|
||||
* in pixel coordinates, where the upper left corner is the origin
|
||||
*/
|
||||
void drawText(const Point2i &pos,
|
||||
void drawText(const Point2i &pos,
|
||||
const Font *font, const std::string &text);
|
||||
|
||||
/// Set the size of point primitives
|
||||
|
@ -159,7 +159,7 @@ public:
|
|||
void drawFilledRectangle(const Point2i &a, const Point2i &b);
|
||||
|
||||
/// Draw an ellipse with the specified center and axes
|
||||
void drawEllipse(const Point ¢er,
|
||||
void drawEllipse(const Point ¢er,
|
||||
const Vector &axis1, const Vector &axis2);
|
||||
|
||||
/// Draw a wire-frame axis-aligned box
|
||||
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
/// Set the current fixed-function pipeline color
|
||||
void setColor(const Color3 &color, Float alpha = 1.0f);
|
||||
|
||||
|
||||
/// Set the current fixed-function pipeline color
|
||||
void setColor(const Spectrum &spec, Float alpha = 1.0f);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
/// Refresh (re-upload) the texture
|
||||
void refresh();
|
||||
|
||||
|
||||
/**
|
||||
* \brief Refresh (re-upload) a subregion of the texture
|
||||
*
|
||||
|
@ -56,7 +56,7 @@ public:
|
|||
* Specifies the unit to which this texture should be bound
|
||||
* \param textureIndex
|
||||
* When this texture has multiple sub-textures (e.g.
|
||||
* a color and depth map in the case of a
|
||||
* a color and depth map in the case of a
|
||||
* \ref EColorAndDepthBuffer texture), this parameter
|
||||
* specifies the one to be bound
|
||||
*/
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
|
||||
/// Unbind the texture and disable texturing
|
||||
void unbind() const;
|
||||
|
||||
|
||||
/// Activate the render target
|
||||
void activateTarget();
|
||||
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
* \param target
|
||||
* Specifies the target render buffer (or NULL for the framebuffer)
|
||||
* \param what
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
*/
|
||||
void blit(GPUTexture *target, int what) const;
|
||||
|
||||
|
@ -96,14 +96,14 @@ public:
|
|||
* \param target
|
||||
* Specifies the target render buffer (or NULL for the framebuffer)
|
||||
* \param what
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* \param sourceOffset
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* \param sourceOffset
|
||||
* Offset in the source render buffer
|
||||
* \param sourceOffset
|
||||
* \param sourceOffset
|
||||
* Size of the region to be copied from the source render buffer
|
||||
* \param destOffset
|
||||
* \param destOffset
|
||||
* Offset in the destination render buffer
|
||||
* \param destOffset
|
||||
* \param destOffset
|
||||
* Size of the region to be copied into the dest destination buffer
|
||||
*/
|
||||
void blit(GPUTexture *target, int what, const Point2i &sourceOffset,
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
/// Return the rendering context
|
||||
inline GLXContext getGLXContext() { return m_context; }
|
||||
|
||||
|
||||
/// Initialize the renderer
|
||||
void init(Device *device, Renderer *other = NULL);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
/// Unbind the geometry object
|
||||
virtual void unbind() = 0;
|
||||
|
||||
|
||||
/// Free the geometry object from GPU memory
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
|
|
|
@ -80,104 +80,104 @@ public:
|
|||
virtual int getParameterID(const std::string &name, bool failIfMissing = true) const = 0;
|
||||
|
||||
/// Set a boolean parameter by name
|
||||
inline void setParameter(const std::string &name, bool value,
|
||||
inline void setParameter(const std::string &name, bool value,
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a integer parameter by name
|
||||
inline void setParameter(const std::string &name, int value,
|
||||
inline void setParameter(const std::string &name, int value,
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set an unsigned integer parameter by name
|
||||
inline void setParameter(const std::string &name, uint32_t value,
|
||||
inline void setParameter(const std::string &name, uint32_t value,
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a float parameter by name
|
||||
inline void setParameter(const std::string &name, Float value,
|
||||
inline void setParameter(const std::string &name, Float value,
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Vector parameter by name
|
||||
inline void setParameter(const std::string &name, const Vector &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Vector3i parameter by name
|
||||
inline void setParameter(const std::string &name, const Vector3i &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Vector2 parameter by name
|
||||
inline void setParameter(const std::string &name, const Vector2 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Vector2i parameter by name
|
||||
inline void setParameter(const std::string &name, const Vector2i &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Vector4 parameter by name
|
||||
inline void setParameter(const std::string &name, const Vector4 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Point parameter by name
|
||||
inline void setParameter(const std::string &name, const Point &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Point3i parameter by name
|
||||
inline void setParameter(const std::string &name, const Point3i &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Point2 parameter by name
|
||||
inline void setParameter(const std::string &name, const Point2 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Point2i parameter by name
|
||||
inline void setParameter(const std::string &name, const Point2i &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Point4 parameter by name
|
||||
inline void setParameter(const std::string &name, const Point4 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Matrix2x2 parameter by name
|
||||
inline void setParameter(const std::string &name, const Matrix2x2 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Matrix3x3 parameter by name
|
||||
inline void setParameter(const std::string &name, const Matrix3x3 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Matrix4x4 parameter by name
|
||||
inline void setParameter(const std::string &name, const Matrix4x4 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
|
@ -189,20 +189,20 @@ public:
|
|||
|
||||
/// Set a Color3 parameter by name
|
||||
inline void setParameter(const std::string &name, const Color3 &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/// Set a Spectrum parameter (will be converted to linear RGB) by name
|
||||
inline void setParameter(const std::string &name, const Spectrum &value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
/** Set a GPUTexture parameter by name. Must be executed after
|
||||
binding the texture to a texture unit */
|
||||
inline void setParameter(const std::string &name, const GPUTexture *value,
|
||||
bool failIfMissing = true) {
|
||||
bool failIfMissing = true) {
|
||||
setParameter(getParameterID(name, failIfMissing), value);
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ public:
|
|||
|
||||
/// Set a int parameter
|
||||
virtual void setParameter(int id, int value) = 0;
|
||||
|
||||
|
||||
/// Set a uint32_t parameter
|
||||
virtual void setParameter(int id, uint32_t value) = 0;
|
||||
|
||||
|
|
|
@ -49,14 +49,14 @@ public:
|
|||
ETextureCubeMap
|
||||
};
|
||||
|
||||
/** \brief If the texture type is set to EFrameBuffer, the
|
||||
/** \brief If the texture type is set to EFrameBuffer, the
|
||||
* configuration must be one of the following constants */
|
||||
enum EFrameBufferType {
|
||||
/// This is not a framebuffer
|
||||
ENone = 0x00,
|
||||
|
||||
/**
|
||||
* \brief Color framebuffer (\a including an internal depth
|
||||
* \brief Color framebuffer (\a including an internal depth
|
||||
* buffer that cannot be accessed as a texture)
|
||||
*/
|
||||
EColorBuffer = 0x01,
|
||||
|
@ -81,10 +81,10 @@ public:
|
|||
|
||||
/// 16-bit floating point (\c half) HDR component encoding
|
||||
EFloat16,
|
||||
|
||||
|
||||
/// 32-bit floating point (\c float) HDR component encoding
|
||||
EFloat32,
|
||||
|
||||
|
||||
/// 64-bit floating point (\c float) HDR component encoding
|
||||
EFloat64
|
||||
};
|
||||
|
@ -148,7 +148,7 @@ public:
|
|||
enum EFilterType {
|
||||
/// Use the color value of the closest pixel
|
||||
ENearest = 0,
|
||||
/// Use 4 surrounding pixels and weigh them
|
||||
/// Use 4 surrounding pixels and weigh them
|
||||
ELinear,
|
||||
/**
|
||||
* Blend the color values of the closest matching
|
||||
|
@ -168,7 +168,7 @@ public:
|
|||
* associated texture unit. 'ENormal' means that texture
|
||||
* values are returned as with any other texture, whereas
|
||||
* 'ECompare' causes a depth comparison to take place
|
||||
* (this is the default).
|
||||
* (this is the default).
|
||||
*/
|
||||
enum EDepthMode {
|
||||
ENormal,
|
||||
|
@ -177,7 +177,7 @@ public:
|
|||
|
||||
/** \brief Construct a new texture.
|
||||
*
|
||||
* If bitmap is non-NULL, the texture type, format
|
||||
* If bitmap is non-NULL, the texture type, format
|
||||
* will be automatically set
|
||||
*
|
||||
* \param name A human-readable name (for debugging)
|
||||
|
@ -229,7 +229,7 @@ public:
|
|||
|
||||
/// Set the wrap type along the U axis
|
||||
inline void setWrapTypeU(EWrapType wrapType) { m_wrapTypeU = wrapType; }
|
||||
|
||||
|
||||
/// Return the wrap type along the U axis
|
||||
inline EWrapType getWrapTypeU() { return m_wrapTypeU; }
|
||||
|
||||
|
@ -249,7 +249,7 @@ public:
|
|||
inline Float getMaxAnisotropy() const { return m_maxAnisotropy; }
|
||||
|
||||
/** \brief Set the maximal anisotropy.
|
||||
*
|
||||
*
|
||||
* A value of 1 will result in isotropic
|
||||
* texture filtering. A value of 0 (default) will
|
||||
* use the global max. anisotropy value
|
||||
|
@ -264,7 +264,7 @@ public:
|
|||
|
||||
/// Return the depth map read mode
|
||||
inline EDepthMode getDepthMode() const { return m_depthMode; }
|
||||
|
||||
|
||||
/// Set the depth map read mode
|
||||
inline void setDepthMode(EDepthMode mode) { m_depthMode = mode; }
|
||||
|
||||
|
@ -291,7 +291,7 @@ public:
|
|||
|
||||
/// Refresh (re-upload) the texture
|
||||
virtual void refresh() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Refresh (re-upload) a subregion of the texture
|
||||
*
|
||||
|
@ -301,7 +301,7 @@ public:
|
|||
|
||||
/// Free the texture from GPU memory
|
||||
virtual void cleanup() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Bind the texture and enable texturing
|
||||
*
|
||||
|
@ -309,7 +309,7 @@ public:
|
|||
* Specifies the unit to which this texture should be bound
|
||||
* \param textureIndex
|
||||
* When this texture has multiple sub-textures (e.g.
|
||||
* a color and depth map in the case of a
|
||||
* a color and depth map in the case of a
|
||||
* \ref EColorAndDepthBuffer texture), this parameter
|
||||
* specifies the one to be bound
|
||||
*/
|
||||
|
@ -342,14 +342,14 @@ public:
|
|||
|
||||
/// Set the number of samples (for multisample color render targets)
|
||||
inline void setSampleCount(int samples) { m_samples = samples; }
|
||||
|
||||
|
||||
/// Return the number of samples (for multisample color render targets)
|
||||
inline int getSampleCount() const { return m_samples; }
|
||||
|
||||
/// Set the border color (applicable if <tt>wrapMode=EClamp/EClampToBorder</tt>)
|
||||
inline void setBorderColor(const Color3 &borderColor) { m_borderColor = borderColor; }
|
||||
|
||||
/// Return the border color
|
||||
|
||||
/// Return the border color
|
||||
inline const Color3 &getBorderColor() const { return m_borderColor; }
|
||||
|
||||
/**
|
||||
|
@ -358,7 +358,7 @@ public:
|
|||
* \param target
|
||||
* Specifies the target render buffer
|
||||
* \param what
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
*/
|
||||
virtual void blit(GPUTexture *target, int what) const = 0;
|
||||
|
||||
|
@ -368,14 +368,14 @@ public:
|
|||
* \param target
|
||||
* Specifies the target render buffer (or NULL for the framebuffer)
|
||||
* \param what
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* \param sourceOffset
|
||||
* A bitwise-OR of the components in \ref EFrameBufferType to copy
|
||||
* \param sourceOffset
|
||||
* Offset in the source render buffer
|
||||
* \param sourceOffset
|
||||
* \param sourceOffset
|
||||
* Size of the region to be copied from the source render buffer
|
||||
* \param destOffset
|
||||
* \param destOffset
|
||||
* Offset in the destination render buffer
|
||||
* \param destOffset
|
||||
* \param destOffset
|
||||
* Size of the region to be copied into the dest destination buffer
|
||||
*/
|
||||
virtual void blit(GPUTexture *target, int what, const Point2i &sourceOffset,
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
/// Set the window title
|
||||
void setTitle(const std::string &title);
|
||||
|
||||
|
||||
/// Display the NSGL cursor?
|
||||
void showCursor(bool enabled);
|
||||
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
|
||||
/**
|
||||
* Deliver all events which have been
|
||||
* received asynchronously
|
||||
* received asynchronously
|
||||
*/
|
||||
void processEvents();
|
||||
|
||||
|
@ -122,7 +122,7 @@ private:
|
|||
NSWindow *m_window;
|
||||
CustomView *m_view;
|
||||
NSOpenGLPixelFormat *m_fmt;
|
||||
NSOpenGLContext *m_currentContext;
|
||||
NSOpenGLContext *m_currentContext;
|
||||
#else
|
||||
void *m_window;
|
||||
void *m_view;
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
/**
|
||||
* \brief Process all events and call event callbacks.
|
||||
*
|
||||
* This function will run until the \c stop parameter is set
|
||||
* This function will run until the \c stop parameter is set
|
||||
* to \c true from within an event callback.
|
||||
*/
|
||||
void processEventsBlocking(bool &stop);
|
||||
|
|
|
@ -62,7 +62,7 @@ public:
|
|||
m_capabilities[cap] = supported;
|
||||
}
|
||||
|
||||
inline bool isSupported(ECapability cap) const {
|
||||
inline bool isSupported(ECapability cap) const {
|
||||
return m_capabilities[cap];
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,8 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialize the renderer. Optionally, an existing renderer instance
|
||||
* can be provided as a second argument -- this establishes a link
|
||||
* Initialize the renderer. Optionally, an existing renderer instance
|
||||
* can be provided as a second argument -- this establishes a link
|
||||
* between them to permit sharing of textures, programs, etc.
|
||||
*/
|
||||
virtual void init(Device *device, Renderer *other = NULL);
|
||||
|
@ -137,7 +137,7 @@ public:
|
|||
/// Clear the viewport
|
||||
virtual void clear() = 0;
|
||||
|
||||
/// Configure the camera
|
||||
/// Configure the camera
|
||||
virtual void setCamera(const ProjectiveCamera *pCamera,
|
||||
const Point2 &apertureSample = Point2(0.5f),
|
||||
const Point2 &aaSample = Point2(0.5f),
|
||||
|
@ -153,19 +153,19 @@ public:
|
|||
virtual Matrix4x4 getMatrix(EMatrixType type) const = 0;
|
||||
|
||||
/// Set up the renderer for drawing triangle geometry
|
||||
virtual void beginDrawingMeshes(bool transmitOnlyPositions = false) = 0;
|
||||
virtual void beginDrawingMeshes(bool transmitOnlyPositions = false) = 0;
|
||||
|
||||
/// Send a triangle mesh to the renderer
|
||||
virtual void drawMesh(const TriMesh *shape) = 0;
|
||||
virtual void drawMesh(const TriMesh *shape) = 0;
|
||||
|
||||
/// Send a triangle mesh to the renderer
|
||||
virtual void drawMesh(const GPUGeometry *geo) = 0;
|
||||
virtual void drawMesh(const GPUGeometry *geo) = 0;
|
||||
|
||||
/// Clean up the renderer after drawing triangle geometry
|
||||
virtual void endDrawingMeshes() = 0;
|
||||
virtual void endDrawingMeshes() = 0;
|
||||
|
||||
/**
|
||||
* \brief Quickly draw all geometry that has been registered
|
||||
* \brief Quickly draw all geometry that has been registered
|
||||
* with the renderer.
|
||||
*
|
||||
* Only transmits positions, hence this is mainly useful for
|
||||
|
@ -175,7 +175,7 @@ public:
|
|||
|
||||
/// Draw a quad using the given texture
|
||||
virtual void blitTexture(const GPUTexture *texture,
|
||||
bool flipVertically = false,
|
||||
bool flipVertically = false,
|
||||
bool centerHoriz = true, bool centerVert = true,
|
||||
const Vector2i &offset = Vector2i(0, 0)) = 0;
|
||||
|
||||
|
@ -186,7 +186,7 @@ public:
|
|||
* Draw a line of text on the screen. The coordinates are specified
|
||||
* in pixel coordinates, where the upper left corner is the origin
|
||||
*/
|
||||
virtual void drawText(const Point2i &pos,
|
||||
virtual void drawText(const Point2i &pos,
|
||||
const Font *font, const std::string &text) = 0;
|
||||
|
||||
/// Set the size of point primitives
|
||||
|
@ -223,7 +223,7 @@ public:
|
|||
virtual void drawFilledRectangle(const Point2i &a, const Point2i &b) = 0;
|
||||
|
||||
/// Draw an ellipse with the specified center and axes
|
||||
virtual void drawEllipse(const Point ¢er,
|
||||
virtual void drawEllipse(const Point ¢er,
|
||||
const Vector &axis1, const Vector &axis2) = 0;
|
||||
|
||||
/// Draw a wire-frame axis-aligned box
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
/**
|
||||
* \brief Process all events and call event callbacks.
|
||||
*
|
||||
* This function will run until the \c stop parameter is set
|
||||
* This function will run until the \c stop parameter is set
|
||||
* to \c true from within an event callback.
|
||||
*/
|
||||
virtual void processEventsBlocking(bool &stop) = 0;
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
|
||||
MTS_NAMESPACE_BEGIN
|
||||
|
||||
/** \brief Utility class for creating different kinds of shadow maps (cube,
|
||||
* directional, and paraboloid shadow maps) using hardware rasterization
|
||||
/** \brief Utility class for creating different kinds of shadow maps (cube,
|
||||
* directional, and paraboloid shadow maps) using hardware rasterization
|
||||
*
|
||||
* \ingroup libhw
|
||||
*/
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
* \param trafo
|
||||
* View transformation of the source
|
||||
*/
|
||||
void render(Renderer *renderer, GPUTexture *shadowMap, EShadowMapType type,
|
||||
void render(Renderer *renderer, GPUTexture *shadowMap, EShadowMapType type,
|
||||
const Transform &trafo, Float minDepth, Float maxDepth,
|
||||
const std::vector<Renderer::TransformedGPUGeometry> &geo);
|
||||
|
||||
|
|
|
@ -50,14 +50,14 @@ protected:
|
|||
/// Draw a heads-up display
|
||||
void drawHUD(const std::string &text);
|
||||
|
||||
/// Request that the draw() routine be called
|
||||
/// Request that the draw() routine be called
|
||||
inline void redraw() { m_leaveEventLoop = true; }
|
||||
|
||||
/// To be overwritten by the subclass: main drawing routine
|
||||
virtual void draw() = 0;
|
||||
|
||||
/**
|
||||
* \brief To be overwritten (optionally): perform any necessary
|
||||
* \brief To be overwritten (optionally): perform any necessary
|
||||
* initializations
|
||||
*
|
||||
* The default implementation does nothing and returns \c true.
|
||||
|
@ -73,13 +73,13 @@ protected:
|
|||
|
||||
/// To be overwritten (optionally): handle a key press event
|
||||
virtual void keyPressed(const DeviceEvent &event);
|
||||
|
||||
|
||||
/// To be overwritten (optionally): handle a key release event
|
||||
virtual void keyReleased(const DeviceEvent &event);
|
||||
|
||||
|
||||
/// To be overwritten (optionally): handle a mouse button press event
|
||||
virtual void mouseButtonPressed(const DeviceEvent &event);
|
||||
|
||||
|
||||
/// To be overwritten (optionally): handle a mouse button release event
|
||||
virtual void mouseButtonReleased(const DeviceEvent &event);
|
||||
|
||||
|
@ -94,7 +94,7 @@ protected:
|
|||
|
||||
/// To be overwritten (optionally): handle a mouse end drag event
|
||||
virtual void mouseEndDrag(const DeviceEvent &event);
|
||||
|
||||
|
||||
/// To be overwritten (optionally): handle a window resize event
|
||||
virtual void windowResized(const DeviceEvent &event);
|
||||
|
||||
|
|
|
@ -28,25 +28,25 @@ MTS_NAMESPACE_BEGIN
|
|||
|
||||
/**
|
||||
* \brief This class is responsible for the on-demand creation of
|
||||
* GPU shaders to render shapes that are illuminated by virtual
|
||||
* point light sources.
|
||||
* GPU shaders to render shapes that are illuminated by virtual
|
||||
* point light sources.
|
||||
*
|
||||
* This is used to drive the \c vpl integrator as well as the
|
||||
* This is used to drive the \c vpl integrator as well as the
|
||||
* interactive preview in the Mitsuba GUI.
|
||||
*
|
||||
* For each encountered BSDF-VPL pair, a custom piece of code
|
||||
* For each encountered BSDF-VPL pair, a custom piece of code
|
||||
* describing the characteristic light transport between them is
|
||||
* created and cached. The implementation carefully looks at
|
||||
* the tree of shader dependencies and creates code that can be
|
||||
* shared with other materials that have a similar configuration.
|
||||
* This is necessary to avoid generating a potentially huge O(N^2)
|
||||
* This is necessary to avoid generating a potentially huge O(N^2)
|
||||
* number of very similar programs and brings it down to O(n^2)
|
||||
* where n << N.
|
||||
*
|
||||
* \ingroup libhw
|
||||
*/
|
||||
class MTS_EXPORT_HW VPLShaderManager : public Object {
|
||||
public:
|
||||
public:
|
||||
/// Create a new shader manager
|
||||
VPLShaderManager(Renderer *renderer);
|
||||
|
||||
|
@ -73,14 +73,14 @@ public:
|
|||
* \brief Prepare the shader manager for rendering
|
||||
* with a new VPL
|
||||
*
|
||||
* Must be called after \ref setScene() and before
|
||||
* \ref bind(). This function creates a suitable
|
||||
* Must be called after \ref setScene() and before
|
||||
* \ref bind(). This function creates a suitable
|
||||
* shadow map for the VPL.
|
||||
*/
|
||||
void setVPL(const VPL &vpl);
|
||||
|
||||
/**
|
||||
* \brief Bind a shader for rendering a certain
|
||||
* \brief Bind a shader for rendering a certain
|
||||
* VPL/BSDF/Emitter triplet
|
||||
*
|
||||
* \param vpl
|
||||
|
@ -100,12 +100,12 @@ public:
|
|||
* When set to \c true, a special shader is used to
|
||||
* create face normals for the geometry
|
||||
*/
|
||||
void bind(const VPL &vpl, const BSDF *bsdf,
|
||||
const Sensor *sensor, const Emitter *emitter,
|
||||
void bind(const VPL &vpl, const BSDF *bsdf,
|
||||
const Sensor *sensor, const Emitter *emitter,
|
||||
const Matrix4x4 &instanceTransform, bool faceNormals);
|
||||
|
||||
/**
|
||||
* \brief Release the currently bound shader and
|
||||
* \brief Release the currently bound shader and
|
||||
* any resources (textures,..) that it references
|
||||
*/
|
||||
void unbind();
|
||||
|
@ -115,8 +115,8 @@ public:
|
|||
* for a given VPL
|
||||
*
|
||||
* This function issues the necessary calls to \ref bind()
|
||||
* \ref unbind(), etc., and schedules draw calls for all
|
||||
* of the scene geometry.
|
||||
* \ref unbind(), etc., and schedules draw calls for all
|
||||
* of the scene geometry.
|
||||
*/
|
||||
void drawAllGeometryForVPL(const VPL &vpl, const Sensor *sensor);
|
||||
|
||||
|
@ -141,7 +141,7 @@ public:
|
|||
|
||||
/// Return whether or not non-diffuse VPLs are used
|
||||
inline bool getDiffuseSources() const { return m_diffuseSources; }
|
||||
|
||||
|
||||
/// Set whether or not surfaces are drawn assumed to be diffuse
|
||||
inline void setDiffuseReceivers(bool diffuseReceivers) { m_diffuseReceivers = diffuseReceivers; }
|
||||
|
||||
|
@ -165,7 +165,7 @@ protected:
|
|||
const Shader *shader;
|
||||
std::vector<DependencyNode> children;
|
||||
std::vector<int> parameterIDs;
|
||||
|
||||
|
||||
/// Create from a \ref Shader object
|
||||
inline DependencyNode(Shader *shader = NULL) : shader(shader) {
|
||||
if (!shader)
|
||||
|
@ -176,12 +176,12 @@ protected:
|
|||
it != deps.end(); ++it)
|
||||
children.push_back(DependencyNode(*it));
|
||||
}
|
||||
|
||||
|
||||
/// Copy constructor
|
||||
inline DependencyNode(const DependencyNode &node)
|
||||
: shader(node.shader), children(node.children),
|
||||
inline DependencyNode(const DependencyNode &node)
|
||||
: shader(node.shader), children(node.children),
|
||||
parameterIDs(node.parameterIDs) { }
|
||||
|
||||
|
||||
/// Generate GLSL code for the entire shader chain
|
||||
inline std::string generateCode(std::ostringstream &oss, int &id) const {
|
||||
std::vector<std::string> depNames;
|
||||
|
@ -192,17 +192,17 @@ protected:
|
|||
oss << endl;
|
||||
return evalName;
|
||||
}
|
||||
|
||||
|
||||
/// Resolve all parameters of the shader chain
|
||||
inline void resolve(GPUProgram *program, int &id) {
|
||||
std::vector<std::string> depNames;
|
||||
for (size_t i=0; i<children.size(); ++i)
|
||||
children[i].resolve(program, id);
|
||||
|
||||
|
||||
std::string evalName = formatString("shader_%i", id++);
|
||||
shader->resolve(program, evalName, parameterIDs);
|
||||
}
|
||||
|
||||
|
||||
/// Bind all referenced resources (textures etc)
|
||||
inline void bind(GPUProgram *program, const DependencyNode &targetNode, int &textureUnitOffset) {
|
||||
if (!shader)
|
||||
|
@ -211,7 +211,7 @@ protected:
|
|||
children[i].bind(program, targetNode.children[i], textureUnitOffset);
|
||||
shader->bind(program, targetNode.parameterIDs, textureUnitOffset);
|
||||
}
|
||||
|
||||
|
||||
/// Release resources that were bound by \ref bind()
|
||||
inline void unbind() {
|
||||
if (!shader)
|
||||
|
@ -220,7 +220,7 @@ protected:
|
|||
for (size_t i=0; i<children.size(); ++i)
|
||||
children[i].unbind();
|
||||
}
|
||||
|
||||
|
||||
/// Generate a textual summary of the entire shader chain
|
||||
inline void toString(std::ostringstream &oss) const {
|
||||
if (!shader)
|
||||
|
@ -236,14 +236,14 @@ protected:
|
|||
oss << "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
toString(oss);
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief Describes the configuration of a (vpl, bsdf, emitter)
|
||||
* shader chain triplet
|
||||
|
@ -252,7 +252,7 @@ protected:
|
|||
DependencyNode vpl, bsdf, emitter;
|
||||
bool faceNormals;
|
||||
GPUProgram *program;
|
||||
|
||||
|
||||
/* GLSL program paramter IDs */
|
||||
int param_instanceTransform, param_vplTransform;
|
||||
int param_vplPosition, param_vplDirection;
|
||||
|
@ -268,7 +268,7 @@ protected:
|
|||
/// Create a new configuration for the given (vpl, bsdf, emitter) triplet
|
||||
inline VPLConfiguration(Shader *vpl, Shader *bsdf, Shader *emitter, bool faceNormals)
|
||||
: vpl(vpl), bsdf(bsdf), emitter(emitter), faceNormals(faceNormals), program(NULL) { }
|
||||
|
||||
|
||||
/// Generate GLSL code for the entire shader chain
|
||||
inline void generateCode(std::ostringstream &oss, std::string &vplEvalName,
|
||||
std::string &bsdfEvalName, std::string &emitterEvalName) const {
|
||||
|
@ -278,7 +278,7 @@ protected:
|
|||
if (emitter.shader)
|
||||
emitterEvalName = emitter.generateCode(oss, id);
|
||||
}
|
||||
|
||||
|
||||
/// Resolve all parameters of the shader chain
|
||||
inline void resolve(GPUProgram *program) {
|
||||
int id = 0;
|
||||
|
@ -287,7 +287,7 @@ protected:
|
|||
if (emitter.shader)
|
||||
emitter.resolve(program, id);
|
||||
}
|
||||
|
||||
|
||||
/// Bind all referenced resources (textures etc)
|
||||
inline void bind(const VPLConfiguration &targetConf, int textureUnitOffset) {
|
||||
vpl.bind(targetConf.program, targetConf.vpl, textureUnitOffset);
|
||||
|
@ -295,7 +295,7 @@ protected:
|
|||
if (emitter.shader)
|
||||
emitter.bind(targetConf.program, targetConf.emitter, textureUnitOffset);
|
||||
}
|
||||
|
||||
|
||||
/// Release resources that were bound by \ref bind()
|
||||
inline void unbind() {
|
||||
vpl.unbind();
|
||||
|
@ -303,7 +303,7 @@ protected:
|
|||
if (emitter.shader)
|
||||
emitter.unbind();
|
||||
}
|
||||
|
||||
|
||||
/// Generate a textual summary of the entire shader chain
|
||||
inline std::string toString() const {
|
||||
std::ostringstream oss;
|
||||
|
@ -357,7 +357,7 @@ private:
|
|||
/* Background rendering - related */
|
||||
ref<GPUProgram> m_backgroundProgram;
|
||||
DependencyNode m_backgroundDependencies;
|
||||
int m_backgroundParam_camPosition;
|
||||
int m_backgroundParam_camPosition;
|
||||
int m_backgroundParam_camDirection;
|
||||
int m_backgroundParam_clipToWorld;
|
||||
int m_backgroundParam_emitterScale;
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
|
||||
/// Set the window title
|
||||
void setTitle(const std::string &title);
|
||||
|
||||
|
||||
/// Display the WGL cursor?
|
||||
void showCursor(bool enabled);
|
||||
|
||||
|
@ -81,7 +81,7 @@ protected:
|
|||
bool translateKey(WPARAM vkey, LPARAM lParam, DeviceEvent &event);
|
||||
|
||||
/// Translate a WIN32 mouse event
|
||||
bool translateMouse(UINT uMsg, WPARAM wParam, DeviceEvent &event);
|
||||
bool translateMouse(UINT uMsg, WPARAM wParam, DeviceEvent &event);
|
||||
protected:
|
||||
ref<WGLDevice> m_parent;
|
||||
HWND m_hwnd;
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
/**
|
||||
* \brief Process all events and call event callbacks.
|
||||
*
|
||||
* This function will run until the \c stop parameter is set
|
||||
* This function will run until the \c stop parameter is set
|
||||
* to \c true from within an event callback.
|
||||
*/
|
||||
void processEventsBlocking(bool &stop);
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
/// Set the window title
|
||||
void setTitle(const std::string &title);
|
||||
|
||||
|
||||
/// Display the X11 cursor?
|
||||
void showCursor(bool enabled);
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue