Forráskód Böngészése

Improved Q3BSPZipArchive + added material merging

Léo Terziman 12 éve
szülő
commit
bb9288fa26
3 módosított fájl, 64 hozzáadás és 17 törlés
  1. 0 17
      code/Q3BSPZipArchive.cpp
  2. 50 0
      code/SceneCombiner.cpp
  3. 14 0
      code/SceneCombiner.h

+ 0 - 17
code/Q3BSPZipArchive.cpp

@@ -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;
 						}
 					}

+ 50 - 0
code/SceneCombiner.cpp

@@ -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)

+ 14 - 0
code/SceneCombiner.h

@@ -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