diff options
Diffstat (limited to '3rdparty/assimp/code/MaterialSystem.cpp')
-rw-r--r-- | 3rdparty/assimp/code/MaterialSystem.cpp | 612 |
1 files changed, 0 insertions, 612 deletions
diff --git a/3rdparty/assimp/code/MaterialSystem.cpp b/3rdparty/assimp/code/MaterialSystem.cpp deleted file mode 100644 index 0df12ba0..00000000 --- a/3rdparty/assimp/code/MaterialSystem.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* -Open Asset Import Library (ASSIMP) ----------------------------------------------------------------------- - -Copyright (c) 2006-2010, ASSIMP Development 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 Development 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 "AssimpPCH.h" - -#include "Hash.h" -#include "fast_atof.h" -#include "ParsingUtils.h" - -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 != NULL); - ai_assert (pKey != NULL); - ai_assert (pPropOut != NULL); - - /* 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 ) - && (0xffffffff == type || prop->mSemantic == type) /* 0xffffffff is a wildcard, but this is undocumented :-) */ - && (0xffffffff == index || prop->mIndex == index)) - { - *pPropOut = pMat->mProperties[i]; - return AI_SUCCESS; - } - } - *pPropOut = NULL; - 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, - float* pOut, - unsigned int* pMax) -{ - ai_assert (pOut != NULL); - ai_assert (pMat != NULL); - - const aiMaterialProperty* prop; - aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop); - if (!prop) { - return AI_FAILURE; - } - - // data is given in floats, simply copy it - unsigned int iWrite; - 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<float> ( reinterpret_cast<float*>(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<float> ( 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 && !prop->mData[prop->mDataLength-1]); - for (unsigned int a = 0; ;++a) { - cur = fast_atof_move(cur,pOut[a]); - if (a==iWrite-1) { - break; - } - if (!IsSpace(*cur)) { - DefaultLogger::get()->error("Material property" + std::string(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 != NULL); - ai_assert (pMat != NULL); - - 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; - if ( aiPTI_Integer == prop->mType || aiPTI_Buffer == 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<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 && !prop->mData[prop->mDataLength-1]); - for (unsigned int a = 0; ;++a) { - pOut[a] = strtol10s(cur,&cur); - if (a==iWrite-1) { - break; - } - if (!IsSpace(*cur)) { - DefaultLogger::get()->error("Material property" + std::string(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,(float*)pOut,&iMax); - - // if no alpha channel is defined: set it to 1.0 - if (3 == iMax) { - pOut->a = 1.0f; - } - - return eRet; -} - -// ------------------------------------------------------------------------------------------------ -// 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 != NULL); - - 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 && !prop->mData[prop->mDataLength-1]); - memcpy(pOut->data,prop->mData+4,pOut->length+1); - } - else { - // TODO - implement lexical cast as well - DefaultLogger::get()->error("Material property" + std::string(pKey) + - " was found, but is no string" ); - return AI_FAILURE; - } - return AI_SUCCESS; -} - -// ------------------------------------------------------------------------------------------------ -// Get the number of textures on a particular texture stack -ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, - C_ENUM aiTextureType type) -{ - ai_assert (pMat != NULL); - - /* 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 ) - && 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 /*= NULL*/, - unsigned int* uvindex /*= NULL*/, - float* blend /*= NULL*/, - aiTextureOp* op /*= NULL*/, - aiTextureMapMode* mapmode /*= NULL*/, - unsigned int* flags /*= NULL*/ - ) -{ - ai_assert(NULL != mat && NULL != path); - - // Get the path to the texture - if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) { - return AI_FAILURE; - } - // Determine mapping type - aiTextureMapping mapping = aiTextureMapping_UV; - aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&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; -} - -// ------------------------------------------------------------------------------------------------ -// Construction. Actually the one and only way to get an aiMaterial instance -MaterialHelper::MaterialHelper() -{ - // Allocate 5 entries by default - mNumProperties = 0; - mNumAllocated = 5; - mProperties = new aiMaterialProperty*[5]; -} - -// ------------------------------------------------------------------------------------------------ -MaterialHelper::~MaterialHelper() -{ - _InternDestruct(); -} - -// ------------------------------------------------------------------------------------------------ -aiMaterial::~aiMaterial() -{ - // HACK (Aramis): This is safe: aiMaterial has a private constructor, - // so instances must be created indirectly via MaterialHelper. We can't - // use a virtual d'tor because we need to preserve binary compatibility - // with good old C ... - ((MaterialHelper*)this)->_InternDestruct(); -} - -// ------------------------------------------------------------------------------------------------ -// Manual destructor -void MaterialHelper::_InternDestruct() -{ - // First clean up all properties - Clear(); - - // Then delete the array that stored them - delete[] mProperties; - AI_DEBUG_INVALIDATE_PTR(mProperties); - - // Update members - mNumAllocated = 0; -} - -// ------------------------------------------------------------------------------------------------ -void MaterialHelper::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 -} - -// ------------------------------------------------------------------------------------------------ -uint32_t MaterialHelper::ComputeHash(bool includeMatName /*= false*/) -{ - uint32_t hash = 1503; // magic start value, choosen to be my birthday :-) - for (unsigned int i = 0; i < mNumProperties;++i) { - aiMaterialProperty* prop; - - // Exclude all properties whose first character is '?' from the hash - // See doc for aiMaterialProperty. - if ((prop = mProperties[i]) && (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; -} - -// ------------------------------------------------------------------------------------------------ -aiReturn MaterialHelper::RemoveProperty (const char* pKey,unsigned int type, - unsigned int index - ) -{ - ai_assert(NULL != 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 MaterialHelper::AddBinaryProperty (const void* pInput, - unsigned int pSizeInBytes, - const char* pKey, - unsigned int type, - unsigned int index, - aiPropertyTypeInfo pType - ) -{ - ai_assert (pInput != NULL); - ai_assert (pKey != NULL); - ai_assert (0 != pSizeInBytes); - - // first search the list whether there is already an entry with this key - unsigned int iOutIndex = 0xffffffff; - 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 = ::strlen(pKey); - ai_assert ( MAXLEN > pcNew->mKey.length); - strcpy( pcNew->mKey.data, pKey ); - - if (0xffffffff != 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&) { - 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 MaterialHelper::AddProperty (const aiString* pInput, - const char* pKey, - unsigned int type, - unsigned int index) -{ - // We don't want to add the whole buffer .. write a 32 bit length - // prefix followed by the zero-terminated UTF8 string. - // (HACK) I don't want to break the ABI now, but we definitely - // ought to change aiString::mLength to uint32_t one day. - if (sizeof(size_t) == 8) { - aiString copy = *pInput; - uint32_t* s = reinterpret_cast<uint32_t*>(©.length); - s[1] = static_cast<uint32_t>(pInput->length); - - return AddBinaryProperty(s+1, - pInput->length+1+4, - pKey, - type, - index, - aiPTI_String); - } - ai_assert(sizeof(size_t)==4); - return AddBinaryProperty(pInput, - pInput->length+1+4, - pKey, - type, - index, - aiPTI_String); -} - -// ------------------------------------------------------------------------------------------------ -void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest, - const MaterialHelper* pcSrc - ) -{ - ai_assert(NULL != pcDest); - ai_assert(NULL != pcSrc); - - unsigned int iOldNum = pcDest->mNumProperties; - pcDest->mNumAllocated += pcSrc->mNumAllocated; - pcDest->mNumProperties += pcSrc->mNumProperties; - - aiMaterialProperty** pcOld = pcDest->mProperties; - pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated]; - - if (iOldNum && pcOld) { - for (unsigned int i = 0; i < iOldNum;++i) { - pcDest->mProperties[i] = pcOld[i]; - } - - 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); - } - return; -} - |