Commit 5bf4ed6c authored by Lukas Werner's avatar Lukas Werner
Browse files

Added padding for AABB intersection testing

parent 7573ebab
Pipeline #6948 failed with stage
in 104 minutes and 11 seconds
......@@ -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();
......
......@@ -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_();
}
......
......@@ -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
......
......@@ -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;
......
Markdown is supported
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