From 5dd0ce5d8e1ebc32e12e48dab2fa85543cbe5b90 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Thu, 30 Jun 2022 21:44:37 +0300 Subject: [PATCH 01/46] Add UINT mesh index format support. --- core/3d/CCMesh.cpp | 11 +++++++-- core/3d/CCMesh.h | 7 ++++++ core/base/CCDirector.cpp | 27 ++++++++++++++++++++--- core/base/CCDirector.h | 1 + core/renderer/CCCustomCommand.h | 2 ++ core/renderer/CCRenderer.h | 7 +++++- core/renderer/backend/opengl/BufferGL.cpp | 4 ++++ 7 files changed, 53 insertions(+), 6 deletions(-) diff --git a/core/3d/CCMesh.cpp b/core/3d/CCMesh.cpp index e09d260f6b..e89ebb3991 100644 --- a/core/3d/CCMesh.cpp +++ b/core/3d/CCMesh.cpp @@ -113,6 +113,7 @@ Mesh::Mesh() , _visible(true) , _isTransparent(false) , _force2DQueue(false) + , meshIndexFormat(CustomCommand::IndexFormat::U_SHORT) , _meshIndexData(nullptr) , _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED) , _blendDirty(true) @@ -728,12 +729,18 @@ CustomCommand::PrimitiveType Mesh::getPrimitiveType() const ssize_t Mesh::getIndexCount() const { - return _meshIndexData->getIndexBuffer()->getSize() / sizeof(uint16_t); + return _meshIndexData->getIndexBuffer()->getSize() / + (meshIndexFormat == CustomCommand::IndexFormat::U_INT ? sizeof(uint32_t) : sizeof(uint16_t)); } CustomCommand::IndexFormat Mesh::getIndexFormat() const { - return CustomCommand::IndexFormat::U_SHORT; + return meshIndexFormat; +} + +void Mesh::setIndexFormat(CustomCommand::IndexFormat indexFormat) +{ + meshIndexFormat = indexFormat; } backend::Buffer* Mesh::getIndexBuffer() const diff --git a/core/3d/CCMesh.h b/core/3d/CCMesh.h index 0ecac8a450..342e7bfd74 100644 --- a/core/3d/CCMesh.h +++ b/core/3d/CCMesh.h @@ -191,6 +191,12 @@ public: * @lua NA */ CustomCommand::IndexFormat getIndexFormat() const; + /** + * set index format + * + * @lua NA + */ + void setIndexFormat(CustomCommand::IndexFormat indexFormat); /** * get index buffer * @@ -253,6 +259,7 @@ protected: bool _visible; // is the submesh visible bool _isTransparent; // is this mesh transparent, it is a property of material in fact bool _force2DQueue; // add this mesh to 2D render queue + CustomCommand::IndexFormat meshIndexFormat; std::string _name; MeshIndexData* _meshIndexData; diff --git a/core/base/CCDirector.cpp b/core/base/CCDirector.cpp index 633f9392bc..8df3f21f51 100644 --- a/core/base/CCDirector.cpp +++ b/core/base/CCDirector.cpp @@ -153,6 +153,7 @@ Director::~Director() CC_SAFE_RELEASE(_FPSLabel); CC_SAFE_RELEASE(_drawnVerticesLabel); CC_SAFE_RELEASE(_drawnBatchesLabel); + CC_SAFE_RELEASE(_drawnBuffersLabel); CC_SAFE_RELEASE(_runningScene); CC_SAFE_RELEASE(_notificationNode); @@ -1019,6 +1020,7 @@ void Director::reset() CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_drawnBatchesLabel); CC_SAFE_RELEASE_NULL(_drawnVerticesLabel); + CC_SAFE_RELEASE_NULL(_drawnBuffersLabel); // purge bitmap cache FontFNT::purgeCachedData(); @@ -1183,11 +1185,12 @@ void Director::showStats() static uint32_t prevCalls = 0; static uint32_t prevVerts = 0; + static uint32_t prevBuffers = 0; ++_frames; _accumDt += _deltaTime; - if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel) + if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel && _drawnBuffersLabel) { char buffer[30] = {0}; @@ -1204,23 +1207,32 @@ void Director::showStats() auto currentCalls = (uint32_t)_renderer->getDrawnBatches(); auto currentVerts = (uint32_t)_renderer->getDrawnVertices(); + auto currentBuffers = (uint32_t)_renderer->getModifiedBuffers(); if (currentCalls != prevCalls) { - sprintf(buffer, "GL calls:%6u", currentCalls); + sprintf(buffer, "GL calls :%6u", currentCalls); _drawnBatchesLabel->setString(buffer); prevCalls = currentCalls; } if (currentVerts != prevVerts) { - sprintf(buffer, "GL verts:%6u", currentVerts); + sprintf(buffer, "GL verts :%6u", currentVerts); _drawnVerticesLabel->setString(buffer); prevVerts = currentVerts; } + if (currentBuffers != prevBuffers) + { + sprintf(buffer, "GL buffers:%6u", currentBuffers); + _drawnBuffersLabel->setString(buffer); + prevBuffers = currentBuffers; + } + const Mat4& identity = Mat4::IDENTITY; _drawnVerticesLabel->visit(_renderer, identity, 0); _drawnBatchesLabel->visit(_renderer, identity, 0); + _drawnBuffersLabel->visit(_renderer, identity, 0); _FPSLabel->visit(_renderer, identity, 0); } } @@ -1248,15 +1260,18 @@ void Director::createStatsLabel() std::string fpsString = "00.0"; std::string drawBatchString = "000"; std::string drawVerticesString = "00000"; + std::string drawBuffersString = "000"; if (_FPSLabel) { fpsString = _FPSLabel->getString(); drawBatchString = _drawnBatchesLabel->getString(); drawVerticesString = _drawnVerticesLabel->getString(); + drawBuffersString = _drawnBuffersLabel->getString(); CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_drawnBatchesLabel); CC_SAFE_RELEASE_NULL(_drawnVerticesLabel); + CC_SAFE_RELEASE_NULL(_drawnBuffersLabel); _textureCache->removeTextureForKey("/cc_fps_images"); FileUtils::getInstance()->purgeCachedEntries(); } @@ -1303,8 +1318,14 @@ void Director::createStatsLabel() _drawnVerticesLabel->setIgnoreContentScaleFactor(true); _drawnVerticesLabel->setScale(scaleFactor); + _drawnBuffersLabel = LabelAtlas::create(drawVerticesString, texture, 12, 32, '.'); + _drawnBuffersLabel->retain(); + _drawnBuffersLabel->setIgnoreContentScaleFactor(true); + _drawnBuffersLabel->setScale(scaleFactor); + auto safeOrigin = getSafeAreaRect().origin; const int height_spacing = (int)(22 / CC_CONTENT_SCALE_FACTOR()); + _drawnBuffersLabel->setPosition(Vec2(0, height_spacing * 3.0f) + safeOrigin); _drawnVerticesLabel->setPosition(Vec2(0, height_spacing * 2.0f) + safeOrigin); _drawnBatchesLabel->setPosition(Vec2(0, height_spacing * 1.0f) + safeOrigin); _FPSLabel->setPosition(Vec2(0, height_spacing * 0.0f) + safeOrigin); diff --git a/core/base/CCDirector.h b/core/base/CCDirector.h index 05814f90ae..256919a301 100644 --- a/core/base/CCDirector.h +++ b/core/base/CCDirector.h @@ -599,6 +599,7 @@ protected: LabelAtlas* _FPSLabel = nullptr; LabelAtlas* _drawnBatchesLabel = nullptr; LabelAtlas* _drawnVerticesLabel = nullptr; + LabelAtlas* _drawnBuffersLabel = nullptr; /** Whether or not the Director is paused */ bool _paused = false; diff --git a/core/renderer/CCCustomCommand.h b/core/renderer/CCCustomCommand.h index d7326bea5c..f8596924a2 100644 --- a/core/renderer/CCCustomCommand.h +++ b/core/renderer/CCCustomCommand.h @@ -208,6 +208,8 @@ TODO: should remove it. inline IndexFormat getIndexFormat() const { return _indexFormat; } + inline void setIndexFormat(IndexFormat format) { _indexFormat = format; } + /** * set a callback which will be invoke before rendering */ diff --git a/core/renderer/CCRenderer.h b/core/renderer/CCRenderer.h index 33a6fab0fc..2cc83ff6db 100644 --- a/core/renderer/CCRenderer.h +++ b/core/renderer/CCRenderer.h @@ -176,8 +176,12 @@ public: ssize_t getDrawnVertices() const { return _drawnVertices; } /* RenderCommands (except) TrianglesCommand should update this value */ void addDrawnVertices(ssize_t number) { _drawnVertices += number; }; + /* returns the number of modified gpu buffers in the last frame */ + ssize_t getModifiedBuffers() const { return _modifiedBuffers; } + /* adds a number of modified gpu buffers in the last frame */ + void addModifiedBuffers(ssize_t number) { _modifiedBuffers += number; }; /* clear draw stats */ - void clearDrawStats() { _drawnBatches = _drawnVertices = 0; } + void clearDrawStats() { _drawnBatches = _drawnVertices = _modifiedBuffers = 0; } /** Set render targets. If not set, will use default render targets. It will effect all commands. @@ -538,6 +542,7 @@ protected: // stats size_t _drawnBatches = 0; size_t _drawnVertices = 0; + size_t _modifiedBuffers = 0; // the flag for checking whether renderer is rendering bool _isRendering = false; bool _isDepthTestFor2D = false; diff --git a/core/renderer/backend/opengl/BufferGL.cpp b/core/renderer/backend/opengl/BufferGL.cpp index 81d9f6f1e2..5183389edd 100644 --- a/core/renderer/backend/opengl/BufferGL.cpp +++ b/core/renderer/backend/opengl/BufferGL.cpp @@ -108,6 +108,8 @@ void BufferGL::updateData(void* data, std::size_t size) if (_buffer) { + Director::getInstance()->getRenderer()->addModifiedBuffers(1); + if (BufferType::VERTEX == _type) { glBindBuffer(GL_ARRAY_BUFFER, _buffer); @@ -135,6 +137,8 @@ void BufferGL::updateSubData(void* data, std::size_t offset, std::size_t size) if (_buffer) { + Director::getInstance()->getRenderer()->addModifiedBuffers(1); + CHECK_GL_ERROR_DEBUG(); if (BufferType::VERTEX == _type) { From 0c3f7400b0327b6dcf47b3be3849bca436eeccd9 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Thu, 30 Jun 2022 22:26:02 +0300 Subject: [PATCH 02/46] Update BufferGL.h --- core/renderer/backend/opengl/BufferGL.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/renderer/backend/opengl/BufferGL.h b/core/renderer/backend/opengl/BufferGL.h index 1801cfaa86..a8d2e31c91 100644 --- a/core/renderer/backend/opengl/BufferGL.h +++ b/core/renderer/backend/opengl/BufferGL.h @@ -27,6 +27,7 @@ #include "../Buffer.h" #include "platform/CCGL.h" #include "base/CCEventListenerCustom.h" +#include "base/CCDirector.h" #include From 4a0622cb3fa4165a022360fefbd5bc1ca3ed007c Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Thu, 30 Jun 2022 22:43:56 +0300 Subject: [PATCH 03/46] Update BufferGL.h --- core/renderer/backend/opengl/BufferGL.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/renderer/backend/opengl/BufferGL.h b/core/renderer/backend/opengl/BufferGL.h index a8d2e31c91..f78c7796d1 100644 --- a/core/renderer/backend/opengl/BufferGL.h +++ b/core/renderer/backend/opengl/BufferGL.h @@ -28,6 +28,7 @@ #include "platform/CCGL.h" #include "base/CCEventListenerCustom.h" #include "base/CCDirector.h" +#include "renderer/CCRenderer.h" #include From 24c2550a09cbf3cd87bb8fff013dcf615513f3a6 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Thu, 30 Jun 2022 23:21:21 +0300 Subject: [PATCH 04/46] Fix typos. [skip ci] --- core/3d/CCMeshVertexIndexData.cpp | 6 +++--- core/3d/CCMeshVertexIndexData.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 497357a57c..ee782f44bb 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -153,7 +153,7 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata) #if CC_ENABLE_CACHE_TEXTURE_DATA indexdata->setIndexData(index); #endif - vertexdata->_indexs.pushBack(indexdata); + vertexdata->_indices.pushBack(indexdata); } vertexdata->autorelease(); @@ -162,7 +162,7 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata) MeshIndexData* MeshVertexData::getMeshIndexDataById(std::string_view id) const { - for (auto it : _indexs) + for (auto it : _indices) { if (it->getId() == id) return it; @@ -193,7 +193,7 @@ MeshVertexData::MeshVertexData() MeshVertexData::~MeshVertexData() { CC_SAFE_RELEASE(_vertexBuffer); - _indexs.clear(); + _indices.clear(); _vertexData.clear(); #if CC_ENABLE_CACHE_TEXTURE_DATA Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundListener); diff --git a/core/3d/CCMeshVertexIndexData.h b/core/3d/CCMeshVertexIndexData.h index 889eded961..633fb9334b 100644 --- a/core/3d/CCMeshVertexIndexData.h +++ b/core/3d/CCMeshVertexIndexData.h @@ -124,9 +124,9 @@ public: const MeshVertexAttrib& getMeshVertexAttrib(ssize_t index) const { return _attribs[index]; } /** get index data count */ - ssize_t getMeshIndexDataCount() const { return _indexs.size(); } + ssize_t getMeshIndexDataCount() const { return _indices.size(); } /** get index data by index */ - MeshIndexData* getMeshIndexDataByIndex(int index) const { return _indexs.at(index); } + MeshIndexData* getMeshIndexDataByIndex(int index) const { return _indices.at(index); } /** get index data by id */ MeshIndexData* getMeshIndexDataById(std::string_view id) const; @@ -144,8 +144,8 @@ public: protected: backend::Buffer* _vertexBuffer = nullptr; // vertex buffer ssize_t _sizePerVertex = -1; - Vector _indexs; // index data - std::vector _attribs; // vertex attributes + Vector _indices; // index data + std::vector _attribs; // vertex attributes int _vertexCount = 0; // vertex count std::vector _vertexData; From b32f4d11968cb7be6f6aa6e5216b5eca1cecdf19 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Fri, 1 Jul 2022 14:11:00 +0300 Subject: [PATCH 05/46] Change shorts to ints --- core/3d/CCBundle3D.cpp | 22 +++++++++++----------- core/3d/CCBundle3D.h | 2 +- core/3d/CCBundle3DData.h | 2 +- core/3d/CCMesh.h | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 7133e05b99..28661134ee 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -298,7 +298,7 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, } // split into submesh according to material - std::map> subMeshMap; + std::map> subMeshMap; for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) { int id = mesh.material_ids[k]; @@ -447,7 +447,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) for (unsigned int k = 0; k < meshPartCount; ++k) { - std::vector indexArray; + std::vector indexArray; std::string meshPartid = _binaryReader.readString(); meshData->subMeshIds.push_back(meshPartid); unsigned int nIndexCount; @@ -599,7 +599,7 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) return false; } - std::vector indices; + std::vector indices; indices.resize(nIndexCount); if (_binaryReader.read(&indices[0], 2, nIndexCount) != nIndexCount) { @@ -720,7 +720,7 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) return false; } - std::vector indices; + std::vector indices; indices.resize(nIndexCount); if (_binaryReader.read(&indices[0], 2, nIndexCount) != nIndexCount) { @@ -777,14 +777,14 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) const rapidjson::Value& mesh_part_array = mesh_data[PARTS]; for (rapidjson::SizeType i = 0, mesh_part_array_size = mesh_part_array.Size(); i < mesh_part_array_size; ++i) { - std::vector indexArray; + std::vector indexArray; const rapidjson::Value& mesh_part = mesh_part_array[i]; meshData->subMeshIds.push_back(mesh_part[ID].GetString()); // index_number const rapidjson::Value& indices_val_array = mesh_part[INDICES]; for (rapidjson::SizeType j = 0, indices_val_array_size = indices_val_array.Size(); j < indices_val_array_size; ++j) - indexArray.push_back((unsigned short)indices_val_array[j].GetUint()); + indexArray.push_back((unsigned int)indices_val_array[j].GetUint()); meshData->subMeshIndices.push_back(indexArray); meshData->numIndex = (int)meshData->subMeshIndices.size(); @@ -1185,12 +1185,12 @@ bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) unsigned int indexnum = mesh_data_body_array_0[INDEXNUM].GetUint(); // indices - std::vector indices; + std::vector indices; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) - indices[i] = (unsigned short)indices_val_array[i].GetUint(); + indices[i] = (unsigned int)indices_val_array[i].GetUint(); meshdata->subMeshIndices.push_back(indices); meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); @@ -1239,12 +1239,12 @@ bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) unsigned int indexnum = mesh_submesh_val[INDEXNUM].GetUint(); // indices - std::vector indices; + std::vector indices; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) - indices[j] = (unsigned short)indices_val_array[j].GetUint(); + indices[j] = (unsigned int)indices_val_array[j].GetUint(); meshdata->subMeshIndices.push_back(indices); meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); @@ -2324,7 +2324,7 @@ Bundle3D::~Bundle3D() cocos2d::AABB Bundle3D::calculateAABB(const std::vector& vertex, int stride, - const std::vector& index) + const std::vector& index) { AABB aabb; stride /= 4; diff --git a/core/3d/CCBundle3D.h b/core/3d/CCBundle3D.h index 23f7a34589..e089eb0154 100644 --- a/core/3d/CCBundle3D.h +++ b/core/3d/CCBundle3D.h @@ -113,7 +113,7 @@ public: const char* mtl_basepath = nullptr); // calculate aabb - static AABB calculateAABB(const std::vector& vertex, int stride, const std::vector& index); + static AABB calculateAABB(const std::vector& vertex, int stride, const std::vector& index); Bundle3D(); virtual ~Bundle3D(); diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index e877814287..593dd3affa 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -134,7 +134,7 @@ struct NodeDatas */ struct MeshData { - typedef std::vector IndexArray; + typedef std::vector IndexArray; std::vector vertex; int vertexSizeInFloat; std::vector subMeshIndices; diff --git a/core/3d/CCMesh.h b/core/3d/CCMesh.h index 342e7bfd74..698bdca66b 100644 --- a/core/3d/CCMesh.h +++ b/core/3d/CCMesh.h @@ -64,7 +64,7 @@ class CC_DLL Mesh : public Ref friend class Sprite3D; public: - typedef std::vector IndexArray; + typedef std::vector IndexArray; /**create mesh from positions, normals, and so on, single SubMesh*/ static Mesh* create(const std::vector& positions, const std::vector& normals, From 1ac878881584ed33cd453cc96de0e9885edf80e8 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Fri, 1 Jul 2022 14:40:09 +0300 Subject: [PATCH 06/46] Fix mesh index formatting. --- core/3d/CCMesh.cpp | 15 ++++++++++----- core/3d/CCMesh.h | 6 ++++-- core/3d/CCMeshVertexIndexData.cpp | 15 +++++++++++---- core/3d/CCMeshVertexIndexData.h | 2 +- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/core/3d/CCMesh.cpp b/core/3d/CCMesh.cpp index e89ebb3991..212e41d53d 100644 --- a/core/3d/CCMesh.cpp +++ b/core/3d/CCMesh.cpp @@ -159,7 +159,8 @@ int Mesh::getVertexSizeInBytes() const Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, - const IndexArray& indices) + const IndexArray& indices, + CustomCommand::IndexFormat format) { int perVertexSizeInFloat = 0; std::vector vertices; @@ -210,23 +211,27 @@ Mesh* Mesh::create(const std::vector& positions, vertices.push_back(texs[i * 2 + 1]); } } - return create(vertices, perVertexSizeInFloat, indices, attribs); + return create(vertices, perVertexSizeInFloat, indices, attribs, format); } Mesh* Mesh::create(const std::vector& vertices, int /*perVertexSizeInFloat*/, const IndexArray& indices, - const std::vector& attribs) + const std::vector& attribs, + CustomCommand::IndexFormat format) { MeshData meshdata; meshdata.attribs = attribs; meshdata.vertex = vertices; meshdata.subMeshIndices.push_back(indices); meshdata.subMeshIds.push_back(""); - auto meshvertexdata = MeshVertexData::create(meshdata); + auto meshvertexdata = MeshVertexData::create(meshdata, format); auto indexData = meshvertexdata->getMeshIndexDataByIndex(0); - return create("", indexData); + auto mesh = create("", indexData); + mesh->setIndexFormat(format); + + return mesh; } Mesh* Mesh::create(std::string_view name, MeshIndexData* indexData, MeshSkin* skin) diff --git a/core/3d/CCMesh.h b/core/3d/CCMesh.h index 698bdca66b..2b45b8b522 100644 --- a/core/3d/CCMesh.h +++ b/core/3d/CCMesh.h @@ -69,7 +69,8 @@ public: static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, - const IndexArray& indices); + const IndexArray& indices, + CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); /** * @lua NA @@ -77,7 +78,8 @@ public: static Mesh* create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, - const std::vector& attribs); + const std::vector& attribs, + CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); /** * create mesh diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index ee782f44bb..c486ee7698 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -108,7 +108,7 @@ void MeshVertexData::setVertexData(const std::vector& vertexData) #endif } -MeshVertexData* MeshVertexData::create(const MeshData& meshdata) +MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand::IndexFormat format) { auto vertexdata = new MeshVertexData(); vertexdata->_vertexBuffer = backend::Device::getInstance()->newBuffer( @@ -132,14 +132,21 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata) bool needCalcAABB = (meshdata.subMeshAABB.size() != meshdata.subMeshIndices.size()); for (size_t i = 0, size = meshdata.subMeshIndices.size(); i < size; ++i) { - auto& index = meshdata.subMeshIndices[i]; + auto& index = meshdata.subMeshIndices[i]; + auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); auto indexBuffer = backend::Device::getInstance()->newBuffer( - index.size() * sizeof(index[0]), backend::BufferType::INDEX, backend::BufferUsage::STATIC); + index.size() * indexSize, backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - indexBuffer->updateData((void*)index.data(), index.size() * sizeof(index[0])); + if (format == CustomCommand::IndexFormat::U_SHORT) + { + std::vector shortIndexFormat(index.begin(), index.end()); + indexBuffer->updateData((void*)shortIndexFormat.data(), shortIndexFormat.size() * indexSize); + } + else + indexBuffer->updateData((void*)index.data(), index.size() * indexSize); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; diff --git a/core/3d/CCMeshVertexIndexData.h b/core/3d/CCMeshVertexIndexData.h index 633fb9334b..419db962f4 100644 --- a/core/3d/CCMeshVertexIndexData.h +++ b/core/3d/CCMeshVertexIndexData.h @@ -112,7 +112,7 @@ class CC_DLL MeshVertexData : public Ref public: /**create*/ - static MeshVertexData* create(const MeshData& meshdata); + static MeshVertexData* create(const MeshData& meshdata, CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); /** get vertexbuffer */ backend::Buffer* getVertexBuffer() const { return _vertexBuffer; } From a7a022c48daa0ad083e43b1a87b6bafdccba0b2c Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sat, 2 Jul 2022 18:22:31 +0300 Subject: [PATCH 07/46] Remove buffers stat and add quad mesh shaders. Remove drawn buffers label and Add a simple position_texture_color shader for simple primitives like quads to implement static sprite batching in the future. --- core/3d/CCBundle3DData.h | 2 +- core/3d/CCMesh.cpp | 2 +- core/3d/CCMeshVertexIndexData.cpp | 4 +-- core/3d/CCSprite3DMaterial.cpp | 18 +++++++++- core/3d/CCSprite3DMaterial.h | 5 +++ core/base/CCDirector.cpp | 23 +----------- core/base/CCDirector.h | 1 - core/renderer/CCRenderer.h | 7 +--- core/renderer/backend/ProgramCache.cpp | 1 + core/renderer/backend/Types.h | 2 ++ core/renderer/backend/opengl/BufferGL.cpp | 4 --- core/renderer/backend/opengl/BufferGL.h | 2 -- core/renderer/ccShaders.cpp | 3 ++ core/renderer/ccShaders.h | 3 ++ core/renderer/shaders/sprite.frag | 43 ++++++++++++++++++++++ core/renderer/shaders/sprite.vert | 44 +++++++++++++++++++++++ 16 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 core/renderer/shaders/sprite.frag create mode 100644 core/renderer/shaders/sprite.vert diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 593dd3affa..ed42953771 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -147,7 +147,7 @@ struct MeshData public: /** * Get per vertex size - * @return return the sum of each vertex's all attribute size. + * @return return the sum size of all vertex attributes. */ int getPerVertexSize() const { diff --git a/core/3d/CCMesh.cpp b/core/3d/CCMesh.cpp index 212e41d53d..df2a82744a 100644 --- a/core/3d/CCMesh.cpp +++ b/core/3d/CCMesh.cpp @@ -735,7 +735,7 @@ CustomCommand::PrimitiveType Mesh::getPrimitiveType() const ssize_t Mesh::getIndexCount() const { return _meshIndexData->getIndexBuffer()->getSize() / - (meshIndexFormat == CustomCommand::IndexFormat::U_INT ? sizeof(uint32_t) : sizeof(uint16_t)); + (meshIndexFormat == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t)); } CustomCommand::IndexFormat Mesh::getIndexFormat() const diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index c486ee7698..e893f5d74a 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -142,8 +142,8 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: #endif if (format == CustomCommand::IndexFormat::U_SHORT) { - std::vector shortIndexFormat(index.begin(), index.end()); - indexBuffer->updateData((void*)shortIndexFormat.data(), shortIndexFormat.size() * indexSize); + std::vector shortIndex(index.begin(), index.end()); + indexBuffer->updateData((void*)shortIndex.data(), shortIndex.size() * indexSize); } else indexBuffer->updateData((void*)index.data(), index.size() * indexSize); diff --git a/core/3d/CCSprite3DMaterial.cpp b/core/3d/CCSprite3DMaterial.cpp index 068cdcbb17..d158d93cf8 100644 --- a/core/3d/CCSprite3DMaterial.cpp +++ b/core/3d/CCSprite3DMaterial.cpp @@ -51,6 +51,8 @@ Sprite3DMaterial* Sprite3DMaterial::_vertexLitMaterialSkin = nullptr; Sprite3DMaterial* Sprite3DMaterial::_diffuseMaterialSkin = nullptr; Sprite3DMaterial* Sprite3DMaterial::_bumpedDiffuseMaterialSkin = nullptr; +Sprite3DMaterial* Sprite3DMaterial::_spriteMaterial = nullptr; + backend::ProgramState* Sprite3DMaterial::_unLitMaterialProgState = nullptr; backend::ProgramState* Sprite3DMaterial::_unLitNoTexMaterialProgState = nullptr; backend::ProgramState* Sprite3DMaterial::_vertexLitMaterialProgState = nullptr; @@ -63,6 +65,8 @@ backend::ProgramState* Sprite3DMaterial::_vertexLitMaterialSkinProgState = n backend::ProgramState* Sprite3DMaterial::_diffuseMaterialSkinProgState = nullptr; backend::ProgramState* Sprite3DMaterial::_bumpedDiffuseMaterialSkinProgState = nullptr; +backend::ProgramState* Sprite3DMaterial::_spriteMaterialProgState = nullptr; + void Sprite3DMaterial::createBuiltInMaterial() { auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::SKINPOSITION_TEXTURE_3D); @@ -129,6 +133,14 @@ void Sprite3DMaterial::createBuiltInMaterial() { _bumpedDiffuseMaterialSkin->_type = Sprite3DMaterial::MaterialType::BUMPED_DIFFUSE; } + + program = backend::Program::getBuiltinProgram(backend::ProgramType::SPRITE_TEXTURE_2D); + _spriteMaterialProgState = new backend::ProgramState(program); + _spriteMaterial = new Sprite3DMaterial(); + if (_spriteMaterial && _spriteMaterial->initWithProgramState(_spriteMaterialProgState)) + { + _spriteMaterial->_type = Sprite3DMaterial::MaterialType::SPRITE; + } } void Sprite3DMaterial::releaseBuiltInMaterial() @@ -214,7 +226,7 @@ Sprite3DMaterial* Sprite3DMaterial::createBuiltInMaterial(MaterialType type, boo break; case Sprite3DMaterial::MaterialType::VERTEX_LIT: - CCASSERT(0, "not implement"); + CCASSERT(0, "not implemented"); break; case Sprite3DMaterial::MaterialType::DIFFUSE: @@ -229,6 +241,10 @@ Sprite3DMaterial* Sprite3DMaterial::createBuiltInMaterial(MaterialType type, boo material = skinned ? _bumpedDiffuseMaterialSkin : _bumpedDiffuseMaterial; break; + case Sprite3DMaterial::MaterialType::SPRITE: + material = _spriteMaterial; + break; + default: break; } diff --git a/core/3d/CCSprite3DMaterial.h b/core/3d/CCSprite3DMaterial.h index 8d6473b486..e304fa387f 100644 --- a/core/3d/CCSprite3DMaterial.h +++ b/core/3d/CCSprite3DMaterial.h @@ -63,6 +63,7 @@ public: DIFFUSE, // diffuse (pixel lighting) DIFFUSE_NOTEX, // diffuse (without texture) BUMPED_DIFFUSE, // bumped diffuse + SPRITE, // sprite material // Custom material CUSTOM, // Create from material file @@ -134,6 +135,8 @@ protected: static Sprite3DMaterial* _diffuseMaterialSkin; static Sprite3DMaterial* _bumpedDiffuseMaterialSkin; + static Sprite3DMaterial* _spriteMaterial; + static backend::ProgramState* _unLitMaterialProgState; static backend::ProgramState* _unLitNoTexMaterialProgState; static backend::ProgramState* _vertexLitMaterialProgState; @@ -145,6 +148,8 @@ protected: static backend::ProgramState* _vertexLitMaterialSkinProgState; static backend::ProgramState* _diffuseMaterialSkinProgState; static backend::ProgramState* _bumpedDiffuseMaterialSkinProgState; + + static backend::ProgramState* _spriteMaterialProgState; }; /** diff --git a/core/base/CCDirector.cpp b/core/base/CCDirector.cpp index 2c06b45983..20d636a8e0 100644 --- a/core/base/CCDirector.cpp +++ b/core/base/CCDirector.cpp @@ -153,7 +153,6 @@ Director::~Director() CC_SAFE_RELEASE(_FPSLabel); CC_SAFE_RELEASE(_drawnVerticesLabel); CC_SAFE_RELEASE(_drawnBatchesLabel); - CC_SAFE_RELEASE(_drawnBuffersLabel); CC_SAFE_RELEASE(_runningScene); CC_SAFE_RELEASE(_notificationNode); @@ -1020,7 +1019,6 @@ void Director::reset() CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_drawnBatchesLabel); CC_SAFE_RELEASE_NULL(_drawnVerticesLabel); - CC_SAFE_RELEASE_NULL(_drawnBuffersLabel); // purge bitmap cache FontFNT::purgeCachedData(); @@ -1185,12 +1183,11 @@ void Director::showStats() static uint32_t prevCalls = 0; static uint32_t prevVerts = 0; - static uint32_t prevBuffers = 0; ++_frames; _accumDt += _deltaTime; - if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel && _drawnBuffersLabel) + if (_displayStats && _FPSLabel && _drawnBatchesLabel && _drawnVerticesLabel) { char buffer[30] = {0}; @@ -1207,7 +1204,6 @@ void Director::showStats() auto currentCalls = (uint32_t)_renderer->getDrawnBatches(); auto currentVerts = (uint32_t)_renderer->getDrawnVertices(); - auto currentBuffers = (uint32_t)_renderer->getModifiedBuffers(); if (currentCalls != prevCalls) { sprintf(buffer, "GL calls :%6u", currentCalls); @@ -1222,17 +1218,9 @@ void Director::showStats() prevVerts = currentVerts; } - if (currentBuffers != prevBuffers) - { - sprintf(buffer, "GL buffers:%6u", currentBuffers); - _drawnBuffersLabel->setString(buffer); - prevBuffers = currentBuffers; - } - const Mat4& identity = Mat4::IDENTITY; _drawnVerticesLabel->visit(_renderer, identity, 0); _drawnBatchesLabel->visit(_renderer, identity, 0); - _drawnBuffersLabel->visit(_renderer, identity, 0); _FPSLabel->visit(_renderer, identity, 0); } } @@ -1260,18 +1248,15 @@ void Director::createStatsLabel() std::string fpsString = "00.0"; std::string drawBatchString = "000"; std::string drawVerticesString = "00000"; - std::string drawBuffersString = "000"; if (_FPSLabel) { fpsString = _FPSLabel->getString(); drawBatchString = _drawnBatchesLabel->getString(); drawVerticesString = _drawnVerticesLabel->getString(); - drawBuffersString = _drawnBuffersLabel->getString(); CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_drawnBatchesLabel); CC_SAFE_RELEASE_NULL(_drawnVerticesLabel); - CC_SAFE_RELEASE_NULL(_drawnBuffersLabel); _textureCache->removeTextureForKey("/cc_fps_images"); FileUtils::getInstance()->purgeCachedEntries(); } @@ -1318,14 +1303,8 @@ void Director::createStatsLabel() _drawnVerticesLabel->setIgnoreContentScaleFactor(true); _drawnVerticesLabel->setScale(scaleFactor); - _drawnBuffersLabel = LabelAtlas::create(drawVerticesString, texture, 12, 32, '.'); - _drawnBuffersLabel->retain(); - _drawnBuffersLabel->setIgnoreContentScaleFactor(true); - _drawnBuffersLabel->setScale(scaleFactor); - auto safeOrigin = getSafeAreaRect().origin; const int height_spacing = (int)(22 / CC_CONTENT_SCALE_FACTOR()); - _drawnBuffersLabel->setPosition(Vec2(0, height_spacing * 3.0f) + safeOrigin); _drawnVerticesLabel->setPosition(Vec2(0, height_spacing * 2.0f) + safeOrigin); _drawnBatchesLabel->setPosition(Vec2(0, height_spacing * 1.0f) + safeOrigin); _FPSLabel->setPosition(Vec2(0, height_spacing * 0.0f) + safeOrigin); diff --git a/core/base/CCDirector.h b/core/base/CCDirector.h index fa5f7a9c98..3c4242a37c 100644 --- a/core/base/CCDirector.h +++ b/core/base/CCDirector.h @@ -599,7 +599,6 @@ protected: LabelAtlas* _FPSLabel = nullptr; LabelAtlas* _drawnBatchesLabel = nullptr; LabelAtlas* _drawnVerticesLabel = nullptr; - LabelAtlas* _drawnBuffersLabel = nullptr; /** Whether or not the Director is paused */ bool _paused = false; diff --git a/core/renderer/CCRenderer.h b/core/renderer/CCRenderer.h index 2cc83ff6db..33a6fab0fc 100644 --- a/core/renderer/CCRenderer.h +++ b/core/renderer/CCRenderer.h @@ -176,12 +176,8 @@ public: ssize_t getDrawnVertices() const { return _drawnVertices; } /* RenderCommands (except) TrianglesCommand should update this value */ void addDrawnVertices(ssize_t number) { _drawnVertices += number; }; - /* returns the number of modified gpu buffers in the last frame */ - ssize_t getModifiedBuffers() const { return _modifiedBuffers; } - /* adds a number of modified gpu buffers in the last frame */ - void addModifiedBuffers(ssize_t number) { _modifiedBuffers += number; }; /* clear draw stats */ - void clearDrawStats() { _drawnBatches = _drawnVertices = _modifiedBuffers = 0; } + void clearDrawStats() { _drawnBatches = _drawnVertices = 0; } /** Set render targets. If not set, will use default render targets. It will effect all commands. @@ -542,7 +538,6 @@ protected: // stats size_t _drawnBatches = 0; size_t _drawnVertices = 0; - size_t _modifiedBuffers = 0; // the flag for checking whether renderer is rendering bool _isRendering = false; bool _isDepthTestFor2D = false; diff --git a/core/renderer/backend/ProgramCache.cpp b/core/renderer/backend/ProgramCache.cpp index ba5b8cdfc3..6391f1c686 100644 --- a/core/renderer/backend/ProgramCache.cpp +++ b/core/renderer/backend/ProgramCache.cpp @@ -123,6 +123,7 @@ bool ProgramCache::init() registerProgramFactory(ProgramType::TERRAIN_3D, CC3D_terrain_vert, CC3D_terrain_frag); registerProgramFactory(ProgramType::PARTICLE_TEXTURE_3D, CC3D_particle_vert, CC3D_particleTexture_frag); registerProgramFactory(ProgramType::PARTICLE_COLOR_3D, CC3D_particle_vert, CC3D_particleColor_frag); + registerProgramFactory(ProgramType::SPRITE_TEXTURE_2D, CC2D_sprite_vert, CC2D_spriteTexture_frag); registerProgramFactory(ProgramType::HSV, positionTextureColor_vert, hsv_frag); registerProgramFactory(ProgramType::HSV_DUAL_SAMPLER, positionTextureColor_vert, dualSampler_hsv_frag); diff --git a/core/renderer/backend/Types.h b/core/renderer/backend/Types.h index c54c2637d7..2a204047a6 100644 --- a/core/renderer/backend/Types.h +++ b/core/renderer/backend/Types.h @@ -431,6 +431,8 @@ struct ProgramType PARTICLE_TEXTURE_3D, // CC3D_particle_vert, CC3D_particleTexture_frag PARTICLE_COLOR_3D, // CC3D_particle_vert, CC3D_particleColor_frag + SPRITE_TEXTURE_2D, // CC2D_sprite_vert, CC3D_particle_frag + HSV, HSV_DUAL_SAMPLER, HSV_ETC1 = HSV_DUAL_SAMPLER, diff --git a/core/renderer/backend/opengl/BufferGL.cpp b/core/renderer/backend/opengl/BufferGL.cpp index 5183389edd..81d9f6f1e2 100644 --- a/core/renderer/backend/opengl/BufferGL.cpp +++ b/core/renderer/backend/opengl/BufferGL.cpp @@ -108,8 +108,6 @@ void BufferGL::updateData(void* data, std::size_t size) if (_buffer) { - Director::getInstance()->getRenderer()->addModifiedBuffers(1); - if (BufferType::VERTEX == _type) { glBindBuffer(GL_ARRAY_BUFFER, _buffer); @@ -137,8 +135,6 @@ void BufferGL::updateSubData(void* data, std::size_t offset, std::size_t size) if (_buffer) { - Director::getInstance()->getRenderer()->addModifiedBuffers(1); - CHECK_GL_ERROR_DEBUG(); if (BufferType::VERTEX == _type) { diff --git a/core/renderer/backend/opengl/BufferGL.h b/core/renderer/backend/opengl/BufferGL.h index f78c7796d1..1801cfaa86 100644 --- a/core/renderer/backend/opengl/BufferGL.h +++ b/core/renderer/backend/opengl/BufferGL.h @@ -27,8 +27,6 @@ #include "../Buffer.h" #include "platform/CCGL.h" #include "base/CCEventListenerCustom.h" -#include "base/CCDirector.h" -#include "renderer/CCRenderer.h" #include diff --git a/core/renderer/ccShaders.cpp b/core/renderer/ccShaders.cpp index 0b5cdfb106..5cc0336a4f 100644 --- a/core/renderer/ccShaders.cpp +++ b/core/renderer/ccShaders.cpp @@ -73,4 +73,7 @@ NS_CC_BEGIN #include "renderer/shaders/hsv.frag" #include "renderer/shaders/dualSampler_hsv.frag" +#include "renderer/shaders/sprite.vert" +#include "renderer/shaders/sprite.frag" + NS_CC_END diff --git a/core/renderer/ccShaders.h b/core/renderer/ccShaders.h index 16c00c3800..03b6f1a9a1 100644 --- a/core/renderer/ccShaders.h +++ b/core/renderer/ccShaders.h @@ -78,6 +78,9 @@ extern CC_DLL const char* CC3D_skybox_vert; extern CC_DLL const char* CC3D_terrain_frag; extern CC_DLL const char* CC3D_terrain_vert; +extern CC_DLL const char* CC2D_spriteTexture_frag; +extern CC_DLL const char* CC2D_sprite_vert; + extern CC_DLL const char* hsv_frag; extern CC_DLL const char* dualSampler_hsv_frag; NS_CC_END diff --git a/core/renderer/shaders/sprite.frag b/core/renderer/shaders/sprite.frag new file mode 100644 index 0000000000..19ed7c7ebc --- /dev/null +++ b/core/renderer/shaders/sprite.frag @@ -0,0 +1,43 @@ +/**************************************************************************** + Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. + + https://adxeproject.github.io/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + + +const char* CC2D_spriteTexture_frag = R"( + +#ifdef GL_ES +varying mediump vec2 TextureCoordOut; +varying mediump vec4 ColorOut; +#else +varying vec4 ColorOut; +varying vec2 TextureCoordOut; +#endif +uniform vec4 u_color; + +uniform sampler2D u_texture; + +void main(void) +{ + gl_FragColor = texture2D(u_texture, TextureCoordOut) * ColorOut * u_color; +} +)"; diff --git a/core/renderer/shaders/sprite.vert b/core/renderer/shaders/sprite.vert new file mode 100644 index 0000000000..bdb68e38c7 --- /dev/null +++ b/core/renderer/shaders/sprite.vert @@ -0,0 +1,44 @@ +/**************************************************************************** + Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. + + https://adxeproject.github.io/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + + +const char* CC2D_sprite_vert = R"( + +attribute vec4 a_position; +attribute vec4 a_color; +attribute vec2 a_texCoord; + +varying vec2 TextureCoordOut; +varying vec4 ColorOut; + +uniform mat4 u_PMatrix; +void main() +{ + ColorOut = a_color; + TextureCoordOut = a_texCoord; + TextureCoordOut.y = 1.0 - TextureCoordOut.y; + gl_Position = u_PMatrix * a_position; +} + +)"; From 27c5e9ad8397b7f341eefdc665e99fbec88d7275 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sat, 2 Jul 2022 18:26:17 +0300 Subject: [PATCH 08/46] Update CCDirector.cpp [skip ci] --- core/base/CCDirector.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/base/CCDirector.cpp b/core/base/CCDirector.cpp index 20d636a8e0..9b92b038e6 100644 --- a/core/base/CCDirector.cpp +++ b/core/base/CCDirector.cpp @@ -1206,14 +1206,14 @@ void Director::showStats() auto currentVerts = (uint32_t)_renderer->getDrawnVertices(); if (currentCalls != prevCalls) { - sprintf(buffer, "GL calls :%6u", currentCalls); + sprintf(buffer, "GL calls:%6u", currentCalls); _drawnBatchesLabel->setString(buffer); prevCalls = currentCalls; } if (currentVerts != prevVerts) { - sprintf(buffer, "GL verts :%6u", currentVerts); + sprintf(buffer, "GL verts:%6u", currentVerts); _drawnVerticesLabel->setString(buffer); prevVerts = currentVerts; } From cb7bd4118b70d4109e6f7ae5e0b0ad190c353d65 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sat, 2 Jul 2022 19:46:41 +0300 Subject: [PATCH 09/46] Improve type naming. --- core/3d/CCSprite3DMaterial.cpp | 32 +++++++++++++------ core/3d/CCSprite3DMaterial.h | 9 ++++-- core/renderer/backend/ProgramCache.cpp | 3 +- core/renderer/backend/Types.h | 3 +- core/renderer/ccShaders.cpp | 4 +-- core/renderer/ccShaders.h | 5 +-- .../shaders/{sprite.frag => quad.frag} | 17 +++++++++- .../shaders/{sprite.vert => quad.vert} | 2 +- 8 files changed, 55 insertions(+), 20 deletions(-) rename core/renderer/shaders/{sprite.frag => quad.frag} (86%) rename core/renderer/shaders/{sprite.vert => quad.vert} (97%) diff --git a/core/3d/CCSprite3DMaterial.cpp b/core/3d/CCSprite3DMaterial.cpp index d158d93cf8..d10334a68b 100644 --- a/core/3d/CCSprite3DMaterial.cpp +++ b/core/3d/CCSprite3DMaterial.cpp @@ -51,7 +51,8 @@ Sprite3DMaterial* Sprite3DMaterial::_vertexLitMaterialSkin = nullptr; Sprite3DMaterial* Sprite3DMaterial::_diffuseMaterialSkin = nullptr; Sprite3DMaterial* Sprite3DMaterial::_bumpedDiffuseMaterialSkin = nullptr; -Sprite3DMaterial* Sprite3DMaterial::_spriteMaterial = nullptr; +Sprite3DMaterial* Sprite3DMaterial::_quadTextureMaterial = nullptr; +Sprite3DMaterial* Sprite3DMaterial::_quadColorMaterial = nullptr; backend::ProgramState* Sprite3DMaterial::_unLitMaterialProgState = nullptr; backend::ProgramState* Sprite3DMaterial::_unLitNoTexMaterialProgState = nullptr; @@ -65,7 +66,8 @@ backend::ProgramState* Sprite3DMaterial::_vertexLitMaterialSkinProgState = n backend::ProgramState* Sprite3DMaterial::_diffuseMaterialSkinProgState = nullptr; backend::ProgramState* Sprite3DMaterial::_bumpedDiffuseMaterialSkinProgState = nullptr; -backend::ProgramState* Sprite3DMaterial::_spriteMaterialProgState = nullptr; +backend::ProgramState* Sprite3DMaterial::_quadTextureMaterialProgState = nullptr; +backend::ProgramState* Sprite3DMaterial::_quadColorMaterialProgState = nullptr; void Sprite3DMaterial::createBuiltInMaterial() { @@ -134,12 +136,20 @@ void Sprite3DMaterial::createBuiltInMaterial() _bumpedDiffuseMaterialSkin->_type = Sprite3DMaterial::MaterialType::BUMPED_DIFFUSE; } - program = backend::Program::getBuiltinProgram(backend::ProgramType::SPRITE_TEXTURE_2D); - _spriteMaterialProgState = new backend::ProgramState(program); - _spriteMaterial = new Sprite3DMaterial(); - if (_spriteMaterial && _spriteMaterial->initWithProgramState(_spriteMaterialProgState)) + program = backend::Program::getBuiltinProgram(backend::ProgramType::QUAD_TEXTURE_2D); + _quadTextureMaterialProgState = new backend::ProgramState(program); + _quadTextureMaterial = new Sprite3DMaterial(); + if (_quadTextureMaterial && _quadTextureMaterial->initWithProgramState(_quadTextureMaterialProgState)) { - _spriteMaterial->_type = Sprite3DMaterial::MaterialType::SPRITE; + _quadTextureMaterial->_type = Sprite3DMaterial::MaterialType::QUAD_TEXTURE; + } + + program = backend::Program::getBuiltinProgram(backend::ProgramType::QUAD_COLOR_2D); + _quadColorMaterialProgState = new backend::ProgramState(program); + _quadColorMaterial = new Sprite3DMaterial(); + if (_quadColorMaterial && _quadColorMaterial->initWithProgramState(_quadColorMaterialProgState)) + { + _quadColorMaterial->_type = Sprite3DMaterial::MaterialType::QUAD_COLOR; } } @@ -241,8 +251,12 @@ Sprite3DMaterial* Sprite3DMaterial::createBuiltInMaterial(MaterialType type, boo material = skinned ? _bumpedDiffuseMaterialSkin : _bumpedDiffuseMaterial; break; - case Sprite3DMaterial::MaterialType::SPRITE: - material = _spriteMaterial; + case Sprite3DMaterial::MaterialType::QUAD_TEXTURE: + material = _quadTextureMaterial; + break; + + case Sprite3DMaterial::MaterialType::QUAD_COLOR: + material = _quadColorMaterial; break; default: diff --git a/core/3d/CCSprite3DMaterial.h b/core/3d/CCSprite3DMaterial.h index e304fa387f..dacaf2650a 100644 --- a/core/3d/CCSprite3DMaterial.h +++ b/core/3d/CCSprite3DMaterial.h @@ -63,7 +63,8 @@ public: DIFFUSE, // diffuse (pixel lighting) DIFFUSE_NOTEX, // diffuse (without texture) BUMPED_DIFFUSE, // bumped diffuse - SPRITE, // sprite material + QUAD_TEXTURE, // textured quad material + QUAD_COLOR, // colored quad material (without texture) // Custom material CUSTOM, // Create from material file @@ -135,7 +136,8 @@ protected: static Sprite3DMaterial* _diffuseMaterialSkin; static Sprite3DMaterial* _bumpedDiffuseMaterialSkin; - static Sprite3DMaterial* _spriteMaterial; + static Sprite3DMaterial* _quadTextureMaterial; + static Sprite3DMaterial* _quadColorMaterial; static backend::ProgramState* _unLitMaterialProgState; static backend::ProgramState* _unLitNoTexMaterialProgState; @@ -149,7 +151,8 @@ protected: static backend::ProgramState* _diffuseMaterialSkinProgState; static backend::ProgramState* _bumpedDiffuseMaterialSkinProgState; - static backend::ProgramState* _spriteMaterialProgState; + static backend::ProgramState* _quadTextureMaterialProgState; + static backend::ProgramState* _quadColorMaterialProgState; }; /** diff --git a/core/renderer/backend/ProgramCache.cpp b/core/renderer/backend/ProgramCache.cpp index 6391f1c686..109bb3e3d6 100644 --- a/core/renderer/backend/ProgramCache.cpp +++ b/core/renderer/backend/ProgramCache.cpp @@ -123,7 +123,8 @@ bool ProgramCache::init() registerProgramFactory(ProgramType::TERRAIN_3D, CC3D_terrain_vert, CC3D_terrain_frag); registerProgramFactory(ProgramType::PARTICLE_TEXTURE_3D, CC3D_particle_vert, CC3D_particleTexture_frag); registerProgramFactory(ProgramType::PARTICLE_COLOR_3D, CC3D_particle_vert, CC3D_particleColor_frag); - registerProgramFactory(ProgramType::SPRITE_TEXTURE_2D, CC2D_sprite_vert, CC2D_spriteTexture_frag); + registerProgramFactory(ProgramType::QUAD_COLOR_2D, CC2D_quad_vert, CC2D_quadColor_frag); + registerProgramFactory(ProgramType::QUAD_TEXTURE_2D, CC2D_quad_vert, CC2D_quadTexture_frag); registerProgramFactory(ProgramType::HSV, positionTextureColor_vert, hsv_frag); registerProgramFactory(ProgramType::HSV_DUAL_SAMPLER, positionTextureColor_vert, dualSampler_hsv_frag); diff --git a/core/renderer/backend/Types.h b/core/renderer/backend/Types.h index 2a204047a6..aad618bd00 100644 --- a/core/renderer/backend/Types.h +++ b/core/renderer/backend/Types.h @@ -431,7 +431,8 @@ struct ProgramType PARTICLE_TEXTURE_3D, // CC3D_particle_vert, CC3D_particleTexture_frag PARTICLE_COLOR_3D, // CC3D_particle_vert, CC3D_particleColor_frag - SPRITE_TEXTURE_2D, // CC2D_sprite_vert, CC3D_particle_frag + QUAD_COLOR_2D, // CC2D_quad_vert, CC2D_quadColor_frag + QUAD_TEXTURE_2D, // CC2D_quad_vert, CC2D_quadTexture_frag HSV, HSV_DUAL_SAMPLER, diff --git a/core/renderer/ccShaders.cpp b/core/renderer/ccShaders.cpp index 5cc0336a4f..1e0914d42d 100644 --- a/core/renderer/ccShaders.cpp +++ b/core/renderer/ccShaders.cpp @@ -73,7 +73,7 @@ NS_CC_BEGIN #include "renderer/shaders/hsv.frag" #include "renderer/shaders/dualSampler_hsv.frag" -#include "renderer/shaders/sprite.vert" -#include "renderer/shaders/sprite.frag" +#include "renderer/shaders/quad.vert" +#include "renderer/shaders/quad.frag" NS_CC_END diff --git a/core/renderer/ccShaders.h b/core/renderer/ccShaders.h index 03b6f1a9a1..6168d29b21 100644 --- a/core/renderer/ccShaders.h +++ b/core/renderer/ccShaders.h @@ -78,8 +78,9 @@ extern CC_DLL const char* CC3D_skybox_vert; extern CC_DLL const char* CC3D_terrain_frag; extern CC_DLL const char* CC3D_terrain_vert; -extern CC_DLL const char* CC2D_spriteTexture_frag; -extern CC_DLL const char* CC2D_sprite_vert; +extern CC_DLL const char* CC2D_quadTexture_frag; +extern CC_DLL const char* CC2D_quadColor_frag; +extern CC_DLL const char* CC2D_quad_vert; extern CC_DLL const char* hsv_frag; extern CC_DLL const char* dualSampler_hsv_frag; diff --git a/core/renderer/shaders/sprite.frag b/core/renderer/shaders/quad.frag similarity index 86% rename from core/renderer/shaders/sprite.frag rename to core/renderer/shaders/quad.frag index 19ed7c7ebc..9a9cf0872d 100644 --- a/core/renderer/shaders/sprite.frag +++ b/core/renderer/shaders/quad.frag @@ -23,7 +23,7 @@ ****************************************************************************/ -const char* CC2D_spriteTexture_frag = R"( +const char* CC2D_quadTexture_frag = R"( #ifdef GL_ES varying mediump vec2 TextureCoordOut; @@ -41,3 +41,18 @@ void main(void) gl_FragColor = texture2D(u_texture, TextureCoordOut) * ColorOut * u_color; } )"; + +const char* CC2D_quadColor_frag = R"( + +#ifdef GL_ES +varying mediump vec4 ColorOut; +#else +varying vec4 ColorOut; +#endif +uniform vec4 u_color; + +void main(void) +{ + gl_FragColor = ColorOut * u_color; +} +)"; diff --git a/core/renderer/shaders/sprite.vert b/core/renderer/shaders/quad.vert similarity index 97% rename from core/renderer/shaders/sprite.vert rename to core/renderer/shaders/quad.vert index bdb68e38c7..02d3aaaf9f 100644 --- a/core/renderer/shaders/sprite.vert +++ b/core/renderer/shaders/quad.vert @@ -23,7 +23,7 @@ ****************************************************************************/ -const char* CC2D_sprite_vert = R"( +const char* CC2D_quad_vert = R"( attribute vec4 a_position; attribute vec4 a_color; From 8eea4cccdcfa5d1998beda36e5fd78b5768ebf5d Mon Sep 17 00:00:00 2001 From: halx99 Date: Sun, 3 Jul 2022 17:24:10 +0800 Subject: [PATCH 10/46] [WIP] Wrapper IndexArray with byte_buffer --- core/3d/CCBundle3D.cpp | 107 ++++++++++++++++-------- core/3d/CCBundle3D.h | 13 ++- core/3d/CCBundle3DData.h | 54 +++++++++++- core/3d/CCMesh.h | 2 +- core/3d/CCMeshVertexIndexData.cpp | 10 +-- thirdparty/yasio/detail/byte_buffer.hpp | 36 +++++--- thirdparty/yasio/detail/ifaddrs.hpp | 8 +- 7 files changed, 166 insertions(+), 64 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 28661134ee..5bdd80da39 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -205,7 +205,8 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeDatas& nodedatas, std::string_view fullPath, - const char* mtl_basepath) + const char* mtl_basepath, + CustomCommand::IndexFormat format) { meshdatas.resetData(); materialdatas.resetData(); @@ -298,14 +299,28 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, } // split into submesh according to material - std::map> subMeshMap; - for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) + std::map subMeshMap; + if (format == CustomCommand::IndexFormat::U_SHORT) { - int id = mesh.material_ids[k]; - size_t idx = k * 3; - subMeshMap[id].push_back(mesh.indices[idx]); - subMeshMap[id].push_back(mesh.indices[idx + 1]); - subMeshMap[id].push_back(mesh.indices[idx + 2]); + for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) + { + int id = mesh.material_ids[k]; + size_t idx = k * 3; + subMeshMap[id].push_back(mesh.indices[idx]); + subMeshMap[id].push_back(mesh.indices[idx + 1]); + subMeshMap[id].push_back(mesh.indices[idx + 2]); + } + } + else + { + for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) + { + int id = mesh.material_ids[k]; + size_t idx = k * 3; + subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); + } } auto node = new NodeData(); @@ -314,7 +329,7 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, { meshdata->subMeshIndices.push_back(submesh.second); meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second, format)); sprintf(str, "%d", ++i); meshdata->subMeshIds.push_back(str); @@ -362,7 +377,8 @@ bool Bundle3D::loadAnimationData(std::string_view id, Animation3DData* animation } // since 3.3, to support reskin -bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) +bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas, + CustomCommand::IndexFormat format) { meshdatas.resetData(); if (_isBinary) @@ -373,7 +389,7 @@ bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) } else { - return loadMeshDatasBinary(meshdatas); + return loadMeshDatasBinary(meshdatas, format); } } else @@ -389,7 +405,7 @@ bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) } return true; } -bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) +bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas, CustomCommand::IndexFormat format) { if (!seekToFirstType(BUNDLE_TYPE_MESH)) return false; @@ -447,7 +463,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) for (unsigned int k = 0; k < meshPartCount; ++k) { - std::vector indexArray; + IndexArray indexArray; std::string meshPartid = _binaryReader.readString(); meshData->subMeshIds.push_back(meshPartid); unsigned int nIndexCount; @@ -457,7 +473,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) goto FAILED; } indexArray.resize(nIndexCount); - if (_binaryReader.read(&indexArray[0], 2, nIndexCount) != nIndexCount) + if (_binaryReader.read(indexArray.data(), 2, nIndexCount) != nIndexCount) { CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); goto FAILED; @@ -480,7 +496,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray, format)); } } meshdatas.meshDatas.push_back(meshData); @@ -599,9 +615,9 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) return false; } - std::vector indices; + IndexArray indices; indices.resize(nIndexCount); - if (_binaryReader.read(&indices[0], 2, nIndexCount) != nIndexCount) + if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) { CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); CC_SAFE_DELETE(meshdata); @@ -609,7 +625,7 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) } meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); } meshdatas.meshDatas.push_back(meshdata); @@ -720,9 +736,9 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) return false; } - std::vector indices; + IndexArray indices; indices.resize(nIndexCount); - if (_binaryReader.read(&indices[0], 2, nIndexCount) != nIndexCount) + if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) { CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); CC_SAFE_DELETE(meshdata); @@ -730,7 +746,7 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) } meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); } meshdatas.meshDatas.push_back(meshdata); @@ -777,7 +793,7 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) const rapidjson::Value& mesh_part_array = mesh_data[PARTS]; for (rapidjson::SizeType i = 0, mesh_part_array_size = mesh_part_array.Size(); i < mesh_part_array_size; ++i) { - std::vector indexArray; + IndexArray indexArray; const rapidjson::Value& mesh_part = mesh_part_array[i]; meshData->subMeshIds.push_back(mesh_part[ID].GetString()); // index_number @@ -805,13 +821,13 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray, CustomCommand::IndexFormat::U_SHORT)); } } else { - meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), + indexArray, CustomCommand::IndexFormat::U_SHORT)); } } meshdatas.meshDatas.push_back(meshData); @@ -1185,15 +1201,16 @@ bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) unsigned int indexnum = mesh_data_body_array_0[INDEXNUM].GetUint(); // indices - std::vector indices; + IndexArray indices; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) - indices[i] = (unsigned int)indices_val_array[i].GetUint(); + indices[i] = (unsigned short)indices_val_array[i].GetUint(); meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + meshdata->subMeshAABB.push_back( + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); meshdatas.meshDatas.push_back(meshdata); return true; } @@ -1239,15 +1256,16 @@ bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) unsigned int indexnum = mesh_submesh_val[INDEXNUM].GetUint(); // indices - std::vector indices; + IndexArray indices; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) - indices[j] = (unsigned int)indices_val_array[j].GetUint(); + indices[j] = (unsigned short)indices_val_array[j].GetUint(); meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, + CustomCommand::IndexFormat::U_SHORT)); } meshdatas.meshDatas.push_back(meshdata); return true; @@ -2324,14 +2342,33 @@ Bundle3D::~Bundle3D() cocos2d::AABB Bundle3D::calculateAABB(const std::vector& vertex, int stride, - const std::vector& index) + const IndexArray& index, + CustomCommand::IndexFormat format) { AABB aabb; stride /= 4; - for (const auto& it : index) + // for (const auto& it : index) + // { + // Vec3 point(vertex[it * stride], vertex[it * stride + 1], vertex[it * stride + 2]); + // aabb.updateMinMax(&point, 1); + // } + if (format == CustomCommand::IndexFormat::U_SHORT) { - Vec3 point(vertex[it * stride], vertex[it * stride + 1], vertex[it * stride + 2]); - aabb.updateMinMax(&point, 1); + for (auto it = (const u_short*)index.begin(); it != (const u_short*)index.end(); ++it) + { + auto val = *it; + Vec3 point(vertex[val * stride], vertex[val * stride + 1], vertex[val * stride + 2]); + aabb.updateMinMax(&point, 1); + } + } + else + { + for (auto it = (const unsigned int*)index.begin(); it != (const unsigned int*)index.end(); ++it) + { + auto val = *it; + Vec3 point(vertex[val * stride], vertex[val * stride + 1], vertex[val * stride + 2]); + aabb.updateMinMax(&point, 1); + } } return aabb; } diff --git a/core/3d/CCBundle3D.h b/core/3d/CCBundle3D.h index e089eb0154..cafb5aa954 100644 --- a/core/3d/CCBundle3D.h +++ b/core/3d/CCBundle3D.h @@ -93,7 +93,8 @@ public: virtual bool loadAnimationData(std::string_view id, Animation3DData* animationdata); // since 3.3, to support reskin - virtual bool loadMeshDatas(MeshDatas& meshdatas); + virtual bool loadMeshDatas(MeshDatas& meshdatas, + CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); // since 3.3, to support reskin virtual bool loadNodes(NodeDatas& nodedatas); // since 3.3, to support reskin @@ -110,10 +111,13 @@ public: MaterialDatas& materialdatas, NodeDatas& nodedatas, std::string_view fullPath, - const char* mtl_basepath = nullptr); + const char* mtl_basepath = nullptr, + CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); // calculate aabb - static AABB calculateAABB(const std::vector& vertex, int stride, const std::vector& index); + static AABB calculateAABB(const std::vector& vertex, + int stride, + const IndexArray& index, CustomCommand::IndexFormat format); Bundle3D(); virtual ~Bundle3D(); @@ -123,7 +127,8 @@ protected: bool loadMeshDatasJson(MeshDatas& meshdatas); bool loadMeshDataJson_0_1(MeshDatas& meshdatas); bool loadMeshDataJson_0_2(MeshDatas& meshdatas); - bool loadMeshDatasBinary(MeshDatas& meshdatas); + bool loadMeshDatasBinary( + MeshDatas& meshdatas, CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); bool loadMeshDatasBinary_0_1(MeshDatas& meshdatas); bool loadMeshDatasBinary_0_2(MeshDatas& meshdatas); bool loadMaterialsJson(MaterialDatas& materialdatas); diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index ed42953771..260b85895e 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -39,8 +39,59 @@ #include "3d/CC3DProgramInfo.h" +#include "yasio/detail/byte_buffer.hpp" + NS_CC_BEGIN +class IndexArray +{ +public: + IndexArray() {} + IndexArray(std::initializer_list rhs) : _buffer(rhs) {} + + IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _buffer(rhs) {} + + void push_back(u_short val) { _buffer.append_n((uint8_t*)&val, sizeof(val)); } + + void push_back(unsigned int val, std::true_type /*U_INT*/) { _buffer.append_n((uint8_t*)&val, sizeof(val)); } + + void insert(uint8_t* where, std::initializer_list ilist) + { + _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); + } + + void insert(uint8_t* where, std::initializer_list ilist, std::true_type) + { + _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); + } + + template + void insert(uint8_t* where, _Iter first, const _Iter last) + { + _buffer.insert(where, first, last); + } + + u_short& operator[](size_t index) { return (u_short&) _buffer[index * sizeof(u_short)]; } + + uint8_t* begin() noexcept { return _buffer.begin(); } + uint8_t* end() noexcept { return _buffer.end(); } + const uint8_t* begin() const noexcept { return _buffer.begin(); } + const uint8_t* end() const noexcept { return _buffer.end(); } + + uint8_t* data() noexcept { return _buffer.data(); } + const uint8_t* data() const noexcept { return _buffer.data(); } + + size_t size() const { return _buffer.size(); } + + void resize(size_t size) { _buffer.resize(size * sizeof(u_short)); } + void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(unsigned int)); } + + void clear() { _buffer.clear(); } + +protected: + yasio::byte_buffer _buffer; +}; + /**mesh vertex attribute * @js NA * @lua NA @@ -128,13 +179,14 @@ struct NodeDatas } }; + /**mesh data * @js NA * @lua NA */ struct MeshData { - typedef std::vector IndexArray; + using IndexArray = ::cocos2d::IndexArray; std::vector vertex; int vertexSizeInFloat; std::vector subMeshIndices; diff --git a/core/3d/CCMesh.h b/core/3d/CCMesh.h index 2b45b8b522..1a918e7fd4 100644 --- a/core/3d/CCMesh.h +++ b/core/3d/CCMesh.h @@ -64,7 +64,7 @@ class CC_DLL Mesh : public Ref friend class Sprite3D; public: - typedef std::vector IndexArray; + /**create mesh from positions, normals, and so on, single SubMesh*/ static Mesh* create(const std::vector& positions, const std::vector& normals, diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index e893f5d74a..0eb5447bd3 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -140,19 +140,13 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - if (format == CustomCommand::IndexFormat::U_SHORT) - { - std::vector shortIndex(index.begin(), index.end()); - indexBuffer->updateData((void*)shortIndex.data(), shortIndex.size() * indexSize); - } - else - indexBuffer->updateData((void*)index.data(), index.size() * indexSize); + indexBuffer->updateData((void*)index.data(), index.size()/* * indexSize*/); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; if (needCalcAABB) { - auto aabb = Bundle3D::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index); + auto aabb = Bundle3D::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index, format); indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, aabb); } else diff --git a/thirdparty/yasio/detail/byte_buffer.hpp b/thirdparty/yasio/detail/byte_buffer.hpp index 2afa9d0563..67a68c6724 100644 --- a/thirdparty/yasio/detail/byte_buffer.hpp +++ b/thirdparty/yasio/detail/byte_buffer.hpp @@ -41,6 +41,7 @@ The byte_buffer concepts: #include #include #include +#include #include "yasio/compiler/feature_test.hpp" namespace yasio @@ -48,9 +49,10 @@ namespace yasio struct default_allocator { static void* reallocate(void* old_block, size_t /*old_size*/, size_t new_size) { return ::realloc(old_block, new_size); } }; -template class basic_byte_buffer final { +template class basic_byte_buffer { static_assert(std::is_same<_Elem, char>::value || std::is_same<_Elem, unsigned char>::value, "The basic_byte_buffer only accept type which is char or unsigned char!"); + public: using pointer = _Elem*; using const_pointer = const _Elem*; @@ -61,20 +63,30 @@ public: basic_byte_buffer(size_t count, std::true_type /*fit*/) { resize_fit(count); } basic_byte_buffer(size_t count, _Elem val) { resize(count, val); } basic_byte_buffer(size_t count, _Elem val, std::true_type /*fit*/) { resize_fit(count, val); } - template basic_byte_buffer(_Iter first, _Iter last) { _Assign_range(first, last); } - template basic_byte_buffer(_Iter first, _Iter last, std::true_type /*fit*/) { _Assign_range(first, last, std::true_type{}); } - basic_byte_buffer(const basic_byte_buffer& rhs) { _Assign_range(rhs.begin(), rhs.end()); }; - basic_byte_buffer(const basic_byte_buffer& rhs, std::true_type /*fit*/) { _Assign_range(rhs.begin(), rhs.end(), std::true_type{}); }; - basic_byte_buffer(basic_byte_buffer&& rhs) noexcept { _Assign_rv(std::move(rhs)); } + template basic_byte_buffer(_Iter first, _Iter last) { assign(first, last); } + template basic_byte_buffer(_Iter first, _Iter last, std::true_type /*fit*/) { assign(first, last, std::true_type{}); } + basic_byte_buffer(const basic_byte_buffer& rhs) { assign(rhs); }; + basic_byte_buffer(const basic_byte_buffer& rhs, std::true_type /*fit*/) { assign(rhs, std::true_type{}); }; + basic_byte_buffer(basic_byte_buffer&& rhs) noexcept { assign(std::move(rhs)); } + template basic_byte_buffer(std::initializer_list<_Ty> rhs) { assign(rhs); } + template basic_byte_buffer(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) { assign(rhs, std::true_type{}); } ~basic_byte_buffer() { shrink_to_fit(0); } - basic_byte_buffer& operator=(const basic_byte_buffer& rhs) { return assign(rhs.begin(), rhs.end()); } - basic_byte_buffer& operator=(basic_byte_buffer&& rhs) noexcept { return this->swap(rhs); } - template basic_byte_buffer& assign(const _Iter first, const _Iter last) + basic_byte_buffer& operator=(const basic_byte_buffer& rhs) { - clear(); - _Assign_range(first, last); + assign(rhs); return *this; } + basic_byte_buffer& operator=(basic_byte_buffer&& rhs) noexcept { return this->swap(rhs); } + template void assign(const _Iter first, const _Iter last) { _Assign_range(first, last); } + template void assign(const _Iter first, const _Iter last, std::true_type /*fit*/) { _Assign_range(first, last, std::true_type{}); } + void assign(const basic_byte_buffer& rhs) { _Assign_range(rhs.begin(), rhs.end()); } + void assign(const basic_byte_buffer& rhs, std::true_type) { _Assign_range(rhs.begin(), rhs.end(), std::true_type{}); } + void assign(basic_byte_buffer&& rhs) { _Assign_rv(std::move(rhs)); } + template void assign(std::initializer_list<_Ty> rhs) { _Assign_range((_Elem*)rhs.begin(), (_Elem*)rhs.end()); } + template void assign(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) + { + _Assign_range((_Elem*)rhs.begin(), (_Elem*)rhs.end(), std::true_type{}); + } basic_byte_buffer& swap(basic_byte_buffer& rhs) noexcept { char _Tmp[sizeof(rhs)]; @@ -217,11 +229,13 @@ public: private: template void _Assign_range(_Iter first, _Iter last) { + _Mylast = _Myfirst; if (last > first) std::copy(first, last, resize(std::distance(first, last))); } template void _Assign_range(_Iter first, _Iter last, std::true_type) { + _Mylast = _Myfirst; if (last > first) std::copy(first, last, resize_fit(std::distance(first, last))); } diff --git a/thirdparty/yasio/detail/ifaddrs.hpp b/thirdparty/yasio/detail/ifaddrs.hpp index 1df6135139..7584bd730a 100644 --- a/thirdparty/yasio/detail/ifaddrs.hpp +++ b/thirdparty/yasio/detail/ifaddrs.hpp @@ -372,7 +372,7 @@ static int open_netlink_session(netlink_session* session) assert(session != 0); memset(session, 0, sizeof(*session)); - session->sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + session->sock_fd = ::socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (session->sock_fd == -1) { YASIO_LOG("Failed to create a netlink socket. %s", strerror(errno)); @@ -392,7 +392,7 @@ static int open_netlink_session(netlink_session* session) session->them.nl_family = AF_NETLINK; - if (bind(session->sock_fd, (struct sockaddr*)&session->us, sizeof(session->us)) < 0) + if (::bind(session->sock_fd, (struct sockaddr*)&session->us, sizeof(session->us)) < 0) { YASIO_LOG("Failed to bind to the netlink socket. %s", strerror(errno)); return -1; @@ -430,7 +430,7 @@ static int send_netlink_dump_request(netlink_session* session, int type) session->message_header.msg_iovlen = 1; session->message_header.msg_iov = &session->payload_vector; - if (sendmsg(session->sock_fd, (const struct msghdr*)&session->message_header, 0) < 0) + if (::sendmsg(session->sock_fd, (const struct msghdr*)&session->message_header, 0) < 0) { YASIO_LOG("Failed to send netlink message. %s", strerror(errno)); return -1; @@ -510,7 +510,7 @@ static int parse_netlink_reply(netlink_session* session, struct ifaddrs** ifaddr netlink_reply.msg_iovlen = 1; netlink_reply.msg_iov = &reply_vector; - length = recvmsg(session->sock_fd, &netlink_reply, 0); + length = ::recvmsg(session->sock_fd, &netlink_reply, 0); YASIO_LOGV(" length == %d", static_cast(length)); if (length < 0) From 0e99b4ece047777f3f967c3b4c8a5f1d5a17c166 Mon Sep 17 00:00:00 2001 From: halx99 Date: Sun, 3 Jul 2022 21:17:49 +0800 Subject: [PATCH 11/46] Improve class IndexArray --- core/3d/CCBundle3D.cpp | 93 ++++++++++--------------------- core/3d/CCBundle3D.h | 12 ++-- core/3d/CCBundle3DData.h | 74 +++++++++++++++++++----- core/3d/CCMesh.cpp | 12 ++-- core/3d/CCMesh.h | 6 +- core/3d/CCMeshVertexIndexData.cpp | 10 ++-- core/renderer/backend/Types.h | 3 +- 7 files changed, 107 insertions(+), 103 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 5bdd80da39..2c59fb9d1a 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -205,8 +205,7 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeDatas& nodedatas, std::string_view fullPath, - const char* mtl_basepath, - CustomCommand::IndexFormat format) + const char* mtl_basepath) { meshdatas.resetData(); materialdatas.resetData(); @@ -300,27 +299,13 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, // split into submesh according to material std::map subMeshMap; - if (format == CustomCommand::IndexFormat::U_SHORT) + for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) { - for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) - { - int id = mesh.material_ids[k]; - size_t idx = k * 3; - subMeshMap[id].push_back(mesh.indices[idx]); - subMeshMap[id].push_back(mesh.indices[idx + 1]); - subMeshMap[id].push_back(mesh.indices[idx + 2]); - } - } - else - { - for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) - { - int id = mesh.material_ids[k]; - size_t idx = k * 3; - subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); - } + int id = mesh.material_ids[k]; + size_t idx = k * 3; + subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); } auto node = new NodeData(); @@ -329,7 +314,7 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, { meshdata->subMeshIndices.push_back(submesh.second); meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second, format)); + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); sprintf(str, "%d", ++i); meshdata->subMeshIds.push_back(str); @@ -377,8 +362,7 @@ bool Bundle3D::loadAnimationData(std::string_view id, Animation3DData* animation } // since 3.3, to support reskin -bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas, - CustomCommand::IndexFormat format) +bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) { meshdatas.resetData(); if (_isBinary) @@ -389,7 +373,7 @@ bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas, } else { - return loadMeshDatasBinary(meshdatas, format); + return loadMeshDatasBinary(meshdatas); } } else @@ -405,7 +389,7 @@ bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas, } return true; } -bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas, CustomCommand::IndexFormat format) +bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) { if (!seekToFirstType(BUNDLE_TYPE_MESH)) return false; @@ -463,7 +447,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas, CustomCommand::IndexFor for (unsigned int k = 0; k < meshPartCount; ++k) { - IndexArray indexArray; + IndexArray indexArray{CustomCommand::IndexFormat::U_SHORT}; // TODO: _version == 1.3 use U_INT? std::string meshPartid = _binaryReader.readString(); meshData->subMeshIds.push_back(meshPartid); unsigned int nIndexCount; @@ -496,7 +480,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas, CustomCommand::IndexFor else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray, format)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); } } meshdatas.meshDatas.push_back(meshData); @@ -625,7 +609,7 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) } meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); } meshdatas.meshDatas.push_back(meshdata); @@ -736,7 +720,7 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) return false; } - IndexArray indices; + IndexArray indices{CustomCommand::IndexFormat::U_SHORT}; /* TODO: _version == 1.3 use U_INT?*/ indices.resize(nIndexCount); if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) { @@ -746,7 +730,7 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) } meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); } meshdatas.meshDatas.push_back(meshdata); @@ -821,13 +805,13 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray, CustomCommand::IndexFormat::U_SHORT)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); } } else { meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), - indexArray, CustomCommand::IndexFormat::U_SHORT)); + indexArray)); } } meshdatas.meshDatas.push_back(meshData); @@ -1206,11 +1190,11 @@ bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) - indices[i] = (unsigned short)indices_val_array[i].GetUint(); + indices.at(i) = (unsigned short)indices_val_array[i].GetUint(); meshdata->subMeshIndices.push_back(indices); meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, CustomCommand::IndexFormat::U_SHORT)); + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); meshdatas.meshDatas.push_back(meshdata); return true; } @@ -1261,11 +1245,10 @@ bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) - indices[j] = (unsigned short)indices_val_array[j].GetUint(); + indices.at(j) = (unsigned short)indices_val_array[j].GetUint(); meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices, - CustomCommand::IndexFormat::U_SHORT)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); } meshdatas.meshDatas.push_back(meshdata); return true; @@ -2342,34 +2325,16 @@ Bundle3D::~Bundle3D() cocos2d::AABB Bundle3D::calculateAABB(const std::vector& vertex, int stride, - const IndexArray& index, - CustomCommand::IndexFormat format) + const IndexArray& indices) { AABB aabb; stride /= 4; - // for (const auto& it : index) - // { - // Vec3 point(vertex[it * stride], vertex[it * stride + 1], vertex[it * stride + 2]); - // aabb.updateMinMax(&point, 1); - // } - if (format == CustomCommand::IndexFormat::U_SHORT) - { - for (auto it = (const u_short*)index.begin(); it != (const u_short*)index.end(); ++it) - { - auto val = *it; - Vec3 point(vertex[val * stride], vertex[val * stride + 1], vertex[val * stride + 2]); - aabb.updateMinMax(&point, 1); - } - } - else - { - for (auto it = (const unsigned int*)index.begin(); it != (const unsigned int*)index.end(); ++it) - { - auto val = *it; - Vec3 point(vertex[val * stride], vertex[val * stride + 1], vertex[val * stride + 2]); - aabb.updateMinMax(&point, 1); - } - } + + indices.for_each ([&](uint32_t i) { + Vec3 point(vertex[i * stride], vertex[i * stride + 1], vertex[i * stride + 2]); + aabb.updateMinMax(&point, 1); + }); + return aabb; } diff --git a/core/3d/CCBundle3D.h b/core/3d/CCBundle3D.h index cafb5aa954..a2f1fa3cb1 100644 --- a/core/3d/CCBundle3D.h +++ b/core/3d/CCBundle3D.h @@ -93,8 +93,7 @@ public: virtual bool loadAnimationData(std::string_view id, Animation3DData* animationdata); // since 3.3, to support reskin - virtual bool loadMeshDatas(MeshDatas& meshdatas, - CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); + virtual bool loadMeshDatas(MeshDatas& meshdatas); // since 3.3, to support reskin virtual bool loadNodes(NodeDatas& nodedatas); // since 3.3, to support reskin @@ -111,13 +110,11 @@ public: MaterialDatas& materialdatas, NodeDatas& nodedatas, std::string_view fullPath, - const char* mtl_basepath = nullptr, - CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); + const char* mtl_basepath = nullptr); // calculate aabb static AABB calculateAABB(const std::vector& vertex, - int stride, - const IndexArray& index, CustomCommand::IndexFormat format); + int stride, const IndexArray& indices); Bundle3D(); virtual ~Bundle3D(); @@ -127,8 +124,7 @@ protected: bool loadMeshDatasJson(MeshDatas& meshdatas); bool loadMeshDataJson_0_1(MeshDatas& meshdatas); bool loadMeshDataJson_0_2(MeshDatas& meshdatas); - bool loadMeshDatasBinary( - MeshDatas& meshdatas, CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); + bool loadMeshDatasBinary(MeshDatas& meshdatas); bool loadMeshDatasBinary_0_1(MeshDatas& meshdatas); bool loadMeshDatasBinary_0_2(MeshDatas& meshdatas); bool loadMaterialsJson(MaterialDatas& materialdatas); diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 260b85895e..666755dca8 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -46,32 +46,58 @@ NS_CC_BEGIN class IndexArray { public: - IndexArray() {} - IndexArray(std::initializer_list rhs) : _buffer(rhs) {} + IndexArray() : _format(backend::IndexFormat::U_SHORT) {} + IndexArray(backend::IndexFormat format) : _format(format) {} + IndexArray(std::initializer_list rhs) : _format(backend::IndexFormat::U_SHORT), _buffer(rhs) {} - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _buffer(rhs) {} + IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) + : _format(backend::IndexFormat::U_INT), _buffer(rhs) + {} - void push_back(u_short val) { _buffer.append_n((uint8_t*)&val, sizeof(val)); } + void clear(backend::IndexFormat format = backend::IndexFormat::UNSPEC) + { + _buffer.clear(); + if (format != backend::IndexFormat::UNSPEC) + _format = format; + } - void push_back(unsigned int val, std::true_type /*U_INT*/) { _buffer.append_n((uint8_t*)&val, sizeof(val)); } + void push_back(u_short val) + { + assert(_format == backend::IndexFormat::U_SHORT); + _buffer.append_n((uint8_t*)&val, sizeof(val)); + } + + void push_back(unsigned int val, std::true_type /*U_INT*/) + { + assert(_format == backend::IndexFormat::U_INT); + _buffer.append_n((uint8_t*)&val, sizeof(val)); + } void insert(uint8_t* where, std::initializer_list ilist) { + assert(_format == backend::IndexFormat::U_SHORT); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } void insert(uint8_t* where, std::initializer_list ilist, std::true_type) { + assert(_format == backend::IndexFormat::U_INT); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } - template - void insert(uint8_t* where, _Iter first, const _Iter last) - { - _buffer.insert(where, first, last); - } + //template + //void insert(uint8_t* where, _Iter first, const _Iter last) + //{ + // _buffer.insert(where, first, last); + //} - u_short& operator[](size_t index) { return (u_short&) _buffer[index * sizeof(u_short)]; } + template + _Ty& at(size_t idx) + { + assert((sizeof(_Ty) == sizeof(uint16_t) && _format == backend::IndexFormat::U_SHORT) || + (sizeof(_Ty) == sizeof(uint32_t) && _format == backend::IndexFormat::U_INT)); + return (_Ty&)_buffer[idx * sizeof(_Ty)]; + } uint8_t* begin() noexcept { return _buffer.begin(); } uint8_t* end() noexcept { return _buffer.end(); } @@ -83,12 +109,32 @@ public: size_t size() const { return _buffer.size(); } - void resize(size_t size) { _buffer.resize(size * sizeof(u_short)); } - void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(unsigned int)); } + void resize(size_t size) { _buffer.resize(size * sizeof(uint16_t)); } + void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(uint32_t)); } - void clear() { _buffer.clear(); } + backend::IndexFormat format() const { return _format; } + + template + void for_each(_Fty cb) const + { + if (_format == backend::IndexFormat::U_SHORT) + { + for (auto it = (uint16_t*)_buffer.begin(); it != (uint16_t*)_buffer.end(); ++it) + { + cb(static_cast(*it)); + } + } + else if (_format == backend::IndexFormat::U_INT) + { + for (auto it = (uint32_t*)_buffer.begin(); it != (uint32_t*)_buffer.end(); ++it) + { + cb(*it); + } + } + } protected: + backend::IndexFormat _format; yasio::byte_buffer _buffer; }; diff --git a/core/3d/CCMesh.cpp b/core/3d/CCMesh.cpp index df2a82744a..28ea51deb6 100644 --- a/core/3d/CCMesh.cpp +++ b/core/3d/CCMesh.cpp @@ -159,8 +159,7 @@ int Mesh::getVertexSizeInBytes() const Mesh* Mesh::create(const std::vector& positions, const std::vector& normals, const std::vector& texs, - const IndexArray& indices, - CustomCommand::IndexFormat format) + const IndexArray& indices) { int perVertexSizeInFloat = 0; std::vector vertices; @@ -211,25 +210,24 @@ Mesh* Mesh::create(const std::vector& positions, vertices.push_back(texs[i * 2 + 1]); } } - return create(vertices, perVertexSizeInFloat, indices, attribs, format); + return create(vertices, perVertexSizeInFloat, indices, attribs); } Mesh* Mesh::create(const std::vector& vertices, int /*perVertexSizeInFloat*/, const IndexArray& indices, - const std::vector& attribs, - CustomCommand::IndexFormat format) + const std::vector& attribs) { MeshData meshdata; meshdata.attribs = attribs; meshdata.vertex = vertices; meshdata.subMeshIndices.push_back(indices); meshdata.subMeshIds.push_back(""); - auto meshvertexdata = MeshVertexData::create(meshdata, format); + auto meshvertexdata = MeshVertexData::create(meshdata, indices.format()); auto indexData = meshvertexdata->getMeshIndexDataByIndex(0); auto mesh = create("", indexData); - mesh->setIndexFormat(format); + mesh->setIndexFormat(indices.format()); return mesh; } diff --git a/core/3d/CCMesh.h b/core/3d/CCMesh.h index 1a918e7fd4..8c06727fa2 100644 --- a/core/3d/CCMesh.h +++ b/core/3d/CCMesh.h @@ -69,8 +69,7 @@ public: static Mesh* create(const std::vector& positions, const std::vector& normals, const std::vector& texs, - const IndexArray& indices, - CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); + const IndexArray& indices); /** * @lua NA @@ -78,8 +77,7 @@ public: static Mesh* create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, - const std::vector& attribs, - CustomCommand::IndexFormat format = CustomCommand::IndexFormat::U_SHORT); + const std::vector& attribs); /** * create mesh diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 0eb5447bd3..215bb77bf4 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -132,21 +132,21 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: bool needCalcAABB = (meshdata.subMeshAABB.size() != meshdata.subMeshIndices.size()); for (size_t i = 0, size = meshdata.subMeshIndices.size(); i < size; ++i) { - auto& index = meshdata.subMeshIndices[i]; - auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); + auto& indices = meshdata.subMeshIndices[i]; + // auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); auto indexBuffer = backend::Device::getInstance()->newBuffer( - index.size() * indexSize, backend::BufferType::INDEX, backend::BufferUsage::STATIC); + indices.size()/* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - indexBuffer->updateData((void*)index.data(), index.size()/* * indexSize*/); + indexBuffer->updateData((void*)indices.data(), indices.size() /* * indexSize*/); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; if (needCalcAABB) { - auto aabb = Bundle3D::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index, format); + auto aabb = Bundle3D::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), indices); indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, aabb); } else diff --git a/core/renderer/backend/Types.h b/core/renderer/backend/Types.h index aad618bd00..a4380e2cc4 100644 --- a/core/renderer/backend/Types.h +++ b/core/renderer/backend/Types.h @@ -160,7 +160,8 @@ enum class TextureUsage : uint32_t enum class IndexFormat : uint32_t { U_SHORT, - U_INT + U_INT, + UNSPEC = 0xff, }; enum class VertexStepMode : uint32_t From 7a8b12354845e1826365816c4eb36bfeff646e75 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sun, 3 Jul 2022 22:50:19 +0300 Subject: [PATCH 12/46] Fix mobile compilation. Treat `CC_ENABLE_CACHE_TEXTURE_DATA` portion of code accordingly. --- core/3d/CCBundle3DData.h | 1 + core/3d/CCMeshVertexIndexData.cpp | 4 ++-- core/renderer/CCCustomCommand.h | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 666755dca8..c411dd9f96 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -108,6 +108,7 @@ public: const uint8_t* data() const noexcept { return _buffer.data(); } size_t size() const { return _buffer.size(); } + bool empty() const { return _buffer.size() == 0; } void resize(size_t size) { _buffer.resize(size * sizeof(uint16_t)); } void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(uint32_t)); } diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 215bb77bf4..f32382bbc2 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -75,7 +75,7 @@ MeshIndexData::MeshIndexData() { #if CC_ENABLE_CACHE_TEXTURE_DATA _backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { - _indexBuffer->updateData((void*)_indexData.data(), _indexData.size() * sizeof(_indexData[0])); + _indexBuffer->updateData((void*)_indexData.data(), _indexData.size()); }); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1); #endif @@ -152,7 +152,7 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: else indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, meshdata.subMeshAABB[i]); #if CC_ENABLE_CACHE_TEXTURE_DATA - indexdata->setIndexData(index); + indexdata->setIndexData(indices); #endif vertexdata->_indices.pushBack(indexdata); } diff --git a/core/renderer/CCCustomCommand.h b/core/renderer/CCCustomCommand.h index f8596924a2..9eba70dfe6 100644 --- a/core/renderer/CCCustomCommand.h +++ b/core/renderer/CCCustomCommand.h @@ -53,13 +53,14 @@ public: using PrimitiveType = backend::PrimitiveType; /** - Buffer usage of vertex/index buffer. If the contents is not updated every frame, - then use STATIC, other use DYNAMIC. + Buffer usage of vertex/index buffer. If the contents are not updated every frame, + then STATIC should be used. Otherwise, DYNAMIC should be used. + This flag is not improtant because most GPU drivers ignore it, so it's best left to STATIC. */ using BufferUsage = backend::BufferUsage; /** - The index format determine the size for index data. U_SHORT is enough for most - cases. + The index format that determines the size of index data. U_SHORT (65535 vertices) is enough for most + cases, But support for U_INT (4294967295 vertices) has been added. */ using IndexFormat = backend::IndexFormat; From 07bbe4e06c5c8c44e1f5e26cbda3811c10c27fd8 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sun, 3 Jul 2022 23:25:05 +0300 Subject: [PATCH 13/46] Update CCBundle3D.cpp [skip ci] --- core/3d/CCBundle3D.cpp | 2342 +--------------------------------------- 1 file changed, 1 insertion(+), 2341 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 2c59fb9d1a..32f1489ce0 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -1,2341 +1 @@ -/**************************************************************************** -Copyright (c) 2014-2016 Chukong Technologies Inc. -Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. -Copyright (c) 2021 Bytedance Inc. - - https://adxeproject.github.io/ - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -****************************************************************************/ - -#include "3d/CCBundle3D.h" -#include "3d/CCObjLoader.h" - -#include "base/ccMacros.h" -#include "platform/CCFileUtils.h" -#include "3d/CCBundleReader.h" -#include "base/CCData.h" - -#define BUNDLE_TYPE_SCENE 1 -#define BUNDLE_TYPE_NODE 2 -#define BUNDLE_TYPE_ANIMATIONS 3 -#define BUNDLE_TYPE_ANIMATION 4 -#define BUNDLE_TYPE_ANIMATION_CHANNEL 5 -#define BUNDLE_TYPE_MODEL 10 -#define BUNDLE_TYPE_MATERIAL 16 -#define BUNDLE_TYPE_EFFECT 18 -#define BUNDLE_TYPE_CAMERA 32 -#define BUNDLE_TYPE_LIGHT 33 -#define BUNDLE_TYPE_MESH 34 -#define BUNDLE_TYPE_MESHPART 35 -#define BUNDLE_TYPE_MESHSKIN 36 - -static const char* VERSION = "version"; -static const char* ID = "id"; -static const char* DEFAULTPART = "body"; -static const char* VERTEXSIZE = "vertexsize"; -static const char* VERTEX = "vertex"; -static const char* VERTICES = "vertices"; -static const char* INDEXNUM = "indexnum"; -static const char* INDICES = "indices"; -static const char* SUBMESH = "submesh"; -static const char* ATTRIBUTES = "attributes"; -static const char* ATTRIBUTESIZE = "size"; -static const char* TYPE = "type"; -static const char* ATTRIBUTE = "attribute"; -static const char* SKIN = "skin"; -static const char* BINDSHAPE = "bindshape"; -static const char* MESH = "mesh"; -static const char* MESHES = "meshes"; -static const char* MESHPARTID = "meshpartid"; -static const char* MATERIALID = "materialid"; -static const char* NODE = "node"; -static const char* NODES = "nodes"; -static const char* CHILDREN = "children"; -static const char* PARTS = "parts"; -static const char* BONES = "bones"; -static const char* SKELETON = "skeleton"; -static const char* MATERIALS = "materials"; -static const char* ANIMATIONS = "animations"; -static const char* TRANSFORM = "transform"; -static const char* OLDTRANSFORM = "tansform"; -static const char* ANIMATION = "animation"; -static const char* MATERIAL = "material"; -static const char* BASE = "base"; -static const char* FILENAME = "filename"; -static const char* TEXTURES = "textures"; -static const char* LENGTH = "length"; -static const char* BONEID = "boneId"; -static const char* KEYFRAMES = "keyframes"; -static const char* TRANSLATION = "translation"; -static const char* ROTATION = "rotation"; -static const char* SCALE = "scale"; -static const char* KEYTIME = "keytime"; -static const char* AABBS = "aabb"; - -NS_CC_BEGIN - -void getChildMap(std::map>& map, SkinData* skinData, const rapidjson::Value& val) -{ - if (!skinData) - return; - - // get transform matrix - Mat4 transform; - const rapidjson::Value& parent_transform = val[OLDTRANSFORM]; - for (rapidjson::SizeType j = 0, size = parent_transform.Size(); j < size; ++j) - { - transform.m[j] = parent_transform[j].GetFloat(); - } - - // set origin matrices - std::string parent_name = val[ID].GetString(); - int parent_name_index = skinData->getSkinBoneNameIndex(parent_name); - if (parent_name_index < 0) - { - skinData->addNodeBoneNames(parent_name); - skinData->nodeBoneOriginMatrices.push_back(transform); - parent_name_index = skinData->getBoneNameIndex(parent_name); - } - else if (parent_name_index < static_cast(skinData->skinBoneNames.size())) - { - skinData->skinBoneOriginMatrices[parent_name_index] = transform; - } - - // set root bone index - if (skinData->rootBoneIndex < 0) - skinData->rootBoneIndex = parent_name_index; - - if (!val.HasMember(CHILDREN)) - return; - - const rapidjson::Value& children = val[CHILDREN]; - for (rapidjson::SizeType i = 0, size = children.Size(); i < size; ++i) - { - // get child bone name - const rapidjson::Value& child = children[i]; - - std::string child_name = child[ID].GetString(); - int child_name_index = skinData->getSkinBoneNameIndex(child_name); - if (child_name_index < 0) - { - skinData->addNodeBoneNames(child_name); - child_name_index = skinData->getBoneNameIndex(child_name); - } - - map[parent_name_index].push_back(child_name_index); - - getChildMap(map, skinData, child); - } -} - -Bundle3D* Bundle3D::createBundle() -{ - auto bundle = new Bundle3D(); - return bundle; -} - -void Bundle3D::destroyBundle(Bundle3D* bundle) -{ - delete bundle; -} - -void Bundle3D::clear() -{ - if (_isBinary) - { - _binaryBuffer.clear(); - CC_SAFE_DELETE_ARRAY(_references); - } - else - { - _jsonBuffer.clear(); - } -} - -bool Bundle3D::load(std::string_view path) -{ - if (path.empty()) - return false; - - if (_path == path) - return true; - - getModelRelativePath(path); - - bool ret = false; - std::string ext = FileUtils::getInstance()->getFileExtension(path); - if (ext == ".c3t") - { - _isBinary = false; - ret = loadJson(path); - } - else if (ext == ".c3b") - { - _isBinary = true; - ret = loadBinary(path); - } - else - { - CCLOG("warning: %s is invalid file formate", path.data()); - } - - ret ? (_path = path) : (_path = ""); - - return ret; -} - -bool Bundle3D::loadObj(MeshDatas& meshdatas, - MaterialDatas& materialdatas, - NodeDatas& nodedatas, - std::string_view fullPath, - const char* mtl_basepath) -{ - meshdatas.resetData(); - materialdatas.resetData(); - nodedatas.resetData(); - - std::string mtlPath = ""; - if (mtl_basepath) - mtlPath = mtl_basepath; - else - mtlPath = fullPath.substr(0, fullPath.find_last_of("\\/") + 1); - - std::vector shapes; - std::vector materials; - auto ret = tinyobj::LoadObj(shapes, materials, fullPath.data(), mtlPath.c_str()); - if (ret.empty()) - { - // fill data - // convert material - int i = 0; - char str[20]; - std::string dir = ""; - auto last = fullPath.rfind('/'); - if (last != std::string::npos) - dir = fullPath.substr(0, last + 1); - for (auto& material : materials) - { - NMaterialData materialdata; - - NTextureData tex; - tex.filename = material.diffuse_texname.empty() ? material.diffuse_texname : dir + material.diffuse_texname; - tex.type = NTextureData::Usage::Diffuse; - tex.wrapS = backend::SamplerAddressMode::CLAMP_TO_EDGE; - tex.wrapT = backend::SamplerAddressMode::CLAMP_TO_EDGE; - - sprintf(str, "%d", ++i); - materialdata.textures.push_back(tex); - materialdata.id = str; - material.name = str; - materialdatas.materials.push_back(materialdata); - } - - // convert mesh - i = 0; - for (auto& shape : shapes) - { - auto mesh = shape.mesh; - MeshData* meshdata = new MeshData(); - MeshVertexAttrib attrib; - attrib.type = parseGLDataType("GL_FLOAT", 3); - - if (mesh.positions.size()) - { - attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; - meshdata->attribs.push_back(attrib); - } - bool hasnormal = false, hastex = false; - if (mesh.normals.size()) - { - hasnormal = true; - attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; - meshdata->attribs.push_back(attrib); - } - if (mesh.texcoords.size()) - { - hastex = true; - attrib.type = parseGLDataType("GL_FLOAT", 2); - attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; - meshdata->attribs.push_back(attrib); - } - - auto vertexNum = mesh.positions.size() / 3; - for (unsigned int k = 0; k < vertexNum; ++k) - { - meshdata->vertex.push_back(mesh.positions[k * 3]); - meshdata->vertex.push_back(mesh.positions[k * 3 + 1]); - meshdata->vertex.push_back(mesh.positions[k * 3 + 2]); - - if (hasnormal) - { - meshdata->vertex.push_back(mesh.normals[k * 3]); - meshdata->vertex.push_back(mesh.normals[k * 3 + 1]); - meshdata->vertex.push_back(mesh.normals[k * 3 + 2]); - } - - if (hastex) - { - meshdata->vertex.push_back(mesh.texcoords[k * 2]); - meshdata->vertex.push_back(mesh.texcoords[k * 2 + 1]); - } - } - - // split into submesh according to material - std::map subMeshMap; - for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) - { - int id = mesh.material_ids[k]; - size_t idx = k * 3; - subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); - } - - auto node = new NodeData(); - node->id = shape.name; - for (auto& submesh : subMeshMap) - { - meshdata->subMeshIndices.push_back(submesh.second); - meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); - sprintf(str, "%d", ++i); - meshdata->subMeshIds.push_back(str); - - auto modelnode = new ModelData(); - modelnode->materialId = submesh.first == -1 ? "" : materials[submesh.first].name; - modelnode->subMeshId = str; - node->modelNodeDatas.push_back(modelnode); - } - nodedatas.nodes.push_back(node); - meshdatas.meshDatas.push_back(meshdata); - } - - return true; - } - CCLOG("warning: load %s file error: %s", fullPath.data(), ret.c_str()); - return false; -} - -bool Bundle3D::loadSkinData(std::string_view /*id*/, SkinData* skindata) -{ - skindata->resetData(); - - if (_isBinary) - { - return loadSkinDataBinary(skindata); - } - else - { - return loadSkinDataJson(skindata); - } -} - -bool Bundle3D::loadAnimationData(std::string_view id, Animation3DData* animationdata) -{ - animationdata->resetData(); - - if (_isBinary) - { - return loadAnimationDataBinary(id, animationdata); - } - else - { - return loadAnimationDataJson(id, animationdata); - } -} - -// since 3.3, to support reskin -bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) -{ - meshdatas.resetData(); - if (_isBinary) - { - if (_version == "0.1" || _version == "0.2") - { - return loadMeshDatasBinary_0_1(meshdatas); - } - else - { - return loadMeshDatasBinary(meshdatas); - } - } - else - { - if (_version == "1.2" || _version == "0.2") - { - return loadMeshDataJson_0_1(meshdatas); - } - else - { - return loadMeshDatasJson(meshdatas); - } - } - return true; -} -bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MESH)) - return false; - unsigned int meshSize = 0; - if (_binaryReader.read(&meshSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - return false; - } - MeshData* meshData = nullptr; - for (unsigned int i = 0; i < meshSize; ++i) - { - unsigned int attribSize = 0; - // read mesh data - if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - goto FAILED; - } - meshData = new MeshData(); - meshData->attribCount = attribSize; - meshData->attribs.resize(meshData->attribCount); - for (ssize_t j = 0; j < meshData->attribCount; ++j) - { - std::string attribute = ""; - unsigned int vSize; - if (_binaryReader.read(&vSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); - goto FAILED; - } - std::string type = _binaryReader.readString(); - attribute = _binaryReader.readString(); - meshData->attribs[j].type = parseGLDataType(type, vSize); - meshData->attribs[j].vertexAttrib = parseGLProgramAttribute(attribute); - } - unsigned int vertexSizeInFloat = 0; - // Read vertex data - if (_binaryReader.read(&vertexSizeInFloat, 4, 1) != 1 || vertexSizeInFloat == 0) - { - CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); - goto FAILED; - } - - meshData->vertex.resize(vertexSizeInFloat); - if (_binaryReader.read(&meshData->vertex[0], 4, vertexSizeInFloat) != vertexSizeInFloat) - { - CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); - goto FAILED; - } - - // Read index data - unsigned int meshPartCount = 1; - _binaryReader.read(&meshPartCount, 4, 1); - - for (unsigned int k = 0; k < meshPartCount; ++k) - { - IndexArray indexArray{CustomCommand::IndexFormat::U_SHORT}; // TODO: _version == 1.3 use U_INT? - std::string meshPartid = _binaryReader.readString(); - meshData->subMeshIds.push_back(meshPartid); - unsigned int nIndexCount; - if (_binaryReader.read(&nIndexCount, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); - goto FAILED; - } - indexArray.resize(nIndexCount); - if (_binaryReader.read(indexArray.data(), 2, nIndexCount) != nIndexCount) - { - CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); - goto FAILED; - } - meshData->subMeshIndices.push_back(indexArray); - meshData->numIndex = (int)meshData->subMeshIndices.size(); - // meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), - // indexArray)); - if (_version != "0.3" && _version != "0.4" && _version != "0.5") - { - // read mesh aabb - float aabb[6]; - if (_binaryReader.read(aabb, 4, 6) != 6) - { - CCLOG("warning: Failed to read meshdata: aabb '%s'.", _path.c_str()); - goto FAILED; - } - meshData->subMeshAABB.push_back(AABB(Vec3(aabb[0], aabb[1], aabb[2]), Vec3(aabb[3], aabb[4], aabb[5]))); - } - else - { - meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); - } - } - meshdatas.meshDatas.push_back(meshData); - } - return true; - -FAILED: -{ - CC_SAFE_DELETE(meshData); - for (auto& meshdata : meshdatas.meshDatas) - { - delete meshdata; - } - meshdatas.meshDatas.clear(); - return false; -} -} -bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MESH)) - return false; - - meshdatas.resetData(); - - MeshData* meshdata = new MeshData(); - - // read mesh data - unsigned int attribSize = 0; - if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - enum - { - VERTEX_ATTRIB_POSITION, - VERTEX_ATTRIB_COLOR, - VERTEX_ATTRIB_TEX_COORD, - VERTEX_ATTRIB_NORMAL, - VERTEX_ATTRIB_BLEND_WEIGHT, - VERTEX_ATTRIB_BLEND_INDEX, - - VERTEX_ATTRIB_MAX, - - // backward compatibility - VERTEX_ATTRIB_TEX_COORDS = VERTEX_ATTRIB_TEX_COORD, - }; - for (unsigned int i = 0; i < attribSize; ++i) - { - unsigned int vUsage, vSize; - shaderinfos::VertexKey usage; - if (_binaryReader.read(&vUsage, 4, 1) != 1 || _binaryReader.read(&vSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - MeshVertexAttrib meshVertexAttribute; - meshVertexAttribute.type = parseGLDataType("GL_FLOAT", vSize); - if (vUsage == VERTEX_ATTRIB_NORMAL) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; - } - else if (vUsage == VERTEX_ATTRIB_BLEND_WEIGHT) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; - } - else if (vUsage == VERTEX_ATTRIB_BLEND_INDEX) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; - } - else if (vUsage == VERTEX_ATTRIB_POSITION) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; - } - else if (vUsage == VERTEX_ATTRIB_TEX_COORD) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; - } - else - { - CCASSERT(false, "invalidate usage value"); - } - meshVertexAttribute.vertexAttrib = usage; - - meshdata->attribs.push_back(meshVertexAttribute); - } - - // Read vertex data - if (_binaryReader.read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0) - { - CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - meshdata->vertex.resize(meshdata->vertexSizeInFloat); - if (_binaryReader.read(&meshdata->vertex[0], 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat) - { - CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - // Read index data - unsigned int meshPartCount = 1; - for (unsigned int i = 0; i < meshPartCount; ++i) - { - unsigned int nIndexCount; - if (_binaryReader.read(&nIndexCount, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - IndexArray indices; - indices.resize(nIndexCount); - if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) - { - CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); - } - - meshdatas.meshDatas.push_back(meshdata); - return true; -} - -bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MESH)) - return false; - - meshdatas.resetData(); - - MeshData* meshdata = new MeshData(); - - // read mesh data - unsigned int attribSize = 0; - if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - enum - { - VERTEX_ATTRIB_POSITION, - VERTEX_ATTRIB_COLOR, - VERTEX_ATTRIB_TEX_COORD, - VERTEX_ATTRIB_NORMAL, - VERTEX_ATTRIB_BLEND_WEIGHT, - VERTEX_ATTRIB_BLEND_INDEX, - - VERTEX_ATTRIB_MAX, - - // backward compatibility - VERTEX_ATTRIB_TEX_COORDS = VERTEX_ATTRIB_TEX_COORD, - }; - for (unsigned int i = 0; i < attribSize; ++i) - { - unsigned int vUsage, vSize; - shaderinfos::VertexKey usage = shaderinfos::VertexKey::VERTEX_ATTRIB_ERROR; - if (_binaryReader.read(&vUsage, 4, 1) != 1 || _binaryReader.read(&vSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - MeshVertexAttrib meshVertexAttribute; - meshVertexAttribute.type = parseGLDataType("GL_FLOAT", vSize); - if (vUsage == VERTEX_ATTRIB_NORMAL) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; - } - else if (vUsage == VERTEX_ATTRIB_BLEND_WEIGHT) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; - } - else if (vUsage == VERTEX_ATTRIB_BLEND_INDEX) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; - } - else if (vUsage == VERTEX_ATTRIB_POSITION) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; - } - else if (vUsage == VERTEX_ATTRIB_TEX_COORD) - { - usage = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; - } - meshVertexAttribute.vertexAttrib = usage; - - meshdata->attribs.push_back(meshVertexAttribute); - } - - // Read vertex data - if (_binaryReader.read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0) - { - CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - meshdata->vertex.resize(meshdata->vertexSizeInFloat); - if (_binaryReader.read(&meshdata->vertex[0], 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat) - { - CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - // read submesh - unsigned int submeshCount; - if (_binaryReader.read(&submeshCount, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: submeshCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - for (unsigned int i = 0; i < submeshCount; ++i) - { - unsigned int nIndexCount; - if (_binaryReader.read(&nIndexCount, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - IndexArray indices{CustomCommand::IndexFormat::U_SHORT}; /* TODO: _version == 1.3 use U_INT?*/ - indices.resize(nIndexCount); - if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) - { - CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); - CC_SAFE_DELETE(meshdata); - return false; - } - - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); - } - - meshdatas.meshDatas.push_back(meshdata); - - return true; -} -bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) -{ - const rapidjson::Value& mesh_data_array = _jsonReader[MESHES]; - for (rapidjson::SizeType index = 0, mesh_data_array_size = mesh_data_array.Size(); index < mesh_data_array_size; - ++index) - { - MeshData* meshData = new MeshData(); - const rapidjson::Value& mesh_data = mesh_data_array[index]; - // mesh_vertex_attribute - const rapidjson::Value& mesh_vertex_attribute = mesh_data[ATTRIBUTES]; - MeshVertexAttrib tempAttrib; - meshData->attribCount = mesh_vertex_attribute.Size(); - meshData->attribs.resize(meshData->attribCount); - for (rapidjson::SizeType i = 0, mesh_vertex_attribute_size = mesh_vertex_attribute.Size(); - i < mesh_vertex_attribute_size; ++i) - { - const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; - - int size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetInt(); - std::string type = mesh_vertex_attribute_val[TYPE].GetString(); - std::string attribute = mesh_vertex_attribute_val[ATTRIBUTE].GetString(); - - tempAttrib.type = parseGLDataType(type, size); - tempAttrib.vertexAttrib = parseGLProgramAttribute(attribute); - meshData->attribs[i] = tempAttrib; - } - // mesh vertices - //////////////////////////////////////////////////////////////////////////////////////////////// - const rapidjson::Value& mesh_data_vertex_array = mesh_data[VERTICES]; - auto mesh_data_vertex_array_size = mesh_data_vertex_array.Size(); - meshData->vertexSizeInFloat = mesh_data_vertex_array_size; - for (rapidjson::SizeType i = 0; i < mesh_data_vertex_array_size; ++i) - { - meshData->vertex.push_back(mesh_data_vertex_array[i].GetFloat()); - } - // mesh part - //////////////////////////////////////////////////////////////////////////////////////////////// - const rapidjson::Value& mesh_part_array = mesh_data[PARTS]; - for (rapidjson::SizeType i = 0, mesh_part_array_size = mesh_part_array.Size(); i < mesh_part_array_size; ++i) - { - IndexArray indexArray; - const rapidjson::Value& mesh_part = mesh_part_array[i]; - meshData->subMeshIds.push_back(mesh_part[ID].GetString()); - // index_number - const rapidjson::Value& indices_val_array = mesh_part[INDICES]; - for (rapidjson::SizeType j = 0, indices_val_array_size = indices_val_array.Size(); - j < indices_val_array_size; ++j) - indexArray.push_back((unsigned int)indices_val_array[j].GetUint()); - - meshData->subMeshIndices.push_back(indexArray); - meshData->numIndex = (int)meshData->subMeshIndices.size(); - - if (mesh_data.HasMember(AABBS)) - { - const rapidjson::Value& mesh_part_aabb = mesh_part[AABBS]; - if (mesh_part.HasMember(AABBS) && mesh_part_aabb.Size() == 6) - { - Vec3 min(mesh_part_aabb[(rapidjson::SizeType)0].GetFloat(), - mesh_part_aabb[(rapidjson::SizeType)1].GetFloat(), - mesh_part_aabb[(rapidjson::SizeType)2].GetFloat()); - Vec3 max(mesh_part_aabb[(rapidjson::SizeType)3].GetFloat(), - mesh_part_aabb[(rapidjson::SizeType)4].GetFloat(), - mesh_part_aabb[(rapidjson::SizeType)5].GetFloat()); - meshData->subMeshAABB.push_back(AABB(min, max)); - } - else - { - meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); - } - } - else - { - meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), - indexArray)); - } - } - meshdatas.meshDatas.push_back(meshData); - } - return true; -} -bool Bundle3D::loadNodes(NodeDatas& nodedatas) -{ - if (_version == "0.1" || _version == "1.2" || _version == "0.2") - { - SkinData skinData; - if (!loadSkinData("", &skinData)) - { - auto node = new NodeData(); - auto modelnode = new ModelData(); - modelnode->materialId = ""; - modelnode->subMeshId = ""; - node->modelNodeDatas.push_back(modelnode); - nodedatas.nodes.push_back(node); - return true; - } - - auto nodeDatas = new NodeData*[skinData.skinBoneNames.size() + skinData.nodeBoneNames.size()]; - int index = 0; - size_t i; - auto skinBoneSize = skinData.skinBoneNames.size(); - auto nodeBoneSize = skinData.nodeBoneNames.size(); - for (i = 0; i < skinBoneSize; ++i) - { - nodeDatas[index] = new NodeData(); - nodeDatas[index]->id = skinData.skinBoneNames[i]; - nodeDatas[index]->transform = skinData.skinBoneOriginMatrices[i]; - ++index; - } - for (i = 0; i < nodeBoneSize; ++i) - { - nodeDatas[index] = new NodeData(); - nodeDatas[index]->id = skinData.nodeBoneNames[i]; - nodeDatas[index]->transform = skinData.nodeBoneOriginMatrices[i]; - ++index; - } - for (const auto& it : skinData.boneChild) - { - const auto& children = it.second; - auto parent = nodeDatas[it.first]; - for (const auto& child : children) - { - parent->children.push_back(nodeDatas[child]); - } - } - nodedatas.skeleton.push_back(nodeDatas[skinData.rootBoneIndex]); - auto node = new NodeData(); - auto modelnode = new ModelData(); - modelnode->materialId = ""; - modelnode->subMeshId = ""; - modelnode->bones = skinData.skinBoneNames; - modelnode->invBindPose = skinData.inverseBindPoseMatrices; - node->modelNodeDatas.push_back(modelnode); - nodedatas.nodes.push_back(node); - delete[] nodeDatas; - } - else - { - if (_isBinary) - { - loadNodesBinary(nodedatas); - } - else - { - loadNodesJson(nodedatas); - } - } - return true; -} -bool Bundle3D::loadMaterials(MaterialDatas& materialdatas) -{ - materialdatas.resetData(); - if (_isBinary) - { - if (_version == "0.1") - { - return loadMaterialsBinary_0_1(materialdatas); - } - else if (_version == "0.2") - { - return loadMaterialsBinary_0_2(materialdatas); - } - else - { - return loadMaterialsBinary(materialdatas); - } - } - else - { - if (_version == "1.2") - { - return loadMaterialDataJson_0_1(materialdatas); - } - else if (_version == "0.2") - { - return loadMaterialDataJson_0_2(materialdatas); - } - else - { - return loadMaterialsJson(materialdatas); - } - } - return true; -} -bool Bundle3D::loadMaterialsBinary(MaterialDatas& materialdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) - return false; - unsigned int materialnum = 1; - _binaryReader.read(&materialnum, 4, 1); - for (unsigned int i = 0; i < materialnum; ++i) - { - NMaterialData materialData; - materialData.id = _binaryReader.readString(); - - // skip: diffuse(3), ambient(3), emissive(3), opacity(1), specular(3), shininess(1) - float data[14]; - _binaryReader.read(&data, sizeof(float), 14); - - unsigned int textureNum = 1; - _binaryReader.read(&textureNum, 4, 1); - for (unsigned int j = 0; j < textureNum; ++j) - { - NTextureData textureData; - textureData.id = _binaryReader.readString(); - if (textureData.id.empty()) - { - CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", textureData.id.c_str()); - return false; - } - std::string texturePath = _binaryReader.readString(); - if (texturePath.empty()) - { - CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); - return false; - } - - textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; - float uvdata[4]; - _binaryReader.read(&uvdata, sizeof(float), 4); - textureData.type = parseGLTextureType(_binaryReader.readString()); - textureData.wrapS = parseSamplerAddressMode(_binaryReader.readString()); - textureData.wrapT = parseSamplerAddressMode(_binaryReader.readString()); - materialData.textures.push_back(textureData); - } - materialdatas.materials.push_back(materialData); - } - return true; -} -bool Bundle3D::loadMaterialsBinary_0_1(MaterialDatas& materialdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) - return false; - - NMaterialData materialData; - - std::string texturePath = _binaryReader.readString(); - if (texturePath.empty()) - { - CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); - return false; - } - - NTextureData textureData; - textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; - textureData.type = NTextureData::Usage::Diffuse; - textureData.id = ""; - materialData.textures.push_back(textureData); - materialdatas.materials.push_back(materialData); - return true; -} - -bool Bundle3D::loadMaterialsBinary_0_2(MaterialDatas& materialdatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) - return false; - - unsigned int materialnum = 1; - _binaryReader.read(&materialnum, 4, 1); - - for (unsigned int i = 0; i < materialnum; ++i) - { - NMaterialData materialData; - - std::string texturePath = _binaryReader.readString(); - if (texturePath.empty()) - { - CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); - return true; - } - - NTextureData textureData; - textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; - textureData.type = NTextureData::Usage::Diffuse; - textureData.id = ""; - materialData.textures.push_back(textureData); - materialdatas.materials.push_back(materialData); - } - return true; -} - -bool loadMeshDataJson(MeshData* /*meshdata*/) -{ - return true; -} - -bool loadMeshDataJson_0_1(MeshData* /*meshdata*/) -{ - return true; -} - -bool loadMeshDataJson_0_2(MeshData* /*meshdata*/) -{ - return true; -} - -bool Bundle3D::loadMaterialsJson(MaterialDatas& materialdatas) -{ - if (!_jsonReader.HasMember(MATERIALS)) - return false; - const rapidjson::Value& material_array = _jsonReader[MATERIALS]; - for (rapidjson::SizeType i = 0; i < material_array.Size(); ++i) - { - NMaterialData materialData; - const rapidjson::Value& material_val = material_array[i]; - materialData.id = material_val[ID].GetString(); - if (material_val.HasMember(TEXTURES)) - { - const rapidjson::Value& texture_array = material_val[TEXTURES]; - for (rapidjson::SizeType j = 0; j < texture_array.Size(); ++j) - { - NTextureData textureData; - const rapidjson::Value& texture_val = texture_array[j]; - std::string filename = texture_val[FILENAME].GetString(); - textureData.filename = filename.empty() ? filename : _modelPath + filename; - textureData.type = parseGLTextureType(texture_val["type"].GetString()); - textureData.wrapS = parseSamplerAddressMode(texture_val["wrapModeU"].GetString()); - textureData.wrapT = parseSamplerAddressMode(texture_val["wrapModeV"].GetString()); - materialData.textures.push_back(textureData); - } - } - materialdatas.materials.push_back(materialData); - } - return true; -} -bool Bundle3D::loadJson(std::string_view path) -{ - clear(); - - _jsonBuffer = FileUtils::getInstance()->getStringFromFile(path); - - if (_jsonReader.ParseInsitu<0>((char*)_jsonBuffer.c_str()).HasParseError()) - { - clear(); - CCLOG("Parse json failed in Bundle3D::loadJson function"); - return false; - } - - const rapidjson::Value& mash_data_array = _jsonReader[VERSION]; - if (mash_data_array.IsArray()) // Compatible with the old version - _version = "1.2"; - else - _version = mash_data_array.GetString(); - - return true; -} - -bool Bundle3D::loadBinary(std::string_view path) -{ - clear(); - - // get file data - _binaryBuffer.clear(); - _binaryBuffer = FileUtils::getInstance()->getDataFromFile(path); - if (_binaryBuffer.isNull()) - { - clear(); - CCLOG("warning: Failed to read file: %s", path.data()); - return false; - } - - // Initialise bundle reader - _binaryReader.init((char*)_binaryBuffer.getBytes(), _binaryBuffer.getSize()); - - // Read identifier info - char identifier[] = {'C', '3', 'B', '\0'}; - char sig[4]; - if (_binaryReader.read(sig, 1, 4) != 4 || memcmp(sig, identifier, 4) != 0) - { - clear(); - CCLOG("warning: Invalid identifier: %s", path.data()); - return false; - } - - // Read version - unsigned char ver[2]; - if (_binaryReader.read(ver, 1, 2) != 2) - { - CCLOG("warning: Failed to read version:"); - return false; - } - - char version[20] = {0}; - sprintf(version, "%d.%d", ver[0], ver[1]); - _version = version; - - // Read ref table size - if (_binaryReader.read(&_referenceCount, 4, 1) != 1) - { - clear(); - CCLOG("warning: Failed to read ref table size '%s'.", path.data()); - return false; - } - - // Read all refs - CC_SAFE_DELETE_ARRAY(_references); - _references = new Reference[_referenceCount]; - for (unsigned int i = 0; i < _referenceCount; ++i) - { - if ((_references[i].id = _binaryReader.readString()).empty() || - _binaryReader.read(&_references[i].type, 4, 1) != 1 || - _binaryReader.read(&_references[i].offset, 4, 1) != 1) - { - clear(); - CCLOG("warning: Failed to read ref number %u for bundle '%s'.", i, path.data()); - CC_SAFE_DELETE_ARRAY(_references); - return false; - } - } - - return true; -} - -bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) -{ - const rapidjson::Value& mesh_data_array = _jsonReader[MESH]; - MeshData* meshdata = new MeshData(); - const rapidjson::Value& mesh_data_val = mesh_data_array[(rapidjson::SizeType)0]; - - const rapidjson::Value& mesh_data_body_array = mesh_data_val[DEFAULTPART]; - - const rapidjson::Value& mesh_data_body_array_0 = mesh_data_body_array[(rapidjson::SizeType)0]; - - // mesh_vertex_attribute - const rapidjson::Value& mesh_vertex_attribute = mesh_data_val[ATTRIBUTES]; - meshdata->attribCount = mesh_vertex_attribute.Size(); - meshdata->attribs.resize(meshdata->attribCount); - for (rapidjson::SizeType i = 0; i < mesh_vertex_attribute.Size(); ++i) - { - const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; - - int size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetUint(); - meshdata->attribs[i].type = parseGLDataType(mesh_vertex_attribute_val[TYPE].GetString(), size); - meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val[ATTRIBUTE].GetString()); - } - - // vertices - meshdata->vertexSizeInFloat = mesh_data_body_array_0[VERTEXSIZE].GetInt(); - meshdata->vertex.resize(meshdata->vertexSizeInFloat); - - const rapidjson::Value& mesh_data_body_vertices = mesh_data_body_array_0[VERTICES]; - for (rapidjson::SizeType i = 0; i < mesh_data_body_vertices.Size(); ++i) - meshdata->vertex[i] = mesh_data_body_vertices[i].GetFloat(); - - // index_number - unsigned int indexnum = mesh_data_body_array_0[INDEXNUM].GetUint(); - - // indices - IndexArray indices; - indices.resize(indexnum); - - const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; - for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) - indices.at(i) = (unsigned short)indices_val_array[i].GetUint(); - - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); - meshdatas.meshDatas.push_back(meshdata); - return true; -} - -bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) -{ - MeshData* meshdata = new MeshData(); - const rapidjson::Value& mesh_array = _jsonReader[MESH]; - const rapidjson::Value& mesh_array_0 = mesh_array[(rapidjson::SizeType)0]; - - // mesh_vertex_attribute - const rapidjson::Value& mesh_vertex_attribute = mesh_array_0[ATTRIBUTES]; - meshdata->attribCount = mesh_vertex_attribute.Size(); - meshdata->attribs.resize(meshdata->attribCount); - for (rapidjson::SizeType i = 0; i < mesh_vertex_attribute.Size(); ++i) - { - const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; - - auto size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetUint(); - meshdata->attribs[i].type = parseGLDataType(mesh_vertex_attribute_val[TYPE].GetString(), size); - meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val[ATTRIBUTE].GetString()); - } - - // vertices - const rapidjson::Value& mesh_data_vertex = mesh_array_0[VERTEX]; - const rapidjson::Value& mesh_data_vertex_0 = mesh_data_vertex[(rapidjson::SizeType)0]; - - meshdata->vertexSizeInFloat = mesh_data_vertex_0[VERTEXSIZE].GetInt(); - meshdata->vertex.resize(meshdata->vertexSizeInFloat); - - const rapidjson::Value& mesh_data_body_vertices = mesh_data_vertex_0[VERTICES]; - for (rapidjson::SizeType i = 0; i < mesh_data_body_vertices.Size(); ++i) - meshdata->vertex[i] = mesh_data_body_vertices[i].GetFloat(); - - // submesh - const rapidjson::Value& mesh_submesh_array = mesh_array_0[SUBMESH]; - for (rapidjson::SizeType i = 0; i < mesh_submesh_array.Size(); ++i) - { - const rapidjson::Value& mesh_submesh_val = mesh_submesh_array[i]; - // std::string id = mesh_submesh_val[ID].GetString(); - - // index_number - unsigned int indexnum = mesh_submesh_val[INDEXNUM].GetUint(); - - // indices - IndexArray indices; - indices.resize(indexnum); - - const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; - for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) - indices.at(j) = (unsigned short)indices_val_array[j].GetUint(); - - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); - } - meshdatas.meshDatas.push_back(meshdata); - return true; -} - -bool Bundle3D::loadSkinDataJson(SkinData* skindata) -{ - if (!_jsonReader.HasMember(SKIN)) - return false; - - const rapidjson::Value& skin_data_array = _jsonReader[SKIN]; - - CCASSERT(skin_data_array.IsArray(), "skin data is not an array"); - const rapidjson::Value& skin_data_array_val_0 = skin_data_array[(rapidjson::SizeType)0]; - - if (!skin_data_array_val_0.HasMember(BONES)) - return false; - - const rapidjson::Value& skin_data_bones = skin_data_array_val_0[BONES]; - for (rapidjson::SizeType i = 0; i < skin_data_bones.Size(); ++i) - { - const rapidjson::Value& skin_data_bone = skin_data_bones[i]; - std::string name = skin_data_bone[NODE].GetString(); - skindata->addSkinBoneNames(name); - - Mat4 mat_bind_pos; - const rapidjson::Value& bind_pos = skin_data_bone[BINDSHAPE]; - for (rapidjson::SizeType j = 0; j < bind_pos.Size(); ++j) - { - mat_bind_pos.m[j] = bind_pos[j].GetFloat(); - } - skindata->inverseBindPoseMatrices.push_back(mat_bind_pos); - } - - // set root bone information - const rapidjson::Value& skin_data_1 = skin_data_array[1]; - - // parent and child relationship map - skindata->skinBoneOriginMatrices.resize(skindata->skinBoneNames.size()); - getChildMap(skindata->boneChild, skindata, skin_data_1); - return true; -} - -bool Bundle3D::loadSkinDataBinary(SkinData* skindata) -{ - if (!seekToFirstType(BUNDLE_TYPE_MESHSKIN)) - return false; - - std::string boneName = _binaryReader.readString(); - - // transform - float bindShape[16]; - if (!_binaryReader.readMatrix(bindShape)) - { - CCLOG("warning: Failed to read SkinData: bindShape matrix '%s'.", _path.c_str()); - return false; - } - - // bone count - unsigned int boneNum; - if (!_binaryReader.read(&boneNum)) - { - CCLOG("warning: Failed to read SkinData: boneNum '%s'.", _path.c_str()); - return false; - } - - // Fix bug: check if the bone number is 0. - if (boneNum == 0) - return false; - - // bone names and bind pos - float bindpos[16]; - for (unsigned int i = 0; i < boneNum; ++i) - { - std::string skinBoneName = _binaryReader.readString(); - skindata->skinBoneNames.push_back(skinBoneName); - if (!_binaryReader.readMatrix(bindpos)) - { - CCLOG("warning: Failed to load SkinData: bindpos '%s'.", _path.c_str()); - return false; - } - skindata->inverseBindPoseMatrices.push_back(bindpos); - } - - skindata->skinBoneOriginMatrices.resize(boneNum); - - boneName = _binaryReader.readString(); - - // bind shape - _binaryReader.readMatrix(bindShape); - int rootIndex = skindata->getSkinBoneNameIndex(boneName); - if (rootIndex < 0) - { - skindata->addNodeBoneNames(boneName); - rootIndex = skindata->getBoneNameIndex(boneName); - skindata->nodeBoneOriginMatrices.push_back(bindShape); - } - else - { - skindata->skinBoneOriginMatrices[rootIndex] = bindShape; - } - - // set root bone index - skindata->rootBoneIndex = rootIndex; - - // read parent and child relationship map - float transform[16]; - unsigned int linkNum; - _binaryReader.read(&linkNum); - for (unsigned int i = 0; i < linkNum; ++i) - { - std::string id = _binaryReader.readString(); - int index = skindata->getSkinBoneNameIndex(id); - - std::string parentid = _binaryReader.readString(); - - if (!_binaryReader.readMatrix(transform)) - { - CCLOG("warning: Failed to load SkinData: transform '%s'.", _path.c_str()); - return false; - } - - if (index < 0) - { - skindata->addNodeBoneNames(id); - index = skindata->getBoneNameIndex(id); - skindata->nodeBoneOriginMatrices.push_back(transform); - } - else - { - skindata->skinBoneOriginMatrices[index] = transform; - } - - int parentIndex = skindata->getSkinBoneNameIndex(parentid); - if (parentIndex < 0) - { - skindata->addNodeBoneNames(parentid); - parentIndex = skindata->getBoneNameIndex(parentid); - } - - skindata->boneChild[parentIndex].push_back(index); - } - - return true; -} - -bool Bundle3D::loadMaterialDataJson_0_1(MaterialDatas& materialdatas) -{ - if (!_jsonReader.HasMember(MATERIAL)) - return false; - NMaterialData materialData; - const rapidjson::Value& material_data_array = _jsonReader[MATERIAL]; - - if (material_data_array.Size() > 0) - { - const rapidjson::Value& material_data_array_0 = material_data_array[(rapidjson::SizeType)0]; - if (material_data_array_0.HasMember(BASE)) - { - const rapidjson::Value& material_data_base_array = material_data_array_0[BASE]; - const rapidjson::Value& material_data_base_array_0 = material_data_base_array[(rapidjson::SizeType)0]; - NTextureData textureData; - // set texture - std::string filename = material_data_base_array_0[FILENAME].GetString(); - textureData.filename = filename.empty() ? filename : _modelPath + filename; - textureData.type = NTextureData::Usage::Diffuse; - textureData.id = ""; - materialData.textures.push_back(textureData); - materialdatas.materials.push_back(materialData); - } - } - - return true; -} - -bool Bundle3D::loadMaterialDataJson_0_2(MaterialDatas& materialdatas) -{ - if (!_jsonReader.HasMember(MATERIAL)) - return false; - NMaterialData materialData; - const rapidjson::Value& material_array = _jsonReader[MATERIAL]; - - for (rapidjson::SizeType i = 0; i < material_array.Size(); ++i) - { - NTextureData textureData; - const rapidjson::Value& material_val = material_array[i]; - - // set texture - std::string filename = material_val[TEXTURES].GetString(); - textureData.filename = filename.empty() ? filename : _modelPath + filename; - textureData.type = NTextureData::Usage::Diffuse; - textureData.id = ""; - materialData.textures.push_back(textureData); - } - materialdatas.materials.push_back(materialData); - return true; -} - -bool loadMaterialDataJson(MaterialData* /*materialdata*/) -{ - return true; -} - -bool loadMaterialDataJson_0_1(MaterialData* /*materialdata*/) -{ - return true; -} - -bool loadMaterialDataJson_0_2(MaterialData* /*materialdata*/) -{ - return true; -} - -bool Bundle3D::loadAnimationDataJson(std::string_view id, Animation3DData* animationdata) -{ - std::string anim = ""; - if (_version == "1.2" || _version == "0.2") - anim = ANIMATION; - else - anim = ANIMATIONS; - - if (!_jsonReader.HasMember(anim.c_str())) - return false; - int the_index = -1; - const rapidjson::Value& animation_data_array = _jsonReader[anim.c_str()]; - - if (animation_data_array.Size() == 0) - return false; - - if (!id.empty()) - { - for (rapidjson::SizeType i = 0; i < animation_data_array.Size(); ++i) - { - if (animation_data_array[i][ID].GetString() == id) - { - the_index = static_cast(i); - } - } - if (the_index < 0) - return false; - } - else - { - the_index = 0; - } - - const rapidjson::Value& animation_data_array_val_0 = animation_data_array[(rapidjson::SizeType)the_index]; - - animationdata->_totalTime = animation_data_array_val_0[LENGTH].GetFloat(); - - const rapidjson::Value& bones = animation_data_array_val_0[BONES]; - for (rapidjson::SizeType i = 0; i < bones.Size(); ++i) - { - const rapidjson::Value& bone = bones[i]; - std::string bone_name = bone[BONEID].GetString(); - - if (bone.HasMember(KEYFRAMES)) - { - const rapidjson::Value& bone_keyframes = bone[KEYFRAMES]; - rapidjson::SizeType keyframe_size = bone_keyframes.Size(); - animationdata->_rotationKeys[bone_name].reserve(keyframe_size); - animationdata->_scaleKeys[bone_name].reserve(keyframe_size); - animationdata->_translationKeys[bone_name].reserve(keyframe_size); - - for (rapidjson::SizeType j = 0; j < keyframe_size; ++j) - { - const rapidjson::Value& bone_keyframe = bone_keyframes[j]; - - if (bone_keyframe.HasMember(TRANSLATION)) - { - const rapidjson::Value& bone_keyframe_translation = bone_keyframe[TRANSLATION]; - float keytime = bone_keyframe[KEYTIME].GetFloat(); - Vec3 val(bone_keyframe_translation[(rapidjson::SizeType)0].GetFloat(), - bone_keyframe_translation[1].GetFloat(), bone_keyframe_translation[2].GetFloat()); - animationdata->_translationKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime, val)); - } - - if (bone_keyframe.HasMember(ROTATION)) - { - const rapidjson::Value& bone_keyframe_rotation = bone_keyframe[ROTATION]; - float keytime = bone_keyframe[KEYTIME].GetFloat(); - Quaternion val = Quaternion( - bone_keyframe_rotation[(rapidjson::SizeType)0].GetFloat(), bone_keyframe_rotation[1].GetFloat(), - bone_keyframe_rotation[2].GetFloat(), bone_keyframe_rotation[3].GetFloat()); - animationdata->_rotationKeys[bone_name].push_back(Animation3DData::QuatKey(keytime, val)); - } - - if (bone_keyframe.HasMember(SCALE)) - { - const rapidjson::Value& bone_keyframe_scale = bone_keyframe[SCALE]; - float keytime = bone_keyframe[KEYTIME].GetFloat(); - Vec3 val(bone_keyframe_scale[(rapidjson::SizeType)0].GetFloat(), bone_keyframe_scale[1].GetFloat(), - bone_keyframe_scale[2].GetFloat()); - animationdata->_scaleKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime, val)); - } - } - } - } - - return true; -} - -bool Bundle3D::loadAnimationDataBinary(std::string_view id, Animation3DData* animationdata) -{ - - if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4") - { - if (!seekToFirstType(BUNDLE_TYPE_ANIMATIONS)) - return false; - } - else - { - // if id is not a null string, we need to add a suffix of "animation" for seeding. - std::string id_{id}; - if (!id.empty()) - id_.append("animation"); - - if (!seekToFirstType(BUNDLE_TYPE_ANIMATIONS, id_)) - return false; - } - - unsigned int animNum = 1; - if (_version == "0.3" || _version == "0.4") - { - if (!_binaryReader.read(&animNum)) - { - CCLOG("warning: Failed to read AnimationData: animNum '%s'.", _path.c_str()); - return false; - } - } - - bool has_found = false; - for (unsigned int k = 0; k < animNum; ++k) - { - animationdata->resetData(); - std::string animId = _binaryReader.readString(); - - if (!_binaryReader.read(&animationdata->_totalTime)) - { - CCLOG("warning: Failed to read AnimationData: totalTime '%s'.", _path.c_str()); - return false; - } - - unsigned int nodeAnimationNum; - if (!_binaryReader.read(&nodeAnimationNum)) - { - CCLOG("warning: Failed to read AnimationData: animNum '%s'.", _path.c_str()); - return false; - } - for (unsigned int i = 0; i < nodeAnimationNum; ++i) - { - std::string boneName = _binaryReader.readString(); - unsigned int keyframeNum; - if (!_binaryReader.read(&keyframeNum)) - { - CCLOG("warning: Failed to read AnimationData: keyframeNum '%s'.", _path.c_str()); - return false; - } - - animationdata->_rotationKeys[boneName].reserve(keyframeNum); - animationdata->_scaleKeys[boneName].reserve(keyframeNum); - animationdata->_translationKeys[boneName].reserve(keyframeNum); - - for (unsigned int j = 0; j < keyframeNum; ++j) - { - float keytime; - if (!_binaryReader.read(&keytime)) - { - CCLOG("warning: Failed to read AnimationData: keytime '%s'.", _path.c_str()); - return false; - } - - // transform flag - unsigned char transformFlag(0); - if (_version != "0.1" && _version != "0.2" && _version != "0.3") - { - if (!_binaryReader.read(&transformFlag)) - { - CCLOG("warning: Failed to read AnimationData: transformFlag '%s'.", _path.c_str()); - return false; - } - } - - // rotation - bool hasRotate = true; - if (_version != "0.1" && _version != "0.2" && _version != "0.3") - hasRotate = transformFlag & 0x01; - - if (hasRotate) - { - Quaternion rotate; - if (_binaryReader.read(&rotate, 4, 4) != 4) - { - CCLOG("warning: Failed to read AnimationData: rotate '%s'.", _path.c_str()); - return false; - } - animationdata->_rotationKeys[boneName].push_back(Animation3DData::QuatKey(keytime, rotate)); - } - - // scale - bool hasScale = true; - if (_version != "0.1" && _version != "0.2" && _version != "0.3") - hasScale = (transformFlag >> 1) & 0x01; - - if (hasScale) - { - Vec3 scale; - if (_binaryReader.read(&scale, 4, 3) != 3) - { - CCLOG("warning: Failed to read AnimationData: scale '%s'.", _path.c_str()); - return false; - } - animationdata->_scaleKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, scale)); - } - - // translation - bool hasTranslation = true; - if (_version != "0.1" && _version != "0.2" && _version != "0.3") - hasTranslation = (transformFlag >> 2) & 0x01; - - if (hasTranslation) - { - Vec3 position; - if (_binaryReader.read(&position, 4, 3) != 3) - { - CCLOG("warning: Failed to read AnimationData: position '%s'.", _path.c_str()); - return false; - } - animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, position)); - } - } - } - if (id == animId || id.empty()) - { - has_found = true; - break; - } - } - if (!has_found) - { - animationdata->resetData(); - return false; - } - return true; -} - -bool Bundle3D::loadNodesJson(NodeDatas& nodedatas) -{ - if (!_jsonReader.HasMember(NODES)) - return false; - const rapidjson::Value& nodes = _jsonReader[NODES]; - if (!nodes.IsArray()) - return false; - - // traverse the nodes again - for (rapidjson::SizeType i = 0; i < nodes.Size(); ++i) - { - const rapidjson::Value& jnode = nodes[i]; - std::string id = jnode[ID].GetString(); - NodeData* nodedata = parseNodesRecursivelyJson(jnode, nodes.Size() == 1); - - bool isSkeleton = jnode[SKELETON].GetBool(); - if (isSkeleton) - nodedatas.skeleton.push_back(nodedata); - else - nodedatas.nodes.push_back(nodedata); - } - return true; -} -NodeData* Bundle3D::parseNodesRecursivelyJson(const rapidjson::Value& jvalue, bool singleSprite) -{ - NodeData* nodedata = new NodeData(); - // id - nodedata->id = jvalue[ID].GetString(); - - // transform - Mat4 transform; - const rapidjson::Value& jtransform = jvalue[TRANSFORM]; - - for (rapidjson::SizeType j = 0; j < jtransform.Size(); ++j) - { - transform.m[j] = jtransform[j].GetFloat(); - } - - nodedata->transform = transform; - - bool isSkin = false; - - // parts - if (jvalue.HasMember(PARTS)) - { - const rapidjson::Value& parts = jvalue[PARTS]; - - for (rapidjson::SizeType i = 0; i < parts.Size(); ++i) - { - auto modelnodedata = new ModelData(); - const rapidjson::Value& part = parts[i]; - modelnodedata->subMeshId = part[MESHPARTID].GetString(); - modelnodedata->materialId = part[MATERIALID].GetString(); - - if (modelnodedata->subMeshId == "" || modelnodedata->materialId == "") - { - CCLOG("warning: Node %s part is missing meshPartId or materialId", nodedata->id.c_str()); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - - if (part.HasMember(BONES)) - { - const rapidjson::Value& bones = part[BONES]; - - for (rapidjson::SizeType j = 0; j < bones.Size(); ++j) - { - const rapidjson::Value& bone = bones[j]; - - // node - if (!bone.HasMember(NODE)) - { - CCLOG("warning: Bone node ID missing"); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - - modelnodedata->bones.push_back(bone[NODE].GetString()); - - Mat4 invbindpos; - const rapidjson::Value& jinvbindpos = bone[TRANSFORM]; - - for (rapidjson::SizeType k = 0; k < jinvbindpos.Size(); ++k) - { - invbindpos.m[k] = jinvbindpos[k].GetFloat(); - } - - // invbindpos.inverse(); - modelnodedata->invBindPose.push_back(invbindpos); - } - - if (bones.Size() > 0) - isSkin = true; - } - nodedata->modelNodeDatas.push_back(modelnodedata); - } - } - - // set transform - if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4" || _version == "0.5" || - _version == "0.6") - { - if (isSkin || singleSprite) - { - nodedata->transform = Mat4::IDENTITY; - } - else - { - nodedata->transform = transform; - } - } - else - { - nodedata->transform = transform; - } - - if (jvalue.HasMember(CHILDREN)) - { - const rapidjson::Value& children = jvalue[CHILDREN]; - for (rapidjson::SizeType i = 0; i < children.Size(); ++i) - { - const rapidjson::Value& child = children[i]; - - NodeData* tempdata = parseNodesRecursivelyJson(child, singleSprite); - nodedata->children.push_back(tempdata); - } - } - return nodedata; -} - -bool Bundle3D::loadNodesBinary(NodeDatas& nodedatas) -{ - if (!seekToFirstType(BUNDLE_TYPE_NODE)) - return false; - - unsigned int nodeSize = 0; - if (_binaryReader.read(&nodeSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read nodes"); - return false; - } - - // traverse the nodes again - for (rapidjson::SizeType i = 0; i < nodeSize; ++i) - { - bool skeleton = false; - NodeData* nodedata = parseNodesRecursivelyBinary(skeleton, nodeSize == 1); - - if (skeleton) - nodedatas.skeleton.push_back(nodedata); - else - nodedatas.nodes.push_back(nodedata); - } - return true; -} -NodeData* Bundle3D::parseNodesRecursivelyBinary(bool& skeleton, bool singleSprite) -{ - // id - std::string id = _binaryReader.readString(); - // is skeleton - bool skeleton_; - if (_binaryReader.read(&skeleton_, 1, 1) != 1) - { - CCLOG("warning: Failed to read is skeleton"); - return nullptr; - } - if (skeleton_) - skeleton = true; - - // transform - Mat4 transform; - if (!_binaryReader.readMatrix(transform.m)) - { - CCLOG("warning: Failed to read transform matrix"); - return nullptr; - } - // parts - unsigned int partsSize = 0; - if (_binaryReader.read(&partsSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - return nullptr; - } - - NodeData* nodedata = new NodeData(); - nodedata->id = id; - - bool isSkin = false; - - if (partsSize > 0) - { - for (unsigned int i = 0; i < partsSize; ++i) - { - auto modelnodedata = new ModelData(); - modelnodedata->subMeshId = _binaryReader.readString(); - modelnodedata->materialId = _binaryReader.readString(); - - if (modelnodedata->subMeshId.empty() || modelnodedata->materialId.empty()) - { - CCLOG("Node %s part is missing meshPartId or materialId", nodedata->id.c_str()); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - - // read bone - unsigned int bonesSize = 0; - if (_binaryReader.read(&bonesSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - - if (bonesSize > 0) - { - for (unsigned int j = 0; j < bonesSize; ++j) - { - std::string name = _binaryReader.readString(); - modelnodedata->bones.push_back(name); - - Mat4 invbindpos; - if (!_binaryReader.readMatrix(invbindpos.m)) - { - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - - modelnodedata->invBindPose.push_back(invbindpos); - } - isSkin = true; - } - unsigned int uvMapping = 0; - if (_binaryReader.read(&uvMapping, 4, 1) != 1) - { - CCLOG("warning: Failed to read nodedata: uvMapping '%s'.", _path.c_str()); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - for (unsigned int j = 0; j < uvMapping; ++j) - { - unsigned int textureIndexSize = 0; - if (_binaryReader.read(&textureIndexSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - for (unsigned int k = 0; k < textureIndexSize; ++k) - { - unsigned int index = 0; - if (_binaryReader.read(&index, 4, 1) != 1) - { - CC_SAFE_DELETE(modelnodedata); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - } - } - nodedata->modelNodeDatas.push_back(modelnodedata); - } - } - - // set transform - if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4" || _version == "0.5" || - _version == "0.6") - { - if (isSkin || singleSprite) - { - nodedata->transform = Mat4::IDENTITY; - } - else - { - nodedata->transform = transform; - } - } - else - { - nodedata->transform = transform; - } - - unsigned int childrenSize = 0; - if (_binaryReader.read(&childrenSize, 4, 1) != 1) - { - CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); - CC_SAFE_DELETE(nodedata); - return nullptr; - } - if (childrenSize > 0) - { - for (unsigned int i = 0; i < childrenSize; ++i) - { - NodeData* tempdata = parseNodesRecursivelyBinary(skeleton, singleSprite); - nodedata->children.push_back(tempdata); - } - } - return nodedata; -} - -backend::VertexFormat Bundle3D::parseGLDataType(std::string_view str, int size) -{ - backend::VertexFormat ret = backend::VertexFormat::INT; - if (str == "GL_BYTE") - { - switch (size) - { - case 4: - return backend::VertexFormat::UBYTE4; - default: - CCLOGERROR("parseVertexType GL_BYTE x %d error", size); - } - } - else if (str == "GL_UNSIGNED_BYTE") - { - switch (size) - { - case 4: - return backend::VertexFormat::UBYTE4; - default: - CCLOGERROR("parseVertexType GL_UNSIGNED_BYTE x %d error", size); - } - } - else if (str == "GL_SHORT") - { - switch (size) - { - case 2: - return backend::VertexFormat::USHORT2; - case 4: - return backend::VertexFormat::USHORT4; - default: - CCLOGERROR("parseVertexType GL_SHORT x %d error", size); - } - } - else if (str == "GL_UNSIGNED_SHORT") - { - switch (size) - { - case 2: - return backend::VertexFormat::USHORT2; - case 4: - return backend::VertexFormat::USHORT4; - default: - CCLOGERROR("parseVertexType GL_UNSIGNED_SHORT x %d error", size); - } - } - else if (str == "GL_INT") - { - switch (size) - { - case 1: - return backend::VertexFormat::INT; - case 2: - return backend::VertexFormat::INT2; - case 3: - return backend::VertexFormat::INT3; - case 4: - return backend::VertexFormat::INT4; - default: - CCLOGERROR("parseVertexType GL_INT x %d error", size); - } - } - else if (str == "GL_UNSIGNED_INT") - { - switch (size) - { - case 1: - return backend::VertexFormat::INT; - case 2: - return backend::VertexFormat::INT2; - case 3: - return backend::VertexFormat::INT3; - case 4: - return backend::VertexFormat::INT4; - default: - CCLOGERROR("parseVertexType GL_UNSIGNED_INT x %d error", size); - } - } - else if (str == "GL_FLOAT") - { - switch (size) - { - case 1: - return backend::VertexFormat::FLOAT; - case 2: - return backend::VertexFormat::FLOAT2; - case 3: - return backend::VertexFormat::FLOAT3; - case 4: - return backend::VertexFormat::FLOAT4; - default: - CCLOGERROR("parseVertexType GL_UNSIGNED_INT x %d error", size); - } - } - CCASSERT(false, "parseVertexType failed!"); - return ret; -} - -backend::SamplerAddressMode Bundle3D::parseSamplerAddressMode(std::string_view str) -{ - - if (str == "REPEAT") - { - return backend::SamplerAddressMode::REPEAT; - } - else if (str == "CLAMP") - { - return backend::SamplerAddressMode::CLAMP_TO_EDGE; - } - else - { - CCASSERT(false, "Invalid GL type"); - return backend::SamplerAddressMode::REPEAT; - } -} - -NTextureData::Usage Bundle3D::parseGLTextureType(std::string_view str) -{ - if (str == "AMBIENT") - { - return NTextureData::Usage::Ambient; - } - else if (str == "BUMP") - { - return NTextureData::Usage::Bump; - } - else if (str == "DIFFUSE") - { - return NTextureData::Usage::Diffuse; - } - else if (str == "EMISSIVE") - { - return NTextureData::Usage::Emissive; - } - else if (str == "NONE") - { - return NTextureData::Usage::None; - } - else if (str == "NORMAL") - { - return NTextureData::Usage::Normal; - } - else if (str == "REFLECTION") - { - return NTextureData::Usage::Reflection; - } - else if (str == "SHININESS") - { - return NTextureData::Usage::Shininess; - } - else if (str == "SPECULAR") - { - return NTextureData::Usage::Specular; - } - else if (str == "TRANSPARENCY") - { - return NTextureData::Usage::Transparency; - } - else - { - CCASSERT(false, "Wrong Texture type"); - return NTextureData::Usage::Unknown; - } -} -shaderinfos::VertexKey Bundle3D::parseGLProgramAttribute(std::string_view str) -{ - if (str == "VERTEX_ATTRIB_POSITION") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; - } - else if (str == "VERTEX_ATTRIB_COLOR") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_COLOR; - } - else if (str == "VERTEX_ATTRIB_TEX_COORD") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; - } - else if (str == "VERTEX_ATTRIB_TEX_COORD1") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD1; - } - else if (str == "VERTEX_ATTRIB_TEX_COORD2") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD2; - } - else if (str == "VERTEX_ATTRIB_TEX_COORD3") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD3; - } - // comment out them - // else if (str == "VERTEX_ATTRIB_TEX_COORD4") - // { - // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD4; - // } - // else if (str == "VERTEX_ATTRIB_TEX_COORD5") - // { - // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD5; - // } - // else if (str == "VERTEX_ATTRIB_TEX_COORD6") - // { - // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD6; - // } - // else if (str == "VERTEX_ATTRIB_TEX_COORD7") - // { - // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD7; - // } - else if (str == "VERTEX_ATTRIB_NORMAL") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; - } - else if (str == "VERTEX_ATTRIB_BLEND_WEIGHT") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; - } - else if (str == "VERTEX_ATTRIB_BLEND_INDEX") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; - } - else if (str == "VERTEX_ATTRIB_TANGENT") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_TANGENT; - } - else if (str == "VERTEX_ATTRIB_BINORMAL") - { - return shaderinfos::VertexKey::VERTEX_ATTRIB_BINORMAL; - } - else - { - CCASSERT(false, "Wrong Attribute type"); - return shaderinfos::VertexKey::VERTEX_ATTRIB_ERROR; - } -} - -void Bundle3D::getModelRelativePath(std::string_view path) -{ - ssize_t index = path.find_last_of('/'); - std::string fullModelPath; - _modelPath = path.substr(0, index + 1); -} - -Reference* Bundle3D::seekToFirstType(unsigned int type, std::string_view id) -{ - // for each Reference - for (unsigned int i = 0; i < _referenceCount; ++i) - { - Reference* ref = &_references[i]; - if (ref->type == type) - { - // if id is not a null string, we also need to check the Reference's id. - if (id != "" && id != ref->id) - { - continue; - } - - // Found a match - if (_binaryReader.seek(ref->offset, SEEK_SET) == false) - { - CCLOG("warning: Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str()); - return nullptr; - } - return ref; - } - } - return nullptr; -} - -std::vector Bundle3D::getTrianglesList(std::string_view path) -{ - std::vector trianglesList; - - if (path.length() <= 4) - return trianglesList; - - auto bundle = Bundle3D::createBundle(); - std::string ext = FileUtils::getInstance()->getFileExtension(path); - MeshDatas meshs; - if (ext == ".obj") - { - MaterialDatas materials; - NodeDatas nodes; - if (!Bundle3D::loadObj(meshs, materials, nodes, path)) - { - Bundle3D::destroyBundle(bundle); - return trianglesList; - } - } - else - { - if (!bundle->load(path)) - { - Bundle3D::destroyBundle(bundle); - return trianglesList; - } - - bundle->loadMeshDatas(meshs); - } - - Bundle3D::destroyBundle(bundle); - for (auto iter : meshs.meshDatas) - { - int preVertexSize = iter->getPerVertexSize() / sizeof(float); - for (const auto& indexArray : iter->subMeshIndices) - { - for (auto i : indexArray) - { - trianglesList.push_back(Vec3(iter->vertex[i * preVertexSize], iter->vertex[i * preVertexSize + 1], - iter->vertex[i * preVertexSize + 2])); - } - } - } - - return trianglesList; -} - -Bundle3D::Bundle3D() - : _modelPath(""), _path(""), _version(""), _referenceCount(0), _references(nullptr), _isBinary(false) -{} -Bundle3D::~Bundle3D() -{ - clear(); -} - -cocos2d::AABB Bundle3D::calculateAABB(const std::vector& vertex, - int stride, - const IndexArray& indices) -{ - AABB aabb; - stride /= 4; - - indices.for_each ([&](uint32_t i) { - Vec3 point(vertex[i * stride], vertex[i * stride + 1], vertex[i * stride + 2]); - aabb.updateMinMax(&point, 1); - }); - - return aabb; -} - -NS_CC_END +// Trigger github local ci \ No newline at end of file From 78150ff25a3eb73f83e2451d0d25ae891a89e56b Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Sun, 3 Jul 2022 23:25:36 +0300 Subject: [PATCH 14/46] Revert "Update CCBundle3D.cpp [skip ci]" This reverts commit 07bbe4e06c5c8c44e1f5e26cbda3811c10c27fd8. --- core/3d/CCBundle3D.cpp | 2342 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 2341 insertions(+), 1 deletion(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 32f1489ce0..2c59fb9d1a 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -1 +1,2341 @@ -// Trigger github local ci \ No newline at end of file +/**************************************************************************** +Copyright (c) 2014-2016 Chukong Technologies Inc. +Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd. +Copyright (c) 2021 Bytedance Inc. + + https://adxeproject.github.io/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#include "3d/CCBundle3D.h" +#include "3d/CCObjLoader.h" + +#include "base/ccMacros.h" +#include "platform/CCFileUtils.h" +#include "3d/CCBundleReader.h" +#include "base/CCData.h" + +#define BUNDLE_TYPE_SCENE 1 +#define BUNDLE_TYPE_NODE 2 +#define BUNDLE_TYPE_ANIMATIONS 3 +#define BUNDLE_TYPE_ANIMATION 4 +#define BUNDLE_TYPE_ANIMATION_CHANNEL 5 +#define BUNDLE_TYPE_MODEL 10 +#define BUNDLE_TYPE_MATERIAL 16 +#define BUNDLE_TYPE_EFFECT 18 +#define BUNDLE_TYPE_CAMERA 32 +#define BUNDLE_TYPE_LIGHT 33 +#define BUNDLE_TYPE_MESH 34 +#define BUNDLE_TYPE_MESHPART 35 +#define BUNDLE_TYPE_MESHSKIN 36 + +static const char* VERSION = "version"; +static const char* ID = "id"; +static const char* DEFAULTPART = "body"; +static const char* VERTEXSIZE = "vertexsize"; +static const char* VERTEX = "vertex"; +static const char* VERTICES = "vertices"; +static const char* INDEXNUM = "indexnum"; +static const char* INDICES = "indices"; +static const char* SUBMESH = "submesh"; +static const char* ATTRIBUTES = "attributes"; +static const char* ATTRIBUTESIZE = "size"; +static const char* TYPE = "type"; +static const char* ATTRIBUTE = "attribute"; +static const char* SKIN = "skin"; +static const char* BINDSHAPE = "bindshape"; +static const char* MESH = "mesh"; +static const char* MESHES = "meshes"; +static const char* MESHPARTID = "meshpartid"; +static const char* MATERIALID = "materialid"; +static const char* NODE = "node"; +static const char* NODES = "nodes"; +static const char* CHILDREN = "children"; +static const char* PARTS = "parts"; +static const char* BONES = "bones"; +static const char* SKELETON = "skeleton"; +static const char* MATERIALS = "materials"; +static const char* ANIMATIONS = "animations"; +static const char* TRANSFORM = "transform"; +static const char* OLDTRANSFORM = "tansform"; +static const char* ANIMATION = "animation"; +static const char* MATERIAL = "material"; +static const char* BASE = "base"; +static const char* FILENAME = "filename"; +static const char* TEXTURES = "textures"; +static const char* LENGTH = "length"; +static const char* BONEID = "boneId"; +static const char* KEYFRAMES = "keyframes"; +static const char* TRANSLATION = "translation"; +static const char* ROTATION = "rotation"; +static const char* SCALE = "scale"; +static const char* KEYTIME = "keytime"; +static const char* AABBS = "aabb"; + +NS_CC_BEGIN + +void getChildMap(std::map>& map, SkinData* skinData, const rapidjson::Value& val) +{ + if (!skinData) + return; + + // get transform matrix + Mat4 transform; + const rapidjson::Value& parent_transform = val[OLDTRANSFORM]; + for (rapidjson::SizeType j = 0, size = parent_transform.Size(); j < size; ++j) + { + transform.m[j] = parent_transform[j].GetFloat(); + } + + // set origin matrices + std::string parent_name = val[ID].GetString(); + int parent_name_index = skinData->getSkinBoneNameIndex(parent_name); + if (parent_name_index < 0) + { + skinData->addNodeBoneNames(parent_name); + skinData->nodeBoneOriginMatrices.push_back(transform); + parent_name_index = skinData->getBoneNameIndex(parent_name); + } + else if (parent_name_index < static_cast(skinData->skinBoneNames.size())) + { + skinData->skinBoneOriginMatrices[parent_name_index] = transform; + } + + // set root bone index + if (skinData->rootBoneIndex < 0) + skinData->rootBoneIndex = parent_name_index; + + if (!val.HasMember(CHILDREN)) + return; + + const rapidjson::Value& children = val[CHILDREN]; + for (rapidjson::SizeType i = 0, size = children.Size(); i < size; ++i) + { + // get child bone name + const rapidjson::Value& child = children[i]; + + std::string child_name = child[ID].GetString(); + int child_name_index = skinData->getSkinBoneNameIndex(child_name); + if (child_name_index < 0) + { + skinData->addNodeBoneNames(child_name); + child_name_index = skinData->getBoneNameIndex(child_name); + } + + map[parent_name_index].push_back(child_name_index); + + getChildMap(map, skinData, child); + } +} + +Bundle3D* Bundle3D::createBundle() +{ + auto bundle = new Bundle3D(); + return bundle; +} + +void Bundle3D::destroyBundle(Bundle3D* bundle) +{ + delete bundle; +} + +void Bundle3D::clear() +{ + if (_isBinary) + { + _binaryBuffer.clear(); + CC_SAFE_DELETE_ARRAY(_references); + } + else + { + _jsonBuffer.clear(); + } +} + +bool Bundle3D::load(std::string_view path) +{ + if (path.empty()) + return false; + + if (_path == path) + return true; + + getModelRelativePath(path); + + bool ret = false; + std::string ext = FileUtils::getInstance()->getFileExtension(path); + if (ext == ".c3t") + { + _isBinary = false; + ret = loadJson(path); + } + else if (ext == ".c3b") + { + _isBinary = true; + ret = loadBinary(path); + } + else + { + CCLOG("warning: %s is invalid file formate", path.data()); + } + + ret ? (_path = path) : (_path = ""); + + return ret; +} + +bool Bundle3D::loadObj(MeshDatas& meshdatas, + MaterialDatas& materialdatas, + NodeDatas& nodedatas, + std::string_view fullPath, + const char* mtl_basepath) +{ + meshdatas.resetData(); + materialdatas.resetData(); + nodedatas.resetData(); + + std::string mtlPath = ""; + if (mtl_basepath) + mtlPath = mtl_basepath; + else + mtlPath = fullPath.substr(0, fullPath.find_last_of("\\/") + 1); + + std::vector shapes; + std::vector materials; + auto ret = tinyobj::LoadObj(shapes, materials, fullPath.data(), mtlPath.c_str()); + if (ret.empty()) + { + // fill data + // convert material + int i = 0; + char str[20]; + std::string dir = ""; + auto last = fullPath.rfind('/'); + if (last != std::string::npos) + dir = fullPath.substr(0, last + 1); + for (auto& material : materials) + { + NMaterialData materialdata; + + NTextureData tex; + tex.filename = material.diffuse_texname.empty() ? material.diffuse_texname : dir + material.diffuse_texname; + tex.type = NTextureData::Usage::Diffuse; + tex.wrapS = backend::SamplerAddressMode::CLAMP_TO_EDGE; + tex.wrapT = backend::SamplerAddressMode::CLAMP_TO_EDGE; + + sprintf(str, "%d", ++i); + materialdata.textures.push_back(tex); + materialdata.id = str; + material.name = str; + materialdatas.materials.push_back(materialdata); + } + + // convert mesh + i = 0; + for (auto& shape : shapes) + { + auto mesh = shape.mesh; + MeshData* meshdata = new MeshData(); + MeshVertexAttrib attrib; + attrib.type = parseGLDataType("GL_FLOAT", 3); + + if (mesh.positions.size()) + { + attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; + meshdata->attribs.push_back(attrib); + } + bool hasnormal = false, hastex = false; + if (mesh.normals.size()) + { + hasnormal = true; + attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; + meshdata->attribs.push_back(attrib); + } + if (mesh.texcoords.size()) + { + hastex = true; + attrib.type = parseGLDataType("GL_FLOAT", 2); + attrib.vertexAttrib = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; + meshdata->attribs.push_back(attrib); + } + + auto vertexNum = mesh.positions.size() / 3; + for (unsigned int k = 0; k < vertexNum; ++k) + { + meshdata->vertex.push_back(mesh.positions[k * 3]); + meshdata->vertex.push_back(mesh.positions[k * 3 + 1]); + meshdata->vertex.push_back(mesh.positions[k * 3 + 2]); + + if (hasnormal) + { + meshdata->vertex.push_back(mesh.normals[k * 3]); + meshdata->vertex.push_back(mesh.normals[k * 3 + 1]); + meshdata->vertex.push_back(mesh.normals[k * 3 + 2]); + } + + if (hastex) + { + meshdata->vertex.push_back(mesh.texcoords[k * 2]); + meshdata->vertex.push_back(mesh.texcoords[k * 2 + 1]); + } + } + + // split into submesh according to material + std::map subMeshMap; + for (size_t k = 0, size = mesh.material_ids.size(); k < size; ++k) + { + int id = mesh.material_ids[k]; + size_t idx = k * 3; + subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); + } + + auto node = new NodeData(); + node->id = shape.name; + for (auto& submesh : subMeshMap) + { + meshdata->subMeshIndices.push_back(submesh.second); + meshdata->subMeshAABB.push_back( + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); + sprintf(str, "%d", ++i); + meshdata->subMeshIds.push_back(str); + + auto modelnode = new ModelData(); + modelnode->materialId = submesh.first == -1 ? "" : materials[submesh.first].name; + modelnode->subMeshId = str; + node->modelNodeDatas.push_back(modelnode); + } + nodedatas.nodes.push_back(node); + meshdatas.meshDatas.push_back(meshdata); + } + + return true; + } + CCLOG("warning: load %s file error: %s", fullPath.data(), ret.c_str()); + return false; +} + +bool Bundle3D::loadSkinData(std::string_view /*id*/, SkinData* skindata) +{ + skindata->resetData(); + + if (_isBinary) + { + return loadSkinDataBinary(skindata); + } + else + { + return loadSkinDataJson(skindata); + } +} + +bool Bundle3D::loadAnimationData(std::string_view id, Animation3DData* animationdata) +{ + animationdata->resetData(); + + if (_isBinary) + { + return loadAnimationDataBinary(id, animationdata); + } + else + { + return loadAnimationDataJson(id, animationdata); + } +} + +// since 3.3, to support reskin +bool Bundle3D::loadMeshDatas(MeshDatas& meshdatas) +{ + meshdatas.resetData(); + if (_isBinary) + { + if (_version == "0.1" || _version == "0.2") + { + return loadMeshDatasBinary_0_1(meshdatas); + } + else + { + return loadMeshDatasBinary(meshdatas); + } + } + else + { + if (_version == "1.2" || _version == "0.2") + { + return loadMeshDataJson_0_1(meshdatas); + } + else + { + return loadMeshDatasJson(meshdatas); + } + } + return true; +} +bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MESH)) + return false; + unsigned int meshSize = 0; + if (_binaryReader.read(&meshSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + return false; + } + MeshData* meshData = nullptr; + for (unsigned int i = 0; i < meshSize; ++i) + { + unsigned int attribSize = 0; + // read mesh data + if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + goto FAILED; + } + meshData = new MeshData(); + meshData->attribCount = attribSize; + meshData->attribs.resize(meshData->attribCount); + for (ssize_t j = 0; j < meshData->attribCount; ++j) + { + std::string attribute = ""; + unsigned int vSize; + if (_binaryReader.read(&vSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); + goto FAILED; + } + std::string type = _binaryReader.readString(); + attribute = _binaryReader.readString(); + meshData->attribs[j].type = parseGLDataType(type, vSize); + meshData->attribs[j].vertexAttrib = parseGLProgramAttribute(attribute); + } + unsigned int vertexSizeInFloat = 0; + // Read vertex data + if (_binaryReader.read(&vertexSizeInFloat, 4, 1) != 1 || vertexSizeInFloat == 0) + { + CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); + goto FAILED; + } + + meshData->vertex.resize(vertexSizeInFloat); + if (_binaryReader.read(&meshData->vertex[0], 4, vertexSizeInFloat) != vertexSizeInFloat) + { + CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); + goto FAILED; + } + + // Read index data + unsigned int meshPartCount = 1; + _binaryReader.read(&meshPartCount, 4, 1); + + for (unsigned int k = 0; k < meshPartCount; ++k) + { + IndexArray indexArray{CustomCommand::IndexFormat::U_SHORT}; // TODO: _version == 1.3 use U_INT? + std::string meshPartid = _binaryReader.readString(); + meshData->subMeshIds.push_back(meshPartid); + unsigned int nIndexCount; + if (_binaryReader.read(&nIndexCount, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); + goto FAILED; + } + indexArray.resize(nIndexCount); + if (_binaryReader.read(indexArray.data(), 2, nIndexCount) != nIndexCount) + { + CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); + goto FAILED; + } + meshData->subMeshIndices.push_back(indexArray); + meshData->numIndex = (int)meshData->subMeshIndices.size(); + // meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), + // indexArray)); + if (_version != "0.3" && _version != "0.4" && _version != "0.5") + { + // read mesh aabb + float aabb[6]; + if (_binaryReader.read(aabb, 4, 6) != 6) + { + CCLOG("warning: Failed to read meshdata: aabb '%s'.", _path.c_str()); + goto FAILED; + } + meshData->subMeshAABB.push_back(AABB(Vec3(aabb[0], aabb[1], aabb[2]), Vec3(aabb[3], aabb[4], aabb[5]))); + } + else + { + meshData->subMeshAABB.push_back( + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + } + } + meshdatas.meshDatas.push_back(meshData); + } + return true; + +FAILED: +{ + CC_SAFE_DELETE(meshData); + for (auto& meshdata : meshdatas.meshDatas) + { + delete meshdata; + } + meshdatas.meshDatas.clear(); + return false; +} +} +bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MESH)) + return false; + + meshdatas.resetData(); + + MeshData* meshdata = new MeshData(); + + // read mesh data + unsigned int attribSize = 0; + if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + enum + { + VERTEX_ATTRIB_POSITION, + VERTEX_ATTRIB_COLOR, + VERTEX_ATTRIB_TEX_COORD, + VERTEX_ATTRIB_NORMAL, + VERTEX_ATTRIB_BLEND_WEIGHT, + VERTEX_ATTRIB_BLEND_INDEX, + + VERTEX_ATTRIB_MAX, + + // backward compatibility + VERTEX_ATTRIB_TEX_COORDS = VERTEX_ATTRIB_TEX_COORD, + }; + for (unsigned int i = 0; i < attribSize; ++i) + { + unsigned int vUsage, vSize; + shaderinfos::VertexKey usage; + if (_binaryReader.read(&vUsage, 4, 1) != 1 || _binaryReader.read(&vSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + MeshVertexAttrib meshVertexAttribute; + meshVertexAttribute.type = parseGLDataType("GL_FLOAT", vSize); + if (vUsage == VERTEX_ATTRIB_NORMAL) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; + } + else if (vUsage == VERTEX_ATTRIB_BLEND_WEIGHT) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; + } + else if (vUsage == VERTEX_ATTRIB_BLEND_INDEX) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; + } + else if (vUsage == VERTEX_ATTRIB_POSITION) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; + } + else if (vUsage == VERTEX_ATTRIB_TEX_COORD) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; + } + else + { + CCASSERT(false, "invalidate usage value"); + } + meshVertexAttribute.vertexAttrib = usage; + + meshdata->attribs.push_back(meshVertexAttribute); + } + + // Read vertex data + if (_binaryReader.read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0) + { + CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + meshdata->vertex.resize(meshdata->vertexSizeInFloat); + if (_binaryReader.read(&meshdata->vertex[0], 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat) + { + CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + // Read index data + unsigned int meshPartCount = 1; + for (unsigned int i = 0; i < meshPartCount; ++i) + { + unsigned int nIndexCount; + if (_binaryReader.read(&nIndexCount, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + IndexArray indices; + indices.resize(nIndexCount); + if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) + { + CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + meshdata->subMeshIndices.push_back(indices); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + } + + meshdatas.meshDatas.push_back(meshdata); + return true; +} + +bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MESH)) + return false; + + meshdatas.resetData(); + + MeshData* meshdata = new MeshData(); + + // read mesh data + unsigned int attribSize = 0; + if (_binaryReader.read(&attribSize, 4, 1) != 1 || attribSize < 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + enum + { + VERTEX_ATTRIB_POSITION, + VERTEX_ATTRIB_COLOR, + VERTEX_ATTRIB_TEX_COORD, + VERTEX_ATTRIB_NORMAL, + VERTEX_ATTRIB_BLEND_WEIGHT, + VERTEX_ATTRIB_BLEND_INDEX, + + VERTEX_ATTRIB_MAX, + + // backward compatibility + VERTEX_ATTRIB_TEX_COORDS = VERTEX_ATTRIB_TEX_COORD, + }; + for (unsigned int i = 0; i < attribSize; ++i) + { + unsigned int vUsage, vSize; + shaderinfos::VertexKey usage = shaderinfos::VertexKey::VERTEX_ATTRIB_ERROR; + if (_binaryReader.read(&vUsage, 4, 1) != 1 || _binaryReader.read(&vSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: usage or size '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + MeshVertexAttrib meshVertexAttribute; + meshVertexAttribute.type = parseGLDataType("GL_FLOAT", vSize); + if (vUsage == VERTEX_ATTRIB_NORMAL) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; + } + else if (vUsage == VERTEX_ATTRIB_BLEND_WEIGHT) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; + } + else if (vUsage == VERTEX_ATTRIB_BLEND_INDEX) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; + } + else if (vUsage == VERTEX_ATTRIB_POSITION) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; + } + else if (vUsage == VERTEX_ATTRIB_TEX_COORD) + { + usage = shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; + } + meshVertexAttribute.vertexAttrib = usage; + + meshdata->attribs.push_back(meshVertexAttribute); + } + + // Read vertex data + if (_binaryReader.read(&meshdata->vertexSizeInFloat, 4, 1) != 1 || meshdata->vertexSizeInFloat == 0) + { + CCLOG("warning: Failed to read meshdata: vertexSizeInFloat '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + meshdata->vertex.resize(meshdata->vertexSizeInFloat); + if (_binaryReader.read(&meshdata->vertex[0], 4, meshdata->vertexSizeInFloat) != meshdata->vertexSizeInFloat) + { + CCLOG("warning: Failed to read meshdata: vertex element '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + // read submesh + unsigned int submeshCount; + if (_binaryReader.read(&submeshCount, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: submeshCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + for (unsigned int i = 0; i < submeshCount; ++i) + { + unsigned int nIndexCount; + if (_binaryReader.read(&nIndexCount, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: nIndexCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + IndexArray indices{CustomCommand::IndexFormat::U_SHORT}; /* TODO: _version == 1.3 use U_INT?*/ + indices.resize(nIndexCount); + if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) + { + CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); + CC_SAFE_DELETE(meshdata); + return false; + } + + meshdata->subMeshIndices.push_back(indices); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + } + + meshdatas.meshDatas.push_back(meshdata); + + return true; +} +bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) +{ + const rapidjson::Value& mesh_data_array = _jsonReader[MESHES]; + for (rapidjson::SizeType index = 0, mesh_data_array_size = mesh_data_array.Size(); index < mesh_data_array_size; + ++index) + { + MeshData* meshData = new MeshData(); + const rapidjson::Value& mesh_data = mesh_data_array[index]; + // mesh_vertex_attribute + const rapidjson::Value& mesh_vertex_attribute = mesh_data[ATTRIBUTES]; + MeshVertexAttrib tempAttrib; + meshData->attribCount = mesh_vertex_attribute.Size(); + meshData->attribs.resize(meshData->attribCount); + for (rapidjson::SizeType i = 0, mesh_vertex_attribute_size = mesh_vertex_attribute.Size(); + i < mesh_vertex_attribute_size; ++i) + { + const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; + + int size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetInt(); + std::string type = mesh_vertex_attribute_val[TYPE].GetString(); + std::string attribute = mesh_vertex_attribute_val[ATTRIBUTE].GetString(); + + tempAttrib.type = parseGLDataType(type, size); + tempAttrib.vertexAttrib = parseGLProgramAttribute(attribute); + meshData->attribs[i] = tempAttrib; + } + // mesh vertices + //////////////////////////////////////////////////////////////////////////////////////////////// + const rapidjson::Value& mesh_data_vertex_array = mesh_data[VERTICES]; + auto mesh_data_vertex_array_size = mesh_data_vertex_array.Size(); + meshData->vertexSizeInFloat = mesh_data_vertex_array_size; + for (rapidjson::SizeType i = 0; i < mesh_data_vertex_array_size; ++i) + { + meshData->vertex.push_back(mesh_data_vertex_array[i].GetFloat()); + } + // mesh part + //////////////////////////////////////////////////////////////////////////////////////////////// + const rapidjson::Value& mesh_part_array = mesh_data[PARTS]; + for (rapidjson::SizeType i = 0, mesh_part_array_size = mesh_part_array.Size(); i < mesh_part_array_size; ++i) + { + IndexArray indexArray; + const rapidjson::Value& mesh_part = mesh_part_array[i]; + meshData->subMeshIds.push_back(mesh_part[ID].GetString()); + // index_number + const rapidjson::Value& indices_val_array = mesh_part[INDICES]; + for (rapidjson::SizeType j = 0, indices_val_array_size = indices_val_array.Size(); + j < indices_val_array_size; ++j) + indexArray.push_back((unsigned int)indices_val_array[j].GetUint()); + + meshData->subMeshIndices.push_back(indexArray); + meshData->numIndex = (int)meshData->subMeshIndices.size(); + + if (mesh_data.HasMember(AABBS)) + { + const rapidjson::Value& mesh_part_aabb = mesh_part[AABBS]; + if (mesh_part.HasMember(AABBS) && mesh_part_aabb.Size() == 6) + { + Vec3 min(mesh_part_aabb[(rapidjson::SizeType)0].GetFloat(), + mesh_part_aabb[(rapidjson::SizeType)1].GetFloat(), + mesh_part_aabb[(rapidjson::SizeType)2].GetFloat()); + Vec3 max(mesh_part_aabb[(rapidjson::SizeType)3].GetFloat(), + mesh_part_aabb[(rapidjson::SizeType)4].GetFloat(), + mesh_part_aabb[(rapidjson::SizeType)5].GetFloat()); + meshData->subMeshAABB.push_back(AABB(min, max)); + } + else + { + meshData->subMeshAABB.push_back( + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + } + } + else + { + meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), + indexArray)); + } + } + meshdatas.meshDatas.push_back(meshData); + } + return true; +} +bool Bundle3D::loadNodes(NodeDatas& nodedatas) +{ + if (_version == "0.1" || _version == "1.2" || _version == "0.2") + { + SkinData skinData; + if (!loadSkinData("", &skinData)) + { + auto node = new NodeData(); + auto modelnode = new ModelData(); + modelnode->materialId = ""; + modelnode->subMeshId = ""; + node->modelNodeDatas.push_back(modelnode); + nodedatas.nodes.push_back(node); + return true; + } + + auto nodeDatas = new NodeData*[skinData.skinBoneNames.size() + skinData.nodeBoneNames.size()]; + int index = 0; + size_t i; + auto skinBoneSize = skinData.skinBoneNames.size(); + auto nodeBoneSize = skinData.nodeBoneNames.size(); + for (i = 0; i < skinBoneSize; ++i) + { + nodeDatas[index] = new NodeData(); + nodeDatas[index]->id = skinData.skinBoneNames[i]; + nodeDatas[index]->transform = skinData.skinBoneOriginMatrices[i]; + ++index; + } + for (i = 0; i < nodeBoneSize; ++i) + { + nodeDatas[index] = new NodeData(); + nodeDatas[index]->id = skinData.nodeBoneNames[i]; + nodeDatas[index]->transform = skinData.nodeBoneOriginMatrices[i]; + ++index; + } + for (const auto& it : skinData.boneChild) + { + const auto& children = it.second; + auto parent = nodeDatas[it.first]; + for (const auto& child : children) + { + parent->children.push_back(nodeDatas[child]); + } + } + nodedatas.skeleton.push_back(nodeDatas[skinData.rootBoneIndex]); + auto node = new NodeData(); + auto modelnode = new ModelData(); + modelnode->materialId = ""; + modelnode->subMeshId = ""; + modelnode->bones = skinData.skinBoneNames; + modelnode->invBindPose = skinData.inverseBindPoseMatrices; + node->modelNodeDatas.push_back(modelnode); + nodedatas.nodes.push_back(node); + delete[] nodeDatas; + } + else + { + if (_isBinary) + { + loadNodesBinary(nodedatas); + } + else + { + loadNodesJson(nodedatas); + } + } + return true; +} +bool Bundle3D::loadMaterials(MaterialDatas& materialdatas) +{ + materialdatas.resetData(); + if (_isBinary) + { + if (_version == "0.1") + { + return loadMaterialsBinary_0_1(materialdatas); + } + else if (_version == "0.2") + { + return loadMaterialsBinary_0_2(materialdatas); + } + else + { + return loadMaterialsBinary(materialdatas); + } + } + else + { + if (_version == "1.2") + { + return loadMaterialDataJson_0_1(materialdatas); + } + else if (_version == "0.2") + { + return loadMaterialDataJson_0_2(materialdatas); + } + else + { + return loadMaterialsJson(materialdatas); + } + } + return true; +} +bool Bundle3D::loadMaterialsBinary(MaterialDatas& materialdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) + return false; + unsigned int materialnum = 1; + _binaryReader.read(&materialnum, 4, 1); + for (unsigned int i = 0; i < materialnum; ++i) + { + NMaterialData materialData; + materialData.id = _binaryReader.readString(); + + // skip: diffuse(3), ambient(3), emissive(3), opacity(1), specular(3), shininess(1) + float data[14]; + _binaryReader.read(&data, sizeof(float), 14); + + unsigned int textureNum = 1; + _binaryReader.read(&textureNum, 4, 1); + for (unsigned int j = 0; j < textureNum; ++j) + { + NTextureData textureData; + textureData.id = _binaryReader.readString(); + if (textureData.id.empty()) + { + CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", textureData.id.c_str()); + return false; + } + std::string texturePath = _binaryReader.readString(); + if (texturePath.empty()) + { + CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); + return false; + } + + textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; + float uvdata[4]; + _binaryReader.read(&uvdata, sizeof(float), 4); + textureData.type = parseGLTextureType(_binaryReader.readString()); + textureData.wrapS = parseSamplerAddressMode(_binaryReader.readString()); + textureData.wrapT = parseSamplerAddressMode(_binaryReader.readString()); + materialData.textures.push_back(textureData); + } + materialdatas.materials.push_back(materialData); + } + return true; +} +bool Bundle3D::loadMaterialsBinary_0_1(MaterialDatas& materialdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) + return false; + + NMaterialData materialData; + + std::string texturePath = _binaryReader.readString(); + if (texturePath.empty()) + { + CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); + return false; + } + + NTextureData textureData; + textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; + textureData.type = NTextureData::Usage::Diffuse; + textureData.id = ""; + materialData.textures.push_back(textureData); + materialdatas.materials.push_back(materialData); + return true; +} + +bool Bundle3D::loadMaterialsBinary_0_2(MaterialDatas& materialdatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_MATERIAL)) + return false; + + unsigned int materialnum = 1; + _binaryReader.read(&materialnum, 4, 1); + + for (unsigned int i = 0; i < materialnum; ++i) + { + NMaterialData materialData; + + std::string texturePath = _binaryReader.readString(); + if (texturePath.empty()) + { + CCLOG("warning: Failed to read Materialdata: texturePath is empty '%s'.", _path.c_str()); + return true; + } + + NTextureData textureData; + textureData.filename = texturePath.empty() ? texturePath : _modelPath + texturePath; + textureData.type = NTextureData::Usage::Diffuse; + textureData.id = ""; + materialData.textures.push_back(textureData); + materialdatas.materials.push_back(materialData); + } + return true; +} + +bool loadMeshDataJson(MeshData* /*meshdata*/) +{ + return true; +} + +bool loadMeshDataJson_0_1(MeshData* /*meshdata*/) +{ + return true; +} + +bool loadMeshDataJson_0_2(MeshData* /*meshdata*/) +{ + return true; +} + +bool Bundle3D::loadMaterialsJson(MaterialDatas& materialdatas) +{ + if (!_jsonReader.HasMember(MATERIALS)) + return false; + const rapidjson::Value& material_array = _jsonReader[MATERIALS]; + for (rapidjson::SizeType i = 0; i < material_array.Size(); ++i) + { + NMaterialData materialData; + const rapidjson::Value& material_val = material_array[i]; + materialData.id = material_val[ID].GetString(); + if (material_val.HasMember(TEXTURES)) + { + const rapidjson::Value& texture_array = material_val[TEXTURES]; + for (rapidjson::SizeType j = 0; j < texture_array.Size(); ++j) + { + NTextureData textureData; + const rapidjson::Value& texture_val = texture_array[j]; + std::string filename = texture_val[FILENAME].GetString(); + textureData.filename = filename.empty() ? filename : _modelPath + filename; + textureData.type = parseGLTextureType(texture_val["type"].GetString()); + textureData.wrapS = parseSamplerAddressMode(texture_val["wrapModeU"].GetString()); + textureData.wrapT = parseSamplerAddressMode(texture_val["wrapModeV"].GetString()); + materialData.textures.push_back(textureData); + } + } + materialdatas.materials.push_back(materialData); + } + return true; +} +bool Bundle3D::loadJson(std::string_view path) +{ + clear(); + + _jsonBuffer = FileUtils::getInstance()->getStringFromFile(path); + + if (_jsonReader.ParseInsitu<0>((char*)_jsonBuffer.c_str()).HasParseError()) + { + clear(); + CCLOG("Parse json failed in Bundle3D::loadJson function"); + return false; + } + + const rapidjson::Value& mash_data_array = _jsonReader[VERSION]; + if (mash_data_array.IsArray()) // Compatible with the old version + _version = "1.2"; + else + _version = mash_data_array.GetString(); + + return true; +} + +bool Bundle3D::loadBinary(std::string_view path) +{ + clear(); + + // get file data + _binaryBuffer.clear(); + _binaryBuffer = FileUtils::getInstance()->getDataFromFile(path); + if (_binaryBuffer.isNull()) + { + clear(); + CCLOG("warning: Failed to read file: %s", path.data()); + return false; + } + + // Initialise bundle reader + _binaryReader.init((char*)_binaryBuffer.getBytes(), _binaryBuffer.getSize()); + + // Read identifier info + char identifier[] = {'C', '3', 'B', '\0'}; + char sig[4]; + if (_binaryReader.read(sig, 1, 4) != 4 || memcmp(sig, identifier, 4) != 0) + { + clear(); + CCLOG("warning: Invalid identifier: %s", path.data()); + return false; + } + + // Read version + unsigned char ver[2]; + if (_binaryReader.read(ver, 1, 2) != 2) + { + CCLOG("warning: Failed to read version:"); + return false; + } + + char version[20] = {0}; + sprintf(version, "%d.%d", ver[0], ver[1]); + _version = version; + + // Read ref table size + if (_binaryReader.read(&_referenceCount, 4, 1) != 1) + { + clear(); + CCLOG("warning: Failed to read ref table size '%s'.", path.data()); + return false; + } + + // Read all refs + CC_SAFE_DELETE_ARRAY(_references); + _references = new Reference[_referenceCount]; + for (unsigned int i = 0; i < _referenceCount; ++i) + { + if ((_references[i].id = _binaryReader.readString()).empty() || + _binaryReader.read(&_references[i].type, 4, 1) != 1 || + _binaryReader.read(&_references[i].offset, 4, 1) != 1) + { + clear(); + CCLOG("warning: Failed to read ref number %u for bundle '%s'.", i, path.data()); + CC_SAFE_DELETE_ARRAY(_references); + return false; + } + } + + return true; +} + +bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) +{ + const rapidjson::Value& mesh_data_array = _jsonReader[MESH]; + MeshData* meshdata = new MeshData(); + const rapidjson::Value& mesh_data_val = mesh_data_array[(rapidjson::SizeType)0]; + + const rapidjson::Value& mesh_data_body_array = mesh_data_val[DEFAULTPART]; + + const rapidjson::Value& mesh_data_body_array_0 = mesh_data_body_array[(rapidjson::SizeType)0]; + + // mesh_vertex_attribute + const rapidjson::Value& mesh_vertex_attribute = mesh_data_val[ATTRIBUTES]; + meshdata->attribCount = mesh_vertex_attribute.Size(); + meshdata->attribs.resize(meshdata->attribCount); + for (rapidjson::SizeType i = 0; i < mesh_vertex_attribute.Size(); ++i) + { + const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; + + int size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetUint(); + meshdata->attribs[i].type = parseGLDataType(mesh_vertex_attribute_val[TYPE].GetString(), size); + meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val[ATTRIBUTE].GetString()); + } + + // vertices + meshdata->vertexSizeInFloat = mesh_data_body_array_0[VERTEXSIZE].GetInt(); + meshdata->vertex.resize(meshdata->vertexSizeInFloat); + + const rapidjson::Value& mesh_data_body_vertices = mesh_data_body_array_0[VERTICES]; + for (rapidjson::SizeType i = 0; i < mesh_data_body_vertices.Size(); ++i) + meshdata->vertex[i] = mesh_data_body_vertices[i].GetFloat(); + + // index_number + unsigned int indexnum = mesh_data_body_array_0[INDEXNUM].GetUint(); + + // indices + IndexArray indices; + indices.resize(indexnum); + + const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; + for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) + indices.at(i) = (unsigned short)indices_val_array[i].GetUint(); + + meshdata->subMeshIndices.push_back(indices); + meshdata->subMeshAABB.push_back( + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + meshdatas.meshDatas.push_back(meshdata); + return true; +} + +bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) +{ + MeshData* meshdata = new MeshData(); + const rapidjson::Value& mesh_array = _jsonReader[MESH]; + const rapidjson::Value& mesh_array_0 = mesh_array[(rapidjson::SizeType)0]; + + // mesh_vertex_attribute + const rapidjson::Value& mesh_vertex_attribute = mesh_array_0[ATTRIBUTES]; + meshdata->attribCount = mesh_vertex_attribute.Size(); + meshdata->attribs.resize(meshdata->attribCount); + for (rapidjson::SizeType i = 0; i < mesh_vertex_attribute.Size(); ++i) + { + const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i]; + + auto size = mesh_vertex_attribute_val[ATTRIBUTESIZE].GetUint(); + meshdata->attribs[i].type = parseGLDataType(mesh_vertex_attribute_val[TYPE].GetString(), size); + meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val[ATTRIBUTE].GetString()); + } + + // vertices + const rapidjson::Value& mesh_data_vertex = mesh_array_0[VERTEX]; + const rapidjson::Value& mesh_data_vertex_0 = mesh_data_vertex[(rapidjson::SizeType)0]; + + meshdata->vertexSizeInFloat = mesh_data_vertex_0[VERTEXSIZE].GetInt(); + meshdata->vertex.resize(meshdata->vertexSizeInFloat); + + const rapidjson::Value& mesh_data_body_vertices = mesh_data_vertex_0[VERTICES]; + for (rapidjson::SizeType i = 0; i < mesh_data_body_vertices.Size(); ++i) + meshdata->vertex[i] = mesh_data_body_vertices[i].GetFloat(); + + // submesh + const rapidjson::Value& mesh_submesh_array = mesh_array_0[SUBMESH]; + for (rapidjson::SizeType i = 0; i < mesh_submesh_array.Size(); ++i) + { + const rapidjson::Value& mesh_submesh_val = mesh_submesh_array[i]; + // std::string id = mesh_submesh_val[ID].GetString(); + + // index_number + unsigned int indexnum = mesh_submesh_val[INDEXNUM].GetUint(); + + // indices + IndexArray indices; + indices.resize(indexnum); + + const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; + for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) + indices.at(j) = (unsigned short)indices_val_array[j].GetUint(); + + meshdata->subMeshIndices.push_back(indices); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + } + meshdatas.meshDatas.push_back(meshdata); + return true; +} + +bool Bundle3D::loadSkinDataJson(SkinData* skindata) +{ + if (!_jsonReader.HasMember(SKIN)) + return false; + + const rapidjson::Value& skin_data_array = _jsonReader[SKIN]; + + CCASSERT(skin_data_array.IsArray(), "skin data is not an array"); + const rapidjson::Value& skin_data_array_val_0 = skin_data_array[(rapidjson::SizeType)0]; + + if (!skin_data_array_val_0.HasMember(BONES)) + return false; + + const rapidjson::Value& skin_data_bones = skin_data_array_val_0[BONES]; + for (rapidjson::SizeType i = 0; i < skin_data_bones.Size(); ++i) + { + const rapidjson::Value& skin_data_bone = skin_data_bones[i]; + std::string name = skin_data_bone[NODE].GetString(); + skindata->addSkinBoneNames(name); + + Mat4 mat_bind_pos; + const rapidjson::Value& bind_pos = skin_data_bone[BINDSHAPE]; + for (rapidjson::SizeType j = 0; j < bind_pos.Size(); ++j) + { + mat_bind_pos.m[j] = bind_pos[j].GetFloat(); + } + skindata->inverseBindPoseMatrices.push_back(mat_bind_pos); + } + + // set root bone information + const rapidjson::Value& skin_data_1 = skin_data_array[1]; + + // parent and child relationship map + skindata->skinBoneOriginMatrices.resize(skindata->skinBoneNames.size()); + getChildMap(skindata->boneChild, skindata, skin_data_1); + return true; +} + +bool Bundle3D::loadSkinDataBinary(SkinData* skindata) +{ + if (!seekToFirstType(BUNDLE_TYPE_MESHSKIN)) + return false; + + std::string boneName = _binaryReader.readString(); + + // transform + float bindShape[16]; + if (!_binaryReader.readMatrix(bindShape)) + { + CCLOG("warning: Failed to read SkinData: bindShape matrix '%s'.", _path.c_str()); + return false; + } + + // bone count + unsigned int boneNum; + if (!_binaryReader.read(&boneNum)) + { + CCLOG("warning: Failed to read SkinData: boneNum '%s'.", _path.c_str()); + return false; + } + + // Fix bug: check if the bone number is 0. + if (boneNum == 0) + return false; + + // bone names and bind pos + float bindpos[16]; + for (unsigned int i = 0; i < boneNum; ++i) + { + std::string skinBoneName = _binaryReader.readString(); + skindata->skinBoneNames.push_back(skinBoneName); + if (!_binaryReader.readMatrix(bindpos)) + { + CCLOG("warning: Failed to load SkinData: bindpos '%s'.", _path.c_str()); + return false; + } + skindata->inverseBindPoseMatrices.push_back(bindpos); + } + + skindata->skinBoneOriginMatrices.resize(boneNum); + + boneName = _binaryReader.readString(); + + // bind shape + _binaryReader.readMatrix(bindShape); + int rootIndex = skindata->getSkinBoneNameIndex(boneName); + if (rootIndex < 0) + { + skindata->addNodeBoneNames(boneName); + rootIndex = skindata->getBoneNameIndex(boneName); + skindata->nodeBoneOriginMatrices.push_back(bindShape); + } + else + { + skindata->skinBoneOriginMatrices[rootIndex] = bindShape; + } + + // set root bone index + skindata->rootBoneIndex = rootIndex; + + // read parent and child relationship map + float transform[16]; + unsigned int linkNum; + _binaryReader.read(&linkNum); + for (unsigned int i = 0; i < linkNum; ++i) + { + std::string id = _binaryReader.readString(); + int index = skindata->getSkinBoneNameIndex(id); + + std::string parentid = _binaryReader.readString(); + + if (!_binaryReader.readMatrix(transform)) + { + CCLOG("warning: Failed to load SkinData: transform '%s'.", _path.c_str()); + return false; + } + + if (index < 0) + { + skindata->addNodeBoneNames(id); + index = skindata->getBoneNameIndex(id); + skindata->nodeBoneOriginMatrices.push_back(transform); + } + else + { + skindata->skinBoneOriginMatrices[index] = transform; + } + + int parentIndex = skindata->getSkinBoneNameIndex(parentid); + if (parentIndex < 0) + { + skindata->addNodeBoneNames(parentid); + parentIndex = skindata->getBoneNameIndex(parentid); + } + + skindata->boneChild[parentIndex].push_back(index); + } + + return true; +} + +bool Bundle3D::loadMaterialDataJson_0_1(MaterialDatas& materialdatas) +{ + if (!_jsonReader.HasMember(MATERIAL)) + return false; + NMaterialData materialData; + const rapidjson::Value& material_data_array = _jsonReader[MATERIAL]; + + if (material_data_array.Size() > 0) + { + const rapidjson::Value& material_data_array_0 = material_data_array[(rapidjson::SizeType)0]; + if (material_data_array_0.HasMember(BASE)) + { + const rapidjson::Value& material_data_base_array = material_data_array_0[BASE]; + const rapidjson::Value& material_data_base_array_0 = material_data_base_array[(rapidjson::SizeType)0]; + NTextureData textureData; + // set texture + std::string filename = material_data_base_array_0[FILENAME].GetString(); + textureData.filename = filename.empty() ? filename : _modelPath + filename; + textureData.type = NTextureData::Usage::Diffuse; + textureData.id = ""; + materialData.textures.push_back(textureData); + materialdatas.materials.push_back(materialData); + } + } + + return true; +} + +bool Bundle3D::loadMaterialDataJson_0_2(MaterialDatas& materialdatas) +{ + if (!_jsonReader.HasMember(MATERIAL)) + return false; + NMaterialData materialData; + const rapidjson::Value& material_array = _jsonReader[MATERIAL]; + + for (rapidjson::SizeType i = 0; i < material_array.Size(); ++i) + { + NTextureData textureData; + const rapidjson::Value& material_val = material_array[i]; + + // set texture + std::string filename = material_val[TEXTURES].GetString(); + textureData.filename = filename.empty() ? filename : _modelPath + filename; + textureData.type = NTextureData::Usage::Diffuse; + textureData.id = ""; + materialData.textures.push_back(textureData); + } + materialdatas.materials.push_back(materialData); + return true; +} + +bool loadMaterialDataJson(MaterialData* /*materialdata*/) +{ + return true; +} + +bool loadMaterialDataJson_0_1(MaterialData* /*materialdata*/) +{ + return true; +} + +bool loadMaterialDataJson_0_2(MaterialData* /*materialdata*/) +{ + return true; +} + +bool Bundle3D::loadAnimationDataJson(std::string_view id, Animation3DData* animationdata) +{ + std::string anim = ""; + if (_version == "1.2" || _version == "0.2") + anim = ANIMATION; + else + anim = ANIMATIONS; + + if (!_jsonReader.HasMember(anim.c_str())) + return false; + int the_index = -1; + const rapidjson::Value& animation_data_array = _jsonReader[anim.c_str()]; + + if (animation_data_array.Size() == 0) + return false; + + if (!id.empty()) + { + for (rapidjson::SizeType i = 0; i < animation_data_array.Size(); ++i) + { + if (animation_data_array[i][ID].GetString() == id) + { + the_index = static_cast(i); + } + } + if (the_index < 0) + return false; + } + else + { + the_index = 0; + } + + const rapidjson::Value& animation_data_array_val_0 = animation_data_array[(rapidjson::SizeType)the_index]; + + animationdata->_totalTime = animation_data_array_val_0[LENGTH].GetFloat(); + + const rapidjson::Value& bones = animation_data_array_val_0[BONES]; + for (rapidjson::SizeType i = 0; i < bones.Size(); ++i) + { + const rapidjson::Value& bone = bones[i]; + std::string bone_name = bone[BONEID].GetString(); + + if (bone.HasMember(KEYFRAMES)) + { + const rapidjson::Value& bone_keyframes = bone[KEYFRAMES]; + rapidjson::SizeType keyframe_size = bone_keyframes.Size(); + animationdata->_rotationKeys[bone_name].reserve(keyframe_size); + animationdata->_scaleKeys[bone_name].reserve(keyframe_size); + animationdata->_translationKeys[bone_name].reserve(keyframe_size); + + for (rapidjson::SizeType j = 0; j < keyframe_size; ++j) + { + const rapidjson::Value& bone_keyframe = bone_keyframes[j]; + + if (bone_keyframe.HasMember(TRANSLATION)) + { + const rapidjson::Value& bone_keyframe_translation = bone_keyframe[TRANSLATION]; + float keytime = bone_keyframe[KEYTIME].GetFloat(); + Vec3 val(bone_keyframe_translation[(rapidjson::SizeType)0].GetFloat(), + bone_keyframe_translation[1].GetFloat(), bone_keyframe_translation[2].GetFloat()); + animationdata->_translationKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime, val)); + } + + if (bone_keyframe.HasMember(ROTATION)) + { + const rapidjson::Value& bone_keyframe_rotation = bone_keyframe[ROTATION]; + float keytime = bone_keyframe[KEYTIME].GetFloat(); + Quaternion val = Quaternion( + bone_keyframe_rotation[(rapidjson::SizeType)0].GetFloat(), bone_keyframe_rotation[1].GetFloat(), + bone_keyframe_rotation[2].GetFloat(), bone_keyframe_rotation[3].GetFloat()); + animationdata->_rotationKeys[bone_name].push_back(Animation3DData::QuatKey(keytime, val)); + } + + if (bone_keyframe.HasMember(SCALE)) + { + const rapidjson::Value& bone_keyframe_scale = bone_keyframe[SCALE]; + float keytime = bone_keyframe[KEYTIME].GetFloat(); + Vec3 val(bone_keyframe_scale[(rapidjson::SizeType)0].GetFloat(), bone_keyframe_scale[1].GetFloat(), + bone_keyframe_scale[2].GetFloat()); + animationdata->_scaleKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime, val)); + } + } + } + } + + return true; +} + +bool Bundle3D::loadAnimationDataBinary(std::string_view id, Animation3DData* animationdata) +{ + + if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4") + { + if (!seekToFirstType(BUNDLE_TYPE_ANIMATIONS)) + return false; + } + else + { + // if id is not a null string, we need to add a suffix of "animation" for seeding. + std::string id_{id}; + if (!id.empty()) + id_.append("animation"); + + if (!seekToFirstType(BUNDLE_TYPE_ANIMATIONS, id_)) + return false; + } + + unsigned int animNum = 1; + if (_version == "0.3" || _version == "0.4") + { + if (!_binaryReader.read(&animNum)) + { + CCLOG("warning: Failed to read AnimationData: animNum '%s'.", _path.c_str()); + return false; + } + } + + bool has_found = false; + for (unsigned int k = 0; k < animNum; ++k) + { + animationdata->resetData(); + std::string animId = _binaryReader.readString(); + + if (!_binaryReader.read(&animationdata->_totalTime)) + { + CCLOG("warning: Failed to read AnimationData: totalTime '%s'.", _path.c_str()); + return false; + } + + unsigned int nodeAnimationNum; + if (!_binaryReader.read(&nodeAnimationNum)) + { + CCLOG("warning: Failed to read AnimationData: animNum '%s'.", _path.c_str()); + return false; + } + for (unsigned int i = 0; i < nodeAnimationNum; ++i) + { + std::string boneName = _binaryReader.readString(); + unsigned int keyframeNum; + if (!_binaryReader.read(&keyframeNum)) + { + CCLOG("warning: Failed to read AnimationData: keyframeNum '%s'.", _path.c_str()); + return false; + } + + animationdata->_rotationKeys[boneName].reserve(keyframeNum); + animationdata->_scaleKeys[boneName].reserve(keyframeNum); + animationdata->_translationKeys[boneName].reserve(keyframeNum); + + for (unsigned int j = 0; j < keyframeNum; ++j) + { + float keytime; + if (!_binaryReader.read(&keytime)) + { + CCLOG("warning: Failed to read AnimationData: keytime '%s'.", _path.c_str()); + return false; + } + + // transform flag + unsigned char transformFlag(0); + if (_version != "0.1" && _version != "0.2" && _version != "0.3") + { + if (!_binaryReader.read(&transformFlag)) + { + CCLOG("warning: Failed to read AnimationData: transformFlag '%s'.", _path.c_str()); + return false; + } + } + + // rotation + bool hasRotate = true; + if (_version != "0.1" && _version != "0.2" && _version != "0.3") + hasRotate = transformFlag & 0x01; + + if (hasRotate) + { + Quaternion rotate; + if (_binaryReader.read(&rotate, 4, 4) != 4) + { + CCLOG("warning: Failed to read AnimationData: rotate '%s'.", _path.c_str()); + return false; + } + animationdata->_rotationKeys[boneName].push_back(Animation3DData::QuatKey(keytime, rotate)); + } + + // scale + bool hasScale = true; + if (_version != "0.1" && _version != "0.2" && _version != "0.3") + hasScale = (transformFlag >> 1) & 0x01; + + if (hasScale) + { + Vec3 scale; + if (_binaryReader.read(&scale, 4, 3) != 3) + { + CCLOG("warning: Failed to read AnimationData: scale '%s'.", _path.c_str()); + return false; + } + animationdata->_scaleKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, scale)); + } + + // translation + bool hasTranslation = true; + if (_version != "0.1" && _version != "0.2" && _version != "0.3") + hasTranslation = (transformFlag >> 2) & 0x01; + + if (hasTranslation) + { + Vec3 position; + if (_binaryReader.read(&position, 4, 3) != 3) + { + CCLOG("warning: Failed to read AnimationData: position '%s'.", _path.c_str()); + return false; + } + animationdata->_translationKeys[boneName].push_back(Animation3DData::Vec3Key(keytime, position)); + } + } + } + if (id == animId || id.empty()) + { + has_found = true; + break; + } + } + if (!has_found) + { + animationdata->resetData(); + return false; + } + return true; +} + +bool Bundle3D::loadNodesJson(NodeDatas& nodedatas) +{ + if (!_jsonReader.HasMember(NODES)) + return false; + const rapidjson::Value& nodes = _jsonReader[NODES]; + if (!nodes.IsArray()) + return false; + + // traverse the nodes again + for (rapidjson::SizeType i = 0; i < nodes.Size(); ++i) + { + const rapidjson::Value& jnode = nodes[i]; + std::string id = jnode[ID].GetString(); + NodeData* nodedata = parseNodesRecursivelyJson(jnode, nodes.Size() == 1); + + bool isSkeleton = jnode[SKELETON].GetBool(); + if (isSkeleton) + nodedatas.skeleton.push_back(nodedata); + else + nodedatas.nodes.push_back(nodedata); + } + return true; +} +NodeData* Bundle3D::parseNodesRecursivelyJson(const rapidjson::Value& jvalue, bool singleSprite) +{ + NodeData* nodedata = new NodeData(); + // id + nodedata->id = jvalue[ID].GetString(); + + // transform + Mat4 transform; + const rapidjson::Value& jtransform = jvalue[TRANSFORM]; + + for (rapidjson::SizeType j = 0; j < jtransform.Size(); ++j) + { + transform.m[j] = jtransform[j].GetFloat(); + } + + nodedata->transform = transform; + + bool isSkin = false; + + // parts + if (jvalue.HasMember(PARTS)) + { + const rapidjson::Value& parts = jvalue[PARTS]; + + for (rapidjson::SizeType i = 0; i < parts.Size(); ++i) + { + auto modelnodedata = new ModelData(); + const rapidjson::Value& part = parts[i]; + modelnodedata->subMeshId = part[MESHPARTID].GetString(); + modelnodedata->materialId = part[MATERIALID].GetString(); + + if (modelnodedata->subMeshId == "" || modelnodedata->materialId == "") + { + CCLOG("warning: Node %s part is missing meshPartId or materialId", nodedata->id.c_str()); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + + if (part.HasMember(BONES)) + { + const rapidjson::Value& bones = part[BONES]; + + for (rapidjson::SizeType j = 0; j < bones.Size(); ++j) + { + const rapidjson::Value& bone = bones[j]; + + // node + if (!bone.HasMember(NODE)) + { + CCLOG("warning: Bone node ID missing"); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + + modelnodedata->bones.push_back(bone[NODE].GetString()); + + Mat4 invbindpos; + const rapidjson::Value& jinvbindpos = bone[TRANSFORM]; + + for (rapidjson::SizeType k = 0; k < jinvbindpos.Size(); ++k) + { + invbindpos.m[k] = jinvbindpos[k].GetFloat(); + } + + // invbindpos.inverse(); + modelnodedata->invBindPose.push_back(invbindpos); + } + + if (bones.Size() > 0) + isSkin = true; + } + nodedata->modelNodeDatas.push_back(modelnodedata); + } + } + + // set transform + if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4" || _version == "0.5" || + _version == "0.6") + { + if (isSkin || singleSprite) + { + nodedata->transform = Mat4::IDENTITY; + } + else + { + nodedata->transform = transform; + } + } + else + { + nodedata->transform = transform; + } + + if (jvalue.HasMember(CHILDREN)) + { + const rapidjson::Value& children = jvalue[CHILDREN]; + for (rapidjson::SizeType i = 0; i < children.Size(); ++i) + { + const rapidjson::Value& child = children[i]; + + NodeData* tempdata = parseNodesRecursivelyJson(child, singleSprite); + nodedata->children.push_back(tempdata); + } + } + return nodedata; +} + +bool Bundle3D::loadNodesBinary(NodeDatas& nodedatas) +{ + if (!seekToFirstType(BUNDLE_TYPE_NODE)) + return false; + + unsigned int nodeSize = 0; + if (_binaryReader.read(&nodeSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read nodes"); + return false; + } + + // traverse the nodes again + for (rapidjson::SizeType i = 0; i < nodeSize; ++i) + { + bool skeleton = false; + NodeData* nodedata = parseNodesRecursivelyBinary(skeleton, nodeSize == 1); + + if (skeleton) + nodedatas.skeleton.push_back(nodedata); + else + nodedatas.nodes.push_back(nodedata); + } + return true; +} +NodeData* Bundle3D::parseNodesRecursivelyBinary(bool& skeleton, bool singleSprite) +{ + // id + std::string id = _binaryReader.readString(); + // is skeleton + bool skeleton_; + if (_binaryReader.read(&skeleton_, 1, 1) != 1) + { + CCLOG("warning: Failed to read is skeleton"); + return nullptr; + } + if (skeleton_) + skeleton = true; + + // transform + Mat4 transform; + if (!_binaryReader.readMatrix(transform.m)) + { + CCLOG("warning: Failed to read transform matrix"); + return nullptr; + } + // parts + unsigned int partsSize = 0; + if (_binaryReader.read(&partsSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + return nullptr; + } + + NodeData* nodedata = new NodeData(); + nodedata->id = id; + + bool isSkin = false; + + if (partsSize > 0) + { + for (unsigned int i = 0; i < partsSize; ++i) + { + auto modelnodedata = new ModelData(); + modelnodedata->subMeshId = _binaryReader.readString(); + modelnodedata->materialId = _binaryReader.readString(); + + if (modelnodedata->subMeshId.empty() || modelnodedata->materialId.empty()) + { + CCLOG("Node %s part is missing meshPartId or materialId", nodedata->id.c_str()); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + + // read bone + unsigned int bonesSize = 0; + if (_binaryReader.read(&bonesSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + + if (bonesSize > 0) + { + for (unsigned int j = 0; j < bonesSize; ++j) + { + std::string name = _binaryReader.readString(); + modelnodedata->bones.push_back(name); + + Mat4 invbindpos; + if (!_binaryReader.readMatrix(invbindpos.m)) + { + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + + modelnodedata->invBindPose.push_back(invbindpos); + } + isSkin = true; + } + unsigned int uvMapping = 0; + if (_binaryReader.read(&uvMapping, 4, 1) != 1) + { + CCLOG("warning: Failed to read nodedata: uvMapping '%s'.", _path.c_str()); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + for (unsigned int j = 0; j < uvMapping; ++j) + { + unsigned int textureIndexSize = 0; + if (_binaryReader.read(&textureIndexSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + for (unsigned int k = 0; k < textureIndexSize; ++k) + { + unsigned int index = 0; + if (_binaryReader.read(&index, 4, 1) != 1) + { + CC_SAFE_DELETE(modelnodedata); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + } + } + nodedata->modelNodeDatas.push_back(modelnodedata); + } + } + + // set transform + if (_version == "0.1" || _version == "0.2" || _version == "0.3" || _version == "0.4" || _version == "0.5" || + _version == "0.6") + { + if (isSkin || singleSprite) + { + nodedata->transform = Mat4::IDENTITY; + } + else + { + nodedata->transform = transform; + } + } + else + { + nodedata->transform = transform; + } + + unsigned int childrenSize = 0; + if (_binaryReader.read(&childrenSize, 4, 1) != 1) + { + CCLOG("warning: Failed to read meshdata: attribCount '%s'.", _path.c_str()); + CC_SAFE_DELETE(nodedata); + return nullptr; + } + if (childrenSize > 0) + { + for (unsigned int i = 0; i < childrenSize; ++i) + { + NodeData* tempdata = parseNodesRecursivelyBinary(skeleton, singleSprite); + nodedata->children.push_back(tempdata); + } + } + return nodedata; +} + +backend::VertexFormat Bundle3D::parseGLDataType(std::string_view str, int size) +{ + backend::VertexFormat ret = backend::VertexFormat::INT; + if (str == "GL_BYTE") + { + switch (size) + { + case 4: + return backend::VertexFormat::UBYTE4; + default: + CCLOGERROR("parseVertexType GL_BYTE x %d error", size); + } + } + else if (str == "GL_UNSIGNED_BYTE") + { + switch (size) + { + case 4: + return backend::VertexFormat::UBYTE4; + default: + CCLOGERROR("parseVertexType GL_UNSIGNED_BYTE x %d error", size); + } + } + else if (str == "GL_SHORT") + { + switch (size) + { + case 2: + return backend::VertexFormat::USHORT2; + case 4: + return backend::VertexFormat::USHORT4; + default: + CCLOGERROR("parseVertexType GL_SHORT x %d error", size); + } + } + else if (str == "GL_UNSIGNED_SHORT") + { + switch (size) + { + case 2: + return backend::VertexFormat::USHORT2; + case 4: + return backend::VertexFormat::USHORT4; + default: + CCLOGERROR("parseVertexType GL_UNSIGNED_SHORT x %d error", size); + } + } + else if (str == "GL_INT") + { + switch (size) + { + case 1: + return backend::VertexFormat::INT; + case 2: + return backend::VertexFormat::INT2; + case 3: + return backend::VertexFormat::INT3; + case 4: + return backend::VertexFormat::INT4; + default: + CCLOGERROR("parseVertexType GL_INT x %d error", size); + } + } + else if (str == "GL_UNSIGNED_INT") + { + switch (size) + { + case 1: + return backend::VertexFormat::INT; + case 2: + return backend::VertexFormat::INT2; + case 3: + return backend::VertexFormat::INT3; + case 4: + return backend::VertexFormat::INT4; + default: + CCLOGERROR("parseVertexType GL_UNSIGNED_INT x %d error", size); + } + } + else if (str == "GL_FLOAT") + { + switch (size) + { + case 1: + return backend::VertexFormat::FLOAT; + case 2: + return backend::VertexFormat::FLOAT2; + case 3: + return backend::VertexFormat::FLOAT3; + case 4: + return backend::VertexFormat::FLOAT4; + default: + CCLOGERROR("parseVertexType GL_UNSIGNED_INT x %d error", size); + } + } + CCASSERT(false, "parseVertexType failed!"); + return ret; +} + +backend::SamplerAddressMode Bundle3D::parseSamplerAddressMode(std::string_view str) +{ + + if (str == "REPEAT") + { + return backend::SamplerAddressMode::REPEAT; + } + else if (str == "CLAMP") + { + return backend::SamplerAddressMode::CLAMP_TO_EDGE; + } + else + { + CCASSERT(false, "Invalid GL type"); + return backend::SamplerAddressMode::REPEAT; + } +} + +NTextureData::Usage Bundle3D::parseGLTextureType(std::string_view str) +{ + if (str == "AMBIENT") + { + return NTextureData::Usage::Ambient; + } + else if (str == "BUMP") + { + return NTextureData::Usage::Bump; + } + else if (str == "DIFFUSE") + { + return NTextureData::Usage::Diffuse; + } + else if (str == "EMISSIVE") + { + return NTextureData::Usage::Emissive; + } + else if (str == "NONE") + { + return NTextureData::Usage::None; + } + else if (str == "NORMAL") + { + return NTextureData::Usage::Normal; + } + else if (str == "REFLECTION") + { + return NTextureData::Usage::Reflection; + } + else if (str == "SHININESS") + { + return NTextureData::Usage::Shininess; + } + else if (str == "SPECULAR") + { + return NTextureData::Usage::Specular; + } + else if (str == "TRANSPARENCY") + { + return NTextureData::Usage::Transparency; + } + else + { + CCASSERT(false, "Wrong Texture type"); + return NTextureData::Usage::Unknown; + } +} +shaderinfos::VertexKey Bundle3D::parseGLProgramAttribute(std::string_view str) +{ + if (str == "VERTEX_ATTRIB_POSITION") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_POSITION; + } + else if (str == "VERTEX_ATTRIB_COLOR") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_COLOR; + } + else if (str == "VERTEX_ATTRIB_TEX_COORD") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD; + } + else if (str == "VERTEX_ATTRIB_TEX_COORD1") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD1; + } + else if (str == "VERTEX_ATTRIB_TEX_COORD2") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD2; + } + else if (str == "VERTEX_ATTRIB_TEX_COORD3") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD3; + } + // comment out them + // else if (str == "VERTEX_ATTRIB_TEX_COORD4") + // { + // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD4; + // } + // else if (str == "VERTEX_ATTRIB_TEX_COORD5") + // { + // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD5; + // } + // else if (str == "VERTEX_ATTRIB_TEX_COORD6") + // { + // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD6; + // } + // else if (str == "VERTEX_ATTRIB_TEX_COORD7") + // { + // return shaderinfos::VertexKey::VERTEX_ATTRIB_TEX_COORD7; + // } + else if (str == "VERTEX_ATTRIB_NORMAL") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_NORMAL; + } + else if (str == "VERTEX_ATTRIB_BLEND_WEIGHT") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_WEIGHT; + } + else if (str == "VERTEX_ATTRIB_BLEND_INDEX") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_BLEND_INDEX; + } + else if (str == "VERTEX_ATTRIB_TANGENT") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_TANGENT; + } + else if (str == "VERTEX_ATTRIB_BINORMAL") + { + return shaderinfos::VertexKey::VERTEX_ATTRIB_BINORMAL; + } + else + { + CCASSERT(false, "Wrong Attribute type"); + return shaderinfos::VertexKey::VERTEX_ATTRIB_ERROR; + } +} + +void Bundle3D::getModelRelativePath(std::string_view path) +{ + ssize_t index = path.find_last_of('/'); + std::string fullModelPath; + _modelPath = path.substr(0, index + 1); +} + +Reference* Bundle3D::seekToFirstType(unsigned int type, std::string_view id) +{ + // for each Reference + for (unsigned int i = 0; i < _referenceCount; ++i) + { + Reference* ref = &_references[i]; + if (ref->type == type) + { + // if id is not a null string, we also need to check the Reference's id. + if (id != "" && id != ref->id) + { + continue; + } + + // Found a match + if (_binaryReader.seek(ref->offset, SEEK_SET) == false) + { + CCLOG("warning: Failed to seek to object '%s' in bundle '%s'.", ref->id.c_str(), _path.c_str()); + return nullptr; + } + return ref; + } + } + return nullptr; +} + +std::vector Bundle3D::getTrianglesList(std::string_view path) +{ + std::vector trianglesList; + + if (path.length() <= 4) + return trianglesList; + + auto bundle = Bundle3D::createBundle(); + std::string ext = FileUtils::getInstance()->getFileExtension(path); + MeshDatas meshs; + if (ext == ".obj") + { + MaterialDatas materials; + NodeDatas nodes; + if (!Bundle3D::loadObj(meshs, materials, nodes, path)) + { + Bundle3D::destroyBundle(bundle); + return trianglesList; + } + } + else + { + if (!bundle->load(path)) + { + Bundle3D::destroyBundle(bundle); + return trianglesList; + } + + bundle->loadMeshDatas(meshs); + } + + Bundle3D::destroyBundle(bundle); + for (auto iter : meshs.meshDatas) + { + int preVertexSize = iter->getPerVertexSize() / sizeof(float); + for (const auto& indexArray : iter->subMeshIndices) + { + for (auto i : indexArray) + { + trianglesList.push_back(Vec3(iter->vertex[i * preVertexSize], iter->vertex[i * preVertexSize + 1], + iter->vertex[i * preVertexSize + 2])); + } + } + } + + return trianglesList; +} + +Bundle3D::Bundle3D() + : _modelPath(""), _path(""), _version(""), _referenceCount(0), _references(nullptr), _isBinary(false) +{} +Bundle3D::~Bundle3D() +{ + clear(); +} + +cocos2d::AABB Bundle3D::calculateAABB(const std::vector& vertex, + int stride, + const IndexArray& indices) +{ + AABB aabb; + stride /= 4; + + indices.for_each ([&](uint32_t i) { + Vec3 point(vertex[i * stride], vertex[i * stride + 1], vertex[i * stride + 2]); + aabb.updateMinMax(&point, 1); + }); + + return aabb; +} + +NS_CC_END From 86a08575ba9b241b5e466321992257261140ec7f Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 4 Jul 2022 09:13:06 +0800 Subject: [PATCH 15/46] Improve class IndexArray --- core/3d/CCBundle3DData.h | 21 ++++++- thirdparty/yasio/detail/byte_buffer.hpp | 78 +++++++++++++++++++------ 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index c411dd9f96..e5387dd32e 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -49,11 +49,28 @@ public: IndexArray() : _format(backend::IndexFormat::U_SHORT) {} IndexArray(backend::IndexFormat format) : _format(format) {} IndexArray(std::initializer_list rhs) : _format(backend::IndexFormat::U_SHORT), _buffer(rhs) {} - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _format(backend::IndexFormat::U_INT), _buffer(rhs) {} + IndexArray(const IndexArray& rhs) : _format(rhs._format), _buffer(rhs._buffer) {} + IndexArray(IndexArray&& rhs) : _format(rhs._format), _buffer(std::move(rhs._buffer)) {} + + IndexArray& operator=(const IndexArray& rhs) { + _format = rhs._format; + _buffer = rhs._buffer; + return *this; + } + IndexArray& operator=(IndexArray&& rhs) { + this->swap(rhs); + return *this; + } + + void swap(IndexArray& rhs) { + std::swap(_format, rhs._format); + _buffer.swap(rhs._buffer); + } + void clear(backend::IndexFormat format = backend::IndexFormat::UNSPEC) { _buffer.clear(); @@ -108,7 +125,7 @@ public: const uint8_t* data() const noexcept { return _buffer.data(); } size_t size() const { return _buffer.size(); } - bool empty() const { return _buffer.size() == 0; } + bool empty() const { return _buffer.empty(); } void resize(size_t size) { _buffer.resize(size * sizeof(uint16_t)); } void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(uint32_t)); } diff --git a/thirdparty/yasio/detail/byte_buffer.hpp b/thirdparty/yasio/detail/byte_buffer.hpp index 67a68c6724..65f1c39e10 100644 --- a/thirdparty/yasio/detail/byte_buffer.hpp +++ b/thirdparty/yasio/detail/byte_buffer.hpp @@ -49,7 +49,8 @@ namespace yasio struct default_allocator { static void* reallocate(void* old_block, size_t /*old_size*/, size_t new_size) { return ::realloc(old_block, new_size); } }; -template class basic_byte_buffer { +template +class basic_byte_buffer { static_assert(std::is_same<_Elem, char>::value || std::is_same<_Elem, unsigned char>::value, "The basic_byte_buffer only accept type which is char or unsigned char!"); @@ -63,39 +64,72 @@ public: basic_byte_buffer(size_t count, std::true_type /*fit*/) { resize_fit(count); } basic_byte_buffer(size_t count, _Elem val) { resize(count, val); } basic_byte_buffer(size_t count, _Elem val, std::true_type /*fit*/) { resize_fit(count, val); } - template basic_byte_buffer(_Iter first, _Iter last) { assign(first, last); } - template basic_byte_buffer(_Iter first, _Iter last, std::true_type /*fit*/) { assign(first, last, std::true_type{}); } + template + basic_byte_buffer(_Iter first, _Iter last) + { + assign(first, last); + } + template + basic_byte_buffer(_Iter first, _Iter last, std::true_type /*fit*/) + { + assign(first, last, std::true_type{}); + } basic_byte_buffer(const basic_byte_buffer& rhs) { assign(rhs); }; basic_byte_buffer(const basic_byte_buffer& rhs, std::true_type /*fit*/) { assign(rhs, std::true_type{}); }; basic_byte_buffer(basic_byte_buffer&& rhs) noexcept { assign(std::move(rhs)); } - template basic_byte_buffer(std::initializer_list<_Ty> rhs) { assign(rhs); } - template basic_byte_buffer(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) { assign(rhs, std::true_type{}); } + template + basic_byte_buffer(std::initializer_list<_Ty> rhs) + { + assign(rhs); + } + template + basic_byte_buffer(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) + { + assign(rhs, std::true_type{}); + } ~basic_byte_buffer() { shrink_to_fit(0); } basic_byte_buffer& operator=(const basic_byte_buffer& rhs) { assign(rhs); return *this; } - basic_byte_buffer& operator=(basic_byte_buffer&& rhs) noexcept { return this->swap(rhs); } - template void assign(const _Iter first, const _Iter last) { _Assign_range(first, last); } - template void assign(const _Iter first, const _Iter last, std::true_type /*fit*/) { _Assign_range(first, last, std::true_type{}); } + basic_byte_buffer& operator=(basic_byte_buffer&& rhs) noexcept + { + this->swap(rhs); + return *this; + } + template + void assign(const _Iter first, const _Iter last) + { + _Assign_range(first, last); + } + template + void assign(const _Iter first, const _Iter last, std::true_type /*fit*/) + { + _Assign_range(first, last, std::true_type{}); + } void assign(const basic_byte_buffer& rhs) { _Assign_range(rhs.begin(), rhs.end()); } void assign(const basic_byte_buffer& rhs, std::true_type) { _Assign_range(rhs.begin(), rhs.end(), std::true_type{}); } void assign(basic_byte_buffer&& rhs) { _Assign_rv(std::move(rhs)); } - template void assign(std::initializer_list<_Ty> rhs) { _Assign_range((_Elem*)rhs.begin(), (_Elem*)rhs.end()); } - template void assign(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) + template + void assign(std::initializer_list<_Ty> rhs) + { + _Assign_range((_Elem*)rhs.begin(), (_Elem*)rhs.end()); + } + template + void assign(std::initializer_list<_Ty> rhs, std::true_type /*fit*/) { _Assign_range((_Elem*)rhs.begin(), (_Elem*)rhs.end(), std::true_type{}); } - basic_byte_buffer& swap(basic_byte_buffer& rhs) noexcept + void swap(basic_byte_buffer& rhs) noexcept { char _Tmp[sizeof(rhs)]; memcpy(_Tmp, &rhs, sizeof(rhs)); memcpy(&rhs, this, sizeof(rhs)); memcpy(this, _Tmp, sizeof(_Tmp)); - return *this; } - template void insert(_Elem* where, _Iter first, const _Iter last) + template + void insert(_Elem* where, _Iter first, const _Iter last) { if (where == _Mylast) append(first, last); @@ -114,8 +148,13 @@ public: } } } - template void append(_Iter first, const _Iter last) { append_n(first, std::distance(first, last)); } - template void append_n(_Iter first, ptrdiff_t count) + template + void append(_Iter first, const _Iter last) + { + append_n(first, std::distance(first, last)); + } + template + void append_n(_Iter first, ptrdiff_t count) { if (count > 0) { @@ -218,7 +257,8 @@ public: _Myend = _Mylast = _Myfirst + len; } } - template _Elem* detach(_TSIZE& len) noexcept + template + _Elem* detach(_TSIZE& len) noexcept { auto ptr = _Myfirst; len = static_cast<_TSIZE>(this->size()); @@ -227,13 +267,15 @@ public: } private: - template void _Assign_range(_Iter first, _Iter last) + template + void _Assign_range(_Iter first, _Iter last) { _Mylast = _Myfirst; if (last > first) std::copy(first, last, resize(std::distance(first, last))); } - template void _Assign_range(_Iter first, _Iter last, std::true_type) + template + void _Assign_range(_Iter first, _Iter last, std::true_type) { _Mylast = _Myfirst; if (last > first) From 0e355244d5b0905a5125e1214daf1259e48eaf01 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 05:55:29 +0300 Subject: [PATCH 16/46] Improve function naming and add descriptions. --- core/3d/CCBundle3DData.h | 36 +++++++++++++++++++++++-------- core/3d/CCMeshVertexIndexData.cpp | 4 ++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index e5387dd32e..2fb0143267 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -48,8 +48,8 @@ class IndexArray public: IndexArray() : _format(backend::IndexFormat::U_SHORT) {} IndexArray(backend::IndexFormat format) : _format(format) {} - IndexArray(std::initializer_list rhs) : _format(backend::IndexFormat::U_SHORT), _buffer(rhs) {} - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) + IndexArray(std::initializer_list rhs) : _format(backend::IndexFormat::U_SHORT), _buffer(rhs) {} + IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _format(backend::IndexFormat::U_INT), _buffer(rhs) {} @@ -78,25 +78,29 @@ public: _format = format; } - void push_back(u_short val) + /** Pushes back a value if type unsigned short (uint16_t). */ + void push_back(uint16_t val) { assert(_format == backend::IndexFormat::U_SHORT); _buffer.append_n((uint8_t*)&val, sizeof(val)); } - void push_back(unsigned int val, std::true_type /*U_INT*/) + /** Pushes back a value if type unsigned int (uint32_t). */ + void push_back(uint32_t val, std::true_type /*U_INT*/) { assert(_format == backend::IndexFormat::U_INT); _buffer.append_n((uint8_t*)&val, sizeof(val)); } + /** Inserts a list containing unsigned short (uint16_t) data. */ void insert(uint8_t* where, std::initializer_list ilist) { assert(_format == backend::IndexFormat::U_SHORT); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } - void insert(uint8_t* where, std::initializer_list ilist, std::true_type) + /** Inserts a list containing unsigned int (uint32_t) data. */ + void insert(uint8_t* where, std::initializer_list ilist, std::true_type) { assert(_format == backend::IndexFormat::U_INT); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); @@ -124,12 +128,26 @@ public: uint8_t* data() noexcept { return _buffer.data(); } const uint8_t* data() const noexcept { return _buffer.data(); } - size_t size() const { return _buffer.size(); } + /** returns the count of indices in the container. */ + size_t size() const + { + return _buffer.size() / (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t)); + } + /** returns the size of the container in bytes. */ + size_t sizeInBytes() const { return _buffer.size(); } + + /** resizes the count of indices in the container. */ + void resize(size_t size) + { + _buffer.resize(size * (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t))); + } + /** resizes the container in bytes. */ + void resizeInBytes(size_t size) { _buffer.resize(size); } + + /** returns true if the container is empty. Otherwise, false. */ bool empty() const { return _buffer.empty(); } - void resize(size_t size) { _buffer.resize(size * sizeof(uint16_t)); } - void resize(size_t size, std::true_type) { _buffer.resize(size * sizeof(uint32_t)); } - + /** returns the format of the index array. */ backend::IndexFormat format() const { return _format; } template diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index f32382bbc2..449cebee6a 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -135,12 +135,12 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: auto& indices = meshdata.subMeshIndices[i]; // auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); auto indexBuffer = backend::Device::getInstance()->newBuffer( - indices.size()/* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); + indices.sizeInBytes() /* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - indexBuffer->updateData((void*)indices.data(), indices.size() /* * indexSize*/); + indexBuffer->updateData((void*)indices.data(), indices.sizeInBytes() /* * indexSize*/); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; From 5c8b5dd003945b903539b703c75de5b06ecfb025 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 06:23:49 +0300 Subject: [PATCH 17/46] Improve function naming. --- core/3d/CCBundle3DData.h | 4 ++-- core/3d/CCMeshVertexIndexData.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 2fb0143267..b400901439 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -134,7 +134,7 @@ public: return _buffer.size() / (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t)); } /** returns the size of the container in bytes. */ - size_t sizeInBytes() const { return _buffer.size(); } + size_t bsize() const { return _buffer.size(); } /** resizes the count of indices in the container. */ void resize(size_t size) @@ -142,7 +142,7 @@ public: _buffer.resize(size * (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t))); } /** resizes the container in bytes. */ - void resizeInBytes(size_t size) { _buffer.resize(size); } + void bresize(size_t size) { _buffer.resize(size); } /** returns true if the container is empty. Otherwise, false. */ bool empty() const { return _buffer.empty(); } diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 449cebee6a..02cff84435 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -135,12 +135,12 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: auto& indices = meshdata.subMeshIndices[i]; // auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); auto indexBuffer = backend::Device::getInstance()->newBuffer( - indices.sizeInBytes() /* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); + indices.bsize() /* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - indexBuffer->updateData((void*)indices.data(), indices.sizeInBytes() /* * indexSize*/); + indexBuffer->updateData((void*)indices.data(), indices.bsize() /* * indexSize*/); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; From dd90911e075139d04edcfcc31b1871cb8b7722d3 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 06:34:44 +0300 Subject: [PATCH 18/46] Add safety checks. --- core/3d/CCBundle3DData.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index b400901439..7527bf0434 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -106,18 +106,14 @@ public: _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } - //template - //void insert(uint8_t* where, _Iter first, const _Iter last) - //{ - // _buffer.insert(where, first, last); - //} - - template + template _Ty& at(size_t idx) { assert((sizeof(_Ty) == sizeof(uint16_t) && _format == backend::IndexFormat::U_SHORT) || (sizeof(_Ty) == sizeof(uint32_t) && _format == backend::IndexFormat::U_INT)); - return (_Ty&)_buffer[idx * sizeof(_Ty)]; + if (idx < this->size()) + return (_Ty&)_buffer[idx * sizeof(_Ty)]; + throw std::out_of_range("IndexArray: out of range!"); } uint8_t* begin() noexcept { return _buffer.begin(); } From 13a9949c3081cf1c0dca8e3794fe0e9908611e27 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 07:23:02 +0300 Subject: [PATCH 19/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 72 +++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 7527bf0434..680ddca234 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -46,28 +46,35 @@ NS_CC_BEGIN class IndexArray { public: - IndexArray() : _format(backend::IndexFormat::U_SHORT) {} - IndexArray(backend::IndexFormat format) : _format(format) {} - IndexArray(std::initializer_list rhs) : _format(backend::IndexFormat::U_SHORT), _buffer(rhs) {} - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) - : _format(backend::IndexFormat::U_INT), _buffer(rhs) - {} + IndexArray() { format(backend::IndexFormat::U_SHORT); } + IndexArray(backend::IndexFormat indexFormat) { format(indexFormat); } - IndexArray(const IndexArray& rhs) : _format(rhs._format), _buffer(rhs._buffer) {} - IndexArray(IndexArray&& rhs) : _format(rhs._format), _buffer(std::move(rhs._buffer)) {} + IndexArray(std::initializer_list rhs) : _buffer(rhs) + { + format(backend::IndexFormat::U_SHORT); + } + + IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _buffer(rhs) + { + format(backend::IndexFormat::U_INT); + } + + IndexArray(const IndexArray& rhs) : _buffer(rhs._buffer) { format(rhs.format()); } + IndexArray(IndexArray&& rhs) noexcept : _buffer(std::move(rhs._buffer)) { this->format(rhs.format()); } IndexArray& operator=(const IndexArray& rhs) { - _format = rhs._format; + _stride = rhs._stride; _buffer = rhs._buffer; return *this; } - IndexArray& operator=(IndexArray&& rhs) { + IndexArray& operator=(IndexArray&& rhs) noexcept + { this->swap(rhs); return *this; } void swap(IndexArray& rhs) { - std::swap(_format, rhs._format); + std::swap(_stride, rhs._stride); _buffer.swap(rhs._buffer); } @@ -75,42 +82,42 @@ public: { _buffer.clear(); if (format != backend::IndexFormat::UNSPEC) - _format = format; + _stride = format == backend::IndexFormat::U_SHORT ? 2 : 4; } /** Pushes back a value if type unsigned short (uint16_t). */ void push_back(uint16_t val) { - assert(_format == backend::IndexFormat::U_SHORT); + assert(_stride == 2); _buffer.append_n((uint8_t*)&val, sizeof(val)); } /** Pushes back a value if type unsigned int (uint32_t). */ void push_back(uint32_t val, std::true_type /*U_INT*/) { - assert(_format == backend::IndexFormat::U_INT); + assert(_stride == 4); _buffer.append_n((uint8_t*)&val, sizeof(val)); } /** Inserts a list containing unsigned short (uint16_t) data. */ - void insert(uint8_t* where, std::initializer_list ilist) + void insert(uint8_t* where, std::initializer_list ilist) { - assert(_format == backend::IndexFormat::U_SHORT); + assert(_stride == 2); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } /** Inserts a list containing unsigned int (uint32_t) data. */ void insert(uint8_t* where, std::initializer_list ilist, std::true_type) { - assert(_format == backend::IndexFormat::U_INT); + assert(_stride == 4); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } template _Ty& at(size_t idx) { - assert((sizeof(_Ty) == sizeof(uint16_t) && _format == backend::IndexFormat::U_SHORT) || - (sizeof(_Ty) == sizeof(uint32_t) && _format == backend::IndexFormat::U_INT)); + assert((sizeof(_Ty) == sizeof(uint16_t) && _stride == 2) || + (sizeof(_Ty) == sizeof(uint32_t) && _stride == 4)); if (idx < this->size()) return (_Ty&)_buffer[idx * sizeof(_Ty)]; throw std::out_of_range("IndexArray: out of range!"); @@ -125,18 +132,12 @@ public: const uint8_t* data() const noexcept { return _buffer.data(); } /** returns the count of indices in the container. */ - size_t size() const - { - return _buffer.size() / (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t)); - } + size_t size() const { return _buffer.size() / _stride; } /** returns the size of the container in bytes. */ size_t bsize() const { return _buffer.size(); } /** resizes the count of indices in the container. */ - void resize(size_t size) - { - _buffer.resize(size * (_format == backend::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t))); - } + void resize(size_t size) { _buffer.resize(size * _stride); } /** resizes the container in bytes. */ void bresize(size_t size) { _buffer.resize(size); } @@ -144,19 +145,28 @@ public: bool empty() const { return _buffer.empty(); } /** returns the format of the index array. */ - backend::IndexFormat format() const { return _format; } + backend::IndexFormat format() const + { + return _stride == 2 ? backend::IndexFormat::U_SHORT : backend::IndexFormat::U_INT; + } + + /** returns the format of the index array. */ + void format(backend::IndexFormat format) + { + _stride = (format == backend::IndexFormat::U_SHORT ? 2 : 4); + } template void for_each(_Fty cb) const { - if (_format == backend::IndexFormat::U_SHORT) + if (format() == backend::IndexFormat::U_SHORT) { for (auto it = (uint16_t*)_buffer.begin(); it != (uint16_t*)_buffer.end(); ++it) { cb(static_cast(*it)); } } - else if (_format == backend::IndexFormat::U_INT) + else if (format() == backend::IndexFormat::U_INT) { for (auto it = (uint32_t*)_buffer.begin(); it != (uint32_t*)_buffer.end(); ++it) { @@ -166,7 +176,7 @@ public: } protected: - backend::IndexFormat _format; + uint8_t _stride; yasio::byte_buffer _buffer; }; From 3a5e8821c2dcca4d25a7d81f65859ebcc8127e5d Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 07:25:04 +0300 Subject: [PATCH 20/46] Update CCBundle3D.cpp --- core/3d/CCBundle3D.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 2c59fb9d1a..63ebb0af37 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -303,9 +303,9 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, { int id = mesh.material_ids[k]; size_t idx = k * 3; - subMeshMap[id].push_back(mesh.indices[idx], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 1], std::true_type{}); - subMeshMap[id].push_back(mesh.indices[idx + 2], std::true_type{}); + subMeshMap[id].push_back(mesh.indices[idx]); + subMeshMap[id].push_back(mesh.indices[idx + 1]); + subMeshMap[id].push_back(mesh.indices[idx + 2]); } auto node = new NodeData(); From 6c242f3e356dfdc58b7212d70663431c8a3059ab Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 07:27:35 +0300 Subject: [PATCH 21/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 680ddca234..0a69d9dd93 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -156,22 +156,15 @@ public: _stride = (format == backend::IndexFormat::U_SHORT ? 2 : 4); } - template + template void for_each(_Fty cb) const { - if (format() == backend::IndexFormat::U_SHORT) + assert(_stride != 0); + for (auto it = _buffer.begin(); it != _buffer.end(); it += _stride) { - for (auto it = (uint16_t*)_buffer.begin(); it != (uint16_t*)_buffer.end(); ++it) - { - cb(static_cast(*it)); - } - } - else if (format() == backend::IndexFormat::U_INT) - { - for (auto it = (uint32_t*)_buffer.begin(); it != (uint32_t*)_buffer.end(); ++it) - { - cb(*it); - } + uint32_t val = 0; + memcpy(&val, it, _stride); + cb(val); } } From 13710ff0752d1922ee817f432a4882cddcb3a370 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 07:30:16 +0300 Subject: [PATCH 22/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 0a69d9dd93..b3f751f5a1 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -150,10 +150,10 @@ public: return _stride == 2 ? backend::IndexFormat::U_SHORT : backend::IndexFormat::U_INT; } - /** returns the format of the index array. */ + /** sets the format of the index array. */ void format(backend::IndexFormat format) { - _stride = (format == backend::IndexFormat::U_SHORT ? 2 : 4); + _stride = format == backend::IndexFormat::U_SHORT ? 2 : 4; } template From ad189af97f2929733c0d01d528f6333d9e5cfc39 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 07:36:42 +0300 Subject: [PATCH 23/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index b3f751f5a1..1ae675639e 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -159,7 +159,7 @@ public: template void for_each(_Fty cb) const { - assert(_stride != 0); + assert(_stride == 2 || _stride == 4); for (auto it = _buffer.begin(); it != _buffer.end(); it += _stride) { uint32_t val = 0; From dc02ea5ac5fc8772b978ed7b93cc6f785b3a0aa2 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Mon, 4 Jul 2022 07:57:44 +0300 Subject: [PATCH 24/46] Update CCBundle3DData.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 一线灵 --- core/3d/CCBundle3DData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 1ae675639e..6b0504e7e5 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -60,7 +60,7 @@ public: } IndexArray(const IndexArray& rhs) : _buffer(rhs._buffer) { format(rhs.format()); } - IndexArray(IndexArray&& rhs) noexcept : _buffer(std::move(rhs._buffer)) { this->format(rhs.format()); } + IndexArray(IndexArray&& rhs) noexcept : _stride(rhs._stride), _buffer(std::move(rhs._buffer)) {} IndexArray& operator=(const IndexArray& rhs) { _stride = rhs._stride; From 1a0a06c4b57dca5a92a5b199660d0448b2c69d70 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Mon, 4 Jul 2022 07:59:14 +0300 Subject: [PATCH 25/46] Update CCBundle3DData.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 一线灵 --- core/3d/CCBundle3DData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 6b0504e7e5..5f1a1097c7 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -59,7 +59,7 @@ public: format(backend::IndexFormat::U_INT); } - IndexArray(const IndexArray& rhs) : _buffer(rhs._buffer) { format(rhs.format()); } + IndexArray(const IndexArray& rhs) : _stride(rhs._stride), _buffer(rhs._buffer) {} IndexArray(IndexArray&& rhs) noexcept : _stride(rhs._stride), _buffer(std::move(rhs._buffer)) {} IndexArray& operator=(const IndexArray& rhs) { From 6917430f6e55342c682d954cc21335bd296b9c92 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Mon, 4 Jul 2022 08:22:06 +0300 Subject: [PATCH 26/46] Update CCMeshVertexIndexData.cpp [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 一线灵 --- core/3d/CCMeshVertexIndexData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 02cff84435..676d29963f 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -75,7 +75,7 @@ MeshIndexData::MeshIndexData() { #if CC_ENABLE_CACHE_TEXTURE_DATA _backToForegroundListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { - _indexBuffer->updateData((void*)_indexData.data(), _indexData.size()); + _indexBuffer->updateData((void*)_indexData.data(), _indexData.bsize()); }); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1); #endif From 40e30edd582db0831353e719245fb04484fb1e21 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Mon, 4 Jul 2022 08:22:42 +0300 Subject: [PATCH 27/46] Update CCBundle3D.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 一线灵 --- core/3d/CCBundle3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index 63ebb0af37..acc88f503e 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -784,7 +784,7 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) const rapidjson::Value& indices_val_array = mesh_part[INDICES]; for (rapidjson::SizeType j = 0, indices_val_array_size = indices_val_array.Size(); j < indices_val_array_size; ++j) - indexArray.push_back((unsigned int)indices_val_array[j].GetUint()); + indexArray.push_back((unsigned short)indices_val_array[j].GetUint()); meshData->subMeshIndices.push_back(indexArray); meshData->numIndex = (int)meshData->subMeshIndices.size(); From 7fe382ed54fa85d2d94a7f97c338adf46767b6d1 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 4 Jul 2022 23:23:33 +0800 Subject: [PATCH 28/46] Improve meshdata load - Avoid GC alloc when store indices - Fix indices iterator by IndexArray::for_each --- core/3d/CCBundle3D.cpp | 47 ++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index acc88f503e..e3fe4e5750 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -312,9 +312,9 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, node->id = shape.name; for (auto& submesh : subMeshMap) { - meshdata->subMeshIndices.push_back(submesh.second); + auto& storedIndices = meshdata->subMeshIndices.emplace_back(std::move(submesh.second)); meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), submesh.second)); + calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), storedIndices)); sprintf(str, "%d", ++i); meshdata->subMeshIds.push_back(str); @@ -447,7 +447,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) for (unsigned int k = 0; k < meshPartCount; ++k) { - IndexArray indexArray{CustomCommand::IndexFormat::U_SHORT}; // TODO: _version == 1.3 use U_INT? + IndexArray indexArray{}; std::string meshPartid = _binaryReader.readString(); meshData->subMeshIds.push_back(meshPartid); unsigned int nIndexCount; @@ -462,7 +462,7 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) CCLOG("warning: Failed to read meshdata: indices '%s'.", _path.c_str()); goto FAILED; } - meshData->subMeshIndices.push_back(indexArray); + auto& storedIndices = meshData->subMeshIndices.emplace_back(std::move(indexArray)); meshData->numIndex = (int)meshData->subMeshIndices.size(); // meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), // indexArray)); @@ -474,13 +474,13 @@ bool Bundle3D::loadMeshDatasBinary(MeshDatas& meshdatas) { CCLOG("warning: Failed to read meshdata: aabb '%s'.", _path.c_str()); goto FAILED; - } + } meshData->subMeshAABB.push_back(AABB(Vec3(aabb[0], aabb[1], aabb[2]), Vec3(aabb[3], aabb[4], aabb[5]))); } else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), storedIndices)); } } meshdatas.meshDatas.push_back(meshData); @@ -608,8 +608,8 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) return false; } - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + auto& storedIndices = meshdata->subMeshIndices.emplace_back(std::move(indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), storedIndices)); } meshdatas.meshDatas.push_back(meshdata); @@ -729,8 +729,8 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) return false; } - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + auto& storedIndices = meshdata->subMeshIndices.emplace_back(std::move(indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), storedIndices)); } meshdatas.meshDatas.push_back(meshdata); @@ -786,7 +786,7 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) j < indices_val_array_size; ++j) indexArray.push_back((unsigned short)indices_val_array[j].GetUint()); - meshData->subMeshIndices.push_back(indexArray); + auto& storedIndices = meshData->subMeshIndices.emplace_back(std::move(indexArray)); meshData->numIndex = (int)meshData->subMeshIndices.size(); if (mesh_data.HasMember(AABBS)) @@ -805,13 +805,12 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) else { meshData->subMeshAABB.push_back( - calculateAABB(meshData->vertex, meshData->getPerVertexSize(), indexArray)); + calculateAABB(meshData->vertex, meshData->getPerVertexSize(), storedIndices)); } } else { - meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), - indexArray)); + meshData->subMeshAABB.push_back(calculateAABB(meshData->vertex, meshData->getPerVertexSize(), storedIndices)); } } meshdatas.meshDatas.push_back(meshData); @@ -1192,9 +1191,8 @@ bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) for (rapidjson::SizeType i = 0; i < indices_val_array.Size(); ++i) indices.at(i) = (unsigned short)indices_val_array[i].GetUint(); - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back( - calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + auto& storedIndices = meshdata->subMeshIndices.emplace_back(std::move(indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), storedIndices)); meshdatas.meshDatas.push_back(meshdata); return true; } @@ -1247,8 +1245,8 @@ bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) for (rapidjson::SizeType j = 0; j < indices_val_array.Size(); ++j) indices.at(j) = (unsigned short)indices_val_array[j].GetUint(); - meshdata->subMeshIndices.push_back(indices); - meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), indices)); + auto& storedIndices = meshdata->subMeshIndices.emplace_back(std::move(indices)); + meshdata->subMeshAABB.push_back(calculateAABB(meshdata->vertex, meshdata->getPerVertexSize(), storedIndices)); } meshdatas.meshDatas.push_back(meshdata); return true; @@ -2302,13 +2300,12 @@ std::vector Bundle3D::getTrianglesList(std::string_view path) for (auto iter : meshs.meshDatas) { int preVertexSize = iter->getPerVertexSize() / sizeof(float); - for (const auto& indexArray : iter->subMeshIndices) + for (const auto& indices : iter->subMeshIndices) { - for (auto i : indexArray) - { - trianglesList.push_back(Vec3(iter->vertex[i * preVertexSize], iter->vertex[i * preVertexSize + 1], - iter->vertex[i * preVertexSize + 2])); - } + indices.for_each([&](unsigned int ind) { + trianglesList.push_back(Vec3(iter->vertex[ind * preVertexSize], iter->vertex[ind * preVertexSize + 1], + iter->vertex[ind * preVertexSize + 2])); + }); } } From 399bd7e89fd89169848460668e2bbb8fbe8e78fe Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 19:20:04 +0300 Subject: [PATCH 29/46] Add stride functions and remove unneeded UNSPEC value. --- core/3d/CCBundle3DData.h | 82 +++++++++++++++++------------------ core/renderer/backend/Types.h | 5 +-- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 5f1a1097c7..0c92ecbf23 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -45,24 +45,28 @@ NS_CC_BEGIN class IndexArray { + static constexpr unsigned int formatToStride(backend::IndexFormat fmt) { return 1 << (int)fmt; } + static constexpr backend::IndexFormat strideToFormat(unsigned int stride) + { + return (backend::IndexFormat)(stride >> 1); + } + public: - IndexArray() { format(backend::IndexFormat::U_SHORT); } - IndexArray(backend::IndexFormat indexFormat) { format(indexFormat); } + IndexArray() : _stride(formatToStride(backend::IndexFormat::U_SHORT)) {} + IndexArray(backend::IndexFormat indexFormat) : _stride(formatToStride(indexFormat)) {} - IndexArray(std::initializer_list rhs) : _buffer(rhs) - { - format(backend::IndexFormat::U_SHORT); - } - - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) : _buffer(rhs) - { - format(backend::IndexFormat::U_INT); - } + IndexArray(std::initializer_list rhs) + : _stride(formatToStride(backend::IndexFormat::U_SHORT)), _buffer(rhs) + {} + IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) + : _stride(formatToStride(backend::IndexFormat::U_INT)), _buffer(rhs) + {} IndexArray(const IndexArray& rhs) : _stride(rhs._stride), _buffer(rhs._buffer) {} - IndexArray(IndexArray&& rhs) noexcept : _stride(rhs._stride), _buffer(std::move(rhs._buffer)) {} + IndexArray(IndexArray&& rhs) noexcept : _stride(rhs._stride), _buffer(std::move(rhs._buffer)) {} - IndexArray& operator=(const IndexArray& rhs) { + IndexArray& operator=(const IndexArray& rhs) + { _stride = rhs._stride; _buffer = rhs._buffer; return *this; @@ -73,30 +77,26 @@ public: return *this; } - void swap(IndexArray& rhs) { + void swap(IndexArray& rhs) + { std::swap(_stride, rhs._stride); _buffer.swap(rhs._buffer); } - void clear(backend::IndexFormat format = backend::IndexFormat::UNSPEC) - { - _buffer.clear(); - if (format != backend::IndexFormat::UNSPEC) - _stride = format == backend::IndexFormat::U_SHORT ? 2 : 4; + void clear() { _buffer.clear(); } + + /** clear with new index format */ + void clear(backend::IndexFormat format) + { + clear(); + _stride = formatToStride(format); } - /** Pushes back a value if type unsigned short (uint16_t). */ - void push_back(uint16_t val) + /** Pushes back a value. */ + void push_back(uint32_t val) { - assert(_stride == 2); - _buffer.append_n((uint8_t*)&val, sizeof(val)); - } - - /** Pushes back a value if type unsigned int (uint32_t). */ - void push_back(uint32_t val, std::true_type /*U_INT*/) - { - assert(_stride == 4); - _buffer.append_n((uint8_t*)&val, sizeof(val)); + assert(_stride == 2 || _stride == 4); + _buffer.append_n((uint8_t*)&val, _stride); } /** Inserts a list containing unsigned short (uint16_t) data. */ @@ -113,11 +113,16 @@ public: _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } + /** Inserts range data. */ + void insert(uint8_t* where, const void* first, const void* last) + { + _buffer.insert(where, (const uint8_t*)first, (const uint8_t*)last); + } + template _Ty& at(size_t idx) { - assert((sizeof(_Ty) == sizeof(uint16_t) && _stride == 2) || - (sizeof(_Ty) == sizeof(uint32_t) && _stride == 4)); + assert(sizeof(_Ty) == _stride); if (idx < this->size()) return (_Ty&)_buffer[idx * sizeof(_Ty)]; throw std::out_of_range("IndexArray: out of range!"); @@ -145,16 +150,7 @@ public: bool empty() const { return _buffer.empty(); } /** returns the format of the index array. */ - backend::IndexFormat format() const - { - return _stride == 2 ? backend::IndexFormat::U_SHORT : backend::IndexFormat::U_INT; - } - - /** sets the format of the index array. */ - void format(backend::IndexFormat format) - { - _stride = format == backend::IndexFormat::U_SHORT ? 2 : 4; - } + backend::IndexFormat format() const { return strideToFormat(_stride); } template void for_each(_Fty cb) const @@ -169,7 +165,7 @@ public: } protected: - uint8_t _stride; + unsigned int _stride; yasio::byte_buffer _buffer; }; diff --git a/core/renderer/backend/Types.h b/core/renderer/backend/Types.h index a4380e2cc4..ea877464e9 100644 --- a/core/renderer/backend/Types.h +++ b/core/renderer/backend/Types.h @@ -159,9 +159,8 @@ enum class TextureUsage : uint32_t enum class IndexFormat : uint32_t { - U_SHORT, - U_INT, - UNSPEC = 0xff, + U_SHORT = 1, + U_INT = 2, }; enum class VertexStepMode : uint32_t From d56731a158994ae97e909c6837411926045e3e49 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 19:38:46 +0300 Subject: [PATCH 30/46] Update CCBundle3D.cpp [skip ci] --- core/3d/CCBundle3D.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/3d/CCBundle3D.cpp b/core/3d/CCBundle3D.cpp index e3fe4e5750..c66d8bcdc5 100644 --- a/core/3d/CCBundle3D.cpp +++ b/core/3d/CCBundle3D.cpp @@ -599,7 +599,7 @@ bool Bundle3D::loadMeshDatasBinary_0_1(MeshDatas& meshdatas) return false; } - IndexArray indices; + IndexArray indices{}; indices.resize(nIndexCount); if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) { @@ -720,7 +720,7 @@ bool Bundle3D::loadMeshDatasBinary_0_2(MeshDatas& meshdatas) return false; } - IndexArray indices{CustomCommand::IndexFormat::U_SHORT}; /* TODO: _version == 1.3 use U_INT?*/ + IndexArray indices{}; /* TODO: _version == 1.3 use U_INT?*/ indices.resize(nIndexCount); if (_binaryReader.read(indices.data(), 2, nIndexCount) != nIndexCount) { @@ -777,7 +777,7 @@ bool Bundle3D::loadMeshDatasJson(MeshDatas& meshdatas) const rapidjson::Value& mesh_part_array = mesh_data[PARTS]; for (rapidjson::SizeType i = 0, mesh_part_array_size = mesh_part_array.Size(); i < mesh_part_array_size; ++i) { - IndexArray indexArray; + IndexArray indexArray{}; const rapidjson::Value& mesh_part = mesh_part_array[i]; meshData->subMeshIds.push_back(mesh_part[ID].GetString()); // index_number @@ -1184,7 +1184,7 @@ bool Bundle3D::loadMeshDataJson_0_1(MeshDatas& meshdatas) unsigned int indexnum = mesh_data_body_array_0[INDEXNUM].GetUint(); // indices - IndexArray indices; + IndexArray indices{}; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_data_body_array_0[INDICES]; @@ -1238,7 +1238,7 @@ bool Bundle3D::loadMeshDataJson_0_2(MeshDatas& meshdatas) unsigned int indexnum = mesh_submesh_val[INDEXNUM].GetUint(); // indices - IndexArray indices; + IndexArray indices{}; indices.resize(indexnum); const rapidjson::Value& indices_val_array = mesh_submesh_val[INDICES]; From 1ed03a41ad660b2a4017e6387afb183583c440ef Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 19:52:17 +0300 Subject: [PATCH 31/46] Separate renderer enums to their own file. --- core/base/ccTypes.h | 1 + core/renderer/CMakeLists.txt | 1 + core/renderer/backend/Enums.h | 375 ++++++++++++++++++++++++++++++++++ core/renderer/backend/Types.h | 340 +----------------------------- 4 files changed, 379 insertions(+), 338 deletions(-) create mode 100644 core/renderer/backend/Enums.h diff --git a/core/base/ccTypes.h b/core/base/ccTypes.h index 90d22917f9..ac243bebda 100644 --- a/core/base/ccTypes.h +++ b/core/base/ccTypes.h @@ -33,6 +33,7 @@ THE SOFTWARE. #include "math/CCMath.h" #include "base/CCRef.h" #include "renderer/backend/Types.h" + #include "ccEnums.h" /** diff --git a/core/renderer/CMakeLists.txt b/core/renderer/CMakeLists.txt index aebc22aafa..be2becb233 100644 --- a/core/renderer/CMakeLists.txt +++ b/core/renderer/CMakeLists.txt @@ -33,6 +33,7 @@ set(COCOS_RENDERER_HEADER renderer/backend/Texture.h renderer/backend/PixelFormatUtils.h renderer/backend/Types.h + renderer/backend/Enums.h renderer/backend/VertexLayout.h renderer/backend/ProgramState.h renderer/backend/ProgramStateRegistry.h diff --git a/core/renderer/backend/Enums.h b/core/renderer/backend/Enums.h new file mode 100644 index 0000000000..c761aaaaba --- /dev/null +++ b/core/renderer/backend/Enums.h @@ -0,0 +1,375 @@ +/**************************************************************************** + Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. + Copyright (c) 2020 C4games Ltd. + + https://adxeproject.github.io/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#pragma once + +#include "Macros.h" + +#include +#include +#include +#include "base/bitmask.h" + +CC_BACKEND_BEGIN + +enum class BufferUsage : uint32_t +{ + STATIC, + DYNAMIC +}; + +enum class BufferType : uint32_t +{ + VERTEX, + INDEX +}; + +enum class ShaderStage : uint32_t +{ + VERTEX, + FRAGMENT, + VERTEX_AND_FRAGMENT +}; + +enum class VertexFormat : uint32_t +{ + FLOAT4, + FLOAT3, + FLOAT2, + FLOAT, + INT4, + INT3, + INT2, + INT, + USHORT4, + USHORT2, + UBYTE4 +}; + +/** @typedef backend::PixelFormat + Possible texture pixel formats + */ +enum class PixelFormat : uint32_t +{ + /* below is compression format */ + + /* PVRTCV1, OpenGL support PVRTCv2, but Metal only support PVRTCv1*/ + //! 4-bit PVRTC-compressed texture: PVRTC4 + PVRTC4, + //! 4-bit PVRTC-compressed texture: PVRTC4 (has alpha channel) + PVRTC4A, + //! 2-bit PVRTC-compressed texture: PVRTC2 + PVRTC2, + //! 2-bit PVRTC-compressed texture: PVRTC2 (has alpha channel) + PVRTC2A, + + //! ETC1-compressed texture: ETC1 4 BPP + ETC1, + //! ETC2-compressed texture: ETC2_RGB 4 BPP + ETC2_RGB, + //! ETC2-compressed texture: ETC2_RGBA 8 BPP + ETC2_RGBA, + + //! S3TC-compressed texture: S3TC_Dxt1 + S3TC_DXT1, + //! S3TC-compressed texture: S3TC_Dxt3 + S3TC_DXT3, + //! S3TC-compressed texture: S3TC_Dxt5 + S3TC_DXT5, + + //! ATITC-compressed texture: ATC_RGB + ATC_RGB, + //! ATITC-compressed texture: ATC_EXPLICIT_ALPHA + ATC_EXPLICIT_ALPHA, + //! ATITC-compressed texture: ATC_INTERPOLATED_ALPHA + ATC_INTERPOLATED_ALPHA, + + ASTC4x4, //!< ASTC 4x4 8.0 BPP + ASTC5x5, //!< ASTC 5x5 5.12 BPP + ASTC6x6, //!< ASTC 6x6 3.56 BPP + ASTC8x5, //!< ASTC 8x5 3.20 BPP + ASTC8x6, //!< ASTC 8x6 2.67 BPP + ASTC8x8, //!< ASTC 8x8 2.0 BPP + ASTC10x5, //!< ASTC 10x5 2.56 BPP + //!!!Please append compression pixel format + + /* below is normal pixel format */ + //! 32-bit texture: RGBA8888 + RGBA8, + //! 32-bit texture: BGRA8888 + BGRA8, + //! 24-bit texture: RGBA888 + RGB8, + //! 16-bit texture without Alpha channel + RGB565, // !render as BGR565 + //! 16-bit textures: RGBA4444 + RGBA4, // !render as ABGR4 + //! 16-bit textures: RGB5A1 + RGB5A1, // !render as BGR5A1 + //! 8-bit textures used as masks + A8, + //! 8-bit Luminance texture + L8, + //! 16-bit Luminance with alpha used as masks + LA8, + + //!!!Please append normal pixel format + + /* below is depth compression format */ + // A packed 32-bit combined depth and stencil pixel format with two nomorlized unsigned integer + // components: 24 bits, typically used for a depth render target, and 8 bits, typically used for + // a stencil render target. + D24S8, + //!!!Please append depth stencil pixel format + + /* the count of pixel format supported by adxe */ + COUNT, + + NONE = 0xffff +}; + +enum class TextureUsage : uint32_t +{ + READ, + WRITE, + RENDER_TARGET +}; + +enum class IndexFormat : uint32_t +{ + U_SHORT = 1, + U_INT = 2, +}; + +enum class VertexStepMode : uint32_t +{ + VERTEX, + INSTANCE +}; + +enum class PrimitiveType : uint32_t +{ + POINT, + LINE, + LINE_STRIP, + TRIANGLE, + TRIANGLE_STRIP +}; + +enum class TextureType : uint32_t +{ + TEXTURE_2D, + TEXTURE_CUBE +}; + +enum class SamplerAddressMode : uint32_t +{ + REPEAT, + MIRROR_REPEAT, + CLAMP_TO_EDGE, + DONT_CARE, +}; + +enum class SamplerFilter : uint32_t +{ + NEAREST, + NEAREST_MIPMAP_NEAREST, + NEAREST_MIPMAP_LINEAR, + LINEAR, + LINEAR_MIPMAP_LINEAR, + LINEAR_MIPMAP_NEAREST, + DONT_CARE, +}; + +enum class StencilOperation : uint32_t +{ + KEEP, + ZERO, + REPLACE, + INVERT, + INCREMENT_WRAP, + DECREMENT_WRAP +}; + +enum class CompareFunction : uint32_t +{ + NEVER, + LESS, + LESS_EQUAL, + GREATER, + GREATER_EQUAL, + EQUAL, + NOT_EQUAL, + ALWAYS +}; + +enum class BlendOperation : uint32_t +{ + ADD, + SUBTRACT, + RESERVE_SUBTRACT +}; + +enum class BlendFactor : uint32_t +{ + ZERO, + ONE, + SRC_COLOR, + ONE_MINUS_SRC_COLOR, + SRC_ALPHA, + ONE_MINUS_SRC_ALPHA, + DST_COLOR, + ONE_MINUS_DST_COLOR, + DST_ALPHA, + ONE_MINUS_DST_ALPHA, + CONSTANT_ALPHA, + SRC_ALPHA_SATURATE, + ONE_MINUS_CONSTANT_ALPHA, + BLEND_CLOLOR +}; + +enum class ColorWriteMask : uint32_t +{ + RED_BIT = 0, + GREEN_BIT = 1, + BLUE_BIT = 2, + ALPHA_BIT = 3, + NONE = 0, + RED = 1 << RED_BIT, + GREEN = 1 << GREEN_BIT, + BLUE = 1 << BLUE_BIT, + ALPHA = 1 << ALPHA_BIT, + ALL = 0x0000000F +}; +CC_ENABLE_BITMASK_OPS(ColorWriteMask) +CC_ENABLE_BITSHIFT_OPS(ColorWriteMask) + +/** + * Bitmask for selecting render buffers + */ +enum class TargetBufferFlags : uint8_t +{ + NONE = 0x0u, //!< No buffer selected. + COLOR0 = 0x1u, //!< Color buffer selected. + COLOR1 = 0x2u, //!< Color buffer selected. + COLOR2 = 0x4u, //!< Color buffer selected. + COLOR3 = 0x8u, //!< Color buffer selected. + COLOR = COLOR0, //!< \deprecated + COLOR_ALL = COLOR0 | COLOR1 | COLOR2 | COLOR3, + DEPTH = 0x10u, //!< Depth buffer selected. + STENCIL = 0x20u, //!< Stencil buffer selected. + DEPTH_AND_STENCIL = DEPTH | STENCIL, //!< depth and stencil buffer selected. + ALL = COLOR_ALL | DEPTH | STENCIL //!< Color, depth and stencil buffer selected. +}; +CC_ENABLE_BITMASK_OPS(TargetBufferFlags) + +enum class DepthStencilFlags : unsigned int +{ + NONE = 0, + DEPTH_TEST = 1, + DEPTH_WRITE = 1 << 1, + STENCIL_TEST = 1 << 2, + DEPTH_STENCIL_TEST = DEPTH_TEST | STENCIL_TEST, + ALL = DEPTH_TEST | STENCIL_TEST | DEPTH_WRITE, +}; +CC_ENABLE_BITMASK_OPS(DepthStencilFlags) +CC_ENABLE_BITSHIFT_OPS(DepthStencilFlags) + +enum class CullMode : uint32_t +{ + NONE = 0x00000000, + BACK = 0x00000001, + FRONT = 0x00000002 +}; + +enum class Winding : uint32_t +{ + CLOCK_WISE, + COUNTER_CLOCK_WISE +}; + +enum class TextureCubeFace : uint32_t +{ + POSITIVE_X = 0, + NEGATIVE_X = 1, + POSITIVE_Y = 2, + NEGATIVE_Y = 3, + POSITIVE_Z = 4, + NEGATIVE_Z = 5 +}; + +struct ProgramType +{ + enum : uint32_t + { + POSITION_COLOR_LENGTH_TEXTURE, // positionColorLengthTexture_vert, positionColorLengthTexture_frag + POSITION_COLOR_TEXTURE_AS_POINTSIZE, // positionColorTextureAsPointsize_vert, positionColor_frag + POSITION_COLOR, // positionColor_vert, positionColor_frag + POSITION_UCOLOR, // positionUColor_vert, positionUColor_frag + POSITION_TEXTURE, // positionTexture_vert, positionTexture_frag + POSITION_TEXTURE_COLOR, // positionTextureColor_vert, positionTextureColor_frag + POSITION_TEXTURE_COLOR_ALPHA_TEST, // positionTextureColor_vert, positionTextureColorAlphaTest_frag + LABEL_NORMAL, // positionTextureColor_vert, label_normal_frag + LABLE_OUTLINE, // positionTextureColor_vert, labelOutline_frag + LABLE_DISTANCEFIELD_GLOW, // positionTextureColor_vert, labelDistanceFieldGlow_frag + LABEL_DISTANCE_NORMAL, // positionTextureColor_vert, label_distanceNormal_frag + + LAYER_RADIA_GRADIENT, // position_vert, layer_radialGradient_frag + + DUAL_SAMPLER, + DUAL_SAMPLER_GRAY, + ETC1 = DUAL_SAMPLER, // positionTextureColor_vert, etc1_frag + ETC1_GRAY = DUAL_SAMPLER_GRAY, // positionTextureColor_vert, etc1Gray_frag + GRAY_SCALE, // positionTextureColor_vert, grayScale_frag + CAMERA_CLEAR, // cameraClear_vert, cameraClear_frag + + TERRAIN_3D, // CC3D_terrain_vert, CC3D_terrain_frag + LINE_COLOR_3D, // lineColor3D_vert, lineColor3D_frag + SKYBOX_3D, // CC3D_skybox_vert, CC3D_skybox_frag + SKINPOSITION_TEXTURE_3D, // CC3D_skinPositionTexture_vert, CC3D_colorTexture_frag + SKINPOSITION_NORMAL_TEXTURE_3D, // CC3D_skinPositionNormalTexture_vert, CC3D_colorNormalTexture_frag + POSITION_NORMAL_TEXTURE_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormalTexture_frag + POSITION_NORMAL_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormal_frag + POSITION_TEXTURE_3D, // CC3D_positionTexture_vert, CC3D_colorTexture_frag + POSITION_3D, // CC3D_positionTexture_vert, CC3D_color_frag + POSITION_BUMPEDNORMAL_TEXTURE_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormalTexture_frag + SKINPOSITION_BUMPEDNORMAL_TEXTURE_3D, // CC3D_skinPositionNormalTexture_vert, CC3D_colorNormalTexture_frag + PARTICLE_TEXTURE_3D, // CC3D_particle_vert, CC3D_particleTexture_frag + PARTICLE_COLOR_3D, // CC3D_particle_vert, CC3D_particleColor_frag + + QUAD_COLOR_2D, // CC2D_quad_vert, CC2D_quadColor_frag + QUAD_TEXTURE_2D, // CC2D_quad_vert, CC2D_quadTexture_frag + + HSV, + HSV_DUAL_SAMPLER, + HSV_ETC1 = HSV_DUAL_SAMPLER, + + BUILTIN_COUNT, + + CUSTOM_PROGRAM = 0x1000, // user-define program, used by engine + }; +}; + +CC_BACKEND_END diff --git a/core/renderer/backend/Types.h b/core/renderer/backend/Types.h index fd33f00c98..b3932c99a3 100644 --- a/core/renderer/backend/Types.h +++ b/core/renderer/backend/Types.h @@ -32,259 +32,10 @@ #include #include "base/bitmask.h" +#include "Enums.h" + CC_BACKEND_BEGIN -enum class BufferUsage : uint32_t -{ - STATIC, - DYNAMIC -}; - -enum class BufferType : uint32_t -{ - VERTEX, - INDEX -}; - -enum class ShaderStage : uint32_t -{ - VERTEX, - FRAGMENT, - VERTEX_AND_FRAGMENT -}; - -enum class VertexFormat : uint32_t -{ - FLOAT4, - FLOAT3, - FLOAT2, - FLOAT, - INT4, - INT3, - INT2, - INT, - USHORT4, - USHORT2, - UBYTE4 -}; - -/** @typedef backend::PixelFormat - Possible texture pixel formats - */ -enum class PixelFormat : uint32_t -{ - /* below is compression format */ - - /* PVRTCV1, OpenGL support PVRTCv2, but Metal only support PVRTCv1*/ - //! 4-bit PVRTC-compressed texture: PVRTC4 - PVRTC4, - //! 4-bit PVRTC-compressed texture: PVRTC4 (has alpha channel) - PVRTC4A, - //! 2-bit PVRTC-compressed texture: PVRTC2 - PVRTC2, - //! 2-bit PVRTC-compressed texture: PVRTC2 (has alpha channel) - PVRTC2A, - - //! ETC1-compressed texture: ETC1 4 BPP - ETC1, - //! ETC2-compressed texture: ETC2_RGB 4 BPP - ETC2_RGB, - //! ETC2-compressed texture: ETC2_RGBA 8 BPP - ETC2_RGBA, - - //! S3TC-compressed texture: S3TC_Dxt1 - S3TC_DXT1, - //! S3TC-compressed texture: S3TC_Dxt3 - S3TC_DXT3, - //! S3TC-compressed texture: S3TC_Dxt5 - S3TC_DXT5, - - //! ATITC-compressed texture: ATC_RGB - ATC_RGB, - //! ATITC-compressed texture: ATC_EXPLICIT_ALPHA - ATC_EXPLICIT_ALPHA, - //! ATITC-compressed texture: ATC_INTERPOLATED_ALPHA - ATC_INTERPOLATED_ALPHA, - - ASTC4x4, //!< ASTC 4x4 8.0 BPP - ASTC5x5, //!< ASTC 5x5 5.12 BPP - ASTC6x6, //!< ASTC 6x6 3.56 BPP - ASTC8x5, //!< ASTC 8x5 3.20 BPP - ASTC8x6, //!< ASTC 8x6 2.67 BPP - ASTC8x8, //!< ASTC 8x8 2.0 BPP - ASTC10x5, //!< ASTC 10x5 2.56 BPP - //!!!Please append compression pixel format - - /* below is normal pixel format */ - //! 32-bit texture: RGBA8888 - RGBA8, - //! 32-bit texture: BGRA8888 - BGRA8, - //! 24-bit texture: RGBA888 - RGB8, - //! 16-bit texture without Alpha channel - RGB565, // !render as BGR565 - //! 16-bit textures: RGBA4444 - RGBA4, // !render as ABGR4 - //! 16-bit textures: RGB5A1 - RGB5A1, // !render as BGR5A1 - //! 8-bit textures used as masks - A8, - //! 8-bit Luminance texture - L8, - //! 16-bit Luminance with alpha used as masks - LA8, - - //!!!Please append normal pixel format - - /* below is depth compression format */ - // A packed 32-bit combined depth and stencil pixel format with two nomorlized unsigned integer - // components: 24 bits, typically used for a depth render target, and 8 bits, typically used for - // a stencil render target. - D24S8, - //!!!Please append depth stencil pixel format - - /* the count of pixel format supported by adxe */ - COUNT, - - NONE = 0xffff -}; - -enum class TextureUsage : uint32_t -{ - READ, - WRITE, - RENDER_TARGET -}; - -enum class IndexFormat : uint32_t -{ - U_SHORT = 1, - U_INT = 2, -}; - -enum class VertexStepMode : uint32_t -{ - VERTEX, - INSTANCE -}; - -enum class PrimitiveType : uint32_t -{ - POINT, - LINE, - LINE_STRIP, - TRIANGLE, - TRIANGLE_STRIP -}; - -enum class TextureType : uint32_t -{ - TEXTURE_2D, - TEXTURE_CUBE -}; - -enum class SamplerAddressMode : uint32_t -{ - REPEAT, - MIRROR_REPEAT, - CLAMP_TO_EDGE, - DONT_CARE, -}; - -enum class SamplerFilter : uint32_t -{ - NEAREST, - NEAREST_MIPMAP_NEAREST, - NEAREST_MIPMAP_LINEAR, - LINEAR, - LINEAR_MIPMAP_LINEAR, - LINEAR_MIPMAP_NEAREST, - DONT_CARE, -}; - -enum class StencilOperation : uint32_t -{ - KEEP, - ZERO, - REPLACE, - INVERT, - INCREMENT_WRAP, - DECREMENT_WRAP -}; - -enum class CompareFunction : uint32_t -{ - NEVER, - LESS, - LESS_EQUAL, - GREATER, - GREATER_EQUAL, - EQUAL, - NOT_EQUAL, - ALWAYS -}; - -enum class BlendOperation : uint32_t -{ - ADD, - SUBTRACT, - RESERVE_SUBTRACT -}; - -enum class BlendFactor : uint32_t -{ - ZERO, - ONE, - SRC_COLOR, - ONE_MINUS_SRC_COLOR, - SRC_ALPHA, - ONE_MINUS_SRC_ALPHA, - DST_COLOR, - ONE_MINUS_DST_COLOR, - DST_ALPHA, - ONE_MINUS_DST_ALPHA, - CONSTANT_ALPHA, - SRC_ALPHA_SATURATE, - ONE_MINUS_CONSTANT_ALPHA, - BLEND_CLOLOR -}; - -enum class ColorWriteMask : uint32_t -{ - RED_BIT = 0, - GREEN_BIT = 1, - BLUE_BIT = 2, - ALPHA_BIT = 3, - NONE = 0, - RED = 1 << RED_BIT, - GREEN = 1 << GREEN_BIT, - BLUE = 1 << BLUE_BIT, - ALPHA = 1 << ALPHA_BIT, - ALL = 0x0000000F -}; -CC_ENABLE_BITMASK_OPS(ColorWriteMask) -CC_ENABLE_BITSHIFT_OPS(ColorWriteMask) - -/** - * Bitmask for selecting render buffers - */ -enum class TargetBufferFlags : uint8_t -{ - NONE = 0x0u, //!< No buffer selected. - COLOR0 = 0x1u, //!< Color buffer selected. - COLOR1 = 0x2u, //!< Color buffer selected. - COLOR2 = 0x4u, //!< Color buffer selected. - COLOR3 = 0x8u, //!< Color buffer selected. - COLOR = COLOR0, //!< \deprecated - COLOR_ALL = COLOR0 | COLOR1 | COLOR2 | COLOR3, - DEPTH = 0x10u, //!< Depth buffer selected. - STENCIL = 0x20u, //!< Stencil buffer selected. - DEPTH_AND_STENCIL = DEPTH | STENCIL, //!< depth and stencil buffer selected. - ALL = COLOR_ALL | DEPTH | STENCIL //!< Color, depth and stencil buffer selected. -}; -CC_ENABLE_BITMASK_OPS(TargetBufferFlags) - inline TargetBufferFlags getMRTColorFlag(size_t index) noexcept { assert(index < 4); @@ -294,18 +45,6 @@ inline TargetBufferFlags getMRTColorFlag(size_t index) noexcept typedef TargetBufferFlags ClearFlag; typedef TargetBufferFlags RenderTargetFlag; -enum class DepthStencilFlags : unsigned int -{ - NONE = 0, - DEPTH_TEST = 1, - DEPTH_WRITE = 1 << 1, - STENCIL_TEST = 1 << 2, - DEPTH_STENCIL_TEST = DEPTH_TEST | STENCIL_TEST, - ALL = DEPTH_TEST | STENCIL_TEST | DEPTH_WRITE, -}; -CC_ENABLE_BITMASK_OPS(DepthStencilFlags) -CC_ENABLE_BITSHIFT_OPS(DepthStencilFlags) - struct SamplerDescriptor { SamplerFilter magFilter = SamplerFilter::LINEAR; @@ -323,19 +62,6 @@ struct SamplerDescriptor {} }; -enum class CullMode : uint32_t -{ - NONE = 0x00000000, - BACK = 0x00000001, - FRONT = 0x00000002 -}; - -enum class Winding : uint32_t -{ - CLOCK_WISE, - COUNTER_CLOCK_WISE -}; - struct UniformInfo { int count = 0; @@ -382,68 +108,6 @@ struct AttributeBindInfo int type = 0; }; -enum class TextureCubeFace : uint32_t -{ - POSITIVE_X = 0, - NEGATIVE_X = 1, - POSITIVE_Y = 2, - NEGATIVE_Y = 3, - POSITIVE_Z = 4, - NEGATIVE_Z = 5 -}; - -struct ProgramType -{ - enum : uint32_t - { - POSITION_COLOR_LENGTH_TEXTURE, // positionColorLengthTexture_vert, positionColorLengthTexture_frag - POSITION_COLOR_TEXTURE_AS_POINTSIZE, // positionColorTextureAsPointsize_vert, positionColor_frag - POSITION_COLOR, // positionColor_vert, positionColor_frag - POSITION_UCOLOR, // positionUColor_vert, positionUColor_frag - POSITION_TEXTURE, // positionTexture_vert, positionTexture_frag - POSITION_TEXTURE_COLOR, // positionTextureColor_vert, positionTextureColor_frag - POSITION_TEXTURE_COLOR_ALPHA_TEST, // positionTextureColor_vert, positionTextureColorAlphaTest_frag - LABEL_NORMAL, // positionTextureColor_vert, label_normal_frag - LABLE_OUTLINE, // positionTextureColor_vert, labelOutline_frag - LABLE_DISTANCEFIELD_GLOW, // positionTextureColor_vert, labelDistanceFieldGlow_frag - LABEL_DISTANCE_NORMAL, // positionTextureColor_vert, label_distanceNormal_frag - - LAYER_RADIA_GRADIENT, // position_vert, layer_radialGradient_frag - - DUAL_SAMPLER, - DUAL_SAMPLER_GRAY, - ETC1 = DUAL_SAMPLER, // positionTextureColor_vert, etc1_frag - ETC1_GRAY = DUAL_SAMPLER_GRAY, // positionTextureColor_vert, etc1Gray_frag - GRAY_SCALE, // positionTextureColor_vert, grayScale_frag - CAMERA_CLEAR, // cameraClear_vert, cameraClear_frag - - TERRAIN_3D, // CC3D_terrain_vert, CC3D_terrain_frag - LINE_COLOR_3D, // lineColor3D_vert, lineColor3D_frag - SKYBOX_3D, // CC3D_skybox_vert, CC3D_skybox_frag - SKINPOSITION_TEXTURE_3D, // CC3D_skinPositionTexture_vert, CC3D_colorTexture_frag - SKINPOSITION_NORMAL_TEXTURE_3D, // CC3D_skinPositionNormalTexture_vert, CC3D_colorNormalTexture_frag - POSITION_NORMAL_TEXTURE_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormalTexture_frag - POSITION_NORMAL_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormal_frag - POSITION_TEXTURE_3D, // CC3D_positionTexture_vert, CC3D_colorTexture_frag - POSITION_3D, // CC3D_positionTexture_vert, CC3D_color_frag - POSITION_BUMPEDNORMAL_TEXTURE_3D, // CC3D_positionNormalTexture_vert, CC3D_colorNormalTexture_frag - SKINPOSITION_BUMPEDNORMAL_TEXTURE_3D, // CC3D_skinPositionNormalTexture_vert, CC3D_colorNormalTexture_frag - PARTICLE_TEXTURE_3D, // CC3D_particle_vert, CC3D_particleTexture_frag - PARTICLE_COLOR_3D, // CC3D_particle_vert, CC3D_particleColor_frag - - QUAD_COLOR_2D, // CC2D_quad_vert, CC2D_quadColor_frag - QUAD_TEXTURE_2D, // CC2D_quad_vert, CC2D_quadTexture_frag - - HSV, - HSV_DUAL_SAMPLER, - HSV_ETC1 = HSV_DUAL_SAMPLER, - - BUILTIN_COUNT, - - CUSTOM_PROGRAM = 0x1000, // user-define program, used by engine - }; -}; - /// built-in uniform name static const char* UNIFORM_NAME_MVP_MATRIX = "u_MVPMatrix"; static const char* UNIFORM_NAME_TEXTURE = "u_tex0"; From 9057a479969f488c949239a7a71f061a643ca704 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:25:16 +0300 Subject: [PATCH 32/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 0c92ecbf23..852ac74741 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -43,6 +43,9 @@ NS_CC_BEGIN +using uint16_index_format = std::bool_constant; +using uint32_index_format = std::bool_constant; + class IndexArray { static constexpr unsigned int formatToStride(backend::IndexFormat fmt) { return 1 << (int)fmt; } @@ -55,10 +58,10 @@ public: IndexArray() : _stride(formatToStride(backend::IndexFormat::U_SHORT)) {} IndexArray(backend::IndexFormat indexFormat) : _stride(formatToStride(indexFormat)) {} - IndexArray(std::initializer_list rhs) + IndexArray(std::initializer_list rhs, uint16_index_format /*U_SHORT*/) : _stride(formatToStride(backend::IndexFormat::U_SHORT)), _buffer(rhs) {} - IndexArray(std::initializer_list rhs, std::true_type /*U_INT*/) + IndexArray(std::initializer_list rhs, uint32_index_format /*U_INT*/) : _stride(formatToStride(backend::IndexFormat::U_INT)), _buffer(rhs) {} @@ -100,14 +103,14 @@ public: } /** Inserts a list containing unsigned short (uint16_t) data. */ - void insert(uint8_t* where, std::initializer_list ilist) + void insert(uint8_t* where, std::initializer_list ilist, uint16_index_format /*U_SHORT*/) { assert(_stride == 2); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); } /** Inserts a list containing unsigned int (uint32_t) data. */ - void insert(uint8_t* where, std::initializer_list ilist, std::true_type) + void insert(uint8_t* where, std::initializer_list ilist, uint32_index_format /*U_INT*/) { assert(_stride == 4); _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); @@ -165,7 +168,7 @@ public: } protected: - unsigned int _stride; + unsigned char _stride; yasio::byte_buffer _buffer; }; From 5797662ca1337f98ecb04ed1b1fdccfcb2509c94 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:29:50 +0300 Subject: [PATCH 33/46] Update CCBundle3DData.h [skip ci] --- core/3d/CCBundle3DData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 852ac74741..262ae0fec2 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -44,7 +44,7 @@ NS_CC_BEGIN using uint16_index_format = std::bool_constant; -using uint32_index_format = std::bool_constant; +using uint32_index_format = std::bool_constant; class IndexArray { From ac3aea7aca4ad8ba03744bd2a27c5192c68f00de Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 5 Jul 2022 01:32:06 +0800 Subject: [PATCH 34/46] Update byte_buffer, support insert at offset --- thirdparty/yasio/detail/byte_buffer.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/thirdparty/yasio/detail/byte_buffer.hpp b/thirdparty/yasio/detail/byte_buffer.hpp index 65f1c39e10..bdcb86f840 100644 --- a/thirdparty/yasio/detail/byte_buffer.hpp +++ b/thirdparty/yasio/detail/byte_buffer.hpp @@ -129,6 +129,11 @@ public: memcpy(this, _Tmp, sizeof(_Tmp)); } template + void insert(size_t offset, _Iter first, const _Iter last) + { + insert((std::min)(_Myfirst + offset, _Mylast), first, last); + } + template void insert(_Elem* where, _Iter first, const _Iter last) { if (where == _Mylast) From 31a2f468912d3de0ff6cb00ab9671e3baf7c5d43 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:32:29 +0300 Subject: [PATCH 35/46] Use integral_constant rathar than bool_contant. --- core/3d/CCBundle3DData.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 262ae0fec2..8f29c53c57 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -43,8 +43,8 @@ NS_CC_BEGIN -using uint16_index_format = std::bool_constant; -using uint32_index_format = std::bool_constant; +using uint16_index_format = std::integral_constant; +using uint32_index_format = std::integral_constant; class IndexArray { From 0c6998cf41adef9d21a52af676d272be3681c7b5 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:35:31 +0300 Subject: [PATCH 36/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 8f29c53c57..4885c3245a 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -85,6 +85,11 @@ public: std::swap(_stride, rhs._stride); _buffer.swap(rhs._buffer); } + void insert(size_t offset, _Iter first, const _Iter last) + { + insert((std::min)(_Myfirst + offset, _Mylast), first, last); + } + template void clear() { _buffer.clear(); } From 96a4d83700891ebef03ff6c78fce53c98732587c Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:41:53 +0300 Subject: [PATCH 37/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 4885c3245a..38af1c4df2 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -85,11 +85,6 @@ public: std::swap(_stride, rhs._stride); _buffer.swap(rhs._buffer); } - void insert(size_t offset, _Iter first, const _Iter last) - { - insert((std::min)(_Myfirst + offset, _Mylast), first, last); - } - template void clear() { _buffer.clear(); } @@ -108,23 +103,23 @@ public: } /** Inserts a list containing unsigned short (uint16_t) data. */ - void insert(uint8_t* where, std::initializer_list ilist, uint16_index_format /*U_SHORT*/) + void insert(size_t offset, std::initializer_list ilist, uint16_index_format /*U_SHORT*/) { assert(_stride == 2); - _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); + binsert(offset * _stride, ilist.begin(), ilist.end()); } /** Inserts a list containing unsigned int (uint32_t) data. */ - void insert(uint8_t* where, std::initializer_list ilist, uint32_index_format /*U_INT*/) + void insert(size_t offset, std::initializer_list ilist, uint32_index_format /*U_INT*/) { assert(_stride == 4); - _buffer.insert(where, (uint8_t*)ilist.begin(), (uint8_t*)ilist.end()); + binsert(offset * _stride, ilist.begin(), ilist.end()); } - /** Inserts range data. */ - void insert(uint8_t* where, const void* first, const void* last) + /** Inserts range data based on an offset in bytes. */ + void binsert(size_t offset, const void* first, const void* last) { - _buffer.insert(where, (const uint8_t*)first, (const uint8_t*)last); + _buffer.insert(offset, (const uint8_t*)first, (const uint8_t*)last); } template From 21cb99695a99ff335ac29263f7c3ac9700e13734 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:42:44 +0300 Subject: [PATCH 38/46] Update CCBundle3DData.h [skip ci] --- core/3d/CCBundle3DData.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 38af1c4df2..f3d9e5abce 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -131,11 +131,6 @@ public: throw std::out_of_range("IndexArray: out of range!"); } - uint8_t* begin() noexcept { return _buffer.begin(); } - uint8_t* end() noexcept { return _buffer.end(); } - const uint8_t* begin() const noexcept { return _buffer.begin(); } - const uint8_t* end() const noexcept { return _buffer.end(); } - uint8_t* data() noexcept { return _buffer.data(); } const uint8_t* data() const noexcept { return _buffer.data(); } From 293c28f6b6877711b229114224b94f410ae9617a Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 20:54:56 +0300 Subject: [PATCH 39/46] Expose stride conversion functions. --- core/3d/CCBundle3DData.h | 4 ++-- core/3d/CCMesh.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index f3d9e5abce..1d91a0ef39 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -48,13 +48,13 @@ using uint32_index_format = std::integral_constant; class IndexArray { - static constexpr unsigned int formatToStride(backend::IndexFormat fmt) { return 1 << (int)fmt; } +public: + static constexpr unsigned int formatToStride(backend::IndexFormat format) { return 1 << (int)format; } static constexpr backend::IndexFormat strideToFormat(unsigned int stride) { return (backend::IndexFormat)(stride >> 1); } -public: IndexArray() : _stride(formatToStride(backend::IndexFormat::U_SHORT)) {} IndexArray(backend::IndexFormat indexFormat) : _stride(formatToStride(indexFormat)) {} diff --git a/core/3d/CCMesh.cpp b/core/3d/CCMesh.cpp index 28ea51deb6..2484ebce6a 100644 --- a/core/3d/CCMesh.cpp +++ b/core/3d/CCMesh.cpp @@ -732,8 +732,7 @@ CustomCommand::PrimitiveType Mesh::getPrimitiveType() const ssize_t Mesh::getIndexCount() const { - return _meshIndexData->getIndexBuffer()->getSize() / - (meshIndexFormat == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t)); + return _meshIndexData->getIndexBuffer()->getSize() / IndexArray::formatToStride(meshIndexFormat); } CustomCommand::IndexFormat Mesh::getIndexFormat() const From 74a2ed5ab16ff346dc09fc0eb8f7ad027eccd69f Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:05:27 +0300 Subject: [PATCH 40/46] Update CCBundle3DData.h --- core/3d/CCBundle3DData.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 1d91a0ef39..3b594bc7d4 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -86,15 +86,9 @@ public: _buffer.swap(rhs._buffer); } + /** Clears the internal byte buffer. */ void clear() { _buffer.clear(); } - /** clear with new index format */ - void clear(backend::IndexFormat format) - { - clear(); - _stride = formatToStride(format); - } - /** Pushes back a value. */ void push_back(uint32_t val) { @@ -150,6 +144,13 @@ public: /** returns the format of the index array. */ backend::IndexFormat format() const { return strideToFormat(_stride); } + /** clears the buffer and sets the format specified. */ + void format(backend::IndexFormat format = backend::IndexFormat::U_SHORT) + { + clear(); + _stride = formatToStride(format); + } + template void for_each(_Fty cb) const { From b2583b26144330a0290781a92c8347d50d89f968 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:07:06 +0300 Subject: [PATCH 41/46] Update CCBundle3DData.h [skip ci] --- core/3d/CCBundle3DData.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 3b594bc7d4..5d57300dd4 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -128,23 +128,23 @@ public: uint8_t* data() noexcept { return _buffer.data(); } const uint8_t* data() const noexcept { return _buffer.data(); } - /** returns the count of indices in the container. */ + /** Returns the count of indices in the container. */ size_t size() const { return _buffer.size() / _stride; } - /** returns the size of the container in bytes. */ + /** Returns the size of the container in bytes. */ size_t bsize() const { return _buffer.size(); } - /** resizes the count of indices in the container. */ + /** Resizes the count of indices in the container. */ void resize(size_t size) { _buffer.resize(size * _stride); } - /** resizes the container in bytes. */ + /** Resizes the container in bytes. */ void bresize(size_t size) { _buffer.resize(size); } - /** returns true if the container is empty. Otherwise, false. */ + /** Returns true if the container is empty. Otherwise, false. */ bool empty() const { return _buffer.empty(); } - /** returns the format of the index array. */ + /** Returns the format of the index array. */ backend::IndexFormat format() const { return strideToFormat(_stride); } - /** clears the buffer and sets the format specified. */ + /** Clears the buffer and sets the format specified. */ void format(backend::IndexFormat format = backend::IndexFormat::U_SHORT) { clear(); From 35f7bd2f7664e6ba389bc95e4d2b38450e926738 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:09:54 +0300 Subject: [PATCH 42/46] Update CCBundle3DData.h [skip ci] --- core/3d/CCBundle3DData.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/3d/CCBundle3DData.h b/core/3d/CCBundle3DData.h index 5d57300dd4..7d1d72792a 100644 --- a/core/3d/CCBundle3DData.h +++ b/core/3d/CCBundle3DData.h @@ -144,8 +144,8 @@ public: /** Returns the format of the index array. */ backend::IndexFormat format() const { return strideToFormat(_stride); } - /** Clears the buffer and sets the format specified. */ - void format(backend::IndexFormat format = backend::IndexFormat::U_SHORT) + /** Clears the internal byte buffer and sets the format specified. */ + void clear(backend::IndexFormat format) { clear(); _stride = formatToStride(format); From 995a6469d182ad2cf4dee0a4ed3a0ec4854512a4 Mon Sep 17 00:00:00 2001 From: Turky Mohammed <45469625+DelinWorks@users.noreply.github.com> Date: Mon, 4 Jul 2022 21:12:17 +0300 Subject: [PATCH 43/46] Update quad.frag [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 一线灵 --- core/renderer/shaders/quad.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/renderer/shaders/quad.frag b/core/renderer/shaders/quad.frag index 9a9cf0872d..81e61a575a 100644 --- a/core/renderer/shaders/quad.frag +++ b/core/renderer/shaders/quad.frag @@ -34,7 +34,7 @@ varying vec2 TextureCoordOut; #endif uniform vec4 u_color; -uniform sampler2D u_texture; +uniform sampler2D u_tex0; void main(void) { From 15f43941e809cbf23213dc2514594121b0c73f27 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:13:29 +0300 Subject: [PATCH 44/46] Update quad.frag [skip ci] --- core/renderer/shaders/quad.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/renderer/shaders/quad.frag b/core/renderer/shaders/quad.frag index 81e61a575a..0abd3e4611 100644 --- a/core/renderer/shaders/quad.frag +++ b/core/renderer/shaders/quad.frag @@ -38,7 +38,7 @@ uniform sampler2D u_tex0; void main(void) { - gl_FragColor = texture2D(u_texture, TextureCoordOut) * ColorOut * u_color; + gl_FragColor = texture2D(u_tex0, TextureCoordOut) * ColorOut * u_color; } )"; From ad451adb4b44df830a63b5877cc80a0d09f217c3 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:14:33 +0300 Subject: [PATCH 45/46] Update CCMeshVertexIndexData.cpp [skip ci] --- core/3d/CCMeshVertexIndexData.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 676d29963f..3c3c280237 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -133,14 +133,13 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: for (size_t i = 0, size = meshdata.subMeshIndices.size(); i < size; ++i) { auto& indices = meshdata.subMeshIndices[i]; - // auto indexSize = format == CustomCommand::IndexFormat::U_SHORT ? sizeof(uint16_t) : sizeof(uint32_t); auto indexBuffer = backend::Device::getInstance()->newBuffer( indices.bsize() /* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false); #endif - indexBuffer->updateData((void*)indices.data(), indices.bsize() /* * indexSize*/); + indexBuffer->updateData((void*)indices.data(), indices.bsize()); std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : ""); MeshIndexData* indexdata = nullptr; From 4f1212e65507911a6552f64bf6f28a352efe7d87 Mon Sep 17 00:00:00 2001 From: DelinWorks Date: Mon, 4 Jul 2022 21:15:11 +0300 Subject: [PATCH 46/46] Update CCMeshVertexIndexData.cpp [skip ci] --- core/3d/CCMeshVertexIndexData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/3d/CCMeshVertexIndexData.cpp b/core/3d/CCMeshVertexIndexData.cpp index 3c3c280237..6323544eca 100644 --- a/core/3d/CCMeshVertexIndexData.cpp +++ b/core/3d/CCMeshVertexIndexData.cpp @@ -134,7 +134,7 @@ MeshVertexData* MeshVertexData::create(const MeshData& meshdata, CustomCommand:: { auto& indices = meshdata.subMeshIndices[i]; auto indexBuffer = backend::Device::getInstance()->newBuffer( - indices.bsize() /* * indexSize*/, backend::BufferType::INDEX, backend::BufferUsage::STATIC); + indices.bsize(), backend::BufferType::INDEX, backend::BufferUsage::STATIC); indexBuffer->autorelease(); #if CC_ENABLE_CACHE_TEXTURE_DATA indexBuffer->usingDefaultStoredData(false);