155 lines
4.0 KiB
C++
155 lines
4.0 KiB
C++
/*
|
|
This file is part of Mitsuba, a physically based rendering system.
|
|
|
|
Copyright (c) 2007-2014 by Wenzel Jakob and others.
|
|
|
|
Mitsuba is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License Version 3
|
|
as published by the Free Software Foundation.
|
|
|
|
Mitsuba is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#pragma once
|
|
#if !defined(__MITSUBA_BIDIR_MANIFOLD_H_)
|
|
#define __MITSUBA_BIDIR_MANIFOLD_H_
|
|
|
|
#include <mitsuba/bidir/vertex.h>
|
|
|
|
#define MTS_MANIFOLD_DEBUG 0
|
|
#define MTS_MANIFOLD_EPSILON Epsilon
|
|
#define MTS_MANIFOLD_MAX_ITERATIONS 20
|
|
|
|
MTS_NAMESPACE_BEGIN
|
|
|
|
/**
|
|
* \brief Utility class for perturbing paths located on a specular manifold.
|
|
* \author Wenzel Jakob
|
|
*/
|
|
class MTS_EXPORT_BIDIR SpecularManifold : public Object {
|
|
public:
|
|
/// Construct an unitialized specular manifold data structure
|
|
SpecularManifold(const Scene *scene, int maxIterations = -1);
|
|
|
|
/**
|
|
* \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
|
|
*/
|
|
bool update(Path &path, int start, int end);
|
|
|
|
/// Attempt to move the movable endpoint vertex to position \c target
|
|
bool move(const Point &target, const Normal &normal);
|
|
|
|
/**
|
|
* \brief Compute the generalized geometric term between 'a' and 'b'
|
|
*/
|
|
Float G(const Path &path, int a, int b);
|
|
|
|
/**
|
|
* \brief Compute a product of standard and generalized geometric
|
|
* terms between 'a' and 'b' depending on whether vertices are
|
|
* specular or non-specular.
|
|
*/
|
|
Float multiG(const Path &path, int a, int b);
|
|
|
|
Float det(const Path &path, int a, int b, int c);
|
|
|
|
/// Return the number of iterations used by \ref move()
|
|
inline int getIterationCount() const { return m_iterations; }
|
|
|
|
/// Return the position of a vertex
|
|
inline const Point &getPosition(int i) { return m_vertices[i].p; }
|
|
|
|
/// Return a string representation
|
|
std::string toString() const;
|
|
|
|
MTS_DECLARE_CLASS()
|
|
protected:
|
|
/// Virtual destructor
|
|
virtual ~SpecularManifold() { }
|
|
|
|
private:
|
|
enum EType {
|
|
EPinnedPosition = 0,
|
|
EPinnedDirection,
|
|
EReflection,
|
|
ERefraction,
|
|
EMedium,
|
|
EMovable
|
|
};
|
|
|
|
/// Describes a single interaction on the path
|
|
struct SimpleVertex {
|
|
bool degenerate : 1;
|
|
EType type : 31;
|
|
|
|
/* Position and partials */
|
|
Point p;
|
|
Vector dpdu, dpdv;
|
|
|
|
/* Normal and partials */
|
|
Normal n, gn;
|
|
Vector dndu, dndv;
|
|
|
|
/* "Microfacet" normal */
|
|
Normal m;
|
|
|
|
/* Further information about the vertex */
|
|
Float eta;
|
|
const Object *object;
|
|
|
|
/* Scratch space for matrix assembly */
|
|
Matrix2x2 a, b, c, u;
|
|
|
|
/* Manifold tangent space projected onto this vertex */
|
|
Matrix2x2 Tp;
|
|
|
|
/// 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),
|
|
m(0.0f), eta(1.0f), object(NULL) { }
|
|
|
|
/// Map a tangent space displacement into world space
|
|
inline Vector map(Float u, Float v) const {
|
|
Vector2 T = Tp * Vector2(u, v);
|
|
return T.x * dpdu + T.y * dpdv;
|
|
}
|
|
|
|
std::string toString() const;
|
|
};
|
|
|
|
/// Take the specified step and project back onto the manifold
|
|
bool project(const Vector &d);
|
|
|
|
/**
|
|
* \brief Compute the tangent vectors with the specified
|
|
* components when projected onto the movable endpoint vertex
|
|
*/
|
|
bool computeTangents();
|
|
|
|
void check(SimpleVertex *v);
|
|
protected:
|
|
const Scene *m_scene;
|
|
Float m_time;
|
|
int m_iterations, m_maxIterations;
|
|
|
|
std::vector<SimpleVertex> m_vertices, m_proposal;
|
|
};
|
|
|
|
MTS_NAMESPACE_END
|
|
|
|
#endif /* __MITSUBA_BIDIR_MANIFOLD_H_ */
|