forked from Mirrorlandia_minetest/irrlicht
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:
parent
8447d3f531
commit
c5b349ddb0
@ -1,5 +1,6 @@
|
|||||||
--------------------------
|
--------------------------
|
||||||
Changes in 1.9 (not yet released)
|
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 writer can now write 32 bit buffers
|
||||||
- obj meshloader can now load 32 bit buffers when setPreferredIndexType is set to EIT_32BIT.
|
- 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.
|
It's 16 bit meshes use now also an IDynamicMeshbuffer instead of an SMeshBuffer.
|
||||||
|
@ -120,6 +120,40 @@ namespace scene
|
|||||||
return EMBT_DYNAMIC;
|
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;
|
video::SMaterial Material;
|
||||||
core::aabbox3d<f32> BoundingBox;
|
core::aabbox3d<f32> BoundingBox;
|
||||||
//! Primitive type used for rendering (triangles, lines, ...)
|
//! Primitive type used for rendering (triangles, lines, ...)
|
||||||
|
@ -292,9 +292,33 @@ namespace scene
|
|||||||
return getTypeT();
|
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
|
//! Returns type of the class implementing the IMeshBuffer for template specialization
|
||||||
// Minor note: Some compilers (VS) allow directly specializating the virtual function,
|
// Minor note: Some compilers (VS) allow directly specializing the virtual function,
|
||||||
// but this will fail on other compilers (GCC).
|
// but this will fail on other compilers (GCC). So using a helper function.
|
||||||
EMESH_BUFFER_TYPE getTypeT() const;
|
EMESH_BUFFER_TYPE getTypeT() const;
|
||||||
|
|
||||||
u32 ChangedID_Vertex;
|
u32 ChangedID_Vertex;
|
||||||
|
@ -190,6 +190,16 @@ namespace scene
|
|||||||
return EMBT_UNKNOWN;
|
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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,9 +229,7 @@ namespace scene
|
|||||||
u8 axis, const core::vector3df& offset) const=0;
|
u8 axis, const core::vector3df& offset) const=0;
|
||||||
|
|
||||||
//! Clones a static IMesh into a modifiable SMesh.
|
//! Clones a static IMesh into a modifiable SMesh.
|
||||||
/** All meshbuffers in the returned SMesh
|
/** \param mesh Mesh to copy.
|
||||||
are of type SMeshBuffer or SMeshBufferLightMap.
|
|
||||||
\param mesh Mesh to copy.
|
|
||||||
\return Cloned mesh. If you no longer need the
|
\return Cloned mesh. If you no longer need the
|
||||||
cloned mesh, you should call SMesh::drop(). See
|
cloned mesh, you should call SMesh::drop(). See
|
||||||
IReferenceCounted::drop() for more information. */
|
IReferenceCounted::drop() for more information. */
|
||||||
|
@ -18,17 +18,27 @@ namespace scene
|
|||||||
class IVertexBuffer : public virtual IReferenceCounted
|
class IVertexBuffer : public virtual IReferenceCounted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//! Pointer to first element of vertex data
|
||||||
virtual void* getData() =0;
|
virtual void* getData() =0;
|
||||||
|
|
||||||
virtual video::E_VERTEX_TYPE getType() const =0;
|
virtual video::E_VERTEX_TYPE getType() const =0;
|
||||||
virtual void setType(video::E_VERTEX_TYPE vertexType) =0;
|
virtual void setType(video::E_VERTEX_TYPE vertexType) =0;
|
||||||
|
|
||||||
|
//! Number of bytes per element
|
||||||
virtual u32 stride() const =0;
|
virtual u32 stride() const =0;
|
||||||
|
|
||||||
|
//! Number of elements
|
||||||
virtual u32 size() const =0;
|
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 void push_back(const video::S3DVertex &element) =0;
|
||||||
virtual video::S3DVertex& operator [](const u32 index) const =0;
|
virtual video::S3DVertex& operator [](const u32 index) const =0;
|
||||||
virtual video::S3DVertex& getLast() =0;
|
virtual video::S3DVertex& getLast() =0;
|
||||||
virtual void set_used(u32 usedNow) =0;
|
virtual void set_used(u32 usedNow) =0;
|
||||||
virtual void reallocate(u32 new_size) =0;
|
virtual void reallocate(u32 new_size) =0;
|
||||||
virtual u32 allocated_size() const =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;
|
virtual video::S3DVertex* pointer() =0;
|
||||||
|
|
||||||
//! get the current hardware mapping hint
|
//! get the current hardware mapping hint
|
||||||
|
@ -172,9 +172,16 @@ 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) IRR_OVERRIDE
|
||||||
|
{
|
||||||
|
// 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) IRR_OVERRIDE
|
||||||
|
{
|
||||||
|
// can't do that as it doesn't own the vertex memory
|
||||||
|
}
|
||||||
|
|
||||||
//! get the current hardware mapping hint
|
//! get the current hardware mapping hint
|
||||||
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE
|
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE
|
||||||
@ -232,6 +239,30 @@ namespace scene
|
|||||||
return EMBT_SHARED;
|
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
|
//! Material of this meshBuffer
|
||||||
video::SMaterial Material;
|
video::SMaterial Material;
|
||||||
|
|
||||||
|
@ -389,6 +389,35 @@ struct SSkinMeshBuffer : public IMeshBuffer
|
|||||||
return EMBT_SKIN;
|
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.
|
//! Call this after changing the positions of any vertex.
|
||||||
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
|
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }
|
||||||
|
|
||||||
|
@ -577,8 +577,7 @@ void CMeshManipulator::makePlanarTextureMapping(scene::IMesh* mesh, f32 resoluti
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Clones a static IMesh into a modifyable SMesh.
|
//! Clones a static IMesh into a modifiable SMesh.
|
||||||
// not yet 32bit
|
|
||||||
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
|
SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
|
||||||
{
|
{
|
||||||
if (!mesh)
|
if (!mesh)
|
||||||
@ -590,66 +589,10 @@ SMesh* CMeshManipulator::createMeshCopy(scene::IMesh* mesh) const
|
|||||||
|
|
||||||
for ( u32 b=0; b<meshBufferCount; ++b)
|
for ( u32 b=0; b<meshBufferCount; ++b)
|
||||||
{
|
{
|
||||||
const IMeshBuffer* const mb = mesh->getMeshBuffer(b);
|
IMeshBuffer* bufferClone = mesh->getMeshBuffer(b)->createClone();
|
||||||
switch(mb->getVertexType())
|
clone->addMeshBuffer(bufferClone);
|
||||||
{
|
bufferClone->drop();
|
||||||
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
|
|
||||||
|
|
||||||
clone->BoundingBox = mesh->getBoundingBox();
|
clone->BoundingBox = mesh->getBoundingBox();
|
||||||
return clone;
|
return clone;
|
||||||
|
@ -127,10 +127,10 @@ bool COBJMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||||||
file->write(num.c_str(), num.size());
|
file->write(num.c_str(), num.size());
|
||||||
file->write("\n",1);
|
file->write("\n",1);
|
||||||
|
|
||||||
|
unsigned int idx2=0, idx1=0, idx0 = 0;
|
||||||
const u32 indexCount = buffer->getIndexCount();
|
const u32 indexCount = buffer->getIndexCount();
|
||||||
for (j=0; j<indexCount; j+=3)
|
for (j=0; j<indexCount; j+=3)
|
||||||
{
|
{
|
||||||
unsigned int idx2, idx1, idx0;
|
|
||||||
switch(buffer->getIndexType())
|
switch(buffer->getIndexType())
|
||||||
{
|
{
|
||||||
case video::EIT_16BIT:
|
case video::EIT_16BIT:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Tests finished. 72 tests of 72 passed.
|
Tests finished. 72 tests of 72 passed.
|
||||||
Compiled as DEBUG
|
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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user