Commit 2e37865b authored by Lukas Werner's avatar Lukas Werner
Browse files

Added support for objects in globalStorage and added functionality to hide...

Added support for objects in globalStorage and added functionality to hide certain bodies for raytracer
parent 0e6e3802
Pipeline #6943 failed with stage
in 79 minutes and 26 seconds
......@@ -138,7 +138,7 @@ int main( int argc, char ** argv )
if (cfg == NULL) {
WALBERLA_ABORT("raytracer needs a working config");
}
Raytracer raytracer(forest, storageID, cfg->getBlock("raytracing"));
Raytracer raytracer(forest, storageID, globalBodyStorage, cfg->getBlock("raytracing"));
WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***");
//! [Integrator]
......@@ -165,13 +165,16 @@ int main( int argc, char ** argv )
auto simulationDomain = forest->getDomain();
auto generationDomain = simulationDomain; // simulationDomain.getExtended(-real_c(0.5) * spacing);
//! [Planes]
createPlane(*globalBodyStorage, 0, Vec3(1,0,0), simulationDomain.minCorner(), material );
createPlane(*globalBodyStorage, 0, Vec3(-1,0,0), simulationDomain.maxCorner(), material );
PlaneID xPosPlane = createPlane(*globalBodyStorage, 0, Vec3(1,0,0), simulationDomain.minCorner(), material );
PlaneID xNegPlane = createPlane(*globalBodyStorage, 0, Vec3(-1,0,0), simulationDomain.maxCorner(), material );
createPlane(*globalBodyStorage, 0, Vec3(0,1,0), simulationDomain.minCorner(), material );
createPlane(*globalBodyStorage, 0, Vec3(0,-1,0), simulationDomain.maxCorner(), material );
createPlane(*globalBodyStorage, 0, Vec3(0,0,1), simulationDomain.minCorner(), material );
createPlane(*globalBodyStorage, 0, Vec3(0,0,-1), simulationDomain.maxCorner(), material );
//! [Planes]
raytracer.setBodyInvisible(xNegPlane);
raytracer.setBodyInvisible(xPosPlane);
//! [Gas]
uint_t numParticles = uint_c(0);
......
......@@ -149,7 +149,7 @@ int main( int argc, char ** argv )
if (cfg == NULL) {
WALBERLA_ABORT("raytracer needs a working config");
}
Raytracer raytracer(forest, storageID, cfg->getBlock("Raytracing"));
Raytracer raytracer(forest, storageID, globalBodyStorage, cfg->getBlock("Raytracing"));
WALBERLA_LOG_INFO_ON_ROOT("*** INTEGRATOR ***");
cr::HCSITS cr(globalBodyStorage, forest, storageID, ccdID, fcdID);
......
......@@ -40,11 +40,11 @@ namespace raytracing {
* \param lookAtPoint Point the camera looks at in the global world frame.
* \param upVector Vector indicating the upwards direction of the camera.
*/
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
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)
: forest_(forest), storageID_(storageID),
: forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage),
pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical),
fov_vertical_(fov_vertical),
cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector),
......@@ -63,8 +63,8 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
* and tbuffer_output_directory (string) parameters. Additionally a vector of reals
* for each of cameraPosition, lookAt and the upVector.
*/
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const Config::BlockHandle& config) : forest_(forest), storageID_(storageID) {
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");
......@@ -149,7 +149,7 @@ void Raytracer::writeTBufferToFile(const std::map<Coordinates, real_t, Coordinat
if (realIsIdentical(t, INFINITY)) {
r = g = b = (char)255;
} else {
r = g = b = (char)(200 * ((t-t_min)/(t_max-t_min)));
r = g = b = (char)(240 * ((t-t_min)/(t_max-t_min)));
}
ofs << r << g << b;
}
......
......@@ -66,11 +66,11 @@ class Raytracer {
public:
/*!\name Constructors */
//@{
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
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,
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, const shared_ptr<BodyStorage> globalBodyStorage,
const Config::BlockHandle& config);
//@}
......@@ -80,6 +80,8 @@ private:
const shared_ptr<BlockStorage> forest_; //!< The BlockForest the raytracer operates on.
BlockDataID storageID_; /*!< The storage ID of the block data storage the raytracer operates
on.*/
const shared_ptr<BodyStorage> globalBodyStorage_; //!< The global body storage the raytracer operates on.
size_t pixelsHorizontal_; //!< The horizontal amount of pixels of the generated image.
size_t pixelsVertical_; //!< The vertical amount of pixels of the generated image.
real_t fov_vertical_; //!< The vertical field-of-view of the camera.
......@@ -89,6 +91,8 @@ private:
Vec3 upVector_; //!< The vector indicating the upwards direction of the camera.
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
......@@ -113,12 +117,15 @@ public:
inline const Vec3& getUpVector() const;
inline bool getTBufferOutputEnabled() const;
inline const std::string& getTBufferOutputDirectory() const;
inline bool isBodyInvisible(BodyID body) const;
//@}
/*!\name Set functions */
//@{
inline void setTBufferOutputEnabled(const bool enabled);
inline void setTBufferOutputDirectory(const std::string& path);
inline void setBodyInvisible(BodyID body);
inline void setBodyVisible(BodyID body);
//@}
/*!\name Functions */
......@@ -204,6 +211,14 @@ inline const std::string& Raytracer::getTBufferOutputDirectory() const {
return tBufferOutputDirectory_;
}
/*!\brief Returns if the specified body is invisible.
*
* \return True if body invisible, false otherwise.
*/
inline bool Raytracer::isBodyInvisible(BodyID body) const {
return invisibleBodyIDs_.find(body->getSystemID()) != invisibleBodyIDs_.end();
}
/*!\brief Enabled / disable outputting the tBuffer to a file in the specified directory.
* \param enabled Set to true / false to enable / disable tbuffer output.
*/
......@@ -223,6 +238,20 @@ inline void Raytracer::setTBufferOutputDirectory(const std::string& path) {
tBufferOutputDirectory_ = path;
}
/*!\brief Mark the specified body as invisible for the raytracing algorithm.
* \param body Body to set invisible.
*/
inline void Raytracer::setBodyInvisible(BodyID body) {
invisibleBodyIDs_.insert(body->getSystemID());
}
/*!\brief Mark the specified body as visible for the raytracing algorithm.
* \param body Body to set invisible.
*/
inline void Raytracer::setBodyVisible(BodyID body) {
invisibleBodyIDs_.erase(body->getSystemID());
}
/*!\brief Does one raytracing step.
*
* \param timestep The timestep after which the raytracing starts.
......@@ -252,7 +281,6 @@ void Raytracer::rayTrace(const size_t timestep) const {
id_closest = 0;
body_closest = NULL;
for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) {
// blockIt->getAABB();
#ifndef DISABLE_BLOCK_AABB_INTERSECTION_PRECHECK
const AABB& blockAabb = blockIt->getAABB();
if (!intersects(blockAabb, ray, t)) {
......@@ -260,6 +288,29 @@ void Raytracer::rayTrace(const size_t timestep) const {
}
#endif
for (auto bodyIt = LocalBodyIterator::begin(*blockIt, storageID_); bodyIt != LocalBodyIterator::end(); ++bodyIt) {
if (isBodyInvisible(*bodyIt)) {
continue;
}
bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(*bodyIt, func);
if (intersects && t < t_closest) {
// body was shot by ray and currently closest to camera
t_closest = t;
id_closest = bodyIt->getID();
body_closest = *bodyIt;
}
}
}
// only iterate over global body storage in one process.
// optimization required, e.g. split up global bodies over all processes.
WALBERLA_ROOT_SECTION() {
for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt ) {
if (isBodyInvisible(*bodyIt)) {
continue;
}
bool intersects = SingleCast<BodyTypeTuple, IntersectsFunctor, bool>::execute(*bodyIt, func);
if (intersects && t < t_closest) {
......@@ -306,7 +357,7 @@ void Raytracer::rayTrace(const size_t timestep) const {
std::vector<BodyIntersectionInfo> gatheredIntersections;
std::map<walberla::id_t, bool> visibleBodyIDs;
std::set<walberla::id_t> visibleBodyIDs;
//std::map<Coordinates, BodyIntersectionInfo, CoordinatesComparator> pixelIntersectionMap;
......@@ -348,7 +399,7 @@ void Raytracer::rayTrace(const size_t timestep) const {
}
for (auto& info: localPixelIntersectionMap) {
visibleBodyIDs[info.second.bodySystemID] = true;
visibleBodyIDs.insert(info.second.bodySystemID);
}
tp["Reduction"].end();
......
#include <pe/basic.h>
#include "pe/utility/BodyCast.h"
#include "pe/Materials.h"
......@@ -15,14 +16,13 @@
#include "core/DataTypes.h"
#include "core/math/Vector3.h"
#include <pe/raytracing/Ray.h>
#include <pe/raytracing/Intersects.h>
#include <pe/raytracing/Raytracer.h>
using namespace walberla;
using namespace walberla::pe;
using namespace walberla::pe::raytracing;
typedef boost::tuple<Box, Capsule, Plane, Sphere> BodyTuple ;
typedef boost::tuple<Box, Plane, Sphere> BodyTuple ;
void SphereIntersectsTest()
{
......@@ -114,6 +114,56 @@ void BoxIntersectsTest() {
WALBERLA_CHECK_FLOAT_EQUAL_EPSILON(t, real_t(2.67157), real_t(1e-4));
}
void RaytracerTest() {
WALBERLA_LOG_INFO("Raytracer");
shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
shared_ptr<BlockForest> forest = createBlockForest(AABB(0,-5,-5,10,5,5), Vec3(1,1,1), Vec3(false, false, false));
auto storageID = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage");
Raytracer raytracer(forest, storageID, globalBodyStorage,
size_t(640), size_t(480),
49.13,
Vec3(-5,0,0), Vec3(-1,0,0), Vec3(0,0,1));
MaterialID iron = Material::find("iron");
Plane pl1(1, 1, Vec3(2, 0, 0), Vec3(1, 0, 0), real_t(1.0), iron);
PlaneID xNegPlane = createPlane(*globalBodyStorage, 0, Vec3(-1,0,0), Vec3(5,0,0), iron);
// xNegPlane obstructs only the top left sphere and intersects some objects
WALBERLA_CHECK(xNegPlane != NULL);
WALBERLA_CHECK(!raytracer.isBodyInvisible(xNegPlane), "Body invisible but should be visible.");
raytracer.setBodyInvisible(xNegPlane);
WALBERLA_CHECK(raytracer.isBodyInvisible(xNegPlane), "Body visible but should be invisible.");
raytracer.setBodyVisible(xNegPlane);
WALBERLA_CHECK(!raytracer.isBodyInvisible(xNegPlane), "Body invisible but should be visible.");
raytracer.setBodyInvisible(xNegPlane);
PlaneID xNegPlaneClose = createPlane(*globalBodyStorage, 0, Vec3(-1,0,0), Vec3(1,0,0), iron);
raytracer.setBodyInvisible(xNegPlaneClose); // xNegPlaneClose would obstruct all objects
createPlane(*globalBodyStorage, 0, Vec3(0,1,0), Vec3(0,5,0), iron); // left wall
createPlane(*globalBodyStorage, 0, Vec3(0,1,0), Vec3(0,-5,0), iron); // right wall
createPlane(*globalBodyStorage, 0, Vec3(0,0,1), Vec3(0,0,-5), iron); // floor
createPlane(*globalBodyStorage, 0, Vec3(0,0,1), Vec3(0,0,5), iron); // ceiling
createPlane(*globalBodyStorage, 0, Vec3(1,0,0), Vec3(10,0,0), iron); // back wall
PlaneID frontWall = createPlane(*globalBodyStorage, 0, Vec3(1,0,0), Vec3(0,0,0), iron); // front wall
raytracer.setBodyInvisible(frontWall);
createSphere(*globalBodyStorage, *forest, storageID, 2, Vec3(6,4.5,4.5), real_t(0.5));
createSphere(*globalBodyStorage, *forest, storageID, 3, Vec3(3.5,-2,0), real_t(1));
SphereID sp1 = createSphere(*globalBodyStorage, *forest, storageID, 6, Vec3(3,2,0), real_t(1));
BoxID box = createBox(*globalBodyStorage, *forest, storageID, 7, Vec3(5,0,0), Vec3(2,4,3));
box->rotate(0,math::M_PI/4,math::M_PI/4);
createBox(*globalBodyStorage, *forest, storageID, 7, Vec3(5,-4,3), Vec3(2,2,2));
raytracer.setBodyInvisible(sp1);
raytracer.setTBufferOutputDirectory("/Users/ng/Desktop/walberla");
raytracer.setTBufferOutputEnabled(true);
raytracer.rayTrace<BodyTuple>(0);
}
int main( int argc, char** argv )
{
walberla::debug::enterTestMode();
......@@ -121,9 +171,10 @@ int main( int argc, char** argv )
SetBodyTypeIDs<BodyTuple>::execute();
SphereIntersectsTest();
PlaneIntersectsTest();
BoxIntersectsTest();
//SphereIntersectsTest();
//PlaneIntersectsTest();
//BoxIntersectsTest();
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