- tags are now imported as nodes in the hierarchy

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@344 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2009-02-12 16:44:12 +00:00
parent fd9769eae6
commit e6758ce923
3 changed files with 94 additions and 54 deletions

View File

@ -94,25 +94,22 @@ bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
// no file extension - can't read // no file extension - can't read
if( pos == std::string::npos) if( pos == std::string::npos)
return false; return false;
std::string extension = pFile.substr( pos); std::string extension = pFile.substr( pos);
for( std::string::iterator it = extension.begin(); it != extension.end(); ++it)
*it = tolower( *it);
if (extension.length() < 4)return false; return ( extension == ".md2");
if (extension[0] != '.')return false;
if (extension[1] != 'm' && extension[1] != 'M')return false;
if (extension[2] != 'd' && extension[2] != 'D')return false;
if (extension[3] != '2')return false;
return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties // Setup configuration properties
void MD2Importer::SetupProperties(const Importer* pImp) void MD2Importer::SetupProperties(const Importer* pImp)
{ {
// The AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the // The
// AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option. // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
if(0xffffffff == (configFrameID = pImp->GetPropertyInteger( configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD2_KEYFRAME,0xffffffff);
AI_CONFIG_IMPORT_MD2_KEYFRAME,0xffffffff))) if(0xffffffff == configFrameID){
{
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0); configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
} }
} }

View File

@ -66,6 +66,7 @@ namespace MD3 {
// common limitations // common limitations
#define AI_MD3_VERSION 15 #define AI_MD3_VERSION 15
#define AI_MD3_MAXQPATH 64 #define AI_MD3_MAXQPATH 64
#define AI_MD3_MAXFRAME 16
#define AI_MD3_MAX_FRAMES 1024 #define AI_MD3_MAX_FRAMES 1024
#define AI_MD3_MAX_TAGS 16 #define AI_MD3_MAX_TAGS 16
#define AI_MD3_MAX_SURFACES 32 #define AI_MD3_MAX_SURFACES 32
@ -126,7 +127,21 @@ struct Header
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
struct Frame struct Frame
{ {
// no need to define this, we won't need //! minimum bounds
aiVector3D min;
//! maximum bounds
aiVector3D max;
//! local origin for this frame
aiVector3D origin;
//! radius of bounding sphere
float radius;
//! name of frame
char name[ AI_MD3_MAXFRAME ];
} PACK_STRUCT; } PACK_STRUCT;
@ -136,7 +151,13 @@ struct Frame
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
struct Tag struct Tag
{ {
// no need to define this, we won't need //! name of the tag
unsigned char NAME[ AI_MD3_MAXQPATH ];
//! Local tag origin and orientation
aiVector3D origin;
float orientation[3][3];
} PACK_STRUCT; } PACK_STRUCT;

View File

@ -72,15 +72,12 @@ bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
if( pos == std::string::npos) if( pos == std::string::npos)
return false; return false;
std::string extension = pFile.substr( pos); std::string extension = pFile.substr( pos);
for( std::string::iterator it = extension.begin(); it != extension.end(); ++it)
*it = tolower( *it);
if (extension.length() < 4)return false; return ( extension == ".md3");
if (extension[0] != '.')return false;
if (extension[1] != 'm' && extension[1] != 'M')return false;
if (extension[2] != 'd' && extension[2] != 'D')return false;
if (extension[3] != '3')return false;
return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MD3Importer::ValidateHeaderOffsets() void MD3Importer::ValidateHeaderOffsets()
{ {
@ -97,16 +94,15 @@ void MD3Importer::ValidateHeaderOffsets()
if (!pcHeader->NUM_SURFACES) if (!pcHeader->NUM_SURFACES)
throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0"); throw new ImportErrorException( "Invalid md3 file: NUM_SURFACES is 0");
if (pcHeader->OFS_FRAMES >= fileSize || if (pcHeader->OFS_FRAMES >= fileSize || pcHeader->OFS_SURFACES >= fileSize ||
pcHeader->OFS_SURFACES >= fileSize || pcHeader->OFS_EOF > fileSize) {
pcHeader->OFS_EOF > fileSize)
{
throw new ImportErrorException("Invalid MD3 header: some offsets are outside the file"); throw new ImportErrorException("Invalid MD3 header: some offsets are outside the file");
} }
if (pcHeader->NUM_FRAMES <= this->configFrameID ) if (pcHeader->NUM_FRAMES <= configFrameID )
throw new ImportErrorException("The requested frame is not existing the file"); throw new ImportErrorException("The requested frame is not existing the file");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf) void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
{ {
@ -114,10 +110,9 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer); int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer);
if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > fileSize || if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > fileSize ||
pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize || pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize ||
pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize || pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize ||
pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize) pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize) {
{
throw new ImportErrorException("Invalid MD3 surface header: some offsets are outside the file"); throw new ImportErrorException("Invalid MD3 surface header: some offsets are outside the file");
} }
@ -134,14 +129,15 @@ void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
// Setup configuration properties // Setup configuration properties
void MD3Importer::SetupProperties(const Importer* pImp) void MD3Importer::SetupProperties(const Importer* pImp)
{ {
// The AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the // The
// AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option. // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
if(0xffffffff == (this->configFrameID = pImp->GetPropertyInteger( configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_KEYFRAME,0xffffffff);
AI_CONFIG_IMPORT_MD3_KEYFRAME,0xffffffff))) if(0xffffffff == configFrameID) {
{ configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
this->configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MD3Importer::InternReadFile( void MD3Importer::InternReadFile(
@ -183,11 +179,14 @@ void MD3Importer::InternReadFile(
#endif #endif
// validate the header // validate the header
this->ValidateHeaderOffsets(); ValidateHeaderOffsets();
// now navigate to the list of surfaces // navigate to the list of surfaces
BE_NCONST MD3::Surface* pcSurfaces = (BE_NCONST MD3::Surface*)(mBuffer + pcHeader->OFS_SURFACES); BE_NCONST MD3::Surface* pcSurfaces = (BE_NCONST MD3::Surface*)(mBuffer + pcHeader->OFS_SURFACES);
// navigate to the list of tags
BE_NCONST MD3::Tag* pcTags = (BE_NCONST MD3::Tag*)(mBuffer + pcHeader->OFS_TAGS);
// allocate output storage // allocate output storage
pScene->mNumMeshes = pcHeader->NUM_SURFACES; pScene->mNumMeshes = pcHeader->NUM_SURFACES;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
@ -223,7 +222,7 @@ void MD3Importer::InternReadFile(
#endif #endif
// validate the surface // validate the surface
this->ValidateSurfaceHeaderOffsets(pcSurfaces); ValidateSurfaceHeaderOffsets(pcSurfaces);
// navigate to the vertex list of the surface // navigate to the vertex list of the surface
BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*) BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*)
@ -336,7 +335,7 @@ void MD3Importer::InternReadFile(
bool bSuccess = true; bool bSuccess = true;
for (unsigned int a = 0; a < iLen2;++a) for (unsigned int a = 0; a < iLen2;++a)
{ {
char sz = ::tolower ( pcShaders->NAME[a] ); char sz = ::tolower ( pcShaders->NAME[a] );
char sz2 = ::tolower ( pcHeader->NAME[a] ); char sz2 = ::tolower ( pcHeader->NAME[a] );
if (sz != sz2) if (sz != sz2)
{ {
@ -344,23 +343,19 @@ void MD3Importer::InternReadFile(
break; break;
} }
} }
if (bSuccess) if (bSuccess) {
{
// use the file name only // use the file name only
szEndDir2++; szEndDir2++;
} }
else else {
{
// use the full path // use the full path
szEndDir2 = (const char*)pcShaders->NAME; szEndDir2 = (const char*)pcShaders->NAME;
} }
} }
MaterialHelper* pcHelper = new MaterialHelper(); MaterialHelper* pcHelper = new MaterialHelper();
if (szEndDir2) if (szEndDir2) {
{ if (szEndDir2[0]) {
if (szEndDir2[0])
{
aiString szString; aiString szString;
const size_t iLen = ::strlen(szEndDir2); const size_t iLen = ::strlen(szEndDir2);
::memcpy(szString.data,szEndDir2,iLen); ::memcpy(szString.data,szEndDir2,iLen);
@ -369,10 +364,8 @@ void MD3Importer::InternReadFile(
pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0)); pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
else else {
{ DefaultLogger::get()->warn("Texture file name has zero length. Skipping");
DefaultLogger::get()->warn("Texture file name has zero length. "
"It will be skipped.");
} }
} }
@ -397,8 +390,7 @@ void MD3Importer::InternReadFile(
} }
else else
{ {
if (0xFFFFFFFF != iDefaultMatIndex) if (0xFFFFFFFF != iDefaultMatIndex) {
{
pcMesh->mMaterialIndex = iDefaultMatIndex; pcMesh->mMaterialIndex = iDefaultMatIndex;
} }
else else
@ -429,11 +421,41 @@ void MD3Importer::InternReadFile(
throw new ImportErrorException( "Invalid MD3 file: File contains no valid mesh"); throw new ImportErrorException( "Invalid MD3 file: File contains no valid mesh");
pScene->mNumMaterials = iNumMaterials; pScene->mNumMaterials = iNumMaterials;
// now we need to generate an empty node graph // Now we need to generate an empty node graph
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode("<MD3Root>");
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
// Attach tiny children for all tags
if (pcHeader->NUM_TAGS) {
pScene->mRootNode->mNumChildren = pcHeader->NUM_TAGS;
pScene->mRootNode->mChildren = new aiNode*[pcHeader->NUM_TAGS];
for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
nd->mName.Set((const char*)pcTags->NAME);
nd->mParent = pScene->mRootNode;
AI_SWAP4(pcTags->origin.x);
AI_SWAP4(pcTags->origin.y);
AI_SWAP4(pcTags->origin.z);
// copy local origin
nd->mTransformation.a4 = pcTags->origin.x;
nd->mTransformation.b4 = pcTags->origin.y;
nd->mTransformation.c4 = pcTags->origin.z;
// copy rest of transformation
for (unsigned int a = 0; a < 3;++a) {
for (unsigned int m = 0; m < 3;++m) {
nd->mTransformation[a][m] = pcTags->orientation[a][m];
AI_SWAP4(nd->mTransformation[a][m]);
}
}
}
}
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i; pScene->mRootNode->mMeshes[i] = i;
} }