diff --git a/irr/include/SSkinMeshBuffer.h b/irr/include/SSkinMeshBuffer.h index 2b71cf6c5..abe077076 100644 --- a/irr/include/SSkinMeshBuffer.h +++ b/irr/include/SSkinMeshBuffer.h @@ -5,6 +5,8 @@ #pragma once #include "IMeshBuffer.h" +#include "CVertexBuffer.h" +#include "CIndexBuffer.h" #include "S3DVertex.h" #include "irrArray.h" @@ -18,18 +20,32 @@ struct SSkinMeshBuffer : public IMeshBuffer { //! Default constructor SSkinMeshBuffer(video::E_VERTEX_TYPE vt = video::EVT_STANDARD) : - ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt), - PrimitiveType(EPT_TRIANGLES), HWBuffer(nullptr), - MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), - BoundingBoxNeedsRecalculated(true) - {} + VertexType(vt), PrimitiveType(EPT_TRIANGLES), + HWBuffer(nullptr), BoundingBoxNeedsRecalculated(true) + { +#ifdef _DEBUG + setDebugName("SSkinMeshBuffer"); +#endif + Vertices_Tangents = new SVertexBufferTangents(); + Vertices_2TCoords = new SVertexBufferLightMap(); + Vertices_Standard = new SVertexBuffer(); + Indices = new SIndexBuffer(); + } //! Constructor for standard vertices SSkinMeshBuffer(std::vector &&vertices, std::vector &&indices) : SSkinMeshBuffer() { - Vertices_Standard = std::move(vertices); - Indices = std::move(indices); + Vertices_Standard->Data = std::move(vertices); + Indices->Data = std::move(indices); + } + + ~SSkinMeshBuffer() + { + Vertices_Tangents->drop(); + Vertices_2TCoords->drop(); + Vertices_Standard->drop(); + Indices->drop(); } //! Get Material of this buffer. @@ -44,81 +60,86 @@ struct SSkinMeshBuffer : public IMeshBuffer return Material; } +protected: + const scene::IVertexBuffer *getVertexBuffer() const + { + switch (VertexType) { + case video::EVT_2TCOORDS: + return Vertices_2TCoords; + case video::EVT_TANGENTS: + return Vertices_Tangents; + default: + return Vertices_Standard; + } + } + + scene::IVertexBuffer *getVertexBuffer() + { + switch (VertexType) { + case video::EVT_2TCOORDS: + return Vertices_2TCoords; + case video::EVT_TANGENTS: + return Vertices_Tangents; + default: + return Vertices_Standard; + } + } +public: + //! Get standard vertex at given index virtual video::S3DVertex *getVertex(u32 index) { switch (VertexType) { case video::EVT_2TCOORDS: - return (video::S3DVertex *)&Vertices_2TCoords[index]; + return &Vertices_2TCoords->Data[index]; case video::EVT_TANGENTS: - return (video::S3DVertex *)&Vertices_Tangents[index]; + return &Vertices_Tangents->Data[index]; default: - return &Vertices_Standard[index]; + return &Vertices_Standard->Data[index]; } } //! Get pointer to vertex array const void *getVertices() const override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords.data(); - case video::EVT_TANGENTS: - return Vertices_Tangents.data(); - default: - return Vertices_Standard.data(); - } + return getVertexBuffer()->getData(); } //! Get pointer to vertex array void *getVertices() override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords.data(); - case video::EVT_TANGENTS: - return Vertices_Tangents.data(); - default: - return Vertices_Standard.data(); - } + return getVertexBuffer()->getData(); } //! Get vertex count u32 getVertexCount() const override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return static_cast(Vertices_2TCoords.size()); - case video::EVT_TANGENTS: - return static_cast(Vertices_Tangents.size()); - default: - return static_cast(Vertices_Standard.size()); - } + return getVertexBuffer()->getCount(); } //! Get type of index data which is stored in this meshbuffer. /** \return Index type of this buffer. */ video::E_INDEX_TYPE getIndexType() const override { - return video::EIT_16BIT; + return Indices->getType(); } //! Get pointer to index array const u16 *getIndices() const override { - return Indices.data(); + return static_cast(Indices->getData()); } //! Get pointer to index array u16 *getIndices() override { - return Indices.data(); + return static_cast(Indices->getData()); } //! Get index count u32 getIndexCount() const override { - return static_cast(Indices.size()); + return Indices->getCount(); } //! Get bounding box @@ -143,32 +164,35 @@ struct SSkinMeshBuffer : public IMeshBuffer switch (VertexType) { case video::EVT_STANDARD: { - if (Vertices_Standard.empty()) + if (!Vertices_Standard->getCount()) BoundingBox.reset(0, 0, 0); else { - BoundingBox.reset(Vertices_Standard[0].Pos); - for (size_t i = 1; i < Vertices_Standard.size(); ++i) - BoundingBox.addInternalPoint(Vertices_Standard[i].Pos); + auto &vertices = Vertices_Standard->Data; + BoundingBox.reset(vertices[0].Pos); + for (size_t i = 1; i < vertices.size(); ++i) + BoundingBox.addInternalPoint(vertices[i].Pos); } break; } case video::EVT_2TCOORDS: { - if (Vertices_2TCoords.empty()) + if (!Vertices_2TCoords->getCount()) BoundingBox.reset(0, 0, 0); else { - BoundingBox.reset(Vertices_2TCoords[0].Pos); - for (size_t i = 1; i < Vertices_2TCoords.size(); ++i) - BoundingBox.addInternalPoint(Vertices_2TCoords[i].Pos); + auto &vertices = Vertices_2TCoords->Data; + BoundingBox.reset(vertices[0].Pos); + for (size_t i = 1; i < vertices.size(); ++i) + BoundingBox.addInternalPoint(vertices[i].Pos); } break; } case video::EVT_TANGENTS: { - if (Vertices_Tangents.empty()) + if (!Vertices_Tangents->getCount()) BoundingBox.reset(0, 0, 0); else { - BoundingBox.reset(Vertices_Tangents[0].Pos); - for (size_t i = 1; i < Vertices_Tangents.size(); ++i) - BoundingBox.addInternalPoint(Vertices_Tangents[i].Pos); + auto &vertices = Vertices_Tangents->Data; + BoundingBox.reset(vertices[0].Pos); + for (size_t i = 1; i < vertices.size(); ++i) + BoundingBox.addInternalPoint(vertices[i].Pos); } break; } @@ -185,15 +209,15 @@ struct SSkinMeshBuffer : public IMeshBuffer void convertTo2TCoords() { if (VertexType == video::EVT_STANDARD) { - for (const auto &Vertex_Standard : Vertices_Standard) { - video::S3DVertex2TCoords Vertex; + video::S3DVertex2TCoords Vertex; + for (const auto &Vertex_Standard : Vertices_Standard->Data) { Vertex.Color = Vertex_Standard.Color; Vertex.Pos = Vertex_Standard.Pos; Vertex.Normal = Vertex_Standard.Normal; Vertex.TCoords = Vertex_Standard.TCoords; - Vertices_2TCoords.push_back(Vertex); + Vertices_2TCoords->Data.push_back(Vertex); } - Vertices_Standard.clear(); + Vertices_Standard->Data.clear(); VertexType = video::EVT_2TCOORDS; } } @@ -202,26 +226,26 @@ struct SSkinMeshBuffer : public IMeshBuffer void convertToTangents() { if (VertexType == video::EVT_STANDARD) { - for (const auto &Vertex_Standard : Vertices_Standard) { video::S3DVertexTangents Vertex; + for (const auto &Vertex_Standard : Vertices_Standard->Data) { Vertex.Color = Vertex_Standard.Color; Vertex.Pos = Vertex_Standard.Pos; Vertex.Normal = Vertex_Standard.Normal; Vertex.TCoords = Vertex_Standard.TCoords; - Vertices_Tangents.push_back(Vertex); + Vertices_Tangents->Data.push_back(Vertex); } - Vertices_Standard.clear(); + Vertices_Standard->Data.clear(); VertexType = video::EVT_TANGENTS; } else if (VertexType == video::EVT_2TCOORDS) { - for (const auto &Vertex_2TCoords : Vertices_2TCoords) { - video::S3DVertexTangents Vertex; + video::S3DVertexTangents Vertex; + for (const auto &Vertex_2TCoords : Vertices_2TCoords->Data) { Vertex.Color = Vertex_2TCoords.Color; Vertex.Pos = Vertex_2TCoords.Pos; Vertex.Normal = Vertex_2TCoords.Normal; Vertex.TCoords = Vertex_2TCoords.TCoords; - Vertices_Tangents.push_back(Vertex); + Vertices_Tangents->Data.push_back(Vertex); } - Vertices_2TCoords.clear(); + Vertices_2TCoords->Data.clear(); VertexType = video::EVT_TANGENTS; } } @@ -229,79 +253,37 @@ struct SSkinMeshBuffer : public IMeshBuffer //! returns position of vertex i const core::vector3df &getPosition(u32 i) const override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].Pos; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].Pos; - default: - return Vertices_Standard[i].Pos; - } + return getVertexBuffer()->getPosition(i); } //! returns position of vertex i core::vector3df &getPosition(u32 i) override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].Pos; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].Pos; - default: - return Vertices_Standard[i].Pos; - } + return getVertexBuffer()->getPosition(i); } //! returns normal of vertex i const core::vector3df &getNormal(u32 i) const override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].Normal; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].Normal; - default: - return Vertices_Standard[i].Normal; - } + return getVertexBuffer()->getNormal(i); } //! returns normal of vertex i core::vector3df &getNormal(u32 i) override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].Normal; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].Normal; - default: - return Vertices_Standard[i].Normal; - } + return getVertexBuffer()->getNormal(i); } //! returns texture coords of vertex i const core::vector2df &getTCoords(u32 i) const override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].TCoords; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].TCoords; - default: - return Vertices_Standard[i].TCoords; - } + return getVertexBuffer()->getTCoords(i); } //! returns texture coords of vertex i core::vector2df &getTCoords(u32 i) override { - switch (VertexType) { - case video::EVT_2TCOORDS: - return Vertices_2TCoords[i].TCoords; - case video::EVT_TANGENTS: - return Vertices_Tangents[i].TCoords; - default: - return Vertices_Standard[i].TCoords; - } + return getVertexBuffer()->getTCoords(i); } //! append the vertices and indices to the current buffer @@ -313,26 +295,22 @@ struct SSkinMeshBuffer : public IMeshBuffer //! get the current hardware mapping hint for vertex buffers E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const override { - return MappingHint_Vertex; + return getVertexBuffer()->getHardwareMappingHint(); } //! get the current hardware mapping hint for index buffers E_HARDWARE_MAPPING getHardwareMappingHint_Index() const override { - return MappingHint_Index; + return Indices->getHardwareMappingHint(); } //! set the hardware mapping hint, for driver void setHardwareMappingHint(E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override { - if (Buffer == EBT_VERTEX) - MappingHint_Vertex = NewMappingHint; - else if (Buffer == EBT_INDEX) - MappingHint_Index = NewMappingHint; - else if (Buffer == EBT_VERTEX_AND_INDEX) { - MappingHint_Vertex = NewMappingHint; - MappingHint_Index = NewMappingHint; - } + if (Buffer == EBT_VERTEX || Buffer == EBT_VERTEX_AND_INDEX) + getVertexBuffer()->setHardwareMappingHint(NewMappingHint); + if (Buffer == EBT_INDEX || Buffer == EBT_VERTEX_AND_INDEX) + Indices->setHardwareMappingHint(NewMappingHint); } //! Describe what kind of primitive geometry is used by the meshbuffer @@ -351,14 +329,20 @@ struct SSkinMeshBuffer : public IMeshBuffer void setDirty(E_BUFFER_TYPE Buffer = EBT_VERTEX_AND_INDEX) override { if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_VERTEX) - ++ChangedID_Vertex; + getVertexBuffer()->setDirty(); if (Buffer == EBT_VERTEX_AND_INDEX || Buffer == EBT_INDEX) - ++ChangedID_Index; + Indices->setDirty(); } - u32 getChangedID_Vertex() const override { return ChangedID_Vertex; } + u32 getChangedID_Vertex() const override + { + return getVertexBuffer()->getChangedID(); + } - u32 getChangedID_Index() const override { return ChangedID_Index; } + u32 getChangedID_Index() const override + { + return Indices->getChangedID(); + } void setHWBuffer(void *ptr) const override { @@ -373,15 +357,11 @@ struct SSkinMeshBuffer : public IMeshBuffer //! Call this after changing the positions of any vertex. void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; } - std::vector Vertices_Tangents; - std::vector Vertices_2TCoords; - std::vector Vertices_Standard; - std::vector Indices; + SVertexBufferTangents *Vertices_Tangents; + SVertexBufferLightMap *Vertices_2TCoords; + SVertexBuffer *Vertices_Standard; + SIndexBuffer *Indices; - u32 ChangedID_Vertex; - u32 ChangedID_Index; - - // ISkinnedMesh::SJoint *AttachedJoint; core::matrix4 Transformation; video::SMaterial Material; @@ -394,11 +374,7 @@ struct SSkinMeshBuffer : public IMeshBuffer mutable void *HWBuffer; - // hardware mapping hint - E_HARDWARE_MAPPING MappingHint_Vertex : 3; - E_HARDWARE_MAPPING MappingHint_Index : 3; - - bool BoundingBoxNeedsRecalculated : 1; + bool BoundingBoxNeedsRecalculated; }; } // end namespace scene diff --git a/irr/src/CB3DMeshFileLoader.cpp b/irr/src/CB3DMeshFileLoader.cpp index 008169bd7..4cd7b1d82 100644 --- a/irr/src/CB3DMeshFileLoader.cpp +++ b/irr/src/CB3DMeshFileLoader.cpp @@ -259,14 +259,15 @@ bool CB3DMeshFileLoader::readChunkMESH(CSkinnedMesh::SJoint *inJoint) if (!NormalsInFile) { s32 i; - for (i = 0; i < (s32)meshBuffer->Indices.size(); i += 3) { - core::plane3df p(meshBuffer->getVertex(meshBuffer->Indices[i + 0])->Pos, - meshBuffer->getVertex(meshBuffer->Indices[i + 1])->Pos, - meshBuffer->getVertex(meshBuffer->Indices[i + 2])->Pos); + auto &indices = meshBuffer->Indices->Data; + for (i = 0; i < (s32)indices.size(); i += 3) { + core::plane3df p(meshBuffer->getVertex(indices[i + 0])->Pos, + meshBuffer->getVertex(indices[i + 1])->Pos, + meshBuffer->getVertex(indices[i + 2])->Pos); - meshBuffer->getVertex(meshBuffer->Indices[i + 0])->Normal += p.Normal; - meshBuffer->getVertex(meshBuffer->Indices[i + 1])->Normal += p.Normal; - meshBuffer->getVertex(meshBuffer->Indices[i + 2])->Normal += p.Normal; + meshBuffer->getVertex(indices[i + 0])->Normal += p.Normal; + meshBuffer->getVertex(indices[i + 1])->Normal += p.Normal; + meshBuffer->getVertex(indices[i + 2])->Normal += p.Normal; } for (i = 0; i < (s32)meshBuffer->getVertexCount(); ++i) { @@ -433,7 +434,7 @@ bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 m } const s32 memoryNeeded = B3dStack.getLast().length / sizeof(s32); - meshBuffer->Indices.reserve(memoryNeeded + meshBuffer->Indices.size() + 1); + meshBuffer->Indices->Data.reserve(memoryNeeded + meshBuffer->Indices->Data.size() + 1); while ((B3dStack.getLast().startposition + B3dStack.getLast().length) > B3DFile->getPos()) // this chunk repeats { @@ -471,9 +472,9 @@ bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 m // Add the vertex to the meshbuffer: if (meshBuffer->VertexType == video::EVT_STANDARD) - meshBuffer->Vertices_Standard.push_back(BaseVertices[vertex_id[i]]); + meshBuffer->Vertices_Standard->Data.push_back(BaseVertices[vertex_id[i]]); else - meshBuffer->Vertices_2TCoords.push_back(BaseVertices[vertex_id[i]]); + meshBuffer->Vertices_2TCoords->Data.push_back(BaseVertices[vertex_id[i]]); // create vertex id to meshbuffer index link: AnimatedVertices_VertexID[vertex_id[i]] = meshBuffer->getVertexCount() - 1; @@ -504,9 +505,9 @@ bool CB3DMeshFileLoader::readChunkTRIS(scene::SSkinMeshBuffer *meshBuffer, u32 m } } - meshBuffer->Indices.push_back(AnimatedVertices_VertexID[vertex_id[0]]); - meshBuffer->Indices.push_back(AnimatedVertices_VertexID[vertex_id[1]]); - meshBuffer->Indices.push_back(AnimatedVertices_VertexID[vertex_id[2]]); + meshBuffer->Indices->Data.push_back(AnimatedVertices_VertexID[vertex_id[0]]); + meshBuffer->Indices->Data.push_back(AnimatedVertices_VertexID[vertex_id[1]]); + meshBuffer->Indices->Data.push_back(AnimatedVertices_VertexID[vertex_id[2]]); } B3dStack.erase(B3dStack.size() - 1); diff --git a/irr/src/CXMeshFileLoader.cpp b/irr/src/CXMeshFileLoader.cpp index 4e11fe352..483955805 100644 --- a/irr/src/CXMeshFileLoader.cpp +++ b/irr/src/CXMeshFileLoader.cpp @@ -273,12 +273,12 @@ bool CXMeshFileLoader::load(io::IReadFile *file) } if (mesh->TCoords2.size()) { for (i = 0; i != mesh->Buffers.size(); ++i) { - mesh->Buffers[i]->Vertices_2TCoords.reserve(vCountArray[i]); + mesh->Buffers[i]->Vertices_2TCoords->Data.reserve(vCountArray[i]); mesh->Buffers[i]->VertexType = video::EVT_2TCOORDS; } } else { for (i = 0; i != mesh->Buffers.size(); ++i) - mesh->Buffers[i]->Vertices_Standard.reserve(vCountArray[i]); + mesh->Buffers[i]->Vertices_Standard->Data.reserve(vCountArray[i]); } verticesLinkIndex.set_used(mesh->Vertices.size()); @@ -290,14 +290,14 @@ bool CXMeshFileLoader::load(io::IReadFile *file) scene::SSkinMeshBuffer *buffer = mesh->Buffers[verticesLinkBuffer[i]]; if (mesh->TCoords2.size()) { - verticesLinkIndex[i] = buffer->Vertices_2TCoords.size(); - buffer->Vertices_2TCoords.emplace_back(mesh->Vertices[i]); + verticesLinkIndex[i] = buffer->Vertices_2TCoords->getCount(); + buffer->Vertices_2TCoords->Data.emplace_back(mesh->Vertices[i]); // We have a problem with correct tcoord2 handling here // crash fixed for now by checking the values - buffer->Vertices_2TCoords.back().TCoords2 = (i < mesh->TCoords2.size()) ? mesh->TCoords2[i] : mesh->Vertices[i].TCoords; + buffer->Vertices_2TCoords->Data.back().TCoords2 = (i < mesh->TCoords2.size()) ? mesh->TCoords2[i] : mesh->Vertices[i].TCoords; } else { - verticesLinkIndex[i] = buffer->Vertices_Standard.size(); - buffer->Vertices_Standard.push_back(mesh->Vertices[i]); + verticesLinkIndex[i] = buffer->Vertices_Standard->getCount(); + buffer->Vertices_Standard->Data.push_back(mesh->Vertices[i]); } } @@ -306,13 +306,13 @@ bool CXMeshFileLoader::load(io::IReadFile *file) for (i = 0; i < mesh->FaceMaterialIndices.size(); ++i) ++vCountArray[mesh->FaceMaterialIndices[i]]; for (i = 0; i != mesh->Buffers.size(); ++i) - mesh->Buffers[i]->Indices.reserve(vCountArray[i]); + mesh->Buffers[i]->Indices->Data.reserve(vCountArray[i]); delete[] vCountArray; // create indices per buffer for (i = 0; i < mesh->FaceMaterialIndices.size(); ++i) { scene::SSkinMeshBuffer *buffer = mesh->Buffers[mesh->FaceMaterialIndices[i]]; for (u32 id = i * 3 + 0; id != i * 3 + 3; ++id) { - buffer->Indices.push_back(verticesLinkIndex[mesh->Indices[id]]); + buffer->Indices->Data.push_back(verticesLinkIndex[mesh->Indices[id]]); } } }