diff --git a/libs/opengl/include/mrpt/opengl/CAssimpModel.h b/libs/opengl/include/mrpt/opengl/CAssimpModel.h index a5e1c1f0bd..9811020f68 100644 --- a/libs/opengl/include/mrpt/opengl/CAssimpModel.h +++ b/libs/opengl/include/mrpt/opengl/CAssimpModel.h @@ -120,6 +120,13 @@ class CAssimpModel : mrpt::math::TBoundingBoxf internalBoundingBoxLocal() const override; + /** Enable (or disable if set to .0f) a feature in which textured triangles + * are split into different renderizable smaller objects. + * This is required only for semitransparent objects with overlaping regions. + */ + void split_triangles_rendering_bbox(const float bbox_size = 1.0f); + float split_triangles_rendering_bbox() const { return m_split_triangles_rendering_bbox; } + struct TInfoPerTexture { // indices in \a m_texturedObjects. string::npos for non-initialized @@ -152,6 +159,7 @@ class CAssimpModel : mutable std::vector m_texturedObjects; bool m_verboseLoad = false; bool m_ignoreMaterialColor = false; + float m_split_triangles_rendering_bbox = .0f; void recursive_render( const aiScene* sc, diff --git a/libs/opengl/src/CAssimpModel.cpp b/libs/opengl/src/CAssimpModel.cpp index bb5fea53e4..c04ac100b4 100644 --- a/libs/opengl/src/CAssimpModel.cpp +++ b/libs/opengl/src/CAssimpModel.cpp @@ -33,6 +33,7 @@ #endif #include +#include #include #include #include @@ -273,8 +274,49 @@ void CAssimpModel::onUpdateBuffers_all() process_textures(m_assimp_scene->scene); + // Model -> 3D primitives: const auto transf = mrpt::poses::CPose3D(); recursive_render(m_assimp_scene->scene, m_assimp_scene->scene->mRootNode, transf, re); + + // Handle split: + if (m_split_triangles_rendering_bbox > .0f) + { + const float voxel = m_split_triangles_rendering_bbox; + + auto& cache = internal::TexturesCache::Instance(); + + ASSERT_EQUAL_(m_texturedObjects.size(), m_textureIdMap.size()); + const std::vector origTexturedObjects = m_texturedObjects; + m_texturedObjects.clear(); + + std::unordered_map newTextObjs; + + for (size_t textId = 0; textId < m_textureIdMap.size(); textId++) + { + const auto& glTris = origTexturedObjects.at(textId); + const std::vector& iTris = glTris->shaderTexturedTrianglesBuffer(); + for (const auto& t : iTris) + { + const auto midPt = 0.333f * (t.vertices[0].xyzrgba.pt + t.vertices[1].xyzrgba.pt + + t.vertices[2].xyzrgba.pt); + // hash for "voxels": + const int64_t vxlCoord = mrpt::round(midPt.x / voxel) + // + mrpt::round(midPt.y / voxel) * 10000 + // + mrpt::round(midPt.z / voxel) * 10000000; + + auto& trgObj = newTextObjs[vxlCoord]; + if (!trgObj) + { + // Create + // copy texture + } + // Add triangle: + } + } + + // replace list of objects + } + #endif } @@ -297,14 +339,15 @@ void CAssimpModel::enqueueForRenderRecursive( mrpt::opengl::enqueueForRendering(lst, state, rq, wholeInView, is1stShadowMapPass); } -uint8_t CAssimpModel::serializeGetVersion() const { return 2; } +uint8_t CAssimpModel::serializeGetVersion() const { return 3; } void CAssimpModel::serializeTo(mrpt::serialization::CArchive& out) const { writeToStreamRender(out); #if (MRPT_HAS_OPENGL_GLUT || MRPT_HAS_EGL) && MRPT_HAS_ASSIMP const bool empty = m_assimp_scene->scene == nullptr; out << empty; - out << m_modelPath; // v2 + out << m_modelPath; // v2 + out << m_split_triangles_rendering_bbox; // v3 if (!empty) { #if 0 @@ -348,6 +391,8 @@ void CAssimpModel::serializeFrom(mrpt::serialization::CArchive& in, uint8_t vers { const bool empty = in.ReadAs(); in >> m_modelPath; + if (version >= 3) in >> m_split_triangles_rendering_bbox; + if (!empty) { const auto blobSize = in.ReadAs(); @@ -460,6 +505,14 @@ auto CAssimpModel::internalBoundingBoxLocal() const -> mrpt::math::TBoundingBoxf return mrpt::math::TBoundingBoxf::FromUnsortedPoints(m_bbox_min, m_bbox_max); } +void CAssimpModel::split_triangles_rendering_bbox(const float bbox_size) +{ + m_split_triangles_rendering_bbox = bbox_size; + + CRenderizable::notifyChange(); + after_load_model(); +} + bool CAssimpModel::traceRay( [[maybe_unused]] const mrpt::poses::CPose3D& o, [[maybe_unused]] double& dist) const {