소스 검색

LWO update. ASE cleanup.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@108 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
aramis_acg 17 년 전
부모
커밋
676124e6e6
4개의 변경된 파일105개의 추가작업 그리고 59개의 파일을 삭제
  1. 0 3
      code/ASELoader.cpp
  2. 4 5
      code/DefaultLogger.cpp
  3. 91 47
      code/LWOLoader.cpp
  4. 10 4
      code/LWOLoader.h

+ 0 - 3
code/ASELoader.cpp

@@ -113,9 +113,6 @@ void ASEImporter::InternReadFile(
 
 	size_t fileSize = file->FileSize();
 
-	std::string::size_type pos = pFile.find_last_of('.');
-	std::string extension = pFile.substr( pos);
-
 	// allocate storage and copy the contents of the file to a memory buffer
 	// (terminate it with zero)
 	std::vector<char> mBuffer2(fileSize+1);

+ 4 - 5
code/DefaultLogger.cpp

@@ -89,11 +89,10 @@ Logger *DefaultLogger::create(const std::string &name, LogSeverity severity)
 // ---------------------------------------------------------------------------
 void DefaultLogger::set( Logger *logger )
 {
-	if (!logger)
-	{
-		 DefaultLogger::m_pLogger = &s_pNullLogger;
-		 return;
-	}
+	if (!logger)logger = &s_pNullLogger;
+	if (m_pLogger && !isNullLogger() )
+		delete m_pLogger;
+
 	DefaultLogger::m_pLogger = logger;
 }
 // ---------------------------------------------------------------------------

+ 91 - 47
code/LWOLoader.cpp

@@ -232,44 +232,79 @@ void LWOImporter::InternReadFile( const std::string& pFile,
 		// generate the corresponding material
 		MaterialHelper* pcMat = new MaterialHelper();
 		pScene->mMaterials[p] = pcMat;
-		//ConvertMaterial(mSurfaces[i],pcMat);
+		ConvertMaterial((*mSurfaces)[i],pcMat);
 		++p;
 	}
+
+	// create a dummy nodegraph - the root node renders everything
+	aiNode* p = pScene->mRootNode = new aiNode();
+	p->mNumMeshes = pScene->mNumMeshes;
+	p->mMeshes = new unsigned int[pScene->mNumMeshes];
+	p->mName.Set("<LWORoot>");
+	for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
+		p->mMeshes[i] = i;
 }
+
+// ------------------------------------------------------------------------------------------------
+void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat)
+{
+	// copy the name of the surface
+	aiString st;
+	st.Set(surf.mName);
+	pcMat->AddProperty(&st,AI_MATKEY_NAME);
+
+	int i = surf.bDoubleSided ? 1 : 0;
+	pcMat->AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
+	
+	if (surf.mSpecularValue && surf.mGlossiness)
+	{
+		// this is only an assumption, needs to be confirmed.
+		/*if (16.0f >= surf.mGlossiness)surf.mGlossiness = 10.0f;
+		else if (64.0f >= surf.mGlossiness)surf.mGlossiness = 14.0f;
+		else if (256.0f >= surf.mGlossiness)surf.mGlossiness = 20.0f;
+		else surf.mGlossiness = 24.0f;*/
+
+		pcMat->AddProperty<float>(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
+		pcMat->AddProperty<float>(&surf.mGlossiness,1,AI_MATKEY_SHININESS);
+	}
+
+}
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::CountVertsAndFaces(unsigned int& verts, unsigned int& faces,
-	LE_NCONST uint8_t*& cursor, const uint8_t* const end, unsigned int max)
+	LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
 {
 	while (cursor < end && max--)
 	{
-		uint16_t numIndices = *((LE_NCONST uint16_t*)cursor);cursor+=2;
+		uint16_t numIndices = *cursor++;
 		verts += numIndices;faces++;
-		cursor += numIndices*2;
-		int16_t surface = *((LE_NCONST uint16_t*)cursor);cursor+=2;
+		cursor += numIndices;
+		int16_t surface = *cursor++;
 		if (surface < 0)
 		{
 			// there are detail polygons
-			numIndices = *((LE_NCONST uint16_t*)cursor);cursor+=2;
+			numIndices = *cursor++;
 			CountVertsAndFaces(verts,faces,cursor,end,numIndices);
 		}
 	}
 }
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::CopyFaceIndices(LWOImporter::FaceList::iterator& it,
-	LE_NCONST uint8_t*& cursor, 
-	const uint8_t* const end,
+	LE_NCONST uint16_t*& cursor, 
+	const uint16_t* const end,
 	unsigned int max)
 {
 	while (cursor < end && max--)
 	{
 		LWO::Face& face = *it;++it;
-		if(face.mNumIndices = *((LE_NCONST uint16_t*)cursor))
+		if(face.mNumIndices = *cursor++)
 		{
-			if (cursor + face.mNumIndices*2 + 4 >= end)break;
+			if (cursor + face.mNumIndices >= end)break;
 			face.mIndices = new unsigned int[face.mNumIndices];
 			for (unsigned int i = 0; i < face.mNumIndices;++i)
 			{
-				face.mIndices[i] = *((LE_NCONST uint16_t*)(cursor+=2));
+				face.mIndices[i] = *cursor++;
 				if (face.mIndices[i] >= mTempPoints->size())
 				{
 					face.mIndices[i] = mTempPoints->size()-1;
@@ -278,19 +313,19 @@ void LWOImporter::CopyFaceIndices(LWOImporter::FaceList::iterator& it,
 			}
 		}
 		else DefaultLogger::get()->warn("LWO: Face has 0 indices");
-		cursor+=2;
-		int16_t surface = *((LE_NCONST uint16_t*)cursor);cursor+=2;
+		int16_t surface = *cursor++;
 		if (surface < 0)
 		{
 			surface = -surface;
 
 			// there are detail polygons
-			uint16_t numPolygons = *((LE_NCONST uint16_t*)cursor);cursor+=2;
+			uint16_t numPolygons = *cursor++;
 			if (cursor < end)CopyFaceIndices(it,cursor,end,numPolygons);
 		}
 		face.surfaceIndex = surface-1;
 	}
 }
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::ResolveTags()
 {
@@ -307,6 +342,7 @@ void LWOImporter::ResolveTags()
 		}
 	}
 }
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::ParseString(std::string& out,unsigned int max)
 {
@@ -324,6 +360,7 @@ void LWOImporter::ParseString(std::string& out,unsigned int max)
 	unsigned int len = unsigned int (in-sz);
 	out = std::string(sz,len);
 }
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::AdjustTexturePath(std::string& out)
 {
@@ -336,8 +373,8 @@ void LWOImporter::AdjustTexturePath(std::string& out)
 }
 
 // ------------------------------------------------------------------------------------------------
-#define AI_LWO_VALIDATE_CHUNK_LENGTH(name,size) \
-	if (head->length < size) \
+#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
+	if (length < size) \
 	{ \
 		DefaultLogger::get()->warn("LWO: "#name" chunk is too small"); \
 		break; \
@@ -363,40 +400,45 @@ void LWOImporter::LoadLWOTags(unsigned int size)
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::LoadLWOBSurface(unsigned int size)
 {
+	LE_NCONST uint8_t* const end = mFileBuffer + size;
+
 	uint32_t iCursor = 0;
 	mSurfaces->push_back( LWO::Surface () );
 	LWO::Surface& surf = mSurfaces->back();
 	LWO::Texture* pTex = NULL;
 
 	// at first we'll need to read the name of the surface
-	const uint8_t* sz = mFileBuffer;
+	LE_NCONST uint8_t* sz = mFileBuffer;
 	while (*mFileBuffer)
 	{
-		if (++iCursor > size)throw new ImportErrorException("LWOB: Invalid file, surface name is too long");
-		++mFileBuffer;
+		if (++mFileBuffer > end)throw new ImportErrorException("LWOB: Invalid file, surface name is too long");
 	}
 	unsigned int len = unsigned int (mFileBuffer-sz);
 	surf.mName = std::string((const char*)sz,len);
-	mFileBuffer += 1-(len & 1); // skip one byte if the length of the string is odd
+	mFileBuffer++;
+	if (!(len & 1))++mFileBuffer; // skip one byte if the length of the surface name is odd
 	while (true)
 	{
-		if ((iCursor += sizeof(IFF::ChunkHeader)) > size)break;
-		LE_NCONST IFF::ChunkHeader* head = (LE_NCONST IFF::ChunkHeader*)mFileBuffer;
-		AI_LSWAP4(head->length);
-		AI_LSWAP4(head->type);
-		if ((iCursor += head->length) > size)
+		if (mFileBuffer + 6 > end)
+			break;
+
+		// no proper IFF header here - the chunk length is specified as int16
+		uint32_t head_type		= *((LE_NCONST uint32_t*)mFileBuffer);mFileBuffer+=4;
+		uint16_t head_length	= *((LE_NCONST uint16_t*)mFileBuffer);mFileBuffer+=2;
+		AI_LSWAP4(head_type);
+		AI_LSWAP2(head_length);
+		if (mFileBuffer + head_length > end)
 		{
 			throw new ImportErrorException("LWOB: Invalid file, the size attribute of "
 				"a surface sub chunk points behind the end of the file");
 		}
-		mFileBuffer += sizeof(IFF::ChunkHeader);
-		LE_NCONST uint8_t* next = mFileBuffer+head->length;
-		switch (head->type)
+		LE_NCONST uint8_t* const next = mFileBuffer+head_length;
+		switch (head_type)
 		{
 			// diffuse color
 		case AI_LWO_COLR:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(COLR,3);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,COLR,3);
 				surf.mColor.r = *mFileBuffer++ / 255.0f;
 				surf.mColor.g = *mFileBuffer++ / 255.0f;
 				surf.mColor.b = *mFileBuffer   / 255.0f;
@@ -405,7 +447,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 			// diffuse strength ... hopefully
 		case AI_LWO_DIFF:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(DIFF,2);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,DIFF,2);
 				AI_LSWAP2(mFileBuffer);
 				surf.mDiffuseValue = *((int16_t*)mFileBuffer) / 255.0f;
 				break;
@@ -413,7 +455,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 			// specular strength ... hopefully
 		case AI_LWO_SPEC:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(SPEC,2);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,SPEC,2);
 				AI_LSWAP2(mFileBuffer);
 				surf.mSpecularValue = *((int16_t*)mFileBuffer) / 255.0f;
 				break;
@@ -421,7 +463,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 		// transparency
 		case AI_LWO_TRAN:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(TRAN,2);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,TRAN,2);
 				AI_LSWAP2(mFileBuffer);
 				surf.mTransparency = *((int16_t*)mFileBuffer) / 255.0f;
 				break;
@@ -429,7 +471,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 		// glossiness
 		case AI_LWO_GLOS:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(GLOS,2);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,GLOS,2);
 				AI_LSWAP2(mFileBuffer);
 				surf.mGlossiness = float(*((int16_t*)mFileBuffer));
 				break;
@@ -469,7 +511,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 			{
 				if (pTex)
 				{
-					ParseString(pTex->mFileName,head->length);	
+					ParseString(pTex->mFileName,head_length);	
 					AdjustTexturePath(pTex->mFileName);
 					mFileBuffer += pTex->mFileName.length();
 				}
@@ -480,7 +522,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 		// texture strength
 		case AI_LWO_TVAL:
 			{
-				AI_LWO_VALIDATE_CHUNK_LENGTH(TVAL,1);
+				AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,TVAL,1);
 				if (pTex)pTex->mStrength = *mFileBuffer / 255.0f;
 				else DefaultLogger::get()->warn("LWOB: TVAL tag was encuntered "
 					"although there was no xTEX tag before");
@@ -490,24 +532,26 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
 		mFileBuffer = next;
 	}
 }
+
 // ------------------------------------------------------------------------------------------------
 void LWOImporter::LoadLWOBFile()
 {
-	uint32_t iCursor = 0;
+	LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
 	while (true)
 	{
-		if ((iCursor += sizeof(IFF::ChunkHeader)) > this->fileSize)break;
-		LE_NCONST IFF::ChunkHeader* head = (LE_NCONST IFF::ChunkHeader*)mFileBuffer;
+		if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)
+			break;
+		LE_NCONST IFF::ChunkHeader* const head = (LE_NCONST IFF::ChunkHeader*)mFileBuffer;
 		AI_LSWAP4(head->length);
 		AI_LSWAP4(head->type);
-		if ((iCursor += head->length) > this->fileSize)
+		mFileBuffer += sizeof(IFF::ChunkHeader);
+		if (mFileBuffer + head->length > end)
 		{
-			//throw new ImportErrorException("LWOB: Invalid file, the size attribute of "
-			//	"a chunk points behind the end of the file");
+			throw new ImportErrorException("LWOB: Invalid file, the size attribute of "
+				"a chunk points behind the end of the file");
 			break;
 		}
-		mFileBuffer += sizeof(IFF::ChunkHeader);
-		LE_NCONST uint8_t* next = mFileBuffer+head->length;
+		LE_NCONST uint8_t* const next = mFileBuffer+head->length;
 		switch (head->type)
 		{
 			// vertex list
@@ -525,12 +569,12 @@ void LWOImporter::LoadLWOBFile()
 		case AI_LWO_POLS:
 			{
 				// first find out how many faces and vertices we'll finally need
-				const uint8_t* const end = mFileBuffer + head->length;
-				LE_NCONST uint8_t* cursor = mFileBuffer;
+				LE_NCONST uint16_t* const end	= (LE_NCONST uint16_t*)next;
+				LE_NCONST uint16_t* cursor		= (LE_NCONST uint16_t*)mFileBuffer;
 
 #ifndef AI_BUILD_BIG_ENDIAN
 				while (cursor < end)ByteSwap::Swap2(cursor++);
-				cursor = mFileBuffer;
+				cursor = (LE_NCONST uint16_t*)mFileBuffer;
 #endif
 
 				unsigned int iNumFaces = 0,iNumVertices = 0;
@@ -539,7 +583,7 @@ void LWOImporter::LoadLWOBFile()
 				// allocate the output array and copy face indices
 				if (iNumFaces)
 				{
-					cursor = mFileBuffer;
+					cursor = (LE_NCONST uint16_t*)mFileBuffer;
 					this->mTempPoints->resize(iNumVertices);
 					this->mFaces->resize(iNumFaces);
 					FaceList::iterator it = this->mFaces->begin();

+ 10 - 4
code/LWOLoader.h

@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "BaseImporter.h"
 #include "LWOFileData.h"
+#include "MaterialSystem.h"
 
 #include <vector>
 
@@ -132,16 +133,16 @@ private:
 	*/
 	void CountVertsAndFaces(unsigned int& verts, 
 		unsigned int& faces,
-		LE_NCONST uint8_t*& cursor, 
-		const uint8_t* const end,
+		LE_NCONST uint16_t*& cursor, 
+		const uint16_t* const end,
 		unsigned int max = 0xffffffff);
 
 	// -------------------------------------------------------------------
 	/** Read vertices and faces in a LWOB file
 	*/
 	void CopyFaceIndices(FaceList::iterator& it,
-		LE_NCONST uint8_t*& cursor, 
-		const uint8_t* const end, 
+		LE_NCONST uint16_t*& cursor, 
+		const uint16_t* const end, 
 		unsigned int max = 0xffffffff);
 
 	// -------------------------------------------------------------------
@@ -154,6 +155,11 @@ private:
 	*/
 	void AdjustTexturePath(std::string& out);
 
+	// -------------------------------------------------------------------
+	/** Convert a LWO surface description to an ASSIMP material
+	*/
+	void ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat);
+
 protected:
 
 	/** Temporary point list from the file */