Add IMeshBufffer::clone for buffer copies, use it in CMeshManipulator::createMeshCopy

CMeshManipulator::createMeshCopy creates new meshes which have copies of the actual meshbuffers instead of copying everything into SMeshBuffers (which didn't support 32 bit or any of the other special features).



git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6335 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2022-04-14 16:54:06 +00:00
parent 8447d3f531
commit c5b349ddb0
11 changed files with 151 additions and 71 deletions

View File

@ -1,5 +1,6 @@
--------------------------
Changes in 1.9 (not yet released)
- Add IMeshBufffer::clone function to create buffer copies. CMeshManipulator::createMeshCopy uses that now and works now with all types of meshbuffers.
- obj writer can now write 32 bit buffers
- obj meshloader can now load 32 bit buffers when setPreferredIndexType is set to EIT_32BIT.
It's 16 bit meshes use now also an IDynamicMeshbuffer instead of an SMeshBuffer.

View File

@ -120,6 +120,40 @@ namespace scene
return EMBT_DYNAMIC;
}
//! Create copy of the meshbuffer
virtual IMeshBuffer* createClone(int cloneFlags) const IRR_OVERRIDE
{
CDynamicMeshBuffer* clone = new CDynamicMeshBuffer(VertexBuffer->getType(), IndexBuffer->getType());
if (cloneFlags & ECF_VERTICES)
{
const u32 numVertices = VertexBuffer->size();
clone->VertexBuffer->reallocate(numVertices);
for ( u32 i=0; i<numVertices; ++i )
{
clone->VertexBuffer->push_back((*VertexBuffer)[i]);
}
clone->BoundingBox = BoundingBox;
}
if (cloneFlags & ECF_INDICES)
{
const u32 numIndices = IndexBuffer->size();
clone->IndexBuffer->reallocate(numIndices);
for ( u32 i=0; i<numIndices; ++i )
{
clone->IndexBuffer->push_back((*IndexBuffer)[i]);
}
}
clone->VertexBuffer->setHardwareMappingHint(VertexBuffer->getHardwareMappingHint());
clone->IndexBuffer->setHardwareMappingHint(clone->IndexBuffer->getHardwareMappingHint());
clone->Material = Material;
clone->PrimitiveType = PrimitiveType;
return clone;
}
video::SMaterial Material;
core::aabbox3d<f32> BoundingBox;
//! Primitive type used for rendering (triangles, lines, ...)

View File

@ -292,9 +292,33 @@ namespace scene
return getTypeT();
}
//! Create copy of the meshbuffer
virtual IMeshBuffer* createClone(int cloneFlags) const IRR_OVERRIDE
{
CMeshBuffer<T> * clone = new CMeshBuffer<T>();
if (cloneFlags & ECF_VERTICES)
{
clone->Vertices = Vertices;
clone->BoundingBox = BoundingBox;
}
if (cloneFlags & ECF_INDICES)
{
clone->Indices = Indices;
}
clone->PrimitiveType = PrimitiveType;
clone->Material = getMaterial();
clone->MappingHint_Vertex = MappingHint_Vertex;
clone->MappingHint_Index = MappingHint_Index;
return clone;
}
//! Returns type of the class implementing the IMeshBuffer for template specialization
// Minor note: Some compilers (VS) allow directly specializating the virtual function,
// but this will fail on other compilers (GCC).
// Minor note: Some compilers (VS) allow directly specializing the virtual function,
// but this will fail on other compilers (GCC). So using a helper function.
EMESH_BUFFER_TYPE getTypeT() const;
u32 ChangedID_Vertex;

View File

@ -190,6 +190,16 @@ namespace scene
return EMBT_UNKNOWN;
}
//! Bitflags with options for cloning
enum ECloneFlags
{
ECF_VERTICES = 1, //! clone the vertices (or copy pointer for SSharedMeshBuffer)
ECF_INDICES = 2 //! clone the indices
};
//! Create a new object with a copy of the meshbuffer
//\param cloneFlags A combination of ECloneFlags
virtual IMeshBuffer* createClone(int cloneFlags=ECF_VERTICES|ECF_INDICES) const = 0;
};

View File

@ -229,9 +229,7 @@ namespace scene
u8 axis, const core::vector3df& offset) const=0;
//! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh
are of type SMeshBuffer or SMeshBufferLightMap.
\param mesh Mesh to copy.
/** \param mesh Mesh to copy.
\return Cloned mesh. If you no longer need the
cloned mesh, you should call SMesh::drop(). See
IReferenceCounted::drop() for more information. */

View File

@ -18,17 +18,27 @@ namespace scene
class IVertexBuffer : public virtual IReferenceCounted
{
public:
//! Pointer to first element of vertex data
virtual void* getData() =0;
virtual video::E_VERTEX_TYPE getType() const =0;
virtual void setType(video::E_VERTEX_TYPE vertexType) =0;
//! Number of bytes per element
virtual u32 stride() const =0;
//! Number of elements
virtual u32 size() const =0;
//! Add vertex to end. Note that depending on vertex type this will be one of the types derived from video::S3DVertex.
virtual void push_back(const video::S3DVertex &element) =0;
virtual video::S3DVertex& operator [](const u32 index) const =0;
virtual video::S3DVertex& getLast() =0;
virtual void set_used(u32 usedNow) =0;
virtual void reallocate(u32 new_size) =0;
virtual u32 allocated_size() const =0;
//! Same as getData() - not sure why we got 2, should probably deprecate (and we don't always have video::S3DVertex*, so just confusing)
virtual video::S3DVertex* pointer() =0;
//! get the current hardware mapping hint

View File

@ -172,9 +172,16 @@ 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) 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) IRR_OVERRIDE
{
// can't do that as it doesn't own the vertex memory
}
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE
@ -232,6 +239,30 @@ namespace scene
return EMBT_SHARED;
}
//! Create copy of the meshbuffer
virtual IMeshBuffer* createClone(int cloneFlags) const IRR_OVERRIDE
{
SSharedMeshBuffer * clone = new SSharedMeshBuffer();
if (cloneFlags & ECF_VERTICES)
{
clone->Vertices = Vertices;
clone->BoundingBox = BoundingBox;
}
if (cloneFlags & ECF_INDICES)
{
clone->Indices = Indices;
}
clone->Material = Material;
clone->MappingHintVertex = MappingHintVertex;
clone->MappingHintIndex = MappingHintIndex;
clone->PrimitiveType = PrimitiveType;
return clone;
}
//! Material of this meshBuffer
video::SMaterial Material;

View File

@ -389,6 +389,35 @@ struct SSkinMeshBuffer : public IMeshBuffer
return EMBT_SKIN;
}
//! Create copy of the meshbuffer
virtual IMeshBuffer* createClone(int cloneFlags) const IRR_OVERRIDE
{
SSkinMeshBuffer* clone = new SSkinMeshBuffer(VertexType);
if (cloneFlags & ECF_VERTICES)
{
clone->Vertices_Tangents = Vertices_Tangents;
clone->Vertices_2TCoords = Vertices_2TCoords;
clone->Vertices_Standard = Vertices_Standard;
clone->BoundingBox = BoundingBox;
clone->BoundingBoxNeedsRecalculated = BoundingBoxNeedsRecalculated;
}
if (cloneFlags & ECF_INDICES)
{
clone->Indices = Indices;
}
clone->Transformation = Transformation;
clone->Material = getMaterial();
clone->PrimitiveType = PrimitiveType;
clone->MappingHint_Vertex = MappingHint_Vertex;
clone->MappingHint_Index = MappingHint_Index;
return clone;
}
//! Call this after changing the positions of any vertex.
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }

View File

@ -577,8 +577,7 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resoluti
}
//! Clones a static IMesh into a modifyable SMesh.
// not yet 32bit
//! Clones a static IMesh into a modifiable SMesh.
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
{
if (!mesh)
@ -590,66 +589,10 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
for ( u32 b=0; b<meshBufferCount; ++b)
{
const IMeshBuffer* const mb = mesh->getMeshBuffer(b);
switch(mb->getVertexType())
{
case video::EVT_STANDARD:
{
SMeshBuffer* buffer = new SMeshBuffer();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex* vertices = (video::S3DVertex*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_2TCOORDS:
{
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
case video::EVT_TANGENTS:
{
SMeshBufferTangents* buffer = new SMeshBufferTangents();
buffer->Material = mb->getMaterial();
const u32 vcount = mb->getVertexCount();
buffer->Vertices.reallocate(vcount);
video::S3DVertexTangents* vertices = (video::S3DVertexTangents*)mb->getVertices();
for (u32 i=0; i < vcount; ++i)
buffer->Vertices.push_back(vertices[i]);
const u32 icount = mb->getIndexCount();
buffer->Indices.reallocate(icount);
const u16* indices = mb->getIndices();
for (u32 i=0; i < icount; ++i)
buffer->Indices.push_back(indices[i]);
clone->addMeshBuffer(buffer);
buffer->drop();
}
break;
}// end switch
}// end for all mesh buffers
IMeshBuffer* bufferClone = mesh->getMeshBuffer(b)->createClone();
clone->addMeshBuffer(bufferClone);
bufferClone->drop();
}
clone->BoundingBox = mesh->getBoundingBox();
return clone;

View File

@ -127,10 +127,10 @@ bool COBJMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
file->write(num.c_str(), num.size());
file->write("\n",1);
unsigned int idx2=0, idx1=0, idx0 = 0;
const u32 indexCount = buffer->getIndexCount();
for (j=0; j<indexCount; j+=3)
{
unsigned int idx2, idx1, idx0;
switch(buffer->getIndexType())
{
case video::EIT_16BIT:

View File

@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed.
Compiled as DEBUG
Test suite pass at GMT Thu Apr 14 13:52:29 2022
Test suite pass at GMT Thu Apr 14 16:41:11 2022