From a44e5e3d179fe361c42dd2703ac7cf4c72fb6f6a Mon Sep 17 00:00:00 2001 From: cutealien Date: Wed, 17 May 2023 14:31:50 +0000 Subject: [PATCH] Add updateBoundingBox parameter to IMeshBuffer::append and some fixes and optimizations Fix: When appending to an empty mesh boundingbox has to be initialized with first position Adding updateBoundingBox parameter as there is a bit costs involved in updating that and it might not be necessary at that point Default is still to do it - and with the default parameter it's at least compile compatible to old interface (unless users created their own meshbuffers). Optimizing the copying of vertices in CDynamicMeshBuffer::append by using memset when possible instead of pushing each vertex (which goes through quite a few virtual functions) git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6496 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 1 + include/CDynamicMeshBuffer.h | 74 +++++++++++++++++++++++------------- include/CMeshBuffer.h | 16 ++++++-- include/IMeshBuffer.h | 10 +++-- include/SSharedMeshBuffer.h | 4 +- include/SSkinMeshBuffer.h | 4 +- 6 files changed, 70 insertions(+), 39 deletions(-) diff --git a/changes.txt b/changes.txt index 66e641b..eacde08 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,7 @@ -------------------------- Changes in 1.9 (not yet released) +- Get IMeshBuffer::append functions working for a few more cases and adapt interface so one can prevent the BoundingBox update. - Bugfix: SMaterialLayer::operator!= no longer returns true when comparing a layer without texture matrix with one with a set identity texture matrix. Those are the same. - SMaterialLayer no longer releases allocated texture memory before destructor unless explicitly requested. This can avoid constantly allocation/releasing memory in the active driver material when setting materials. diff --git a/include/CDynamicMeshBuffer.h b/include/CDynamicMeshBuffer.h index 73f8b42..b4e38a5 100644 --- a/include/CDynamicMeshBuffer.h +++ b/include/CDynamicMeshBuffer.h @@ -108,20 +108,20 @@ namespace scene \param numVertices Number of vertices in the array. \param indices Pointer to index array. \param numIndices Number of indices in array. */ - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) IRR_OVERRIDE { // We simply assume it has the same vertex and index type as this object. If other types are passed this will crash - append(getVertexType(), vertices, numVertices, getIndexType(), indices, numIndices); + append(getVertexType(), vertices, numVertices, getIndexType(), indices, numIndices, updateBoundingBox); } //! Append the meshbuffer to the current buffer /** \param other Buffer to append to this one. */ - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) IRR_OVERRIDE { - append(other->getVertexType(), other->getVertices(), other->getVertexCount(), other->getIndexType(), other->getIndices(), other->getIndexCount()); + append(other->getVertexType(), other->getVertices(), other->getVertexCount(), other->getIndexType(), other->getIndices(), other->getIndexCount(), updateBoundingBox); } - void append(video::E_VERTEX_TYPE vertexType, const void* const vertices, u32 numVertices, video::E_INDEX_TYPE indexType, const void* const indices, u32 numIndices) + void append(video::E_VERTEX_TYPE vertexType, const void* const vertices, u32 numVertices, video::E_INDEX_TYPE indexType, const void* const indices, u32 numIndices, bool updateBoundingBox) { if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks return; @@ -129,29 +129,49 @@ namespace scene const u32 vertexCount = getVertexCount(); VertexBuffer->reallocate(vertexCount+numVertices, false); - switch ( vertexType ) + if ( vertexType == getVertexType() ) { - case video::EVT_STANDARD: - for (u32 i=0; ipush_back(static_cast(vertices)[i]); - BoundingBox.addInternalPoint(static_cast(vertices)[i].Pos); - } - break; - case video::EVT_2TCOORDS: - for (u32 i=0; ipush_back(static_cast(vertices)[i]); - BoundingBox.addInternalPoint(static_cast(vertices)[i].Pos); - } - break; - case video::EVT_TANGENTS: - for (u32 i=0; ipush_back(static_cast(vertices)[i]); - BoundingBox.addInternalPoint(static_cast(vertices)[i].Pos); - } - break; + const irr::u32 typeSize = getVertexPitchFromType(vertexType); + VertexBuffer->set_used(vertexCount+numVertices); + irr::u8* target = &static_cast(VertexBuffer->pointer())[vertexCount*typeSize]; + memcpy(target, vertices, numVertices*typeSize); + } + else + { + switch ( vertexType ) + { + case video::EVT_STANDARD: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + case video::EVT_2TCOORDS: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + case video::EVT_TANGENTS: + for (u32 i=0; ipush_back(static_cast(vertices)[i]); + } + break; + } + } + + if ( updateBoundingBox && numVertices > 0) + { + if ( vertexCount == 0 ) + BoundingBox.reset( static_cast(vertices)[0].Pos ); + + const u32 typePitch = getVertexPitchFromType(vertexType); + const irr::u8* v8 = static_cast(vertices); + for (u32 i=0; i(v8)->Pos); + } } IndexBuffer->reallocate(getIndexCount()+numIndices, false); diff --git a/include/CMeshBuffer.h b/include/CMeshBuffer.h index 9089376..e3380cf 100644 --- a/include/CMeshBuffer.h +++ b/include/CMeshBuffer.h @@ -193,7 +193,7 @@ namespace scene or the main buffer is of standard type. Otherwise, behavior is undefined. Also can't append it's own vertices/indices to itself. */ - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) IRR_OVERRIDE { if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks return; @@ -205,7 +205,15 @@ namespace scene for (i=0; i(vertices)[i]); - BoundingBox.addInternalPoint(static_cast(vertices)[i].Pos); + } + + if ( updateBoundingBox && numVertices > 0) + { + if ( vertexCount == 0 ) + BoundingBox.reset(static_cast(vertices)[0].Pos); + + for (i=0; i(vertices)[i].Pos); } Indices.reallocate(getIndexCount()+numIndices, false); @@ -219,12 +227,12 @@ namespace scene //! Append the meshbuffer to the current buffer - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) IRR_OVERRIDE { if ( getVertexType() != other->getVertexType() ) return; - append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount()); + append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount(), updateBoundingBox); } diff --git a/include/IMeshBuffer.h b/include/IMeshBuffer.h index fc32c36..ab8560e 100644 --- a/include/IMeshBuffer.h +++ b/include/IMeshBuffer.h @@ -131,14 +131,16 @@ namespace scene \param vertices Pointer to a vertex array. \param numVertices Number of vertices in the array. \param indices Pointer to index array. - \param numIndices Number of indices in array. */ - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0; + \param numIndices Number of indices in array. + \param updateBoundingBox When true update boundingbox by the added vertices */ + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) = 0; //! Not supported right now by all meshbuffer //! In theory: Append the meshbuffer to the current buffer /** Only works for compatible vertex and index types - \param other Buffer to append to this one. */ - virtual void append(const IMeshBuffer* const other) = 0; + \param other Buffer to append to this one. +s \param updateBoundingBox When true update boundingbox by the added vertices */ + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) = 0; //! get the current hardware mapping hint virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0; diff --git a/include/SSharedMeshBuffer.h b/include/SSharedMeshBuffer.h index f894625..ece6810 100644 --- a/include/SSharedMeshBuffer.h +++ b/include/SSharedMeshBuffer.h @@ -187,13 +187,13 @@ namespace scene //! append the vertices and indices to the current buffer - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox) IRR_OVERRIDE { // can't do that as it doesn't own the vertex memory } //! append the meshbuffer to the current buffer - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE { // can't do that as it doesn't own the vertex memory } diff --git a/include/SSkinMeshBuffer.h b/include/SSkinMeshBuffer.h index b2b812b..9883c65 100644 --- a/include/SSkinMeshBuffer.h +++ b/include/SSkinMeshBuffer.h @@ -355,10 +355,10 @@ struct SSkinMeshBuffer : public IMeshBuffer } //! append the vertices and indices to the current buffer - virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE {} + virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox) IRR_OVERRIDE {} //! append the meshbuffer to the current buffer - virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE {} + virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE {} //! get the current hardware mapping hint for vertex buffers virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE