hslt: util.h: add boilerplate coordinate derivative function

metadata
johannes hanika 2014-11-03 15:54:34 +01:00 committed by Wenzel Jakob
parent 4a0d0aa694
commit 4ce6960230
3 changed files with 34 additions and 2 deletions

View File

@ -329,6 +329,14 @@ extern MTS_EXPORT_CORE bool solveLinearSystem2x2(const Float a[2][2], const Floa
*/
extern MTS_EXPORT_CORE void coordinateSystem(const Vector &a, Vector &b, Vector &c);
/**
* \brief Derivatives of a frame formed by coordinateSystem
* \param n Source tangent frame that was created with coordinateSystem
* \param ds derivative of the frame with respect to s. ds.n should already contain normal derivative along s
* \param dt derivative of the frame with respect to t. dt.n should already contain normal derivative along t
*/
extern MTS_EXPORT_CORE void coordinateSystemDerivatives(const Frame &frame, Frame &ds, Frame &dt);
/**
* \brief Generate (optionally jittered) stratified 1D samples
* \param random Source of random numbers

View File

@ -21,6 +21,7 @@
#include <mitsuba/core/random.h>
#include <mitsuba/core/quad.h>
#include <mitsuba/core/sse.h>
#include <mitsuba/core/frame.h>
#include <boost/bind.hpp>
#include <stdarg.h>
#include <iomanip>
@ -599,6 +600,29 @@ void coordinateSystem(const Vector &a, Vector &b, Vector &c) {
b = cross(c, a);
}
void coordinateSystemDerivatives(const Frame &frame, Frame &ds, Frame &dt) {
const Vector n = frame.n;
const Vector s = frame.s;
if(std::abs(n.x) > std::abs(n.y)) {
const Float invLen = 1 / std::sqrt(n.x * n.x + n.z * n.z);
ds.s = Vector(ds.n.z * invLen, 0, -ds.n.x * invLen);
ds.s -= s * dot(ds.s, s);
dt.s = Vector(dt.n.z * invLen, 0, -dt.n.x * invLen);
dt.s -= s * dot(dt.s, s);
} else {
const Float invLen = 1 / std::sqrt(n.y * n.y + n.z * n.z);
ds.s = Vector(0, ds.n.z * invLen, -ds.n.y * invLen);
ds.s -= s * dot(ds.s, s);
dt.s = Vector(0, dt.n.z * invLen, -dt.n.y * invLen);
dt.s -= s * dot(dt.s, s);
}
dt.t = cross(s, ds.n) + cross(dt.s, n);
ds.t = cross(s, dt.n) + cross(ds.s, n);
}
Point2 toSphericalCoordinates(const Vector &v) {
Point2 result(
std::acos(v.z),