10 #include <mrpt/opengl/COpenGLScene.h> 11 #include <mrpt/opengl/CPolyhedron.h> 12 #include <mrpt/opengl/CSetOfObjects.h> 13 #include <mrpt/version.h> 27 using namespace mvsim;
33 World* parent,
bool insertCustomVizIntoViz,
34 bool insertCustomVizIntoPhysical)
36 insertCustomVizIntoViz_(insertCustomVizIntoViz),
37 insertCustomVizIntoPhysical_(insertCustomVizIntoPhysical)
46 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& viz,
47 const mrpt::optional_ref<mrpt::opengl::COpenGLScene>& physical)
49 using namespace std::string_literals;
51 const auto* meSim =
dynamic_cast<Simulable*
>(
this);
57 const auto objectPose =
58 viz.has_value() ? meSim->getPose() : meSim->getPoseNoLock();
88 const double height = cs.zMax() - cs.zMin();
91 const auto c = cs.getContour();
96 const auto savedMrptGeomEps = mrpt::math::getEpsilon();
98 double smallestEdge = std::abs(height);
99 for (
size_t i = 0; i < c.size(); i++)
101 size_t im1 = i == 0 ? c.size() - 1 : i - 1;
102 const auto Ap = c[i] - c[im1];
103 mrpt::keep_min(smallestEdge, Ap.norm());
105 mrpt::math::setEpsilon(1e-5 * smallestEdge);
107 mrpt::opengl::CPolyhedron::Ptr glCS;
111 glCS = mrpt::opengl::CPolyhedron::CreateCustomPrism(c, height);
113 catch (
const std::exception& e)
116 std::cerr <<
"[mvsim::VisualObject] **WARNING**: Ignoring the " 117 "following error while building the visualization " 118 "of the collision shape for object named '" 120 <<
"' placed by pose=" << meSim->getPose()
121 <<
"). Falling back to rectangular collision shape " 122 "from bounding box:\n" 123 << e.what() << std::endl;
126 mrpt::math::TPoint2D bbMax, bbMin;
127 cs.getContour().getBoundingBox(bbMin, bbMax);
128 mrpt::math::TPolygon2D p;
129 p.emplace_back(bbMin.x, bbMin.y);
130 p.emplace_back(bbMin.x, bbMax.y);
131 p.emplace_back(bbMax.x, bbMax.y);
132 p.emplace_back(bbMax.x, bbMin.y);
133 glCS = mrpt::opengl::CPolyhedron::CreateCustomPrism(p, height);
135 glCS->setWireframe(
true);
137 mrpt::math::setEpsilon(savedMrptGeomEps);
140 glCS->setLocation(0, 0, cs.zMin());
161 for (
auto n = rootNode.
first_node(
"visual"); n;
192 bool visualEnabled =
true;
194 auxPar[
"enabled"] =
TParamEntry(
"%bool", &visualEnabled);
203 std::string modelURI;
204 double modelScale = 1.0;
205 mrpt::math::TPose3D modelPose;
206 bool initialShowBoundingBox =
false;
207 std::string objectName =
"group";
212 params[
"model_uri"] =
TParamEntry(
"%s", &modelURI);
213 params[
"model_scale"] =
TParamEntry(
"%lf", &modelScale);
214 params[
"model_offset_x"] =
TParamEntry(
"%lf", &modelPose.x);
215 params[
"model_offset_y"] =
TParamEntry(
"%lf", &modelPose.y);
216 params[
"model_offset_z"] =
TParamEntry(
"%lf", &modelPose.z);
217 params[
"model_yaw"] =
TParamEntry(
"%lf_deg", &modelPose.yaw);
218 params[
"model_pitch"] =
TParamEntry(
"%lf_deg", &modelPose.pitch);
219 params[
"model_roll"] =
TParamEntry(
"%lf_deg", &modelPose.roll);
220 params[
"show_bounding_box"] =
TParamEntry(
"%bool", &initialShowBoundingBox);
228 if (modelURI.empty())
return false;
234 auto glModel = gModelsCache.get(localFileName, opts);
238 glModel, mrpt::poses::CPose3D(modelPose), modelScale, objectName,
265 const mrpt::opengl::CRenderizable::Ptr& glModel,
266 const mrpt::poses::CPose3D& modelPose,
const float modelScale,
267 const std::string& modelName,
const std::optional<std::string>& modelURI,
268 const bool initialShowBoundingBox)
274 float zMin = -std::numeric_limits<float>::max();
275 float zMax = std::numeric_limits<float>::max();
277 if (
const Block* block = dynamic_cast<const Block*>(
this);
284 std::cout <<
"MODEL: " << (modelURI ? *modelURI :
"none")
285 <<
" glModel: " << glModel->GetRuntimeClass()->className
286 <<
" zmin=" << zMin <<
" zMax:" << zMax <<
"\n";
291 chc.get(*glModel, zMin, zMax, modelPose, modelScale, modelURI);
293 auto glGroup = mrpt::opengl::CSetOfObjects::Create();
297 glGroup->insert(glModel);
298 glGroup->setScale(modelScale);
299 glGroup->setPose(modelPose);
301 glGroup->setName(modelName);
This file contains rapidxml parser and DOM implementation.
static double GeometryEpsilon
virtual void guiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical)
static ModelsCache & Instance()
std::map< std::string, TParamEntry > TParameterDefinitions
void parse_xmlnode_children_as_param(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="", mrpt::system::COutputLogger *logger=nullptr)
bool default_block_z_min_max() const
void parse_xmlnode_attribs(const rapidxml::xml_node< char > &xml_node, const TParameterDefinitions ¶ms, const std::map< std::string, std::string > &variableNamesValues={}, const char *functionNameContext="")
const bool insertCustomVizIntoPhysical_
xml_node< Ch > * first_node(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
mrpt::img::TColor modelColor
virtual void internalGuiUpdate(const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &viz, const mrpt::optional_ref< mrpt::opengl::COpenGLScene > &physical, bool childrenOnly=false)=0
std::shared_ptr< mrpt::opengl::CSetOfObjects > glCustomVisual_
static void FreeOpenGLResources()
std::optional< Shape2p5 > collisionShape_
static CollisionShapeCache & Instance()
void showCollisionShape(bool show)
static std::atomic_int32_t g_uniqueCustomVisualId
const bool insertCustomVizIntoViz_
TListNodes & getListOfNodes()
VisualObject(World *parent, bool insertCustomVizIntoViz=true, bool insertCustomVizIntoPhysical=true)
bool customVisualVisible() const
int32_t glCustomVisualId_
bool parseVisual(const rapidxml::xml_node< char > &rootNode)
Returns true if there is at least one <visual>...</visual> entry.
void addCustomVisualization(const mrpt::opengl::CRenderizable::Ptr &glModel, const mrpt::poses::CPose3D &modelPose={}, const float modelScale=1.0f, const std::string &modelName="group", const std::optional< std::string > &modelURI=std::nullopt, const bool initialShowBoundingBox=false)
bool implParseVisual(const rapidxml::xml_node< char > &visual_node)
Called by parseVisual once per "visual" block.
std::shared_ptr< mrpt::opengl::CSetOfObjects > glCollision_
xml_node< Ch > * next_sibling(const Ch *name=0, std::size_t name_size=0, bool case_sensitive=true) const
std::string xmlPathToActualPath(const std::string &modelURI) const