Improved Q3BSPZipArchive + added material merging

pull/261/head
Léo Terziman 2013-11-12 11:09:31 +01:00
parent 51bf836db4
commit bb9288fa26
3 changed files with 64 additions and 17 deletions

View File

@ -60,38 +60,21 @@ ZipFile::~ZipFile() {
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount ) {
size_t bytes_read = 0;
DefaultLogger::get()->warn("file: \"" + m_Name + "\".");
if(m_zipFile != NULL) {
DefaultLogger::get()->warn("file: zip exist.");
// search file and place file pointer there
if(unzLocateFile(m_zipFile, m_Name.c_str(), 0) == UNZ_OK) {
DefaultLogger::get()->warn("file: file located in the zip archive.");
// get file size, etc.
unz_file_info fileInfo;
if(unzGetCurrentFileInfo(m_zipFile, &fileInfo, 0, 0, 0, 0, 0, 0) == UNZ_OK) {
const size_t size = pSize * pCount;
assert(size <= fileInfo.uncompressed_size);
std::stringstream size_str;
size_str << fileInfo.uncompressed_size;
DefaultLogger::get()->warn("file: size = " + size_str.str() + ".");
// The file has EXACTLY the size of uncompressed_size. In C
// you need to mark the last character with '\0', so add
// another character
if(unzOpenCurrentFile(m_zipFile) == UNZ_OK) {
DefaultLogger::get()->warn("file: file opened.");
if(unzReadCurrentFile(m_zipFile, pvBuffer, fileInfo.uncompressed_size) == (long int) fileInfo.uncompressed_size) {
std::string file((char*) pvBuffer, ((char*) pvBuffer) + (fileInfo.uncompressed_size < 1000 ? fileInfo.uncompressed_size : 1000));
DefaultLogger::get()->warn("file: data = \"" + file + "\".");
if(unzCloseCurrentFile(m_zipFile) == UNZ_OK) {
DefaultLogger::get()->warn("file: file closed.");
bytes_read = fileInfo.uncompressed_size;
}
}

View File

@ -880,6 +880,56 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
delete *it;
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::MergeMaterials(aiMaterial** dest,
std::vector<aiMaterial*>::const_iterator begin,
std::vector<aiMaterial*>::const_iterator end)
{
ai_assert(NULL != dest);
if (begin == end) {
*dest = NULL; // no materials ...
return;
}
// Allocate the output material
aiMaterial* out = *dest = new aiMaterial();
// Get the maximal number of properties
unsigned int size = 0;
for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) {
size += (*it)->mNumProperties;
}
out->mNumAllocated = size;
out->mNumProperties = 0;
out->mProperties = new aiMaterialProperty*[out->mNumAllocated];
for (std::vector<aiMaterial*>::const_iterator it = begin; it != end; ++it) {
for(unsigned int i = 0; i < (*it)->mNumProperties; ++i) {
aiMaterialProperty* sprop = (*it)->mProperties[i];
// Test if we already have a matching property
const aiMaterialProperty* prop_exist;
if(aiGetMaterialProperty(out, sprop->mKey.C_Str(), sprop->mType, sprop->mIndex, &prop_exist) != AI_SUCCESS) {
// If not, we add it to the new material
aiMaterialProperty* prop = out->mProperties[i] = new aiMaterialProperty();
prop->mDataLength = sprop->mDataLength;
prop->mData = new char[prop->mDataLength];
::memcpy(prop->mData, sprop->mData, prop->mDataLength);
prop->mIndex = sprop->mIndex;
prop->mSemantic = sprop->mSemantic;
prop->mKey = sprop->mKey;
prop->mType = sprop->mType;
out->mNumProperties++;
}
}
}
}
// ------------------------------------------------------------------------------------------------
template <typename Type>
inline void CopyPtrArray (Type**& dest, const Type* const * src, unsigned int num)

View File

@ -248,6 +248,20 @@ public:
static void MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
std::vector<aiMesh*>::const_iterator end);
// -------------------------------------------------------------------
/** Merges two or more materials
*
* The materials should be complementary as much as possible. In case
* of a property present in different materials, the first occurence
* is used.
*
* @param dest Destination material. Must be empty.
* @param begin First material to be processed
* @param end Points to the material after the last material to be processed
*/
static void MergeMaterials(aiMaterial** dest,
std::vector<aiMaterial*>::const_iterator begin,
std::vector<aiMaterial*>::const_iterator end);
// -------------------------------------------------------------------
/** Builds a list of uniquely named bones in a mesh list