diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 39db79a3e..32872108b 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -1267,7 +1267,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co const std::vector &normals = mesh.GetNormals(); if (normals.size()) { ai_assert(normals.size() == vertices.size()); - out_mesh->mNormals = new aiVector3D[vertices.size()]; + out_mesh->mNormals = new aiVector3D[count_vertices]; } // allocate tangents, binormals. @@ -1295,8 +1295,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co ai_assert(tangents.size() == vertices.size()); ai_assert(binormals->size() == vertices.size()); - out_mesh->mTangents = new aiVector3D[vertices.size()]; - out_mesh->mBitangents = new aiVector3D[vertices.size()]; + out_mesh->mTangents = new aiVector3D[count_vertices]; + out_mesh->mBitangents = new aiVector3D[count_vertices]; } } @@ -1308,7 +1308,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co break; } - out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()]; + out_mesh->mTextureCoords[i] = new aiVector3D[count_vertices]; out_mesh->mNumUVComponents[i] = 2; } @@ -1320,7 +1320,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co break; } - out_mesh->mColors[i] = new aiColor4D[vertices.size()]; + out_mesh->mColors[i] = new aiColor4D[count_vertices]; } unsigned int cursor = 0, in_cursor = 0; diff --git a/code/AssetLib/Obj/ObjFileImporter.cpp b/code/AssetLib/Obj/ObjFileImporter.cpp index 6dd26956e..68fdb2172 100644 --- a/code/AssetLib/Obj/ObjFileImporter.cpp +++ b/code/AssetLib/Obj/ObjFileImporter.cpp @@ -605,6 +605,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc mat->AddProperty(&sm, 1, AI_MATKEY_SHADING_MODEL); + // Preserve the original illum value + mat->AddProperty(&pCurrentMaterial->illumination_model, 1, AI_MATKEY_OBJ_ILLUM); + // Adding material colors mat->AddProperty(&pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT); mat->AddProperty(&pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE); diff --git a/code/AssetLib/glTF/glTFAsset.h b/code/AssetLib/glTF/glTFAsset.h index 4cd11aa4f..1a42e9020 100644 --- a/code/AssetLib/glTF/glTFAsset.h +++ b/code/AssetLib/glTF/glTFAsset.h @@ -260,20 +260,9 @@ public: VEC4, MAT2, MAT3, - MAT4 }; - -private: - static const size_t NUM_VALUES = static_cast(MAT4) + 1; - - struct Info { - const char *name; - unsigned int numComponents; + MAT4 }; - template - struct data { static const Info infos[NUM_VALUES]; }; - -public: inline static Value FromString(const char *str) { for (size_t i = 0; i < NUM_VALUES; ++i) { if (strcmp(data<0>::infos[i].name, str) == 0) { @@ -290,40 +279,31 @@ public: inline static unsigned int GetNumComponents(Value type) { return data<0>::infos[static_cast(type)].numComponents; } + +private: + static const size_t NUM_VALUES = static_cast(MAT4) + 1; + struct Info { + const char *name; + unsigned int numComponents; + }; + + template + struct data { + static const Info infos[NUM_VALUES]; + }; }; // must match the order of the AttribTypeTraits::Value enum! template -const AttribType::Info - AttribType::data::infos[AttribType::NUM_VALUES] = { - { "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 } - }; - -/* - //! A reference to one top-level object, which is valid - //! until the Asset instance is destroyed - template - class Ref - { - std::vector* vector; - unsigned int index; - - public: - Ref() : vector(0), index(0) {} - Ref(std::vector& vec, unsigned int idx) : vector(&vec), index(idx) {} - - inline unsigned int GetIndex() const - { return index; } - - operator bool() const - { return vector != 0; } - - T* operator->() - { return (*vector)[index]; } - - T& operator*() - { return *((*vector)[index]); } - };*/ +const AttribType::Info AttribType::data::infos[AttribType::NUM_VALUES] = { + { "SCALAR", 1 }, + { "VEC2", 2 }, + { "VEC3", 3 }, + { "VEC4", 4 }, + { "MAT2", 4 }, + { "MAT3", 9 }, + { "MAT4", 16 } +}; //! Base class for all glTF top-level objects struct Object { @@ -333,6 +313,7 @@ struct Object { //! Objects marked as special are not exported (used to emulate the binary body buffer) virtual bool IsSpecial() const { return false; } + Object() = default; virtual ~Object() {} //! Maps special IDs to another ID, where needed. Subclasses may override it (statically) @@ -401,21 +382,19 @@ struct Accessor : public Object { return Indexer(*this); } - Accessor() {} + Accessor() = default; void Read(Value &obj, Asset &r); }; //! A buffer points to binary geometry, animation, or skins. struct Buffer : public Object { /********************* Types *********************/ -public: enum Type { Type_arraybuffer, Type_text }; - /// \struct SEncodedRegion - /// Descriptor of encoded region in "bufferView". + /// @brief Descriptor of encoded region in "bufferView". struct SEncodedRegion { const size_t Offset; ///< Offset from begin of "bufferView" to encoded region, in bytes. const size_t EncodedData_Length; ///< Size of encoded region, in bytes. @@ -423,8 +402,7 @@ public: const size_t DecodedData_Length; ///< Size of decoded region, in bytes. const std::string ID; ///< ID of the region. - /// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID) - /// Constructor. + /// @brief Constructor. /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes. /// \param [in] pEncodedData_Length - size of encoded region, in bytes. /// \param [in] pDecodedData - pointer to decoded data array. @@ -433,16 +411,13 @@ public: SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) : Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {} - /// \fn ~SEncodedRegion() /// Destructor. ~SEncodedRegion() { delete[] DecodedData; } }; /******************* Variables *******************/ - //std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required) size_t byteLength; //!< The length of the buffer in bytes. (default: 0) - //std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer") Type type; @@ -486,7 +461,6 @@ public: bool LoadFromStream(IOStream &stream, size_t length = 0, size_t baseOffset = 0); - /// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID) /// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data. /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes. /// \param [in] pEncodedData_Length - size of encoded region, in bytes. @@ -495,12 +469,10 @@ public: /// \param [in] pID - ID of the region. void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID); - /// \fn void EncodedRegion_SetCurrent(const std::string& pID) /// Select current encoded region by ID. \sa EncodedRegion_Current. /// \param [in] pID - ID of the region. void EncodedRegion_SetCurrent(const std::string &pID); - /// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count) /// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions. /// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed. /// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced. @@ -558,37 +530,29 @@ struct Camera : public Object { } ortographic; }; - Camera() {} + Camera() = default; void Read(Value &obj, Asset &r); }; //! Image data used to create a texture. struct Image : public Object { std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required) - Ref bufferView; - std::string mimeType; - int width, height; -private: - std::unique_ptr mData; - size_t mDataLength; - public: Image(); void Read(Value &obj, Asset &r); - inline bool HasData() const { return mDataLength > 0; } - inline size_t GetDataLength() const { return mDataLength; } - inline const uint8_t *GetData() const { return mData.get(); } - inline uint8_t *StealData(); - inline void SetData(uint8_t *data, size_t length, Asset &r); + +private: + std::unique_ptr mData; + size_t mDataLength; }; //! Holds a material property that can be a texture or a color @@ -671,6 +635,7 @@ struct Mesh : public Object { }; #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC + /// \struct SCompression_Open3DGC /// Compression of mesh data using Open3DGC algorithm. struct SCompression_Open3DGC : public SExtension { @@ -703,7 +668,6 @@ struct Mesh : public Object { Mesh() {} - /// \fn ~Mesh() /// Destructor. ~Mesh() { for (std::list::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) { @@ -711,15 +675,13 @@ struct Mesh : public Object { }; } - /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root) - /// Get mesh data from JSON-object and place them to root asset. + /// @brief Get mesh data from JSON-object and place them to root asset. /// \param [in] pJSON_Object - reference to pJSON-object from which data are read. /// \param [out] pAsset_Root - reference to root asset where data will be stored. void Read(Value &pJSON_Object, Asset &pAsset_Root); #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC - /// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root) - /// Decode part of "buffer" which encoded with Open3DGC algorithm. + /// @brief Decode part of "buffer" which encoded with Open3DGC algorithm. /// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region. /// \param [out] pAsset_Root - reference to root assed where data will be stored. void Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root); @@ -759,7 +721,7 @@ struct Sampler : public Object { SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required) SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required) - Sampler() {} + Sampler() = default; void Read(Value &obj, Asset &r); void SetDefaults(); }; @@ -767,12 +729,12 @@ struct Sampler : public Object { struct Scene : public Object { std::vector> nodes; - Scene() {} + Scene() = default; void Read(Value &obj, Asset &r); }; struct Shader : public Object { - Shader() {} + Shader() = default; void Read(Value &obj, Asset &r); }; @@ -782,7 +744,7 @@ struct Skin : public Object { std::vector> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin. std::string name; //!< The user-defined name of this object. - Skin() {} + Skin() = default; void Read(Value &obj, Asset &r); }; @@ -796,7 +758,7 @@ struct Technique : public Object { struct Functions { }; - Technique() {} + Technique() = default; void Read(Value &obj, Asset &r); }; @@ -805,13 +767,7 @@ struct Texture : public Object { Ref sampler; //!< The ID of the sampler used by this texture. (required) Ref source; //!< The ID of the image used by this texture. (required) - //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA) - //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA) - - //TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D) - //TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE) - - Texture() {} + Texture() = default; void Read(Value &obj, Asset &r); }; @@ -826,7 +782,6 @@ struct Light : public Object { }; Type type; - vec4 color; float distance; float constantAttenuation; @@ -835,9 +790,8 @@ struct Light : public Object { float falloffAngle; float falloffExponent; - Light() {} + Light() = default; void Read(Value &obj, Asset &r); - void SetDefaults(); }; @@ -865,15 +819,11 @@ struct Animation : public Object { Ref translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors. }; - // AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy. - // AnimParameters Parameters; //!< The samplers that interpolate between the key-frames. - // AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data. - std::vector Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy. AnimParameters Parameters; //!< The samplers that interpolate between the key-frames. std::vector Samplers; //!< The parameterized inputs representing the key-frame data. - Animation() {} + Animation() = default; void Read(Value &obj, Asset &r); }; @@ -963,13 +913,11 @@ struct AssetMetadata { //! Root object for a glTF asset class Asset { - typedef std::gltf_unordered_map IdMap; + using IdMap = std::gltf_unordered_map; template friend class LazyDict; - friend struct Buffer; // To access OpenFile - friend class AssetWriter; private: @@ -1010,12 +958,9 @@ public: LazyDict materials; LazyDict meshes; LazyDict nodes; - //LazyDict programs; LazyDict samplers; LazyDict scenes; - //LazyDict shaders; LazyDict skins; - //LazyDict techniques; LazyDict textures; LazyDict lights; // KHR_materials_common ext @@ -1024,16 +969,20 @@ public: public: Asset(IOSystem *io = 0) : - mIOSystem(io), asset(), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), bufferViews(*this, "bufferViews"), cameras(*this, "cameras"), images(*this, "images"), materials(*this, "materials"), meshes(*this, "meshes"), nodes(*this, "nodes") - //, programs (*this, "programs") - , + mIOSystem(io), + asset(), + accessors(*this, "accessors"), + animations(*this, "animations"), + buffers(*this, "buffers"), + bufferViews(*this, "bufferViews"), + cameras(*this, "cameras"), + images(*this, "images"), + materials(*this, "materials"), + meshes(*this, "meshes"), + nodes(*this, "nodes"), samplers(*this, "samplers"), - scenes(*this, "scenes") - //, shaders (*this, "shaders") - , - skins(*this, "skins") - //, techniques (*this, "techniques") - , + scenes(*this, "scenes"), + skins(*this, "skins"), textures(*this, "textures"), lights(*this, "lights", "KHR_materials_common") { memset(&extensionsUsed, 0, sizeof(extensionsUsed)); diff --git a/code/AssetLib/glTF/glTFCommon.h b/code/AssetLib/glTF/glTFCommon.h index caf33009e..edc3c7e03 100644 --- a/code/AssetLib/glTF/glTFCommon.h +++ b/code/AssetLib/glTF/glTFCommon.h @@ -237,8 +237,6 @@ bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out); #define CHECK_EXT(EXT) \ if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true; - - //! Helper struct to represent values that might not be present template struct Nullable { diff --git a/code/AssetLib/glTF2/glTF2Asset.h b/code/AssetLib/glTF2/glTF2Asset.h index e4fb2dc84..c597fc951 100644 --- a/code/AssetLib/glTF2/glTF2Asset.h +++ b/code/AssetLib/glTF2/glTF2Asset.h @@ -106,7 +106,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # define gltf_unordered_map tr1::unordered_map # define gltf_unordered_set tr1::unordered_set # else -# define gltf_unordered_map unordered_map +# define gltf_unordered_map unordered_map # define gltf_unordered_set unordered_set # endif #endif @@ -1087,29 +1087,11 @@ class Asset { template friend class LazyDict; - friend struct Buffer; // To access OpenFile - friend class AssetWriter; -private: - IOSystem *mIOSystem; - rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider; - - std::string mCurrentAssetDir; - - size_t mSceneLength; - size_t mBodyOffset, mBodyLength; - std::vector mDicts; - IdMap mUsedIds; - - Ref mBodyBuffer; - - Asset(Asset &); - Asset &operator=(const Asset &); - public: //! Keeps info about the enabled extensions struct Extensions { @@ -1125,16 +1107,36 @@ public: bool KHR_draco_mesh_compression; bool FB_ngon_encoding; bool KHR_texture_basisu; + + Extensions() : + KHR_materials_pbrSpecularGlossiness(false), + KHR_materials_unlit(false), + KHR_lights_punctual(false), + KHR_texture_transform(false), + KHR_materials_sheen(false), + KHR_materials_clearcoat(false), + KHR_materials_transmission(false), + KHR_materials_volume(false), + KHR_materials_ior(false), + KHR_draco_mesh_compression(false), + FB_ngon_encoding(false), + KHR_texture_basisu(false) { + // empty + } } extensionsUsed; //! Keeps info about the required extensions struct RequiredExtensions { bool KHR_draco_mesh_compression; bool KHR_texture_basisu; + + RequiredExtensions() : KHR_draco_mesh_compression(false), KHR_texture_basisu(false) { + // empty + } } extensionsRequired; AssetMetadata asset; - Value *extras = nullptr; + Value *extras; // Dictionaries for each type of object @@ -1156,10 +1158,12 @@ public: Ref scene; public: - Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) : - mIOSystem(io), - mSchemaDocumentProvider(schemaDocumentProvider), + Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) : + mDicts(), + extensionsUsed(), + extensionsRequired(), asset(), + extras(nullptr), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), @@ -1173,9 +1177,10 @@ public: samplers(*this, "samplers"), scenes(*this, "scenes"), skins(*this, "skins"), - textures(*this, "textures") { - memset(&extensionsUsed, 0, sizeof(extensionsUsed)); - memset(&extensionsRequired, 0, sizeof(extensionsRequired)); + textures(*this, "textures") , + mIOSystem(io), + mSchemaDocumentProvider(schemaDocumentProvider) { + // empty } //! Main function @@ -1192,18 +1197,31 @@ public: Ref GetBodyBuffer() { return mBodyBuffer; } + Asset(Asset &) = delete; + Asset &operator=(const Asset &) = delete; + private: void ReadBinaryHeader(IOStream &stream, std::vector &sceneData); - //! Obtain a JSON document from the stream. - // \param second argument is a buffer used by the document. It must be kept - // alive while the document is in use. + /// Obtain a JSON document from the stream. + /// \param second argument is a buffer used by the document. It must be kept + /// alive while the document is in use. Document ReadDocument(IOStream& stream, bool isBinary, std::vector& sceneData); void ReadExtensionsUsed(Document &doc); void ReadExtensionsRequired(Document &doc); IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false); + +private: + IOSystem *mIOSystem; + rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider; + std::string mCurrentAssetDir; + size_t mSceneLength; + size_t mBodyOffset; + size_t mBodyLength; + IdMap mUsedIds; + Ref mBodyBuffer; }; inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) { diff --git a/code/AssetLib/glTF2/glTF2Exporter.cpp b/code/AssetLib/glTF2/glTF2Exporter.cpp index e779a7be4..ffd8d223e 100644 --- a/code/AssetLib/glTF2/glTF2Exporter.cpp +++ b/code/AssetLib/glTF2/glTF2Exporter.cpp @@ -515,72 +515,74 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char } void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) { - if (mat.GetTextureCount(tt) > 0) { - aiString tex; + if (mat.GetTextureCount(tt) == 0) { + return; + } + + aiString tex; - // Read texcoord (UV map index) - mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); + // Read texcoord (UV map index) + mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); - if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { - std::string path = tex.C_Str(); + if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { + std::string path = tex.C_Str(); - if (path.size() > 0) { - std::map::iterator it = mTexturesByPath.find(path); - if (it != mTexturesByPath.end()) { - texture = mAsset->textures.Get(it->second); - } + if (path.size() > 0) { + std::map::iterator it = mTexturesByPath.find(path); + if (it != mTexturesByPath.end()) { + texture = mAsset->textures.Get(it->second); + } - bool useBasisUniversal = false; - if (!texture) { - std::string texId = mAsset->FindUniqueID("", "texture"); - texture = mAsset->textures.Create(texId); - mTexturesByPath[path] = texture.GetIndex(); + bool useBasisUniversal = false; + if (!texture) { + std::string texId = mAsset->FindUniqueID("", "texture"); + texture = mAsset->textures.Create(texId); + mTexturesByPath[path] = texture.GetIndex(); - std::string imgId = mAsset->FindUniqueID("", "image"); - texture->source = mAsset->images.Create(imgId); + std::string imgId = mAsset->FindUniqueID("", "image"); + texture->source = mAsset->images.Create(imgId); - const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str()); - if (curTex != nullptr) { // embedded - texture->source->name = curTex->mFilename.C_Str(); + const aiTexture *curTex = mScene->GetEmbeddedTexture(path.c_str()); + if (curTex != nullptr) { // embedded + texture->source->name = curTex->mFilename.C_Str(); - //basisu: embedded ktx2, bu - if (curTex->achFormatHint[0]) { - std::string mimeType = "image/"; - if (memcmp(curTex->achFormatHint, "jpg", 3) == 0) - mimeType += "jpeg"; - else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) { - useBasisUniversal = true; - mimeType += "ktx"; - } else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) { - useBasisUniversal = true; - mimeType += "ktx2"; - } else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) { - useBasisUniversal = true; - mimeType += "basis"; - } else - mimeType += curTex->achFormatHint; - texture->source->mimeType = mimeType; - } - - // The asset has its own buffer, see Image::SetData - //basisu: "image/ktx2", "image/basis" as is - texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); - } else { - texture->source->uri = path; - if (texture->source->uri.find(".ktx") != std::string::npos || - texture->source->uri.find(".basis") != std::string::npos) { + //basisu: embedded ktx2, bu + if (curTex->achFormatHint[0]) { + std::string mimeType = "image/"; + if (memcmp(curTex->achFormatHint, "jpg", 3) == 0) + mimeType += "jpeg"; + else if (memcmp(curTex->achFormatHint, "ktx", 3) == 0) { useBasisUniversal = true; - } + mimeType += "ktx"; + } else if (memcmp(curTex->achFormatHint, "kx2", 3) == 0) { + useBasisUniversal = true; + mimeType += "ktx2"; + } else if (memcmp(curTex->achFormatHint, "bu", 2) == 0) { + useBasisUniversal = true; + mimeType += "basis"; + } else + mimeType += curTex->achFormatHint; + texture->source->mimeType = mimeType; } - //basisu - if (useBasisUniversal) { - mAsset->extensionsUsed.KHR_texture_basisu = true; - mAsset->extensionsRequired.KHR_texture_basisu = true; + // The asset has its own buffer, see Image::SetData + //basisu: "image/ktx2", "image/basis" as is + texture->source->SetData(reinterpret_cast(curTex->pcData), curTex->mWidth, *mAsset); + } else { + texture->source->uri = path; + if (texture->source->uri.find(".ktx") != std::string::npos || + texture->source->uri.find(".basis") != std::string::npos) { + useBasisUniversal = true; } - - GetTexSampler(mat, texture, tt, slot); } + + //basisu + if (useBasisUniversal) { + mAsset->extensionsUsed.KHR_texture_basisu = true; + mAsset->extensionsRequired.KHR_texture_basisu = true; + } + + GetTexSampler(mat, texture, tt, slot); } } } @@ -588,12 +590,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref &texture, unsi void glTF2Exporter::GetMatTex(const aiMaterial &mat, TextureInfo &prop, aiTextureType tt, unsigned int slot = 0) { Ref &texture = prop.texture; - GetMatTex(mat, texture, prop.texCoord, tt, slot); - - //if (texture) { - // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); - //} } void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, aiTextureType tt, unsigned int slot = 0) { @@ -681,12 +678,14 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) { // Return true if got any valid Sheen properties or textures - if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) + if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) { return false; + } // Default Sheen color factor {0,0,0} disables Sheen, so do not export - if (sheen.sheenColorFactor == defaultSheenFactor) + if (sheen.sheenColorFactor == defaultSheenFactor) { return false; + } mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor); @@ -781,9 +780,7 @@ void glTF2Exporter::ExportMaterials() { aiColor4D specularColor; ai_real shininess; - if ( - mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && - mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) { + if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) { // convert specular color to luminance float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f; //normalize shininess (assuming max is 1000) with an inverse exponentional curve @@ -916,7 +913,8 @@ Ref FindSkeletonRootJoint(Ref &skinRef) { return parentNodeRef; } -void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref &bufferRef, Ref &skinRef, std::vector &inverseBindMatricesData) { +void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Ref &bufferRef, Ref &skinRef, + std::vector &inverseBindMatricesData) { if (aimesh->mNumBones < 1) { return; } @@ -986,7 +984,8 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref &meshRef, Refprimitives.back(); - Ref vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); + Ref vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, + vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); if (vertexJointAccessor) { size_t offset = vertexJointAccessor->bufferView->byteOffset; size_t bytesLen = vertexJointAccessor->bufferView->byteLength; @@ -1069,8 +1068,11 @@ void glTF2Exporter::ExportMeshes() { p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0; /******************* Vertices ********************/ - Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (v) p.attributes.position.push_back(v); + Ref v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, + AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (v) { + p.attributes.position.push_back(v); + } /******************** Normals ********************/ // Normalize all normals as the validator can emit a warning otherwise @@ -1080,13 +1082,17 @@ void glTF2Exporter::ExportMeshes() { } } - Ref n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (n) p.attributes.normal.push_back(n); + Ref n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, + AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (n) { + p.attributes.normal.push_back(n); + } /************** Texture coordinates **************/ for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { - if (!aim->HasTextureCoords(i)) + if (!aim->HasTextureCoords(i)) { continue; + } // Flip UV y coords if (aim->mNumUVComponents[i] > 1) { @@ -1098,16 +1104,21 @@ void glTF2Exporter::ExportMeshes() { if (aim->mNumUVComponents[i] > 0) { AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3; - Ref tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (tc) p.attributes.texcoord.push_back(tc); + Ref tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], + AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (tc) { + p.attributes.texcoord.push_back(tc); + } } } /*************** Vertex colors ****************/ for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) { - Ref c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); - if (c) + Ref c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], + AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); + if (c) { p.attributes.color.push_back(c); + } } /*************** Vertices indices ****************/ @@ -1121,7 +1132,8 @@ void glTF2Exporter::ExportMeshes() { } } - p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER); + p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, + ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER); } switch (aim->mPrimitiveTypes) { @@ -1136,6 +1148,7 @@ void glTF2Exporter::ExportMeshes() { break; default: // aiPrimitiveType_TRIANGLE p.mode = PrimitiveMode_TRIANGLES; + break; } /*************** Skins ****************/ @@ -1155,8 +1168,9 @@ void glTF2Exporter::ExportMeshes() { p.targets.resize(aim->mNumAnimMeshes); for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) { aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am]; - if (bExportTargetNames) - m->targetNames.push_back(pAnimMesh->mName.data); + if (bExportTargetNames) { + m->targetNames.emplace_back(pAnimMesh->mName.data); + } // position if (pAnimMesh->HasPositions()) { // NOTE: in gltf it is the diff stored @@ -1319,12 +1333,12 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) { } for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i])); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { unsigned int idx = ExportNode(n->mChildren[i], node); - node->children.push_back(mAsset->nodes.Get(idx)); + node->children.emplace_back(mAsset->nodes.Get(idx)); } return node.GetIndex(); @@ -1366,12 +1380,12 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref &parent) { } for (unsigned int i = 0; i < n->mNumMeshes; ++i) { - node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i])); + node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i])); } for (unsigned int i = 0; i < n->mNumChildren; ++i) { unsigned int idx = ExportNode(n->mChildren[i], node); - node->children.push_back(mAsset->nodes.Get(idx)); + node->children.emplace_back(mAsset->nodes.Get(idx)); } return node.GetIndex(); @@ -1386,7 +1400,7 @@ void glTF2Exporter::ExportScene() { // root node will be the first one exported (idx 0) if (mAsset->nodes.Size() > 0) { - scene->nodes.push_back(mAsset->nodes.Get(0u)); + scene->nodes.emplace_back(mAsset->nodes.Get(0u)); } // set as the default scene @@ -1521,12 +1535,6 @@ void glTF2Exporter::ExportAnimations() { AddSampler(animRef, animNode, scaleSampler, AnimationPath_SCALE); } } - - // Assimp documentation states this is not used (not implemented) - // for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) { - // const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex]; - // } - } // End: for-loop mNumAnimations } diff --git a/include/assimp/Hash.h b/include/assimp/Hash.h index 1f2baedac..5a02f5f31 100644 --- a/include/assimp/Hash.h +++ b/include/assimp/Hash.h @@ -4,7 +4,6 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2022, assimp team - All rights reserved. Redistribution and use of this software in source and binary forms, @@ -76,7 +75,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) { uint32_t tmp; int rem; - +size_t offset; + if (!data) return 0; if (!len)len = (uint32_t)::strlen(data); @@ -96,7 +96,11 @@ int rem; switch (rem) { case 3: hash += get16bits (data); hash ^= hash << 16; - hash ^= data[sizeof (uint16_t)] << 18; + offset = static_cast(sizeof(uint16_t)); + if (offset < 0) { + return 0; + } + hash ^= data[offset] << 18; hash += hash >> 11; break; case 2: hash += get16bits (data); diff --git a/include/assimp/ObjMaterial.h b/include/assimp/ObjMaterial.h index 39894a696..bba207638 100644 --- a/include/assimp/ObjMaterial.h +++ b/include/assimp/ObjMaterial.h @@ -53,6 +53,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +// --------------------------------------------------------------------------- + +// the original illum property +#define AI_MATKEY_OBJ_ILLUM "$mat.illum", 0, 0 + +// --------------------------------------------------------------------------- + // --------------------------------------------------------------------------- // Pure key names for all obj texture-related properties //! @cond MATS_DOC_FULL diff --git a/test/unit/Common/utMesh.cpp b/test/unit/Common/utMesh.cpp index edb3de3de..77a711394 100644 --- a/test/unit/Common/utMesh.cpp +++ b/test/unit/Common/utMesh.cpp @@ -60,7 +60,7 @@ protected: }; TEST_F(utMesh, emptyMeshHasNoContentTest) { - EXPECT_EQ(0, mesh->mName.length); + EXPECT_EQ(0u, mesh->mName.length); EXPECT_FALSE(mesh->HasPositions()); EXPECT_FALSE(mesh->HasFaces()); EXPECT_FALSE(mesh->HasNormals()); @@ -69,8 +69,8 @@ TEST_F(utMesh, emptyMeshHasNoContentTest) { EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS)); EXPECT_FALSE(mesh->HasTextureCoords(0)); EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS)); - EXPECT_EQ(0, mesh->GetNumUVChannels()); - EXPECT_EQ(0, mesh->GetNumColorChannels()); + EXPECT_EQ(0u, mesh->GetNumUVChannels()); + EXPECT_EQ(0u, mesh->GetNumColorChannels()); EXPECT_FALSE(mesh->HasBones()); EXPECT_FALSE(mesh->HasTextureCoordsName(0)); EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS)); @@ -80,8 +80,8 @@ TEST_F(utMesh, setTextureCoordsName) { EXPECT_FALSE(mesh->HasTextureCoordsName(0)); const aiString texcoords_name("texcoord_name"); mesh->SetTextureCoordsName(0, texcoords_name); - EXPECT_TRUE(mesh->HasTextureCoordsName(0)); - EXPECT_FALSE(mesh->HasTextureCoordsName(1)); + EXPECT_TRUE(mesh->HasTextureCoordsName(0u)); + EXPECT_FALSE(mesh->HasTextureCoordsName(1u)); ASSERT_NE(nullptr, mesh->mTextureCoordsNames); ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]); EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str()); @@ -94,3 +94,4 @@ TEST_F(utMesh, setTextureCoordsName) { EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]); EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0)); } + diff --git a/test/unit/utColladaExport.cpp b/test/unit/utColladaExport.cpp index 4488f9f90..bb87071bb 100644 --- a/test/unit/utColladaExport.cpp +++ b/test/unit/utColladaExport.cpp @@ -124,9 +124,9 @@ TEST_F(utColladaExport, testExportLight) { ASSERT_NE(pTest, nullptr); ASSERT_TRUE(pTest->HasLights()); - const unsigned int origNumLights(pTest->mNumLights); + const unsigned int origNumLights = pTest->mNumLights; // There are FIVE!!! LIGHTS!!! - EXPECT_EQ(5, origNumLights) << "lights.dae should contain five lights"; + EXPECT_EQ(5u, origNumLights) << "lights.dae should contain five lights"; std::vector origLights(5); for (size_t i = 0; i < origNumLights; i++) {