mitsuba/include/mitsuba/core/ray.h

233 lines
6.7 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_CORE_RAY_H_)
#define __MITSUBA_CORE_RAY_H_
#include <mitsuba/mitsuba.h>
MTS_NAMESPACE_BEGIN
/** \brief Simple n-dimensional ray data structure with
* minimum / maximum extent information.
*
* The somewhat peculiar ordering of the attributes is due
* to alignment purposes and should not be changed.
*
* \ingroup libcore
* \ingroup libpython
*/
template <typename _PointType, typename _VectorType> struct TRay {
typedef _PointType PointType;
typedef _VectorType VectorType;
typedef typename PointType::Scalar Scalar;
/* The somewhat peculiar ordering of the attributes is for
alignment purposes in the 3D case and should not be changed. */
PointType o; ///< Ray origin
Scalar mint; ///< Minimum range for intersection tests
VectorType d; ///< Ray direction
Scalar maxt; ///< Maximum range for intersection tests
VectorType dRcp; ///< Componentwise reciprocals of the ray direction
Float time; ///< Time value associated with this ray
/// Construct a new ray
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),
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),
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),
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),
maxt(std::numeric_limits<Scalar>::infinity()), time(time) {
#ifdef MTS_DEBUG_FP
bool state = disableFPExceptions();
#endif
for (int i=0; i<3; ++i)
dRcp[i] = (Scalar) 1 / d[i];
#ifdef MTS_DEBUG_FP
restoreFPExceptions(state);
#endif
}
/// Construct a new ray
inline TRay(const PointType &o, const VectorType &d, Scalar mint, Scalar maxt,
Scalar time) : o(o), mint(mint), d(d), maxt(maxt), time(time) {
#ifdef MTS_DEBUG_FP
bool state = disableFPExceptions();
#endif
for (int i=0; i<3; ++i)
dRcp[i] = (Scalar) 1 / d[i];
#ifdef MTS_DEBUG_FP
restoreFPExceptions(state);
#endif
}
/// Set the origin
inline void setOrigin(const PointType &pos) { o = pos; }
/// Set the time
inline void setTime(Scalar tval) { time = tval; }
/// Set the direction and update the reciprocal
inline void setDirection(const VectorType &dir) {
d = dir;
#ifdef MTS_DEBUG_FP
bool state = disableFPExceptions();
#endif
for (int i=0; i<3; ++i)
dRcp[i] = (Scalar) 1 / dir[i];
#ifdef MTS_DEBUG_FP
restoreFPExceptions(state);
#endif
}
/**
* \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.
* position lookups should be written as \c ray.eval(t)
*/
inline PointType operator() (Scalar t) const { return o + t * d; }
/// 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
<< ", maxt=" << maxt << ", time=" << time << "]";
return oss.str();
}
};
/** \brief %Ray differential -- enhances the basic ray class with
information about the rays of adjacent pixels on the view plane
\ingroup libcore
*/
struct RayDifferential : public Ray {
Point rxOrigin, ryOrigin;
Vector rxDirection, ryDirection;
bool hasDifferentials;
inline RayDifferential()
: hasDifferentials(false) {
}
inline RayDifferential(const Point &p, const Vector &d, Float time)
: Ray(p, d, time), hasDifferentials(false) {
}
inline explicit RayDifferential(const Ray &ray)
: Ray(ray), hasDifferentials(false) {
}
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;
rxDirection = d + (rxDirection - d) * amount;
ryDirection = d + (ryDirection - d) * amount;
}
void scaleDifferentialUV(const Vector2 amountUV) {
rxOrigin = o + (rxOrigin - o) * amountUV.x;
ryOrigin = o + (ryOrigin - o) * amountUV.y;
rxDirection = d + (rxDirection - d) * amountUV.x;
ryDirection = d + (ryDirection - d) * amountUV.y;
}
inline void operator=(const RayDifferential &ray) {
o = ray.o;
mint = ray.mint;
d = ray.d;
maxt = ray.maxt;
#ifdef MTS_DEBUG_FP
bool state = disableFPExceptions();
#endif
dRcp = ray.dRcp;
#ifdef MTS_DEBUG_FP
restoreFPExceptions(state);
#endif
hasDifferentials = ray.hasDifferentials;
rxOrigin = ray.rxOrigin;
ryOrigin = ray.ryOrigin;
rxDirection = ray.rxDirection;
ryDirection = ray.ryDirection;
}
inline void operator=(const Ray &ray) {
o = ray.o;
mint = ray.mint;
d = ray.d;
maxt = ray.maxt;
#ifdef MTS_DEBUG_FP
bool state = disableFPExceptions();
#endif
dRcp = ray.dRcp;
#ifdef MTS_DEBUG_FP
restoreFPExceptions(state);
#endif
hasDifferentials = false;
}
/// Return a string representation of this ray
inline std::string toString() const {
std::ostringstream oss;
oss << "RayDifferential[" << endl
<< " origin = " << o.toString() << "," << endl
<< " direction = " << d.toString() << "," << endl
<< " mint = " << mint << "," << endl
<< " maxt = " << maxt << "," << endl
<< " time = " << time << "," << endl
<< " hasDifferentials = " << hasDifferentials << "," << endl
<< " rxOrigin = " << rxOrigin.toString() << "," << endl
<< " ryOrigin = " << ryOrigin.toString() << "," << endl
<< " rxDirection = " << rxDirection.toString() << "," << endl
<< " ryDirection = " << ryDirection.toString() << endl
<< "]" << endl;
return oss.str();
}
};
MTS_NAMESPACE_END
#endif /* __MITSUBA_CORE_RAY_H_ */