LWO update. ASE cleanup.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@108 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-08-12 01:50:16 +00:00
parent 0b1e8fefa5
commit 676124e6e6
4 changed files with 105 additions and 59 deletions

View File

@ -113,9 +113,6 @@ void ASEImporter::InternReadFile(
size_t fileSize = file->FileSize(); 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 // allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero) // (terminate it with zero)
std::vector<char> mBuffer2(fileSize+1); std::vector<char> mBuffer2(fileSize+1);

View File

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

View File

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

View File

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