11 #include <mrpt/opengl/CAssimpModel.h> 12 #include <mrpt/opengl/CBox.h> 13 #include <mrpt/opengl/CCylinder.h> 14 #include <mrpt/opengl/CSphere.h> 15 #include <mrpt/version.h> 18 using namespace mvsim;
27 mrpt::opengl::CRenderizable& obj,
float zMin,
float zMax,
28 const mrpt::poses::CPose3D& modelPose,
const float modelScale,
29 const std::optional<std::string>& modelFile)
34 if (
auto it =
cache.find(modelFile.value()); it !=
cache.end())
35 return it->second.shape;
43 const auto simpleGeom =
48 ret = simpleGeom.value();
55 const auto vol = ret.
volume();
58 std::cout <<
"shape2.5 for [" 59 << (modelFile.has_value() ? *modelFile :
"none")
60 <<
"] glClass=" << obj.GetRuntimeClass()->className
61 <<
" shape=" << ret.
getContour().size() <<
" pts, " 62 <<
" volume=" << vol <<
" zMin=" << zMin <<
" zMax=" << zMax
63 <<
" was simpleGeom=" << (simpleGeom ?
"yes" :
"no") <<
"\n";
69 "Error: Collision volume for visual model ('%s') has almost null " 70 "volume (=%g m³). A possible cause, if this is a <block>, is not " 71 "enough vertices within the given range [zmin,zmax]",
72 modelFile.has_value() ? modelFile->c_str() :
"none", vol);
79 const mrpt::opengl::CRenderizable& obj,
float zMin,
float zMax,
80 const mrpt::poses::CPose3D& modelPose,
const float modelScale)
82 #if MRPT_VERSION >= 0x260 83 using namespace mrpt::literals;
88 if (
auto oCyl = dynamic_cast<const mrpt::opengl::CCylinder*>(&obj); oCyl)
94 if (std::abs(modelPose.pitch()) > 0.02_deg ||
95 std::abs(modelPose.roll()) > 0.02_deg)
98 const size_t actualEdgeCount = oCyl->getSlicesCount();
100 std::max<double>(oCyl->getTopRadius(), oCyl->getBottomRadius());
103 actualEdgeCount, actualRadius, zMin, zMax, modelPose, modelScale);
105 else if (
auto oSph = dynamic_cast<const mrpt::opengl::CSphere*>(&obj); oSph)
110 #if MRPT_VERSION >= 0x271 111 const size_t actualEdgeCount = oSph->getNumberOfSegments();
114 const size_t actualEdgeCount =
115 const_cast<mrpt::opengl::CSphere*
>(oSph)->getNumberOfSegments();
118 double actualRadius = oSph->getRadius();
121 actualEdgeCount, actualRadius, zMin, zMax, modelPose, modelScale);
123 else if (
auto oBox = dynamic_cast<const mrpt::opengl::CBox*>(&obj); oBox)
129 if (std::abs(modelPose.pitch()) > 0.02_deg ||
130 std::abs(modelPose.roll()) > 0.02_deg)
133 mrpt::math::TPoint3D p1, p2;
134 oBox->getBoxCorners(p1, p2);
138 const mrpt::math::TPoint3D corners[4] = {
139 modelPose.composePoint({p1.x, p1.y, 0}),
140 modelPose.composePoint({p1.x, p2.y, 0}),
141 modelPose.composePoint({p2.x, p2.y, 0}),
142 modelPose.composePoint({p2.x, p1.y, 0})};
144 mrpt::math::TPolygon2D contour;
145 for (
int i = 0; i < 4; i++)
146 contour.emplace_back(corners[i].x, corners[i].y);
160 mrpt::opengl::CRenderizable& obj,
float zMin,
float zMax,
161 const mrpt::poses::CPose3D& modelPose,
const float modelScale)
167 auto* oAssimp =
dynamic_cast<mrpt::opengl::CAssimpModel*
>(&obj);
170 oAssimp->onUpdateBuffers_all();
173 dynamic_cast<mrpt::opengl::CRenderizableShaderWireFrame*
>(&obj);
176 oRSWF->onUpdateBuffers_Wireframe();
179 dynamic_cast<mrpt::opengl::CRenderizableShaderTriangles*
>(&obj);
182 oRST->onUpdateBuffers_Triangles();
185 dynamic_cast<mrpt::opengl::CRenderizableShaderTexturedTriangles*
>(&obj);
188 oRSTT->onUpdateBuffers_TexturedTriangles();
190 auto* oRP =
dynamic_cast<mrpt::opengl::CRenderizableShaderPoints*
>(&obj);
193 oRP->onUpdateBuffers_Points();
197 size_t numTotalPts = 0, numPassedPts = 0;
199 auto rawBB = obj.getBoundingBox();
201 rawBB.max *= modelScale;
202 rawBB.min *= modelScale;
203 const auto coarseBB = rawBB.compose(modelPose);
205 mrpt::math::TPoint2Df(coarseBB.min.x, coarseBB.min.y),
206 mrpt::math::TPoint2Df(coarseBB.max.x, coarseBB.max.y));
208 auto lambdaUpdatePt = [&](
const mrpt::math::TPoint3Df& orgPt) {
210 auto pt = modelPose.composePoint(orgPt * modelScale);
211 if (pt.z < zMin || pt.z > zMax)
return;
215 auto lambdaUpdateTri = [&](
const mrpt::opengl::TTriangle& tri) {
218 mrpt::opengl::TTriangle
t = tri;
219 for (
int i = 0; i < 3; i++)
220 t.vertex(i) = modelPose.composePoint(t.vertex(i) * modelScale);
224 bool outDown =
false, outUp =
false, anyIn =
false;
225 for (
int i = 0; i < 3; i++)
227 const auto& p = t.vertex(i);
228 if (p.z >= zMin && p.z <= zMax)
233 if (p.z > zMax) outUp =
true;
234 if (p.z < zMin) outDown =
true;
236 if (!(anyIn || (outUp && outDown)))
return;
244 auto lck = mrpt::lockHelper(oRST->shaderTrianglesBufferMutex().data);
245 const auto& tris = oRST->shaderTrianglesBuffer();
246 for (
const auto& tri : tris) lambdaUpdateTri(tri);
251 mrpt::lockHelper(oRSTT->shaderTexturedTrianglesBufferMutex().data);
252 const auto& tris = oRSTT->shaderTexturedTrianglesBuffer();
253 for (
const auto& tri : tris) lambdaUpdateTri(tri);
257 auto lck = mrpt::lockHelper(oRP->shaderPointsBuffersMutex().data);
258 const auto& pts = oRP->shaderPointsVertexPointBuffer();
259 for (
const auto& pt : pts) lambdaUpdatePt(pt);
263 auto lck = mrpt::lockHelper(oRSWF->shaderWireframeBuffersMutex().data);
264 const auto& pts = oRSWF->shaderWireframeVertexPointBuffer();
265 for (
const auto& pt : pts) lambdaUpdatePt(pt);
268 #if MRPT_VERSION >= 0x260 271 const auto& txtrdObjs = oAssimp->texturedObjects();
272 for (
const auto& o : txtrdObjs)
277 mrpt::lockHelper(o->shaderTexturedTrianglesBufferMutex().data);
278 const auto& tris = o->shaderTexturedTrianglesBuffer();
279 for (
const auto& tri : tris) lambdaUpdateTri(tri);
295 const size_t actualEdgeCount,
double actualRadius,
float zMin,
float zMax,
296 const mrpt::poses::CPose3D& modelPose,
const float modelScale)
300 const auto nFaces = std::min<size_t>(maxEdges, actualEdgeCount);
302 const bool isApprox = actualEdgeCount > maxEdges;
305 const int i = mrpt::round(nFaces / 4);
306 double newR = actualRadius;
307 for (
int j = -1; j <= 1; j++)
309 const double ang = (i + j) * 2 *
M_PI / nFaces;
310 const double angp1 = (i + j + 1) * 2 *
M_PI / nFaces;
311 const mrpt::math::TPoint2D pt0 = {
cos(ang),
sin(ang)};
312 const mrpt::math::TPoint2D pt1 = {
cos(angp1),
sin(angp1)};
314 const double midDist = ((pt0 + pt1) * 0.5).norm();
316 newR = std::max(newR, actualRadius * (1.0 / midDist));
321 mrpt::math::TPolygon2D contour;
322 for (
size_t i = 0; i < nFaces; i++)
324 const double ang = i * 2 *
M_PI / nFaces;
325 const mrpt::math::TPoint2D localPt = {
326 cos(ang) * actualRadius,
sin(ang) * actualRadius};
327 const auto pt = modelPose.composePoint(localPt * modelScale);
328 contour.emplace_back(pt.x, pt.y);
const mrpt::math::TPolygon2D & getContour() const
std::map< std::string, Entry > cache
std::optional< Shape2p5 > processSimpleGeometries(const mrpt::opengl::CRenderizable &obj, float zMin, float zMax, const mrpt::poses::CPose3D &modelPose, const float modelScale)
geometry_msgs::TransformStamped t
Shape2p5 processCylinderLike(const size_t actualEdgeCount, double actualRadius, float zMin, float zMax, const mrpt::poses::CPose3D &modelPose, const float modelScale)
void setShapeManual(const mrpt::math::TPolygon2D &contour, const float zMin, const float zMax)
Shape2p5 processGenericGeometry(mrpt::opengl::CRenderizable &obj, float zMin, float zMax, const mrpt::poses::CPose3D &modelPose, const float modelScale)
void buildAddPoint(const mrpt::math::TPoint3Df &pt)
static CollisionShapeCache & Instance()
void buildAddTriangle(const mrpt::opengl::TTriangle &t)
#define b2_maxPolygonVertices
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Shape2p5 get(mrpt::opengl::CRenderizable &obj, float zMin, float zMax, const mrpt::poses::CPose3D &modelPose, const float modelScale, const std::optional< std::string > &modelFile=std::nullopt)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
void buildInit(const mrpt::math::TPoint2Df &bbMin, const mrpt::math::TPoint2Df &bbMax, int numCells=100)