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
This commit is contained in:
cutealien 2023-05-17 14:31:50 +00:00
parent 7c92944860
commit a44e5e3d17
6 changed files with 70 additions and 39 deletions

@ -1,6 +1,7 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) 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. - 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. - 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. This can avoid constantly allocation/releasing memory in the active driver material when setting materials.

@ -108,20 +108,20 @@ namespace scene
\param numVertices Number of vertices in the array. \param numVertices Number of vertices in the array.
\param indices Pointer to index array. \param indices Pointer to index array.
\param numIndices Number of indices in 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 // 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 //! Append the meshbuffer to the current buffer
/** \param other Buffer to append to this one. */ /** \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 if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks
return; return;
@ -129,29 +129,49 @@ namespace scene
const u32 vertexCount = getVertexCount(); const u32 vertexCount = getVertexCount();
VertexBuffer->reallocate(vertexCount+numVertices, false); VertexBuffer->reallocate(vertexCount+numVertices, false);
switch ( vertexType ) if ( vertexType == getVertexType() )
{ {
case video::EVT_STANDARD: const irr::u32 typeSize = getVertexPitchFromType(vertexType);
for (u32 i=0; i<numVertices; ++i) VertexBuffer->set_used(vertexCount+numVertices);
{ irr::u8* target = &static_cast<irr::u8*>(VertexBuffer->pointer())[vertexCount*typeSize];
VertexBuffer->push_back(static_cast<const video::S3DVertex*>(vertices)[i]); memcpy(target, vertices, numVertices*typeSize);
BoundingBox.addInternalPoint(static_cast<const video::S3DVertex*>(vertices)[i].Pos); }
} else
break; {
case video::EVT_2TCOORDS: switch ( vertexType )
for (u32 i=0; i<numVertices; ++i) {
{ case video::EVT_STANDARD:
VertexBuffer->push_back(static_cast<const video::S3DVertex2TCoords*>(vertices)[i]); for (u32 i=0; i<numVertices; ++i)
BoundingBox.addInternalPoint(static_cast<const video::S3DVertex2TCoords*>(vertices)[i].Pos); {
} VertexBuffer->push_back(static_cast<const video::S3DVertex*>(vertices)[i]);
break; }
case video::EVT_TANGENTS: break;
for (u32 i=0; i<numVertices; ++i) case video::EVT_2TCOORDS:
{ for (u32 i=0; i<numVertices; ++i)
VertexBuffer->push_back(static_cast<const video::S3DVertexTangents*>(vertices)[i]); {
BoundingBox.addInternalPoint(static_cast<const video::S3DVertexTangents*>(vertices)[i].Pos); VertexBuffer->push_back(static_cast<const video::S3DVertex2TCoords*>(vertices)[i]);
} }
break; break;
case video::EVT_TANGENTS:
for (u32 i=0; i<numVertices; ++i)
{
VertexBuffer->push_back(static_cast<const video::S3DVertexTangents*>(vertices)[i]);
}
break;
}
}
if ( updateBoundingBox && numVertices > 0)
{
if ( vertexCount == 0 )
BoundingBox.reset( static_cast<const video::S3DVertex*>(vertices)[0].Pos );
const u32 typePitch = getVertexPitchFromType(vertexType);
const irr::u8* v8 = static_cast<const irr::u8*>(vertices);
for (u32 i=0; i<numVertices; ++i, v8 += typePitch)
{
BoundingBox.addInternalPoint(reinterpret_cast<const video::S3DVertex*>(v8)->Pos);
}
} }
IndexBuffer->reallocate(getIndexCount()+numIndices, false); IndexBuffer->reallocate(getIndexCount()+numIndices, false);

@ -193,7 +193,7 @@ namespace scene
or the main buffer is of standard type. Otherwise, behavior is or the main buffer is of standard type. Otherwise, behavior is
undefined. Also can't append it's own vertices/indices to itself. 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 if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks
return; return;
@ -205,7 +205,15 @@ namespace scene
for (i=0; i<numVertices; ++i) for (i=0; i<numVertices; ++i)
{ {
Vertices.push_back(static_cast<const T*>(vertices)[i]); Vertices.push_back(static_cast<const T*>(vertices)[i]);
BoundingBox.addInternalPoint(static_cast<const T*>(vertices)[i].Pos); }
if ( updateBoundingBox && numVertices > 0)
{
if ( vertexCount == 0 )
BoundingBox.reset(static_cast<const T*>(vertices)[0].Pos);
for (i=0; i<numVertices; ++i)
BoundingBox.addInternalPoint(static_cast<const T*>(vertices)[i].Pos);
} }
Indices.reallocate(getIndexCount()+numIndices, false); Indices.reallocate(getIndexCount()+numIndices, false);
@ -219,12 +227,12 @@ namespace scene
//! Append the meshbuffer to the current buffer //! 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() ) if ( getVertexType() != other->getVertexType() )
return; return;
append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount()); append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount(), updateBoundingBox);
} }

@ -131,14 +131,16 @@ namespace scene
\param vertices Pointer to a vertex array. \param vertices Pointer to a vertex array.
\param numVertices Number of vertices in the array. \param numVertices Number of vertices in the array.
\param indices Pointer to index array. \param indices Pointer to index array.
\param numIndices Number of indices in 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 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 //! Not supported right now by all meshbuffer
//! In theory: Append the meshbuffer to the current buffer //! In theory: Append the meshbuffer to the current buffer
/** Only works for compatible vertex and index types /** Only works for compatible vertex and index types
\param other Buffer to append to this one. */ \param other Buffer to append to this one.
virtual void append(const IMeshBuffer* const other) = 0; 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 //! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0; virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0;

@ -187,13 +187,13 @@ namespace scene
//! append the vertices and indices to the current buffer //! 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 // can't do that as it doesn't own the vertex memory
} }
//! append the meshbuffer to the current buffer //! 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 // can't do that as it doesn't own the vertex memory
} }

@ -355,10 +355,10 @@ struct SSkinMeshBuffer : public IMeshBuffer
} }
//! append the vertices and indices to the current buffer //! 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 //! 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 //! get the current hardware mapping hint for vertex buffers
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE