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();
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);

View File

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

View File

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

View File

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