Example: opengl_ray_trace_example
C++ example source code:
/* +------------------------------------------------------------------------+ | Mobile Robot Programming Toolkit (MRPT) | | https://www.mrpt.org/ | | | | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file | | See: https://www.mrpt.org/Authors - All rights reserved. | | Released under BSD License. See: https://www.mrpt.org/License | +------------------------------------------------------------------------+ */ #include <mrpt/gui/CDisplayWindow3D.h> #include <mrpt/opengl/CAngularObservationMesh.h> #include <mrpt/opengl/CAxis.h> #include <mrpt/opengl/CCylinder.h> #include <mrpt/opengl/CDisk.h> #include <mrpt/opengl/CEllipsoid3D.h> #include <mrpt/opengl/CGridPlaneXY.h> #include <mrpt/opengl/CPolyhedron.h> #include <mrpt/opengl/CSphere.h> #include <mrpt/opengl/CTexturedPlane.h> #include <mrpt/poses/CPoint3D.h> #include <mrpt/poses/CPose3D.h> #include <mrpt/random.h> #include <mrpt/system/CTicTac.h> #include <mrpt/system/os.h> #include <chrono> #include <iostream> #include <thread> #define COLORR 1.0f #define COLORG 0.0f #define COLORB 0.0f #define GRID_R 1.0f #define GRID_G 1.0f #define GRID_B 1.0f using namespace std; using namespace mrpt; using namespace mrpt::gui; using namespace mrpt::opengl; using namespace mrpt::poses; using namespace mrpt::math; using namespace mrpt::random; using namespace mrpt::serialization; using namespace mrpt::system; using mrpt::opengl::CAngularObservationMesh; // Increase this values to get more precision. It will also increase run time. const size_t HOW_MANY_YAWS = 150; const size_t HOW_MANY_PITCHS = 75; const float RANDOM_POSE_DISTANCE = 10; inline double MYRAND1() { // return static_cast<float>(rand()%prec)/prec; return getRandomGenerator().drawUniform(0, 1); } inline double MYRANDG(double scale, double shift = 0) { // return shift+(static_cast<float>(rand()%prec)/prec)*scale; return shift + scale * getRandomGenerator().drawUniform(0, 1); } CPose3D randomPose() { return CPose3D( MYRANDG(2 * RANDOM_POSE_DISTANCE, -RANDOM_POSE_DISTANCE), MYRANDG(2 * RANDOM_POSE_DISTANCE, -RANDOM_POSE_DISTANCE), MYRANDG(2 * RANDOM_POSE_DISTANCE, -RANDOM_POSE_DISTANCE), MYRAND1(), MYRAND1(), MYRAND1()); } void configRandom(const CRenderizable::Ptr& obj) { obj->setColor(MYRAND1(), MYRAND1(), MYRAND1(), MYRANDG(0.75, 0.25)); obj->setPose(randomPose()); } void guideLines(const CPose3D& base, CSetOfLines::Ptr& lines, float dist) { CPoint3D pDist = CPoint3D(dist, 0, 0); CPoint3D pps[4]; pps[0] = base + pDist; pps[1] = base + CPose3D(0, 0, 0, 0, -M_PI / 2, 0) + pDist; pps[2] = base + CPose3D(0, 0, 0, -M_PI / 2, 0, 0) + pDist; pps[3] = base + CPose3D(0, 0, 0, M_PI / 2, 0, 0) + pDist; for (size_t i = 0; i < 4; i++) lines->appendLine( base.x(), base.y(), base.z(), pps[i].x(), pps[i].y(), pps[i].z()); lines->setLineWidth(5); lines->setColor(0, 0, 1); } // Add objects at your will to check results void generateObjects(CSetOfObjects::Ptr& world) { // create object, give it a random pose/color, insert it in the world CDisk::Ptr dsk = CDisk::Create(); dsk->setDiskRadius(MYRANDG(5, 5), MYRANDG(5)); configRandom(dsk); world->insert(dsk); CSphere::Ptr sph = CSphere::Create(MYRANDG(5, 1)); configRandom(sph); world->insert(sph); CTexturedPlane::Ptr pln = CTexturedPlane::Create( MYRANDG(10, -10), MYRANDG(10), MYRANDG(10, -10), MYRANDG(10)); configRandom(pln); world->insert(pln); for (size_t i = 0; i < 5; i++) { CPolyhedron::Ptr poly = CPolyhedron::CreateRandomPolyhedron(MYRANDG(2, 2)); configRandom(poly); world->insert(poly); } CCylinder::Ptr cil = CCylinder::Create( MYRANDG(3.0, 3.0), MYRANDG(3.0, 1.0), MYRANDG(2.0f, 3.0f), 50); configRandom(cil); world->insert(cil); CEllipsoid3D::Ptr ell = CEllipsoid3D::Create(); CMatrixDouble md = CMatrixDouble(3, 3); for (size_t i = 0; i < 3; i++) md(i, i) = MYRANDG(8.0, 1.0); for (size_t i = 0; i < 3; i++) { size_t ii = (i + 1) % 3; md(i, ii) = md(ii, i) = MYRANDG(sqrt(md(i, i) * md(ii, ii))); } ell->setCovMatrix(md); configRandom(std::dynamic_pointer_cast<CRenderizable>(ell)); world->insert(ell); } void display() { CDisplayWindow3D window("Ray trace demo", 640, 480); window.setPos(10, 10); std::this_thread::sleep_for(20ms); Scene::Ptr scene1 = Scene::Create(); // Scene::Ptr &scene1=window.get3DSceneAndLock(); opengl::CGridPlaneXY::Ptr plane1 = CGridPlaneXY::Create(-20, 20, -20, 20, 0, 1); plane1->setColor(GRID_R, GRID_G, GRID_B); scene1->insert(plane1); scene1->insert(CAxis::Create(-5, -5, -5, 5, 5, 5, 2.5, 3, true)); CSetOfObjects::Ptr world = CSetOfObjects::Create(); generateObjects(world); scene1->insert(world); CPose3D basePose = randomPose(); CAngularObservationMesh::Ptr aom = CAngularObservationMesh::Create(); CTicTac t; t.Tic(); CAngularObservationMesh::trace2DSetOfRays( scene1, basePose, aom, CAngularObservationMesh::TDoubleRange::CreateFromAmount( -M_PI / 2, 0, HOW_MANY_PITCHS), CAngularObservationMesh::TDoubleRange::CreateFromAperture( M_PI, HOW_MANY_YAWS)); cout << "Elapsed time: " << t.Tac() << " seconds.\n"; aom->setColor(0, 1, 0); aom->setWireframe(true); // Comment to stop showing traced rays and scan range guidelines. CSetOfLines::Ptr traced = CSetOfLines::Create(); CSetOfLines::Ptr guides = CSetOfLines::Create(); aom->getTracedRays(traced); traced->setLineWidth(1.5); traced->setColor(1, 0, 0); guideLines(basePose, guides, 10); scene1->insert(traced); scene1->insert(guides); // Uncomment to show also traced rays who got lost. /* CSetOfLines::Ptr untraced=CSetOfLines::Create(); aom->getUntracedRays(untraced,20); untraced->setLineWidth(1); untraced->setColor(1,1,1,0.5); scene1->insert(untraced); */ CSphere::Ptr point = CSphere::Create(0.2); point->setColor(0, 1, 0); point->setPose(basePose); scene1->insert(point); CDisplayWindow3D window2("Observed mesh", 640, 480); window2.setPos(660, 10); std::this_thread::sleep_for(20ms); window.get3DSceneAndLock() = scene1; window.unlockAccess3DScene(); window.setCameraElevationDeg(25.0f); Scene::Ptr& scene2 = window2.get3DSceneAndLock(); scene2->insert(aom); opengl::CGridPlaneXY::Ptr plane2 = CGridPlaneXY::Create(-20, 20, -20, 20, 0, 1); plane2->setColor(GRID_R, GRID_G, GRID_B); scene2->insert(plane2); scene2->insert(CAxis::Create(-5, -5, -5, 5, 5, 5, 2.5, 3, true)); window2.unlockAccess3DScene(); window2.setCameraElevationDeg(25.0f); window.waitForKey(); } int main() { mrpt::random::getRandomGenerator().randomize(); try { display(); return 0; } catch (const exception& e) { cout << "Error: " << e.what() << '.' << endl; mrpt::system::pause(); return -1; } catch (...) { cout << "Unknown Error.\n"; return -1; } }