Skip to content
Snippets Groups Projects
Commit 5bf4ed6c authored by Lukas Werner's avatar Lukas Werner
Browse files

Added padding for AABB intersection testing

parent 7573ebab
Branches
Tags
No related merge requests found
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
namespace walberla { namespace walberla {
namespace pe { namespace pe {
namespace raytracing { namespace raytracing {
inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t); inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t, real_t padding = real_t(0.0));
inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t); inline bool intersects(const SphereID sphere, const Ray& ray, real_t& t);
inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t); inline bool intersects(const PlaneID plane, const Ray& ray, real_t& t);
...@@ -172,11 +172,12 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) { ...@@ -172,11 +172,12 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) {
return true; return true;
} }
inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t) { inline bool intersects(const AABB& aabb, const Ray& ray, real_t& t, real_t padding) {
// An Efficient and Robust Ray–Box Intersection Algorithm: http://people.csail.mit.edu/amy/papers/box-jgt.pdf // An Efficient and Robust Ray–Box Intersection Algorithm: http://people.csail.mit.edu/amy/papers/box-jgt.pdf
const Vec3 paddingVector(padding, padding, padding);
Vec3 bounds[2] = { Vec3 bounds[2] = {
aabb.min(), aabb.min() - paddingVector,
aabb.max() aabb.max() + paddingVector
}; };
const Vector3<int8_t>& sign = ray.getInvDirectionSigns(); const Vector3<int8_t>& sign = ray.getInvDirectionSigns();
......
...@@ -39,15 +39,21 @@ namespace raytracing { ...@@ -39,15 +39,21 @@ namespace raytracing {
* \param cameraPosition Position of the camera in the global world frame. * \param cameraPosition Position of the camera in the global world frame.
* \param lookAtPoint Point the camera looks at in the global world frame. * \param lookAtPoint Point the camera looks at in the global world frame.
* \param upVector Vector indicating the upwards direction of the camera. * \param upVector Vector indicating the upwards direction of the camera.
* \param blockAABBIntersectionPadding The padding applied in block AABB intersection pretesting. Usually not required.
* Set it to the value of the farthest distance a object might protrude from
* its containing block.
*/ */
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const shared_ptr<BodyStorage> globalBodyStorage,
size_t pixelsHorizontal, size_t pixelsVertical, size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical, real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector) const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector,
real_t blockAABBIntersectionPadding)
: forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage), : forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage),
pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical), pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical),
fov_vertical_(fov_vertical), fov_vertical_(fov_vertical),
cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector), cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector),
blockAABBIntersectionPadding_(blockAABBIntersectionPadding),
tBufferOutputEnabled_(false) tBufferOutputEnabled_(false)
{ {
setupView_(); setupView_();
...@@ -61,10 +67,12 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI ...@@ -61,10 +67,12 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
* *
* The config block has to contain image_x (int), image_y (int), fov_vertical (real, in degrees) * The config block has to contain image_x (int), image_y (int), fov_vertical (real, in degrees)
* and tbuffer_output_directory (string) parameters. Additionally a vector of reals * and tbuffer_output_directory (string) parameters. Additionally a vector of reals
* for each of cameraPosition, lookAt and the upVector. * for each of cameraPosition, lookAt and the upVector. Optional is blockAABBIntersectionPadding (real).
*/ */
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const Config::BlockHandle& config) : forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage) { const shared_ptr<BodyStorage> globalBodyStorage,
const Config::BlockHandle& config)
: forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage) {
WALBERLA_CHECK(config.isValid(), "No valid config passed to raytracer"); WALBERLA_CHECK(config.isValid(), "No valid config passed to raytracer");
pixelsHorizontal_ = config.getParameter<size_t>("image_x"); pixelsHorizontal_ = config.getParameter<size_t>("image_x");
...@@ -80,6 +88,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI ...@@ -80,6 +88,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
cameraPosition_ = config.getParameter<Vec3>("cameraPosition"); cameraPosition_ = config.getParameter<Vec3>("cameraPosition");
lookAtPoint_ = config.getParameter<Vec3>("lookAt"); lookAtPoint_ = config.getParameter<Vec3>("lookAt");
upVector_ = config.getParameter<Vec3>("upVector"); upVector_ = config.getParameter<Vec3>("upVector");
blockAABBIntersectionPadding_ = config.getParameter<real_t>("blockAABBIntersectionPadding", real_t(0.0));
setupView_(); setupView_();
} }
......
...@@ -66,11 +66,14 @@ class Raytracer { ...@@ -66,11 +66,14 @@ class Raytracer {
public: public:
/*!\name Constructors */ /*!\name Constructors */
//@{ //@{
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const shared_ptr<BodyStorage> globalBodyStorage,
size_t pixelsHorizontal, size_t pixelsVertical, size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical, real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector); const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector,
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, real_t blockAABBIntersectionPadding = real_t(0.0));
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const shared_ptr<BodyStorage> globalBodyStorage,
const Config::BlockHandle& config); const Config::BlockHandle& config);
//@} //@}
...@@ -89,10 +92,15 @@ private: ...@@ -89,10 +92,15 @@ private:
Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame, Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame,
marks the center of the view plane.*/ marks the center of the view plane.*/
Vec3 upVector_; //!< The vector indicating the upwards direction of the camera. Vec3 upVector_; //!< The vector indicating the upwards direction of the camera.
real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as
some objects within a block might protrude from the block's AABB.*/
bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to a file bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to a file
std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory
std::set<walberla::id_t> invisibleBodyIDs_; //!< The set for invisible body IDs. std::set<walberla::id_t> invisibleBodyIDs_; //!< The set for invisible body IDs.
// std::set is used here because for a small number of elements it is often faster than std::unordered_set // std::set is used here because for a small number of elements it is often faster than std::unordered_set
//@} //@}
Vec3 n; // normal vector of viewing plane Vec3 n; // normal vector of viewing plane
...@@ -283,7 +291,7 @@ void Raytracer::rayTrace(const size_t timestep) const { ...@@ -283,7 +291,7 @@ void Raytracer::rayTrace(const size_t timestep) const {
for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) { for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) {
#ifndef DISABLE_BLOCK_AABB_INTERSECTION_PRECHECK #ifndef DISABLE_BLOCK_AABB_INTERSECTION_PRECHECK
const AABB& blockAabb = blockIt->getAABB(); const AABB& blockAabb = blockIt->getAABB();
if (!intersects(blockAabb, ray, t)) { if (!intersects(blockAabb, ray, t, blockAABBIntersectionPadding_)) {
continue; continue;
} }
#endif #endif
......
...@@ -114,6 +114,26 @@ void BoxIntersectsTest() { ...@@ -114,6 +114,26 @@ void BoxIntersectsTest() {
WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(2.67157), real_t(1e-4)); WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(2.67157), real_t(1e-4));
} }
void AABBIntersectsTest() {
WALBERLA_LOG_INFO("RAY -> AABB");
Ray ray1(Vec3(-5,5,5), Vec3(1,0,0));
real_t t;
AABB aabb(0,0,0,
10,10,10);
WALBERLA_CHECK(intersects(aabb, ray1, t));
WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(5));
WALBERLA_CHECK(intersects(aabb, ray1, t, 1.0));
WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(4));
Ray ray2(Vec3(-5,5,10.5), Vec3(1,0,0)); // ray shooting over aabb, but within padding passed to intersects
WALBERLA_CHECK(intersects(aabb, ray1, t, 1.0));
WALBERLA_CHECK_FLOAT_EQUAL(t, real_t(4));
}
void RaytracerTest() { void RaytracerTest() {
WALBERLA_LOG_INFO("Raytracer"); WALBERLA_LOG_INFO("Raytracer");
shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>(); shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
...@@ -171,9 +191,10 @@ int main( int argc, char** argv ) ...@@ -171,9 +191,10 @@ int main( int argc, char** argv )
SetBodyTypeIDs<BodyTuple>::execute(); SetBodyTypeIDs<BodyTuple>::execute();
//SphereIntersectsTest(); SphereIntersectsTest();
//PlaneIntersectsTest(); PlaneIntersectsTest();
//BoxIntersectsTest(); BoxIntersectsTest();
AABBIntersectsTest();
RaytracerTest(); RaytracerTest();
return EXIT_SUCCESS; return EXIT_SUCCESS;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment