From 4ce6960230001d59d3d076ebc880a5da623ecaa4 Mon Sep 17 00:00:00 2001 From: johannes hanika Date: Mon, 3 Nov 2014 15:54:34 +0100 Subject: [PATCH] hslt: util.h: add boilerplate coordinate derivative function --- include/mitsuba/core/util.h | 8 ++++++++ src/libcore/util.cpp | 24 ++++++++++++++++++++++++ src/librender/trimesh.cpp | 4 ++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/mitsuba/core/util.h b/include/mitsuba/core/util.h index 27547f11..d76acd7b 100644 --- a/include/mitsuba/core/util.h +++ b/include/mitsuba/core/util.h @@ -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 diff --git a/src/libcore/util.cpp b/src/libcore/util.cpp index 07005112..292f44cb 100644 --- a/src/libcore/util.cpp +++ b/src/libcore/util.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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), diff --git a/src/librender/trimesh.cpp b/src/librender/trimesh.cpp index 994df18b..e28ba68e 100644 --- a/src/librender/trimesh.cpp +++ b/src/librender/trimesh.cpp @@ -40,7 +40,7 @@ MTS_NAMESPACE_BEGIN TriMesh::TriMesh(const std::string &name, size_t triangleCount, size_t vertexCount, bool hasNormals, bool hasTexcoords, bool hasVertexColors, bool flipNormals, bool faceNormals) - : Shape(Properties()), m_triangleCount(triangleCount), + : Shape(Properties()), m_triangleCount(triangleCount), m_vertexCount(vertexCount), m_flipNormals(flipNormals), m_faceNormals(faceNormals) { m_name = name; @@ -762,7 +762,7 @@ void TriMesh::getNormalDerivative(const Intersection &its, /* Recompute the barycentric coordinates, since 'its.uv' may have been overwritten with coordinates of the texture "parameterization". */ - Vector rel = its.p - p0, du = p1 - p0, dv = p2 - p0; + Vector rel = its.p - p0, du = p1 - p0, dv = p2 - p0; Float b1 = dot(du, rel), b2 = dot(dv, rel), /* Normal equations */ a11 = dot(du, du), a12 = dot(du, dv),