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,
const mrpt::poses::CPose3D& modelPose,
28 const float modelScale,
const std::optional<std::string>& modelFile)
33 if (
auto it =
cache.find(modelFile.value()); it !=
cache.end())
return it->second.shape;
45 ret = simpleGeom.value();
52 const auto vol = ret.
volume();
55 std::cout <<
"shape2.5 for ["
56 << (modelFile.has_value() ? *modelFile :
"none")
57 <<
"] glClass=" << obj.GetRuntimeClass()->className
58 <<
" shape=" << ret.
getContour().size() <<
" pts, "
59 <<
" volume=" << vol <<
" zMin=" << zMin <<
" zMax=" << zMax
60 <<
" modelScale= " << modelScale
61 <<
" was simpleGeom=" << (simpleGeom ?
"yes" :
"no") <<
"\n"
68 "Error: Collision volume for visual model ('%s') has almost null "
69 "volume (=%g m³). A possible cause, if this is a <block>, is not "
70 "enough vertices within the given range [zmin,zmax]",
71 modelFile.has_value() ? modelFile->c_str() :
"none", vol);
78 const mrpt::opengl::CRenderizable& obj,
float zMin,
float zMax,
79 const mrpt::poses::CPose3D& modelPose,
const float modelScale)
81 #if MRPT_VERSION >= 0x260
82 using namespace mrpt::literals;
87 if (
auto oCyl =
dynamic_cast<const mrpt::opengl::CCylinder*
>(&obj); oCyl)
93 if (std::abs(modelPose.pitch()) > 0.02_deg || std::abs(modelPose.roll()) > 0.02_deg)
96 const size_t actualEdgeCount = oCyl->getSlicesCount();
97 double actualRadius = std::max<double>(oCyl->getTopRadius(), oCyl->getBottomRadius());
100 actualEdgeCount, actualRadius, zMin, zMax, modelPose, modelScale);
102 else if (
auto oSph =
dynamic_cast<const mrpt::opengl::CSphere*
>(&obj); oSph)
107 #if MRPT_VERSION >= 0x271
108 const size_t actualEdgeCount = oSph->getNumberOfSegments();
111 const size_t actualEdgeCount =
112 const_cast<mrpt::opengl::CSphere*
>(oSph)->getNumberOfSegments();
115 double actualRadius = oSph->getRadius();
118 actualEdgeCount, actualRadius, zMin, zMax, modelPose, modelScale);
120 else if (
auto oBox =
dynamic_cast<const mrpt::opengl::CBox*
>(&obj); oBox)
126 if (std::abs(modelPose.pitch()) > 0.02_deg || std::abs(modelPose.roll()) > 0.02_deg)
129 mrpt::math::TPoint3D p1, p2;
130 oBox->getBoxCorners(p1, p2);
134 const mrpt::math::TPoint3D corners[4] = {
135 modelPose.composePoint({p1.x, p1.y, 0}), modelPose.composePoint({p1.x, p2.y, 0}),
136 modelPose.composePoint({p2.x, p2.y, 0}), modelPose.composePoint({p2.x, p1.y, 0})};
138 mrpt::math::TPolygon2D contour;
139 for (
int i = 0; i < 4; i++) contour.emplace_back(corners[i].x, corners[i].y);
142 s.setShapeManual(contour, zMin, zMax);
153 mrpt::opengl::CRenderizable& obj,
float zMin,
float zMax,
const mrpt::poses::CPose3D& modelPose,
154 const float modelScale)
160 auto* oAssimp =
dynamic_cast<mrpt::opengl::CAssimpModel*
>(&obj);
163 oAssimp->onUpdateBuffers_all();
165 auto* oRSWF =
dynamic_cast<mrpt::opengl::CRenderizableShaderWireFrame*
>(&obj);
168 oRSWF->onUpdateBuffers_Wireframe();
170 auto* oRST =
dynamic_cast<mrpt::opengl::CRenderizableShaderTriangles*
>(&obj);
173 oRST->onUpdateBuffers_Triangles();
175 auto* oRSTT =
dynamic_cast<mrpt::opengl::CRenderizableShaderTexturedTriangles*
>(&obj);
178 oRSTT->onUpdateBuffers_TexturedTriangles();
180 auto* oRP =
dynamic_cast<mrpt::opengl::CRenderizableShaderPoints*
>(&obj);
183 oRP->onUpdateBuffers_Points();
187 size_t numTotalPts = 0, numPassedPts = 0;
189 auto rawBB = obj.getBoundingBox();
191 rawBB.max *= modelScale;
192 rawBB.min *= modelScale;
193 const auto coarseBB = rawBB.compose(modelPose);
195 mrpt::math::TPoint2Df(coarseBB.min.x, coarseBB.min.y),
196 mrpt::math::TPoint2Df(coarseBB.max.x, coarseBB.max.y));
198 auto lambdaUpdatePt = [&](
const mrpt::math::TPoint3Df& orgPt)
201 auto pt = modelPose.composePoint(orgPt * modelScale);
202 if (pt.z < zMin || pt.z > zMax)
return;
206 auto lambdaUpdateTri = [&](
const mrpt::opengl::TTriangle& tri)
210 mrpt::opengl::TTriangle
t = tri;
211 for (
int i = 0; i < 3; i++)
t.vertex(i) = modelPose.composePoint(
t.vertex(i) * modelScale);
215 bool outDown =
false, outUp =
false, anyIn =
false;
216 for (
int i = 0; i < 3; i++)
218 const auto& p =
t.vertex(i);
219 if (p.z >= zMin && p.z <= zMax)
224 if (p.z > zMax) outUp =
true;
225 if (p.z < zMin) outDown =
true;
227 if (!(anyIn || (outUp && outDown)))
return;
235 auto lck = mrpt::lockHelper(oRST->shaderTrianglesBufferMutex().data);
236 const auto& tris = oRST->shaderTrianglesBuffer();
237 for (
const auto& tri : tris) lambdaUpdateTri(tri);
241 auto lck = mrpt::lockHelper(oRSTT->shaderTexturedTrianglesBufferMutex().data);
242 const auto& tris = oRSTT->shaderTexturedTrianglesBuffer();
243 for (
const auto& tri : tris) lambdaUpdateTri(tri);
247 auto lck = mrpt::lockHelper(oRP->shaderPointsBuffersMutex().data);
248 const auto& pts = oRP->shaderPointsVertexPointBuffer();
249 for (
const auto& pt : pts) lambdaUpdatePt(pt);
253 auto lck = mrpt::lockHelper(oRSWF->shaderWireframeBuffersMutex().data);
254 const auto& pts = oRSWF->shaderWireframeVertexPointBuffer();
255 for (
const auto& pt : pts) lambdaUpdatePt(pt);
258 #if MRPT_VERSION >= 0x260
261 const auto& txtrdObjs = oAssimp->texturedObjects();
262 for (
const auto& o : txtrdObjs)
266 auto lck = mrpt::lockHelper(o->shaderTexturedTrianglesBufferMutex().data);
267 const auto& tris = o->shaderTexturedTrianglesBuffer();
268 for (
const auto& tri : tris) lambdaUpdateTri(tri);
284 const size_t actualEdgeCount,
double actualRadius,
float zMin,
float zMax,
285 const mrpt::poses::CPose3D& modelPose,
const float modelScale)
289 const auto nFaces = std::min<size_t>(maxEdges, actualEdgeCount);
291 const bool isApprox = actualEdgeCount > maxEdges;
294 const int i = mrpt::round(nFaces / 4);
295 double newR = actualRadius;
296 for (
int j = -1; j <= 1; j++)
298 const double ang = (i + j) * 2 * M_PI / nFaces;
299 const double angp1 = (i + j + 1) * 2 * M_PI / nFaces;
300 const mrpt::math::TPoint2D pt0 = {cos(ang), sin(ang)};
301 const mrpt::math::TPoint2D pt1 = {cos(angp1), sin(angp1)};
303 const double midDist = ((pt0 + pt1) * 0.5).norm();
305 newR = std::max(newR, actualRadius * (1.0 / midDist));
310 mrpt::math::TPolygon2D contour;
311 for (
size_t i = 0; i < nFaces; i++)
313 const double ang = i * 2 * M_PI / nFaces;
314 const mrpt::math::TPoint3D localPt = {cos(ang) * actualRadius, sin(ang) * actualRadius, .0};
315 const auto pt = modelPose.composePoint(localPt * modelScale);
316 contour.emplace_back(pt.x, pt.y);
320 s.setShapeManual(contour, zMin, zMax);