[*] Merge with fresh master.
authorAlexandr Arutjunov <smal.root@gmail.com>
Tue, 20 Sep 2016 13:02:41 +0000 (16:02 +0300)
committerAlexandr Arutjunov <smal.root@gmail.com>
Tue, 20 Sep 2016 13:02:41 +0000 (16:02 +0300)
1  2 
code/glTFExporter.cpp

@@@ -274,49 -267,15 +274,56 @@@ void glTFExporter::ExportMaterials(
  
  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) {