From 5bf4ed6c996ee03ee9d5fcc425d46dc4acfd5c7b Mon Sep 17 00:00:00 2001 From: Lukas Werner <lks.werner@fau.de> Date: Wed, 24 Jan 2018 23:33:07 +0100 Subject: [PATCH] Added padding for AABB intersection testing --- src/pe/raytracing/Intersects.h | 9 +++++---- src/pe/raytracing/Raytracer.cpp | 20 +++++++++++++++----- src/pe/raytracing/Raytracer.h | 16 ++++++++++++---- tests/pe/Raytracing.cpp | 27 ++++++++++++++++++++++++--- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/pe/raytracing/Intersects.h b/src/pe/raytracing/Intersects.h index 3b274630e..90d17f29b 100644 --- a/src/pe/raytracing/Intersects.h +++ b/src/pe/raytracing/Intersects.h @@ -38,7 +38,7 @@ namespace walberla { namespace pe { 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 PlaneID plane, const Ray& ray, real_t& t); @@ -172,11 +172,12 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t) { 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 + const Vec3 paddingVector(padding, padding, padding); Vec3 bounds[2] = { - aabb.min(), - aabb.max() + aabb.min() - paddingVector, + aabb.max() + paddingVector }; const Vector3<int8_t>& sign = ray.getInvDirectionSigns(); diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp index 0e56f74cb..0cce4b37c 100644 --- a/src/pe/raytracing/Raytracer.cpp +++ b/src/pe/raytracing/Raytracer.cpp @@ -39,15 +39,21 @@ namespace raytracing { * \param cameraPosition Position of the camera 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 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, 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), pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical), fov_vertical_(fov_vertical), cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector), + blockAABBIntersectionPadding_(blockAABBIntersectionPadding), tBufferOutputEnabled_(false) { setupView_(); @@ -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) * 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, - const Config::BlockHandle& config) : forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage) { +Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, + 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"); pixelsHorizontal_ = config.getParameter<size_t>("image_x"); @@ -80,6 +88,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI cameraPosition_ = config.getParameter<Vec3>("cameraPosition"); lookAtPoint_ = config.getParameter<Vec3>("lookAt"); upVector_ = config.getParameter<Vec3>("upVector"); + + blockAABBIntersectionPadding_ = config.getParameter<real_t>("blockAABBIntersectionPadding", real_t(0.0)); setupView_(); } diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h index a0a8580f7..873760d30 100644 --- a/src/pe/raytracing/Raytracer.h +++ b/src/pe/raytracing/Raytracer.h @@ -66,11 +66,14 @@ class Raytracer { public: /*!\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, real_t fov_vertical, - const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector); - explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage, + const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector, + 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); //@} @@ -89,10 +92,15 @@ private: Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame, marks the center of the view plane.*/ 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 std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory + 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 + //@} Vec3 n; // normal vector of viewing plane @@ -283,7 +291,7 @@ void Raytracer::rayTrace(const size_t timestep) const { for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) { #ifndef DISABLE_BLOCK_AABB_INTERSECTION_PRECHECK const AABB& blockAabb = blockIt->getAABB(); - if (!intersects(blockAabb, ray, t)) { + if (!intersects(blockAabb, ray, t, blockAABBIntersectionPadding_)) { continue; } #endif diff --git a/tests/pe/Raytracing.cpp b/tests/pe/Raytracing.cpp index 43ca24d2b..17f738282 100644 --- a/tests/pe/Raytracing.cpp +++ b/tests/pe/Raytracing.cpp @@ -114,6 +114,26 @@ void BoxIntersectsTest() { 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() { WALBERLA_LOG_INFO("Raytracer"); shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>(); @@ -171,9 +191,10 @@ int main( int argc, char** argv ) SetBodyTypeIDs<BodyTuple>::execute(); - //SphereIntersectsTest(); - //PlaneIntersectsTest(); - //BoxIntersectsTest(); + SphereIntersectsTest(); + PlaneIntersectsTest(); + BoxIntersectsTest(); + AABBIntersectsTest(); RaytracerTest(); return EXIT_SUCCESS; -- GitLab