void glTFExporter::ExportMeshes()
{
- std::string bufferId = mAsset->FindUniqueID("", "buffer");
-
- Ref<Buffer> b = mAsset->GetBodyBuffer();
- if (!b) {
- b = mAsset->buffers.Create(bufferId);
- }
-
- for (unsigned int i = 0; i < mScene->mNumMeshes; ++i) {
- const aiMesh* aim = mScene->mMeshes[i];
+// Not for
+// using IndicesType = decltype(aiFace::mNumIndices);
+// But yes for
+// using IndicesType = unsigned short;
+// because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
+typedef unsigned short IndicesType;
+
+// Variables needed for compression. BEGIN.
+// Indices, not pointers - because pointer to buffer is changin while writing to it.
+size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
+size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
+std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
+size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
+bool comp_allow;// Point that data of current mesh can be compressed.
+// Variables needed for compression. END.
+
++ std::string bufferId = mAsset->FindUniqueID("", "buffer");
++
++ Ref<Buffer> b = mAsset->GetBodyBuffer();
++ if (!b) {
++ b = mAsset->buffers.Create(bufferId);
++ }
++
+ for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
+ const aiMesh* aim = mScene->mMeshes[idx_mesh];
+
+ // Check if compressing requested and mesh can be encoded.
+#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
+ comp_allow = mProperties->GetPropertyBool("extensions.Open3DGC.use", false);
+#else
+ comp_allow = false;
+#endif
+
+ if(comp_allow && (aim->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) && (aim->mNumVertices > 0) && (aim->mNumFaces > 0))
+ {
+ idx_srcdata_tc.clear();
+ idx_srcdata_tc.reserve(AI_MAX_NUMBER_OF_TEXTURECOORDS);
+ }
+ else
+ {
+ std::string msg;
+
+ if(aim->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
+ msg = "all primitives of the mesh must be a triangles.";
+ else
+ msg = "mesh must has vertices and faces.";
+
+ DefaultLogger::get()->warn("GLTF: can not use Open3DGC-compression: " + msg);
+ comp_allow = false;
+ }
std::string meshId = mAsset->FindUniqueID(aim->mName.C_Str(), "mesh");
Ref<Mesh> m = mAsset->meshes.Create(meshId);
p.material = mAsset->materials.Get(aim->mMaterialIndex);
- std::string bufferId = mAsset->FindUniqueID(meshId, "buffer");
-
- Ref<Buffer> b = mAsset->GetBodyBuffer();
- if (!b) {
- b = mAsset->buffers.Create(bufferId);
- }
-
+ /******************* Vertices ********************/
+ // If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored.
+ if(comp_allow) idx_srcdata_begin = b->byteLength;
+
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (v) p.attributes.position.push_back(v);
+ if (v) p.attributes.position.push_back(v);
+
+ /******************** Normals ********************/
+ if(comp_allow && (aim->mNormals > 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array.
- Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (n) p.attributes.normal.push_back(n);
+ Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
+ if (n) p.attributes.normal.push_back(n);
+ /************** Texture coordinates **************/
for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
+ // Flip UV y coords
+ if (aim -> mNumUVComponents[i] > 1) {
+ for (unsigned int j = 0; j < aim->mNumVertices; ++j) {
+ aim->mTextureCoords[i][j].y = 1 - aim->mTextureCoords[i][j].y;
+ }
+ }
+
if (aim->mNumUVComponents[i] > 0) {
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
- Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, true);
- if (tc) p.attributes.texcoord.push_back(tc);
- }
- }
- if (aim->mNumFaces > 0) {
- unsigned int nIndicesPerFace = aim->mFaces[0].mNumIndices;
- std::vector<uint16_t> indices;
+ if(comp_allow) idx_srcdata_tc.push_back(b->byteLength);// Store index of texture coordinates array.
+
+ Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, true);
+ if (tc) p.attributes.texcoord.push_back(tc);
+ }
+ }
+
+ /*************** Vertices indices ****************/
+ idx_srcdata_ind = b->byteLength;// Store index of indices array.
+
+ if (aim->mNumFaces > 0) {
+ std::vector<IndicesType> indices;
+ unsigned int nIndicesPerFace = aim->mFaces[0].mNumIndices;
indices.resize(aim->mNumFaces * nIndicesPerFace);
for (size_t i = 0; i < aim->mNumFaces; ++i) {
for (size_t j = 0; j < nIndicesPerFace; ++j) {