diff --git a/code/B3DImporter.cpp b/code/B3DImporter.cpp index 8a7bdda99..aa0f2314a 100644 --- a/code/B3DImporter.cpp +++ b/code/B3DImporter.cpp @@ -54,6 +54,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; using namespace std; +// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings +#ifdef _MSC_VER +# pragma warning (disable: 4018) +#endif + //#define DEBUG_B3D // ------------------------------------------------------------------------------------------------ diff --git a/code/MaterialSystem.cpp b/code/MaterialSystem.cpp index 644484687..449d7f5e6 100644 --- a/code/MaterialSystem.cpp +++ b/code/MaterialSystem.cpp @@ -61,14 +61,14 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat, /* Just search for a property with exactly this name .. * could be improved by hashing, but it's possibly - * no worth the effort. - */ + * 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 */ + && 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]; @@ -180,8 +180,10 @@ aiReturn aiGetMaterialColor(const aiMaterial* pMat, aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(float*)pOut,&iMax); // if no alpha channel is defined: set it to 1.0 - if (3 == iMax) + if (3 == iMax) { pOut->a = 1.0f; + } + return eRet; } @@ -197,14 +199,15 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat, aiMaterialProperty* prop; aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop); - if (!prop) + if (!prop) { return AI_FAILURE; + } if( aiPTI_String == prop->mType) { // WARN: There's not the whole string stored .. const aiString* pcSrc = (const aiString*)prop->mData; - ::memcpy (pOut->data, pcSrc->data, (pOut->length = pcSrc->length)+1); + memcpy (pOut->data, pcSrc->data, (pOut->length = pcSrc->length)+1); } // Wrong type else { @@ -214,6 +217,77 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat, 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 check) */ + 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() @@ -425,8 +499,9 @@ void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest, pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated]; if (iOldNum && pcOld) { - for (unsigned int i = 0; i < iOldNum;++i) + for (unsigned int i = 0; i < iOldNum;++i) { pcDest->mProperties[i] = pcOld[i]; + } delete[] pcOld; } @@ -444,8 +519,9 @@ void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest, delete prop; // collapse the whole array ... - ::memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q); - i--;pcDest->mNumProperties--; + memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q); + i--; + pcDest->mNumProperties--; } } @@ -458,57 +534,8 @@ void MaterialHelper::CopyPropertyList(MaterialHelper* pcDest, prop->mIndex = propSrc->mIndex; prop->mData = new char[propSrc->mDataLength]; - ::memcpy(prop->mData,propSrc->mData,prop->mDataLength); + memcpy(prop->mData,propSrc->mData,prop->mDataLength); } return; } -// ------------------------------------------------------------------------------------------------ -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; -} - diff --git a/include/aiMaterial.h b/include/aiMaterial.h index f541d91f5..f425530a2 100644 --- a/include/aiMaterial.h +++ b/include/aiMaterial.h @@ -685,14 +685,24 @@ public: unsigned int idx,Type& pOut) const; // ------------------------------------------------------------------- - /** @brief Helper function to get a texture from a material. + /** Get the number of textures for a particular texture type. + * @param type Texture type to check for + * @return Number of textures for this type. + * @note A texture can be easily queried using #GetTexture() */ + unsigned int GetTextureCount(aiTextureType type) const; + + // ------------------------------------------------------------------- + /** Helper function to get all parameters pertaining to a + * particular texture slot from a material. * * This function is provided just for convenience, you could also * read the single material properties manually. * @param type Specifies the type of the texture to be retrieved ( * e.g. diffuse, specular, height map ...) * @param index Index of the texture to be retrieved. The function fails - * if there is no texture of that type with this index. + * if there is no texture of that type with this index. + * #GetTextureCount() can be used to determine the number of textures + * per texture type. * @param path Receives the path to the texture. * NULL is a valid value. * @param mapping The texture mapping. @@ -1174,8 +1184,7 @@ extern "C" { * e.g. diffuse, specular, height map ...) * @param index Index of the texture to be retrieved. * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty - * structure or NULL if the key has not been found. - */ + * structure or NULL if the key has not been found. */ // --------------------------------------------------------------------------- ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty( const C_STRUCT aiMaterial* pMat, @@ -1208,8 +1217,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty( * @param type (see the code sample above) * @param index (see the code sample above) * @return Specifies whether the key has been found. If not, the output - * arrays remains unmodified and pMax is set to 0. - */ + * arrays remains unmodified and pMax is set to 0.*/ // --------------------------------------------------------------------------- ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray( const C_STRUCT aiMaterial* pMat, @@ -1239,8 +1247,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray( * @param type (see the code sample above) * @param index (see the code sample above) * @return Specifies whether the key has been found. If not, the output -* float remains unmodified. -*/ +* float remains unmodified.*/ // --------------------------------------------------------------------------- inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat, const char* pKey, @@ -1264,8 +1271,7 @@ inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat, /** @brief Retrieve an array of integer values with a specific key * from a material * - * See the sample for aiGetMaterialFloatArray for more information. - */ + * See the sample for aiGetMaterialFloatArray for more information.*/ ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat, const char* pKey, unsigned int type, @@ -1279,8 +1285,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* // --------------------------------------------------------------------------- /** @brief Retrieve an integer property with a specific key from a material * - * See the sample for aiGetMaterialFloat for more information. - */ + * See the sample for aiGetMaterialFloat for more information.*/ // --------------------------------------------------------------------------- inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, const char* pKey, @@ -1304,8 +1309,7 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat, // --------------------------------------------------------------------------- /** @brief Retrieve a color value from the material property table * -* See the sample for aiGetMaterialFloat for more information. -*/ +* See the sample for aiGetMaterialFloat for more information*/ // --------------------------------------------------------------------------- ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat, const char* pKey, @@ -1317,8 +1321,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat, // --------------------------------------------------------------------------- /** @brief Retrieve a string from the material property table * -* See the sample for aiGetMaterialFloat for more information. -*/ +* See the sample for aiGetMaterialFloat for more information.*/ // --------------------------------------------------------------------------- ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, const char* pKey, @@ -1326,19 +1329,31 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, unsigned int index, C_STRUCT aiString* pOut); +// --------------------------------------------------------------------------- +/** Get the number of textures for a particular texture type. + * @param[in] pMat Pointer to the input material. May not be NULL + * @param type Texture type to check for + * @return Number of textures for this type. + * @note A texture can be easily queried using #aiGetMaterialTexture() */ +// --------------------------------------------------------------------------- +ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, + C_ENUM aiTextureType type); // --------------------------------------------------------------------------- -/** @brief Helper function to get a texture from a material structure. +/** @brief Helper function to get all values pertaining to a particular + * texture slot from a material structure. * * This function is provided just for convenience. You could also read the - * texture by reading all of its properties manually. This function bundles - * all of them in a huge function-monster. + * texture by parsing all of its properties manually. This function bundles + * all of them in a huge function monster. * * @param[in] mat Pointer to the input material. May not be NULL - * @param[in] type Specifies the type of the texture to read (e.g. diffuse, + * @param[in] type Specifies the texture stack to read from (e.g. diffuse, * specular, height map ...). - * @param[in] index Index of the texture layer to be read. The function - * fails if the requested layer is not available. + * @param[in] index Index of the texture. The function fails if the + * requested index is not available for this texture type. + * #aiGetMaterialTextureCount() can be used to determine the number of + * textures in a particular texture stack. * @param[out] path Receives the output path * This parameter must be non-null. * @param mapping The texture mapping mode to be used. @@ -1355,8 +1370,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat, * Pass NULL if you're not interested in this information. Otherwise, * pass a pointer to an array of two aiTextureMapMode's (one for each * axis, UV order). - * @return AI_SUCCESS on success, something else otherwise. Have fun. - */ + * @return AI_SUCCESS on success, otherwise something else. Have fun.*/ // --------------------------------------------------------------------------- #ifdef __cplusplus ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat, diff --git a/include/aiMaterial.inl b/include/aiMaterial.inl index 009bff423..0221031db 100644 --- a/include/aiMaterial.inl +++ b/include/aiMaterial.inl @@ -61,6 +61,12 @@ inline aiReturn aiMaterial::GetTexture( aiTextureType type, return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode); } +// --------------------------------------------------------------------------- +inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const +{ + return ::aiGetMaterialTextureCount(this,type); +} + // --------------------------------------------------------------------------- template inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, @@ -71,17 +77,20 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, aiMaterialProperty* prop; aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,&prop); - if ( AI_SUCCESS == ret ) - { - if (prop->mDataLength < sizeof(Type)*iNum) + if ( AI_SUCCESS == ret ) { + + if (prop->mDataLength < sizeof(Type)*iNum) { return AI_FAILURE; + } // if (::strcmp(prop->mData,(char*)aiPTI_Buffer)!=0) // return AI_FAILURE; iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type)); - ::memcpy(pOut,prop->mData,iNum * sizeof(Type)); - if (pMax)*pMax = iNum; + memcpy(pOut,prop->mData,iNum * sizeof(Type)); + if (pMax) { + *pMax = iNum; + } } return ret; } @@ -93,15 +102,17 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type, { aiMaterialProperty* prop; aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,&prop); - if ( AI_SUCCESS == ret ) - { - if (prop->mDataLength < sizeof(Type)) - return AI_FAILURE; + if ( AI_SUCCESS == ret ) { - if (::strcmp(prop->mData,(char*)aiPTI_Buffer)!=0) + if (prop->mDataLength < sizeof(Type)) { return AI_FAILURE; + } - ::memcpy(&pOut,prop->mData,sizeof(Type)); + if (strcmp(prop->mData,(char*)aiPTI_Buffer)!=0) { + return AI_FAILURE; + } + + memcpy(&pOut,prop->mData,sizeof(Type)); } return ret; }