mitsuba/include/mitsuba/core/bsphere.h

115 lines
3.6 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_BSPHERE_H_)
#define __MITSUBA_CORE_BSPHERE_H_
#include <mitsuba/core/ray.h>
MTS_NAMESPACE_BEGIN
/** \brief Bounding sphere data structure in three dimensions
*
* \ingroup libcore
* \ingroup libpython
*/
struct BSphere {
Point center;
Float radius;
/// Construct a bounding sphere at the origin having radius zero
inline BSphere() : center(0.0f), radius(0.0f) { }
/// Unserialize a bounding sphere from a binary data stream
inline BSphere(Stream *stream) {
center = Point(stream);
radius = stream->readFloat();
}
/// Create a bounding sphere from a given center point and radius
inline BSphere(const Point &center, Float radius)
: center(center), radius(radius) {
}
/// Copy constructor
inline BSphere(const BSphere &boundingSphere)
: center(boundingSphere.center), radius(boundingSphere.radius) {
}
/// Return whether this bounding sphere has a radius of zero or less.
inline bool isEmpty() const {
return radius <= 0.0f;
}
/// Expand the bounding sphere radius to contain another point.
inline void expandBy(const Point p) {
radius = std::max(radius, (p-center).length());
}
/// Check whether the specified point is inside or on the sphere
inline bool contains(const Point p) const {
return (p - center).length() <= radius;
}
/// Equality test
inline bool operator==(const BSphere &boundingSphere) const {
return center == boundingSphere.center && radius == boundingSphere.radius;
}
/// Inequality test
inline bool operator!=(const BSphere &boundingSphere) const {
return center != boundingSphere.center || radius != boundingSphere.radius;
}
/**
* \brief Calculate the intersection points with the given ray
* \return \c true if the ray intersects the bounding sphere
*
* \remark In the Python bindings, this function returns the
* \c nearT and \c farT values as a tuple (or \c None, when no
* intersection was found)
*/
inline bool rayIntersect(const Ray &ray, Float &nearHit, Float &farHit) const {
Vector o = ray.o - center;
Float A = ray.d.lengthSquared();
Float B = 2 * dot(o, ray.d);
Float C = o.lengthSquared() - radius*radius;
return solveQuadratic(A, B, C, nearHit, farHit);
}
/// Serialize this bounding sphere to a binary data stream
inline void serialize(Stream *stream) const {
center.serialize(stream);
stream->writeFloat(radius);
}
/// Return a string representation of the bounding sphere
inline std::string toString() const {
std::ostringstream oss;
oss << "BSphere[center = " << center.toString()
<< ", radius = " << radius << "]";
return oss.str();
}
};
MTS_NAMESPACE_END
#endif /* __MITSUBA_CORE_BSPHERE_H_ */