diff options
Diffstat (limited to 'src/mesh/assimp-master/code/Material/MaterialSystem.cpp')
-rw-r--r-- | src/mesh/assimp-master/code/Material/MaterialSystem.cpp | 614 |
1 files changed, 0 insertions, 614 deletions
diff --git a/src/mesh/assimp-master/code/Material/MaterialSystem.cpp b/src/mesh/assimp-master/code/Material/MaterialSystem.cpp deleted file mode 100644 index b2f7389..0000000 --- a/src/mesh/assimp-master/code/Material/MaterialSystem.cpp +++ /dev/null @@ -1,614 +0,0 @@ -/* -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, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ----------------------------------------------------------------------- -*/ - -/** @file MaterialSystem.cpp - * @brief Implementation of the material system of the library - */ - -#include "MaterialSystem.h" -#include <assimp/Hash.h> -#include <assimp/ParsingUtils.h> -#include <assimp/fast_atof.h> -#include <assimp/material.h> -#include <assimp/types.h> -#include <assimp/DefaultLogger.hpp> - -using namespace Assimp; - -// ------------------------------------------------------------------------------------------------ -// Get a specific property from a material -aiReturn aiGetMaterialProperty(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - const aiMaterialProperty **pPropOut) { - ai_assert(pMat != nullptr); - ai_assert(pKey != nullptr); - ai_assert(pPropOut != nullptr); - - /* Just search for a property with exactly this name .. - * could be improved by hashing, but it's possibly - * no worth the effort (we're bound to C structures, - * thus std::map or derivates are not applicable. */ - for (unsigned int i = 0; i < pMat->mNumProperties; ++i) { - aiMaterialProperty *prop = pMat->mProperties[i]; - - if (prop /* just for safety ... */ - && 0 == strcmp(prop->mKey.data, pKey) && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */ - && (UINT_MAX == index || prop->mIndex == index)) { - *pPropOut = pMat->mProperties[i]; - return AI_SUCCESS; - } - } - *pPropOut = nullptr; - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -// Get an array of floating-point values from the material. -aiReturn aiGetMaterialFloatArray(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - ai_real *pOut, - unsigned int *pMax) { - ai_assert(pOut != nullptr); - ai_assert(pMat != nullptr); - - const aiMaterialProperty *prop; - aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop); - if (nullptr == prop) { - return AI_FAILURE; - } - - // data is given in floats, convert to ai_real - unsigned int iWrite = 0; - if (aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) { - iWrite = prop->mDataLength / sizeof(float); - if (pMax) { - iWrite = std::min(*pMax, iWrite); - ; - } - - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[a] = static_cast<ai_real>(reinterpret_cast<float *>(prop->mData)[a]); - } - - if (pMax) { - *pMax = iWrite; - } - } - // data is given in doubles, convert to float - else if (aiPTI_Double == prop->mType) { - iWrite = prop->mDataLength / sizeof(double); - if (pMax) { - iWrite = std::min(*pMax, iWrite); - ; - } - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[a] = static_cast<ai_real>(reinterpret_cast<double *>(prop->mData)[a]); - } - if (pMax) { - *pMax = iWrite; - } - } - // data is given in ints, convert to float - else if (aiPTI_Integer == prop->mType) { - iWrite = prop->mDataLength / sizeof(int32_t); - if (pMax) { - iWrite = std::min(*pMax, iWrite); - ; - } - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[a] = static_cast<ai_real>(reinterpret_cast<int32_t *>(prop->mData)[a]); - } - if (pMax) { - *pMax = iWrite; - } - } - // a string ... read floats separated by spaces - else { - if (pMax) { - iWrite = *pMax; - } - // strings are zero-terminated with a 32 bit length prefix, so this is safe - const char *cur = prop->mData + 4; - ai_assert(prop->mDataLength >= 5); - ai_assert(!prop->mData[prop->mDataLength - 1]); - for (unsigned int a = 0;; ++a) { - cur = fast_atoreal_move<ai_real>(cur, pOut[a]); - if (a == iWrite - 1) { - break; - } - if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property", pKey, - " is a string; failed to parse a float array out of it."); - return AI_FAILURE; - } - } - - if (pMax) { - *pMax = iWrite; - } - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get an array if integers from the material -aiReturn aiGetMaterialIntegerArray(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - int *pOut, - unsigned int *pMax) { - ai_assert(pOut != nullptr); - ai_assert(pMat != nullptr); - - const aiMaterialProperty *prop; - aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop); - if (!prop) { - return AI_FAILURE; - } - - // data is given in ints, simply copy it - unsigned int iWrite = 0; - if (aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) { - iWrite = std::max(static_cast<unsigned int>(prop->mDataLength / sizeof(int32_t)), 1u); - if (pMax) { - iWrite = std::min(*pMax, iWrite); - } - if (1 == prop->mDataLength) { - // bool type, 1 byte - *pOut = static_cast<int>(*prop->mData); - } else { - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[a] = static_cast<int>(reinterpret_cast<int32_t *>(prop->mData)[a]); - } - } - if (pMax) { - *pMax = iWrite; - } - } - // data is given in floats convert to int - else if (aiPTI_Float == prop->mType) { - iWrite = prop->mDataLength / sizeof(float); - if (pMax) { - iWrite = std::min(*pMax, iWrite); - ; - } - for (unsigned int a = 0; a < iWrite; ++a) { - pOut[a] = static_cast<int>(reinterpret_cast<float *>(prop->mData)[a]); - } - if (pMax) { - *pMax = iWrite; - } - } - // it is a string ... no way to read something out of this - else { - if (pMax) { - iWrite = *pMax; - } - // strings are zero-terminated with a 32 bit length prefix, so this is safe - const char *cur = prop->mData + 4; - ai_assert(prop->mDataLength >= 5); - ai_assert(!prop->mData[prop->mDataLength - 1]); - for (unsigned int a = 0;; ++a) { - pOut[a] = strtol10(cur, &cur); - if (a == iWrite - 1) { - break; - } - if (!IsSpace(*cur)) { - ASSIMP_LOG_ERROR("Material property", pKey, - " is a string; failed to parse an integer array out of it."); - return AI_FAILURE; - } - } - - if (pMax) { - *pMax = iWrite; - } - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get a color (3 or 4 floats) from the material -aiReturn aiGetMaterialColor(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - aiColor4D *pOut) { - unsigned int iMax = 4; - const aiReturn eRet = aiGetMaterialFloatArray(pMat, pKey, type, index, (ai_real *)pOut, &iMax); - - // if no alpha channel is defined: set it to 1.0 - if (3 == iMax) { - pOut->a = 1.0; - } - - return eRet; -} - -// ------------------------------------------------------------------------------------------------ -// Get a aiUVTransform (5 floats) from the material -aiReturn aiGetMaterialUVTransform(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - aiUVTransform *pOut) { - unsigned int iMax = 5; - return aiGetMaterialFloatArray(pMat, pKey, type, index, (ai_real *)pOut, &iMax); -} - -// ------------------------------------------------------------------------------------------------ -// Get a string from the material -aiReturn aiGetMaterialString(const aiMaterial *pMat, - const char *pKey, - unsigned int type, - unsigned int index, - aiString *pOut) { - ai_assert(pOut != nullptr); - - const aiMaterialProperty *prop; - aiGetMaterialProperty(pMat, pKey, type, index, (const aiMaterialProperty **)&prop); - if (!prop) { - return AI_FAILURE; - } - - if (aiPTI_String == prop->mType) { - ai_assert(prop->mDataLength >= 5); - - // The string is stored as 32 but length prefix followed by zero-terminated UTF8 data - pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t *>(prop->mData)); - - ai_assert(pOut->length + 1 + 4 == prop->mDataLength); - ai_assert(!prop->mData[prop->mDataLength - 1]); - memcpy(pOut->data, prop->mData + 4, pOut->length + 1); - } else { - // TODO - implement lexical cast as well - ASSIMP_LOG_ERROR("Material property", pKey, " was found, but is no string"); - return AI_FAILURE; - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get the number of textures on a particular texture stack -unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial *pMat, C_ENUM aiTextureType type) { - ai_assert(pMat != nullptr); - - // Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again) - unsigned int max = 0; - for (unsigned int i = 0; i < pMat->mNumProperties; ++i) { - aiMaterialProperty *prop = pMat->mProperties[i]; - - if (prop /* just a sanity check ... */ - && 0 == strcmp(prop->mKey.data, _AI_MATKEY_TEXTURE_BASE) && static_cast<aiTextureType>(prop->mSemantic) == type) { - - max = std::max(max, prop->mIndex + 1); - } - } - return max; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial *mat, - aiTextureType type, - unsigned int index, - C_STRUCT aiString *path, - aiTextureMapping *_mapping /*= nullptr*/, - unsigned int *uvindex /*= nullptr*/, - ai_real *blend /*= nullptr*/, - aiTextureOp *op /*= nullptr*/, - aiTextureMapMode *mapmode /*= nullptr*/, - unsigned int *flags /*= nullptr*/ -) { - ai_assert(nullptr != mat); - ai_assert(nullptr != path); - - // Get the path to the texture - if (AI_SUCCESS != aiGetMaterialString(mat, AI_MATKEY_TEXTURE(type, index), path)) { - return AI_FAILURE; - } - - // Determine mapping type - int mapping_ = static_cast<int>(aiTextureMapping_UV); - aiGetMaterialInteger(mat, AI_MATKEY_MAPPING(type, index), &mapping_); - aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_); - if (_mapping) - *_mapping = mapping; - - // Get UV index - if (aiTextureMapping_UV == mapping && uvindex) { - aiGetMaterialInteger(mat, AI_MATKEY_UVWSRC(type, index), (int *)uvindex); - } - // Get blend factor - if (blend) { - aiGetMaterialFloat(mat, AI_MATKEY_TEXBLEND(type, index), blend); - } - // Get texture operation - if (op) { - aiGetMaterialInteger(mat, AI_MATKEY_TEXOP(type, index), (int *)op); - } - // Get texture mapping modes - if (mapmode) { - aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(type, index), (int *)&mapmode[0]); - aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(type, index), (int *)&mapmode[1]); - } - // Get texture flags - if (flags) { - aiGetMaterialInteger(mat, AI_MATKEY_TEXFLAGS(type, index), (int *)flags); - } - - return AI_SUCCESS; -} - -static const unsigned int DefaultNumAllocated = 5; - -// ------------------------------------------------------------------------------------------------ -// Construction. Actually the one and only way to get an aiMaterial instance -aiMaterial::aiMaterial() : - mProperties(nullptr), mNumProperties(0), mNumAllocated(DefaultNumAllocated) { - // Allocate 5 entries by default - mProperties = new aiMaterialProperty *[DefaultNumAllocated]; -} - -// ------------------------------------------------------------------------------------------------ -aiMaterial::~aiMaterial() { - Clear(); - - delete[] mProperties; -} - -// ------------------------------------------------------------------------------------------------ -aiString aiMaterial::GetName() const { - aiString name; - Get(AI_MATKEY_NAME, name); - - return name; -} - -// ------------------------------------------------------------------------------------------------ -void aiMaterial::Clear() { - for (unsigned int i = 0; i < mNumProperties; ++i) { - // delete this entry - delete mProperties[i]; - AI_DEBUG_INVALIDATE_PTR(mProperties[i]); - } - mNumProperties = 0; - - // The array remains allocated, we just invalidated its contents -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::RemoveProperty(const char *pKey, unsigned int type, unsigned int index) { - ai_assert(nullptr != pKey); - - for (unsigned int i = 0; i < mNumProperties; ++i) { - aiMaterialProperty *prop = mProperties[i]; - - if (prop && !strcmp(prop->mKey.data, pKey) && - prop->mSemantic == type && prop->mIndex == index) { - // Delete this entry - delete mProperties[i]; - - // collapse the array behind --. - --mNumProperties; - for (unsigned int a = i; a < mNumProperties; ++a) { - mProperties[a] = mProperties[a + 1]; - } - return AI_SUCCESS; - } - } - - return AI_FAILURE; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::AddBinaryProperty(const void *pInput, - unsigned int pSizeInBytes, - const char *pKey, - unsigned int type, - unsigned int index, - aiPropertyTypeInfo pType) { - ai_assert(pInput != nullptr); - ai_assert(pKey != nullptr); - ai_assert(0 != pSizeInBytes); - - if (0 == pSizeInBytes) { - return AI_FAILURE; - } - - // first search the list whether there is already an entry with this key - unsigned int iOutIndex(UINT_MAX); - for (unsigned int i = 0; i < mNumProperties; ++i) { - aiMaterialProperty *prop(mProperties[i]); - - if (prop /* just for safety */ && !strcmp(prop->mKey.data, pKey) && - prop->mSemantic == type && prop->mIndex == index) { - - delete mProperties[i]; - iOutIndex = i; - } - } - - // Allocate a new material property - aiMaterialProperty *pcNew = new aiMaterialProperty(); - - // .. and fill it - pcNew->mType = pType; - pcNew->mSemantic = type; - pcNew->mIndex = index; - - pcNew->mDataLength = pSizeInBytes; - pcNew->mData = new char[pSizeInBytes]; - memcpy(pcNew->mData, pInput, pSizeInBytes); - - pcNew->mKey.length = static_cast<ai_uint32>(::strlen(pKey)); - ai_assert(MAXLEN > pcNew->mKey.length); - strcpy(pcNew->mKey.data, pKey); - - if (UINT_MAX != iOutIndex) { - mProperties[iOutIndex] = pcNew; - return AI_SUCCESS; - } - - // resize the array ... double the storage allocated - if (mNumProperties == mNumAllocated) { - const unsigned int iOld = mNumAllocated; - mNumAllocated *= 2; - - aiMaterialProperty **ppTemp; - try { - ppTemp = new aiMaterialProperty *[mNumAllocated]; - } catch (std::bad_alloc &) { - delete pcNew; - return AI_OUTOFMEMORY; - } - - // just copy all items over; then replace the old array - memcpy(ppTemp, mProperties, iOld * sizeof(void *)); - - delete[] mProperties; - mProperties = ppTemp; - } - // push back ... - mProperties[mNumProperties++] = pcNew; - - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn aiMaterial::AddProperty(const aiString *pInput, - const char *pKey, - unsigned int type, - unsigned int index) { - ai_assert(sizeof(ai_uint32) == 4); - return AddBinaryProperty(pInput, - static_cast<unsigned int>(pInput->length + 1 + 4), - pKey, - type, - index, - aiPTI_String); -} - -// ------------------------------------------------------------------------------------------------ -uint32_t Assimp::ComputeMaterialHash(const aiMaterial *mat, bool includeMatName /*= false*/) { - uint32_t hash = 1503; // magic start value, chosen to be my birthday :-) - for (unsigned int i = 0; i < mat->mNumProperties; ++i) { - aiMaterialProperty *prop; - - // Exclude all properties whose first character is '?' from the hash - // See doc for aiMaterialProperty. - prop = mat->mProperties[i]; - if (nullptr != prop && (includeMatName || prop->mKey.data[0] != '?')) { - - hash = SuperFastHash(prop->mKey.data, (unsigned int)prop->mKey.length, hash); - hash = SuperFastHash(prop->mData, prop->mDataLength, hash); - - // Combine the semantic and the index with the hash - hash = SuperFastHash((const char *)&prop->mSemantic, sizeof(unsigned int), hash); - hash = SuperFastHash((const char *)&prop->mIndex, sizeof(unsigned int), hash); - } - } - return hash; -} - -// ------------------------------------------------------------------------------------------------ -void aiMaterial::CopyPropertyList(aiMaterial *const pcDest, - const aiMaterial *pcSrc) { - ai_assert(nullptr != pcDest); - ai_assert(nullptr != pcSrc); - ai_assert(pcDest->mNumProperties <= pcDest->mNumAllocated); - ai_assert(pcSrc->mNumProperties <= pcSrc->mNumAllocated); - - const unsigned int iOldNum = pcDest->mNumProperties; - pcDest->mNumAllocated += pcSrc->mNumAllocated; - pcDest->mNumProperties += pcSrc->mNumProperties; - - const unsigned int numAllocated = pcDest->mNumAllocated; - aiMaterialProperty **pcOld = pcDest->mProperties; - pcDest->mProperties = new aiMaterialProperty *[numAllocated]; - - ai_assert(!iOldNum || pcOld); - ai_assert(iOldNum < numAllocated); - - if (iOldNum && pcOld) { - for (unsigned int i = 0; i < iOldNum; ++i) { - pcDest->mProperties[i] = pcOld[i]; - } - } - - if (pcOld) { - delete[] pcOld; - } - - for (unsigned int i = iOldNum; i < pcDest->mNumProperties; ++i) { - aiMaterialProperty *propSrc = pcSrc->mProperties[i]; - - // search whether we have already a property with this name -> if yes, overwrite it - aiMaterialProperty *prop; - for (unsigned int q = 0; q < iOldNum; ++q) { - prop = pcDest->mProperties[q]; - if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic && prop->mIndex == propSrc->mIndex) { - delete prop; - - // collapse the whole array ... - memmove(&pcDest->mProperties[q], &pcDest->mProperties[q + 1], i - q); - i--; - pcDest->mNumProperties--; - } - } - - // Allocate the output property and copy the source property - prop = pcDest->mProperties[i] = new aiMaterialProperty(); - prop->mKey = propSrc->mKey; - prop->mDataLength = propSrc->mDataLength; - prop->mType = propSrc->mType; - prop->mSemantic = propSrc->mSemantic; - prop->mIndex = propSrc->mIndex; - - prop->mData = new char[propSrc->mDataLength]; - memcpy(prop->mData, propSrc->mData, prop->mDataLength); - } -} |