LWOB loader nearly finished, LWO2 is WIP (many hours with the hex editor to come ...). Added test models for LWOB. Cleaned up the 3DS loader, overloaded ASSIMP_stricmp for std::string.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@109 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-08-13 15:45:57 +00:00
parent 676124e6e6
commit 0148d06678
17 changed files with 593 additions and 293 deletions

View File

@ -114,24 +114,20 @@ void Dot3DSImporter::InternReadFile(
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if( file.get() == NULL)
{ throw new ImportErrorException( "Failed to open 3DS file " + pFile + ".");
throw new ImportErrorException( "Failed to open file " + pFile + ".");
}
// check whether the .3ds file is large enough to contain // check whether the .3ds file is large enough to contain
// at least one chunk. // at least one chunk.
size_t fileSize = file->FileSize(); size_t fileSize = file->FileSize();
if( fileSize < 16) if( fileSize < 16)
{
throw new ImportErrorException( "3DS File is too small."); throw new ImportErrorException( "3DS File is too small.");
}
this->mScene = new Dot3DS::Scene(); this->mScene = new Dot3DS::Scene();
// 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
this->mBuffer = new unsigned char[fileSize]; std::vector<unsigned char> mBuffer2(fileSize);
file->Read( mBuffer, 1, fileSize); file->Read( &mBuffer2[0], 1, fileSize);
this->mCurrent = this->mBuffer; this->mCurrent = this->mBuffer = &mBuffer2[0];
this->mLast = this->mBuffer+fileSize; this->mLast = this->mBuffer+fileSize;
// initialize members // initialize members
@ -146,51 +142,39 @@ void Dot3DSImporter::InternReadFile(
this->bHasBG = false; this->bHasBG = false;
int iRemaining = (unsigned int)fileSize; int iRemaining = (unsigned int)fileSize;
this->ParseMainChunk(iRemaining);
// parse the file // Generate an unique set of vertices/indices for
try // all meshes contained in the file
for (std::vector<Dot3DS::Mesh>::iterator
i = this->mScene->mMeshes.begin();
i != this->mScene->mMeshes.end();++i)
{ {
this->ParseMainChunk(iRemaining); // TODO: see function body
this->CheckIndices(&(*i));
// Generate an unique set of vertices/indices for this->MakeUnique(&(*i));
// all meshes contained in the file
for (std::vector<Dot3DS::Mesh>::iterator
i = this->mScene->mMeshes.begin();
i != this->mScene->mMeshes.end();++i)
{
// TODO: see function body
this->CheckIndices(&(*i));
this->MakeUnique(&(*i));
// first generate normals for the mesh
this->GenNormals(&(*i));
}
// Apply scaling and offsets to all texture coordinates
TextureTransform::ApplyScaleNOffset(this->mScene->mMaterials);
// Replace all occurences of the default material with a valid material.
// Generate it if no material containing DEFAULT in its name has been
// found in the file
this->ReplaceDefaultMaterial();
// Convert the scene from our internal representation to an aiScene object
this->ConvertScene(pScene);
// Generate the node graph for the scene. This is a little bit
// tricky since we'll need to split some meshes into submeshes
this->GenerateNodeGraph(pScene);
// Now apply a master scaling factor to the scene
this->ApplyMasterScale(pScene);
// first generate normals for the mesh
this->GenNormals(&(*i));
} }
catch ( ImportErrorException* ex)
{ // Apply scaling and offsets to all texture coordinates
delete[] this->mBuffer;AI_DEBUG_INVALIDATE_PTR(this->mBuffer); TextureTransform::ApplyScaleNOffset(this->mScene->mMaterials);
throw ex;
} // Replace all occurences of the default material with a valid material.
delete[] this->mBuffer;AI_DEBUG_INVALIDATE_PTR(this->mBuffer); // Generate it if no material containing DEFAULT in its name has been
// found in the file
this->ReplaceDefaultMaterial();
// Convert the scene from our internal representation to an aiScene object
this->ConvertScene(pScene);
// Generate the node graph for the scene. This is a little bit
// tricky since we'll need to split some meshes into submeshes
this->GenerateNodeGraph(pScene);
// Now apply a master scaling factor to the scene
this->ApplyMasterScale(pScene);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Dot3DSImporter::ApplyMasterScale(aiScene* pScene) void Dot3DSImporter::ApplyMasterScale(aiScene* pScene)
@ -250,8 +234,6 @@ void Dot3DSImporter::ParseMainChunk(int& piRemaining)
switch (psChunk->Flag) switch (psChunk->Flag)
{ {
case Dot3DSFile::CHUNK_MAIN: case Dot3DSFile::CHUNK_MAIN:
//case 0x444d: // bugfix
this->ParseEditorChunk(iRemaining); this->ParseEditorChunk(iRemaining);
break; break;
}; };
@ -274,11 +256,8 @@ void Dot3DSImporter::ParseEditorChunk(int& piRemaining)
const Dot3DSFile::Chunk* psChunk; const Dot3DSFile::Chunk* psChunk;
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk)); int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk));
@ -331,11 +310,8 @@ void Dot3DSImporter::ParseObjectChunk(int& piRemaining)
const Dot3DSFile::Chunk* psChunk; const Dot3DSFile::Chunk* psChunk;
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
const unsigned char* sz = this->mCurrent; const unsigned char* sz = this->mCurrent;
unsigned int iCnt = 0; unsigned int iCnt = 0;
@ -384,9 +360,7 @@ void Dot3DSImporter::ParseObjectChunk(int& piRemaining)
} }
break; break;
case Dot3DSFile::CHUNK_BIT_MAP: case Dot3DSFile::CHUNK_BIT_MAP:
this->mBackgroundImage = std::string((const char*)this->mCurrent); this->mBackgroundImage = std::string((const char*)this->mCurrent);
break; break;
@ -438,11 +412,8 @@ void Dot3DSImporter::ParseChunk(int& piRemaining)
const Dot3DSFile::Chunk* psChunk; const Dot3DSFile::Chunk* psChunk;
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk)); int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk));
@ -473,11 +444,8 @@ void Dot3DSImporter::ParseKeyframeChunk(int& piRemaining)
const Dot3DSFile::Chunk* psChunk; const Dot3DSFile::Chunk* psChunk;
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk)); int iRemaining = (psChunk->Size - sizeof(Dot3DSFile::Chunk));
@ -512,8 +480,7 @@ void Dot3DSImporter::InverseNodeSearch(Dot3DS::Node* pcNode,Dot3DS::Node* pcCurr
} }
if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos)
{ {
if(NULL != pcCurrent->mParent) if(pcCurrent->mParent)pcCurrent->mParent->push_back(pcNode);
pcCurrent->mParent->push_back(pcNode);
else pcCurrent->push_back(pcNode); else pcCurrent->push_back(pcNode);
return; return;
} }
@ -535,7 +502,6 @@ void Dot3DSImporter::ParseHierarchyChunk(int& piRemaining)
const unsigned char* sz = (unsigned char*)this->mCurrent; const unsigned char* sz = (unsigned char*)this->mCurrent;
unsigned int iCnt = 0; unsigned int iCnt = 0;
uint16_t iHierarchy; uint16_t iHierarchy;
// uint16_t iTemp;
Dot3DS::Node* pcNode; Dot3DS::Node* pcNode;
switch (psChunk->Flag) switch (psChunk->Flag)
{ {
@ -754,11 +720,8 @@ void Dot3DSImporter::ParseFaceChunk(int& piRemaining)
Dot3DS::Mesh& mMesh = this->mScene->mMeshes.back(); Dot3DS::Mesh& mMesh = this->mScene->mMeshes.back();
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
const unsigned char* sz = this->mCurrent; const unsigned char* sz = this->mCurrent;
@ -855,11 +818,8 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
Dot3DS::Mesh& mMesh = this->mScene->mMeshes.back(); Dot3DS::Mesh& mMesh = this->mScene->mMeshes.back();
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
const unsigned char* sz = this->mCurrent; const unsigned char* sz = this->mCurrent;
@ -884,8 +844,6 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
break; break;
case Dot3DSFile::CHUNK_TRMATRIX: case Dot3DSFile::CHUNK_TRMATRIX:
{ {
// http://www.gamedev.net/community/forums/topic.asp?topic_id=263063
// http://www.gamedev.net/community/forums/topic.asp?topic_id=392310
pf = (float*)this->mCurrent; pf = (float*)this->mCurrent;
this->mCurrent += 12 * sizeof(float); this->mCurrent += 12 * sizeof(float);
@ -901,7 +859,6 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
mMesh.mMat.a4 = pf[9]; mMesh.mMat.a4 = pf[9];
mMesh.mMat.b4 = pf[10]; mMesh.mMat.b4 = pf[10];
mMesh.mMat.c4 = pf[11]; mMesh.mMat.c4 = pf[11];
//mMesh.mMat.Transpose(); // todo ----
// now check whether the matrix has got a negative determinant // now check whether the matrix has got a negative determinant
// If yes, we need to flip all vertices' x axis .... // If yes, we need to flip all vertices' x axis ....
@ -941,15 +898,6 @@ void Dot3DSImporter::ParseMeshChunk(int& piRemaining)
} }
break; break;
#if 0
case Dot3DSFile::CHUNK_TXTINFO:
// for debugging purposes. Read two bytes to determine the mapping type
iNum = *((uint16_t*)this->mCurrent);
this->mCurrent += sizeof(uint16_t);
break;
#endif
case Dot3DSFile::CHUNK_FACELIST: case Dot3DSFile::CHUNK_FACELIST:
iNum = *((uint16_t*)this->mCurrent); iNum = *((uint16_t*)this->mCurrent);
@ -996,11 +944,8 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
const Dot3DSFile::Chunk* psChunk; const Dot3DSFile::Chunk* psChunk;
this->ReadChunk(&psChunk); this->ReadChunk(&psChunk);
const unsigned char* pcCur = this->mCurrent; const unsigned char* pcCur = this->mCurrent;
const unsigned char* pcCurNext = pcCur + (psChunk->Size const unsigned char* pcCurNext = pcCur + (psChunk->Size - sizeof(Dot3DSFile::Chunk));
- sizeof(Dot3DSFile::Chunk));
// get chunk type // get chunk type
const unsigned char* sz = this->mCurrent; const unsigned char* sz = this->mCurrent;
@ -1018,11 +963,14 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
// truncate it. // truncate it.
while (*sz++ != '\0') while (*sz++ != '\0')
{ {
if (sz > pcCurNext-1)break; if (sz > pcCurNext-1)
{
DefaultLogger::get()->error("Material name string is too long");
break;
}
++iCnt; ++iCnt;
} }
this->mScene->mMaterials.back().mName = std::string( this->mScene->mMaterials.back().mName = std::string((const char*)this->mCurrent,iCnt);
(const char*)this->mCurrent,iCnt);
break; break;
case Dot3DSFile::CHUNK_MAT_DIFFUSE: case Dot3DSFile::CHUNK_MAT_DIFFUSE:
pc = &this->mScene->mMaterials.back().mDiffuse; pc = &this->mScene->mMaterials.back().mDiffuse;
@ -1030,6 +978,7 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read DIFFUSE chunk");
pc->r = pc->g = pc->b = 1.0f; pc->r = pc->g = pc->b = 1.0f;
} }
break; break;
@ -1039,6 +988,7 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read SPECULAR chunk");
pc->r = pc->g = pc->b = 1.0f; pc->r = pc->g = pc->b = 1.0f;
} }
break; break;
@ -1048,6 +998,7 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
if (is_qnan(pc->r)) if (is_qnan(pc->r))
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
DefaultLogger::get()->error("Unable to read AMBIENT chunk");
pc->r = pc->g = pc->b = 1.0f; pc->r = pc->g = pc->b = 1.0f;
} }
break; break;
@ -1058,6 +1009,7 @@ void Dot3DSImporter::ParseMaterialChunk(int& piRemaining)
{ {
// color chunk is invalid. Simply ignore it // color chunk is invalid. Simply ignore it
// EMISSSIVE TO 0|0|0 // EMISSSIVE TO 0|0|0
DefaultLogger::get()->error("Unable to read EMISSIVE chunk");
pc->r = pc->g = pc->b = 0.0f; pc->r = pc->g = pc->b = 0.0f;
} }
break; break;

View File

@ -392,8 +392,7 @@ void ASEImporter::BuildNodes()
{ {
continue; continue;
} }
if (szMyName[1].length() == szMyName2[0].length() && if (!ASSIMP_stricmp ( szMyName[1], szMyName2[0]))
0 == ASSIMP_stricmp ( szMyName[1].c_str(), szMyName2[0].c_str()))
{ {
bKnowParent = true; bKnowParent = true;
break; break;
@ -403,8 +402,7 @@ void ASEImporter::BuildNodes()
// that has already been handled and added to the list // that has already been handled and added to the list
if (i2 < i) if (i2 < i)
{ {
if (szMyName[1].length() == szMyName2[1].length() && if (ASSIMP_stricmp ( szMyName[1], szMyName2[1]))
0 == ASSIMP_stricmp ( szMyName[1].c_str(), szMyName2[1].c_str()))
{ {
bKnowParent = true; bKnowParent = true;
break; break;

View File

@ -88,7 +88,7 @@ void CalcTangentsProcess::SetupProperties(const Importer* pImp)
// get the current value of the property // get the current value of the property
this->configMaxAngle = pImp->GetProperty(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45000) / 1000.0f; this->configMaxAngle = pImp->GetProperty(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45000) / 1000.0f;
this->configMaxAngle = std::max(std::min(this->configMaxAngle,180.0f),0.0f); this->configMaxAngle = std::max(std::min(this->configMaxAngle,180.0f),0.0f);
this->configMaxAngle *= 0.0174532925f; this->configMaxAngle = AI_DEG_TO_RAD(this->configMaxAngle);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -78,7 +78,7 @@ void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
// get the current value of the property // get the current value of the property
this->configMaxAngle = pImp->GetProperty(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,180000) / 1000.0f; this->configMaxAngle = pImp->GetProperty(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,180000) / 1000.0f;
this->configMaxAngle = std::max(std::min(this->configMaxAngle,180.0f),0.0f); this->configMaxAngle = std::max(std::min(this->configMaxAngle,180.0f),0.0f);
this->configMaxAngle *= 0.0174532925f; this->configMaxAngle = AI_DEG_TO_RAD(this->configMaxAngle);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.

View File

@ -51,6 +51,7 @@ Original copyright notice: "Ernie Wright 17 Sep 00"
#include "IFF.h" #include "IFF.h"
#include <vector>
#include "../include/aiMesh.h" #include "../include/aiMesh.h"
namespace Assimp { namespace Assimp {
@ -239,6 +240,29 @@ struct Face : public aiFace
unsigned int surfaceIndex; unsigned int surfaceIndex;
}; };
// ---------------------------------------------------------------------------
/** \brief LWO2 gradient keyframe
*/
struct GradientKey
{
aiColor4D color;
float value;
};
// ---------------------------------------------------------------------------
/** \brief Data structure for a LWO2 gradient
*/
struct GradientInfo
{
GradientInfo()
: mStart(0.0f)
, mEnd(1.0f)
{}
float mStart,mEnd;
bool mRepeat;
std::vector<GradientKey> mKeys;
};
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -255,6 +279,14 @@ struct Texture
//! Strength of the texture //! Strength of the texture
float mStrength; float mStrength;
/*************** SPECIFIC TO LWO2 *********************/
uint32_t type; // type of the texture
GradientInfo mGradient;
// todo ... maybe support for procedurals?
}; };
@ -285,7 +317,7 @@ struct Surface
float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness; float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness;
//! Maximum angle between two adjacent triangles //! Maximum angle between two adjacent triangles
//! that they can be smoothed //! that they can be smoothed - in degrees
float mMaximumSmoothAngle; float mMaximumSmoothAngle;
//! Textures //! Textures
@ -293,6 +325,14 @@ struct Surface
mBumpTexture,mTransparencyTexture; mBumpTexture,mTransparencyTexture;
}; };
// ---------------------------------------------------------------------------
#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
if (length < size) \
{ \
DefaultLogger::get()->warn("LWO: "#name" chunk is too small"); \
break; \
} \
}} }}

View File

@ -44,22 +44,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// internal headers // internal headers
#include "LWOLoader.h" #include "LWOLoader.h"
#include "MaterialSystem.h" #include "MaterialSystem.h"
#include "StringComparison.h"
#include "ByteSwap.h" #include "ByteSwap.h"
// public assimp headers // public assimp headers
#include "../include/IOStream.h" #include "../include/IOStream.h"
#include "../include/IOSystem.h" #include "../include/IOSystem.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h" #include "../include/aiScene.h"
#include "../include/aiAssert.h" #include "../include/aiAssert.h"
#include "../include/DefaultLogger.h" #include "../include/DefaultLogger.h"
#include "../include/assimp.hpp"
// boost headers // boost headers
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
LWOImporter::LWOImporter() LWOImporter::LWOImporter()
@ -92,6 +92,13 @@ bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties
void LWOImporter::SetupProperties(const Importer* pImp)
{
this->configGradientResX = pImp->GetProperty(AI_CONFIG_IMPORT_LWO_GRADIENT_RESX,512);
this->configGradientResY = pImp->GetProperty(AI_CONFIG_IMPORT_LWO_GRADIENT_RESY,512);
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void LWOImporter::InternReadFile( const std::string& pFile, void LWOImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
@ -134,10 +141,18 @@ void LWOImporter::InternReadFile( const std::string& pFile,
mSurfaces = &_mSurfaces; mSurfaces = &_mSurfaces;
// old lightwave file format (prior to v6) // old lightwave file format (prior to v6)
if (AI_LWO_FOURCC_LWOB == fileType)this->LoadLWOBFile(); if (AI_LWO_FOURCC_LWOB == fileType)
{
mIsLWO2 = false;
this->LoadLWOBFile();
}
// new lightwave format // new lightwave format
else if (AI_LWO_FOURCC_LWO2 == fileType)this->LoadLWO2File(); else if (AI_LWO_FOURCC_LWO2 == fileType)
{
mIsLWO2 = true;
this->LoadLWO2File();
}
// we don't know this format // we don't know this format
else else
@ -198,6 +213,7 @@ void LWOImporter::InternReadFile( const std::string& pFile,
// generate the mesh // generate the mesh
aiMesh* mesh = pScene->mMeshes[p] = new aiMesh(); aiMesh* mesh = pScene->mMeshes[p] = new aiMesh();
mesh->mNumFaces = sorted.size(); mesh->mNumFaces = sorted.size();
mesh->mMaxSmoothingAngle = AI_DEG_TO_RAD((*mSurfaces)[i].mMaximumSmoothAngle);
for (SortedRep::const_iterator it = sorted.begin(), end = sorted.end(); for (SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
it != end;++it) it != end;++it)
@ -259,15 +275,40 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,MaterialHelper* pcMat
if (surf.mSpecularValue && surf.mGlossiness) if (surf.mSpecularValue && surf.mGlossiness)
{ {
// this is only an assumption, needs to be confirmed. // this is only an assumption, needs to be confirmed.
/*if (16.0f >= surf.mGlossiness)surf.mGlossiness = 10.0f; // the values have been tweaked by hand and seem to be correct.
else if (64.0f >= surf.mGlossiness)surf.mGlossiness = 14.0f; float fGloss;
else if (256.0f >= surf.mGlossiness)surf.mGlossiness = 20.0f; if (mIsLWO2)fGloss = surf.mGlossiness * 0.8f;
else surf.mGlossiness = 24.0f;*/ else
{
if (16.0f >= surf.mGlossiness)fGloss = 6.0f;
else if (64.0f >= surf.mGlossiness)fGloss = 20.0f;
else if (256.0f >= surf.mGlossiness)fGloss = 50.0f;
else fGloss = 80.0f;
}
pcMat->AddProperty<float>(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH); pcMat->AddProperty<float>(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
pcMat->AddProperty<float>(&surf.mGlossiness,1,AI_MATKEY_SHININESS); pcMat->AddProperty<float>(&fGloss,1,AI_MATKEY_SHININESS);
} }
// (the diffuse value is just a scaling factor)
aiColor3D clr = surf.mColor;
clr.r *= surf.mDiffuseValue;
clr.g *= surf.mDiffuseValue;
clr.b *= surf.mDiffuseValue;
pcMat->AddProperty<aiColor3D>(&surf.mColor,1,AI_MATKEY_COLOR_DIFFUSE);
// specular color
clr.r = surf.mSpecularValue;
clr.g = surf.mSpecularValue;
clr.b = surf.mSpecularValue;
pcMat->AddProperty<aiColor3D>(&surf.mColor,1,AI_MATKEY_COLOR_SPECULAR);
// opacity
float f = 1.0f-surf.mTransparency;
pcMat->AddProperty<float>(&f,1,AI_MATKEY_OPACITY);
// now handle all textures ...
// TODO
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -334,7 +375,9 @@ void LWOImporter::ResolveTags()
{ {
for (unsigned int i = 0; i < mSurfaces->size();++i) for (unsigned int i = 0; i < mSurfaces->size();++i)
{ {
if ((*mTags)[a] == (*mSurfaces)[i].mName) const std::string& c = (*mTags)[a];
const std::string& d = (*mSurfaces)[i].mName;
if (!ASSIMP_stricmp(c,d))
{ {
(*mMapping)[a] = i; (*mMapping)[a] = i;
break; break;
@ -352,7 +395,7 @@ void LWOImporter::ParseString(std::string& out,unsigned int max)
{ {
if (++iCursor > max) if (++iCursor > max)
{ {
DefaultLogger::get()->warn("LWOB: Invalid file, texture name (TIMG) is too long"); DefaultLogger::get()->warn("LWOB: Invalid file, string is is too long");
break; break;
} }
++in; ++in;
@ -372,14 +415,6 @@ void LWOImporter::AdjustTexturePath(std::string& out)
} }
} }
// ------------------------------------------------------------------------------------------------
#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
if (length < size) \
{ \
DefaultLogger::get()->warn("LWO: "#name" chunk is too small"); \
break; \
} \
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOTags(unsigned int size) void LWOImporter::LoadLWOTags(unsigned int size)
{ {
@ -387,149 +422,14 @@ void LWOImporter::LoadLWOTags(unsigned int size)
const char* const szEnd = szLast+size; const char* const szEnd = szLast+size;
while (szCur < szEnd) while (szCur < szEnd)
{ {
if (!(*szCur++)) if (!(*szCur))
{ {
const unsigned int len = unsigned int(szCur-szLast); const unsigned int len = unsigned int(szCur-szLast);
mTags->push_back(std::string(szLast,len)); mTags->push_back(std::string(szLast,len));
szCur += len & 1; szCur += len & 1;
szLast = szCur; szLast = szCur;
} }
} szCur++;
}
// ------------------------------------------------------------------------------------------------
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
LE_NCONST uint8_t* sz = mFileBuffer;
while (*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++;
if (!(len & 1))++mFileBuffer; // skip one byte if the length of the surface name is odd
while (true)
{
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");
}
LE_NCONST uint8_t* const next = mFileBuffer+head_length;
switch (head_type)
{
// diffuse color
case AI_LWO_COLR:
{
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;
break;
}
// diffuse strength ... hopefully
case AI_LWO_DIFF:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,DIFF,2);
AI_LSWAP2(mFileBuffer);
surf.mDiffuseValue = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// specular strength ... hopefully
case AI_LWO_SPEC:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,SPEC,2);
AI_LSWAP2(mFileBuffer);
surf.mSpecularValue = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// transparency
case AI_LWO_TRAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,TRAN,2);
AI_LSWAP2(mFileBuffer);
surf.mTransparency = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// glossiness
case AI_LWO_GLOS:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,GLOS,2);
AI_LSWAP2(mFileBuffer);
surf.mGlossiness = float(*((int16_t*)mFileBuffer));
break;
}
// color texture
case AI_LWO_CTEX:
{
pTex = &surf.mColorTexture;
break;
}
// diffuse texture
case AI_LWO_DTEX:
{
pTex = &surf.mDiffuseTexture;
break;
}
// specular texture
case AI_LWO_STEX:
{
pTex = &surf.mSpecularTexture;
break;
}
// bump texture
case AI_LWO_BTEX:
{
pTex = &surf.mBumpTexture;
break;
}
// transparency texture
case AI_LWO_TTEX:
{
pTex = &surf.mTransparencyTexture;
break;
}
// texture path
case AI_LWO_TIMG:
{
if (pTex)
{
ParseString(pTex->mFileName,head_length);
AdjustTexturePath(pTex->mFileName);
mFileBuffer += pTex->mFileName.length();
}
else DefaultLogger::get()->warn("LWOB: TIMG tag was encuntered although "
"there was no xTEX tag before");
break;
}
// texture strength
case AI_LWO_TVAL:
{
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");
break;
}
}
mFileBuffer = next;
} }
} }

View File

@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MaterialSystem.h" #include "MaterialSystem.h"
#include <vector> #include <vector>
struct aiTexture;
namespace Assimp { namespace Assimp {
using namespace LWO; using namespace LWO;
@ -74,6 +75,14 @@ public:
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
// -------------------------------------------------------------------
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.
*/
void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -95,22 +104,49 @@ protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Loads a LWO file in the older LWOB format (LW < 6) /** Loads a LWO file in the older LWOB format (LW < 6)
*/ */
void LoadLWOBFile(); void LoadLWOBFile();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Loads a LWO file in the newer LWO2 format (LW >= 6) /** Loads a LWO file in the newer LWO2 format (LW >= 6)
*/ */
void LoadLWO2File(); void LoadLWO2File();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Loads a surface chunk from an LWOB file /** Loads a surface chunk from an LWOB file
*/ * @param size Maximum size to be read, in bytes.
*/
void LoadLWOBSurface(unsigned int size); void LoadLWOBSurface(unsigned int size);
// -------------------------------------------------------------------
/** Loads a surface chunk from an LWO2 file
* @param size Maximum size to be read, in bytes.
*/
void LoadLWO2Surface(unsigned int size);
// -------------------------------------------------------------------
/** Loads a texture block from a LWO2 file.
* @param size Maximum size to be read, in bytes.
* @param type Type of the texture block - PROC, GRAD or IMAP
*/
void LoadLWO2TextureBlock(uint32_t type, unsigned int size );
// -------------------------------------------------------------------
/** Loads an image map from a LWO2 file
* @param size Maximum size to be read, in bytes.
* @param tex Texture object to be filled
*/
void LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex );
void LoadLWO2Gradient(unsigned int size, LWO::Texture& tex );
void LoadLWO2Procedural(unsigned int size, LWO::Texture& tex );
// loads the header - used by thethree functions above
void LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex );
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Loads the LWO tag list from the file /** Loads the LWO tag list from the file
*/ * @param size Maximum size to be read, in bytes.
*/
void LoadLWOTags(unsigned int size); void LoadLWOTags(unsigned int size);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -119,6 +155,17 @@ protected:
*/ */
void ResolveTags(); void ResolveTags();
// -------------------------------------------------------------------
/** Computes a proper texture form a procedural gradient
* description.
* @param grad Gradient description
* @param out List of output textures. The new texture should
* be added to the list, if the conversion was successful.
* @return true if successful
*/
bool ComputeGradientTexture(LWO::GradientInfo& grad,
std::vector<aiTexture*>& out);
typedef std::vector<aiVector3D> PointList; typedef std::vector<aiVector3D> PointList;
typedef std::vector<LWO::Face> FaceList; typedef std::vector<LWO::Face> FaceList;
@ -162,6 +209,9 @@ private:
protected: protected:
/** true if the file is a LWO2 file*/
bool mIsLWO2;
/** Temporary point list from the file */ /** Temporary point list from the file */
PointList* mTempPoints; PointList* mTempPoints;
@ -187,6 +237,8 @@ protected:
/** Output scene */ /** Output scene */
aiScene* pScene; aiScene* pScene;
/** Configuration option: X and Y size of gradient maps */
unsigned int configGradientResX,configGradientResY;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -0,0 +1,337 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the material oart of the LWO importer class */
// internal headers
#include "LWOLoader.h"
#include "MaterialSystem.h"
#include "ByteSwap.h"
// public assimp headers
#include "../include/IOStream.h"
#include "../include/IOSystem.h"
#include "../include/aiScene.h"
#include "../include/aiAssert.h"
#include "../include/DefaultLogger.h"
// boost headers
#include <boost/scoped_ptr.hpp>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
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;
ParseString(surf.mName,size);
mFileBuffer+=surf.mName.length()+1;
// skip one byte if the length of the surface name is odd
if (!(surf.mName.length() & 1))++mFileBuffer;
while (true)
{
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");
}
LE_NCONST uint8_t* const next = mFileBuffer+head_length;
switch (head_type)
{
// diffuse color
case AI_LWO_COLR:
{
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;
break;
}
// diffuse strength ... hopefully
case AI_LWO_DIFF:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,DIFF,2);
AI_LSWAP2P(mFileBuffer);
surf.mDiffuseValue = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// specular strength ... hopefully
case AI_LWO_SPEC:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,SPEC,2);
AI_LSWAP2P(mFileBuffer);
surf.mSpecularValue = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// transparency
case AI_LWO_TRAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,TRAN,2);
AI_LSWAP2P(mFileBuffer);
surf.mTransparency = *((int16_t*)mFileBuffer) / 255.0f;
break;
}
// glossiness
case AI_LWO_GLOS:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,GLOS,2);
AI_LSWAP2P(mFileBuffer);
surf.mGlossiness = float(*((int16_t*)mFileBuffer));
break;
}
// color texture
case AI_LWO_CTEX:
{
pTex = &surf.mColorTexture;
break;
}
// diffuse texture
case AI_LWO_DTEX:
{
pTex = &surf.mDiffuseTexture;
break;
}
// specular texture
case AI_LWO_STEX:
{
pTex = &surf.mSpecularTexture;
break;
}
// bump texture
case AI_LWO_BTEX:
{
pTex = &surf.mBumpTexture;
break;
}
// transparency texture
case AI_LWO_TTEX:
{
pTex = &surf.mTransparencyTexture;
break;
}
// texture path
case AI_LWO_TIMG:
{
if (pTex)
{
ParseString(pTex->mFileName,head_length);
AdjustTexturePath(pTex->mFileName);
mFileBuffer += pTex->mFileName.length();
}
else DefaultLogger::get()->warn("LWOB: TIMG tag was encuntered although "
"there was no xTEX tag before");
break;
}
// texture strength
case AI_LWO_TVAL:
{
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");
break;
}
}
mFileBuffer = next;
}
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Procedural(unsigned int size, LWO::Texture& tex )
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Gradient(unsigned int size, LWO::Texture& tex )
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2TextureBlock(uint32_t type, unsigned int size )
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
LWO::Surface& surf = mSurfaces->back();
LWO::Texture tex;
// now get the exact type of the texture
}
// ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWO2Surface(unsigned int size)
{
LE_NCONST uint8_t* const end = mFileBuffer + size;
mSurfaces->push_back( LWO::Surface () );
LWO::Surface& surf = mSurfaces->back();
ParseString(surf.mName,size);
mFileBuffer+=surf.mName.length()+1;
// skip one byte if the length of the surface name is odd
if (!(surf.mName.length() & 1))++mFileBuffer;
while (true)
{
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("LWO2: Invalid file, the size attribute of "
"a surface sub chunk points behind the end of the file");
}
LE_NCONST uint8_t* const next = mFileBuffer+head_length;
switch (head_type)
{
// diffuse color
case AI_LWO_COLR:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,COLR,12);
surf.mColor.r = ((float*)mFileBuffer)[0];
surf.mColor.g = ((float*)mFileBuffer)[1];
surf.mColor.b = ((float*)mFileBuffer)[2];
AI_LSWAP4(surf.mColor.r);
AI_LSWAP4(surf.mColor.g);
AI_LSWAP4(surf.mColor.b);
break;
}
// diffuse strength ... hopefully
case AI_LWO_DIFF:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,DIFF,4);
surf.mDiffuseValue = *((float*)mFileBuffer);
AI_LSWAP4(surf.mDiffuseValue);
break;
}
// specular strength ... hopefully
case AI_LWO_SPEC:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,SPEC,4);
surf.mSpecularValue = *((float*)mFileBuffer);
AI_LSWAP4(surf.mSpecularValue);
break;
}
// transparency
case AI_LWO_TRAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,TRAN,4);
surf.mTransparency = *((float*)mFileBuffer);
AI_LSWAP4(surf.mTransparency);
break;
}
// glossiness
case AI_LWO_GLOS:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,GLOS,4);
surf.mGlossiness = *((float*)mFileBuffer);
AI_LSWAP4(surf.mGlossiness);
break;
}
// surface bock entry
case AI_LWO_BLOK:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head_length,BLOK,4);
uint32_t type = *((uint32_t*)mFileBuffer);
AI_LSWAP4(type);
switch (type)
{
case AI_LWO_IMAP:
case AI_LWO_PROC:
case AI_LWO_GRAD:
mFileBuffer+=4;
LoadLWO2TextureBlock(type,head_length-4);
break;
};
break;
}
}
mFileBuffer = next;
}
}
// ------------------------------------------------------------------------------------------------
bool LWOImporter::ComputeGradientTexture(LWO::GradientInfo& grad,
std::vector<aiTexture*>& out)
{
aiTexture* tex = new aiTexture();
tex->mHeight = configGradientResY;
tex->mWidth = configGradientResX;
unsigned int numPixels;
tex->pcData = new aiTexel[numPixels = tex->mHeight * tex->mWidth];
// to be implemented ...
out.push_back(tex);
return true;
}

View File

@ -109,10 +109,13 @@ void STLImporter::InternReadFile(
// 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)
this->mBuffer = new char[fileSize+1]; std::vector<char> mBuffer2(fileSize+1);
file->Read(&mBuffer2[0], 1, fileSize);
mBuffer2[fileSize] = '\0';
this->pScene = pScene; this->pScene = pScene;
file->Read( (void*)mBuffer, 1, fileSize); this->mBuffer = &mBuffer2[0];
const_cast<char*>(this->mBuffer)[fileSize] = '\0';
// the default vertex color is white // the default vertex color is white
clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f; clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 1.0f;
@ -130,32 +133,24 @@ void STLImporter::InternReadFile(
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes[0] = 0;
bool bMatClr = false; bool bMatClr = false;
try
{
// check whether the file starts with 'solid' -
// in this case we can simply assume it IS a text file. finished.
if (!::strncmp(mBuffer,"solid",5))
this->LoadASCIIFile();
else bMatClr = this->LoadBinaryFile();
// now copy faces // check whether the file starts with 'solid' -
pMesh->mFaces = new aiFace[pMesh->mNumFaces]; // in this case we can simply assume it IS a text file. finished.
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) if (!::strncmp(mBuffer,"solid",5))
{ this->LoadASCIIFile();
aiFace& face = pMesh->mFaces[i]; else bMatClr = this->LoadBinaryFile();
face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int o = 0; o < 3;++o,++p) // now copy faces
face.mIndices[o] = p; pMesh->mFaces = new aiFace[pMesh->mNumFaces];
} for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i)
}
catch (ImportErrorException* ex)
{ {
delete[] this->mBuffer;AI_DEBUG_INVALIDATE_PTR(this->mBuffer); aiFace& face = pMesh->mFaces[i];
throw ex; face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int o = 0; o < 3;++o,++p)
face.mIndices[o] = p;
} }
// create a single default material - everything white, as // create a single default material - everything white, as we have vertex colors
// we have vertex colors
MaterialHelper* pcMat = new MaterialHelper(); MaterialHelper* pcMat = new MaterialHelper();
aiString s; aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME); s.Set(AI_DEFAULT_MATERIAL_NAME);

View File

@ -81,6 +81,14 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2)
#endif #endif
} }
// ---------------------------------------------------------------------------
inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
{
int i = (int)b.length()-(int)a.length();
if (i)return i;
return ASSIMP_stricmp(a.c_str(),b.c_str());
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Helper function to do platform independent string comparison. /** \brief Helper function to do platform independent string comparison.
* *
@ -121,6 +129,6 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
} }
#endif #endif
} }
}; }
#endif // ! AI_STRINGCOMPARISON_H_INC #endif // ! AI_STRINGCOMPARISON_H_INC

View File

@ -105,6 +105,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#define AI_CONFIG_IMPORT_3DS_IGNORE_PIVOT "imp.3ds.nopivot" #define AI_CONFIG_IMPORT_3DS_IGNORE_PIVOT "imp.3ds.nopivot"
// ---------------------------------------------------------------------------
/** \brief Sets the resolution of gradient textures generated by
* the LWO loader.
*
* LightWave represents the gradients with infinite detail,
* but for use in realtime the loader computes replacement textures.
* The default size is 512 * 512.
*/
#define AI_CONFIG_IMPORT_LWO_GRADIENT_RESX "imp.lwo.gradres_x"
#define AI_CONFIG_IMPORT_LWO_GRADIENT_RESY "imp.lwo.gradres_y"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** \brief Specifies the maximum angle that may be between two vertex tangents /** \brief Specifies the maximum angle that may be between two vertex tangents
* that their tangents and bitangents are smoothed. * that their tangents and bitangents are smoothed.

View File

@ -107,4 +107,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_MATH_PI (3.1415926538) #define AI_MATH_PI (3.1415926538)
#define AI_MATH_TWO_PI (AI_MATH_PI * 2.0) #define AI_MATH_TWO_PI (AI_MATH_PI * 2.0)
#define AI_DEG_TO_RAD(x) (x*0.0174532925f)
#define AI_RAD_TO_DEG(x) (x*57.2957795f)
#endif // !! AI_DEFINES_H_INC #endif // !! AI_DEFINES_H_INC

View File

@ -356,7 +356,7 @@ struct aiMesh
*/ */
unsigned int mMaterialIndex; unsigned int mMaterialIndex;
/** The maximum vertex smooth angle for the mesh. /** The maximum vertex smooth angle for the mesh, in radians
* If the angle between two vertex normals is larger, * If the angle between two vertex normals is larger,
* the vertex normals should not be smoothed. The GenVertexNormals-Step * the vertex normals should not be smoothed. The GenVertexNormals-Step
* takes care of this value. The angle is specified in radians. * takes care of this value. The angle is specified in radians.

Binary file not shown.

View File

@ -1325,6 +1325,10 @@
RelativePath="..\..\code\LWOLoader.cpp" RelativePath="..\..\code\LWOLoader.cpp"
> >
</File> </File>
<File
RelativePath="..\..\code\LWOMaterial.cpp"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="MDC" Name="MDC"