233 lines
6.7 KiB
C++
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_ */
|