Small update to the ASE loader.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@64 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2008-07-18 20:29:46 +00:00
parent fc8a8b54f9
commit 6ad0892396
11 changed files with 715 additions and 383 deletions
+181 -66
View File
@@ -126,6 +126,7 @@ void ASEImporter::InternReadFile(
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
this->mBuffer = new unsigned char[fileSize+1];
this->pcScene = pScene;
file->Read( (void*)mBuffer, 1, fileSize);
this->mBuffer[fileSize] = '\0';
@@ -135,10 +136,7 @@ void ASEImporter::InternReadFile(
// if absolutely no material has been loaded from the file
// we need to generate a default material
if (this->mParser->m_vMaterials.empty())
{
this->GenerateDefaultMaterial();
}
this->GenerateDefaultMaterial();
// process all meshes
std::vector<aiMesh*> avOutMeshes;
@@ -165,17 +163,26 @@ void ASEImporter::InternReadFile(
this->ConvertMeshes(*i,avOutMeshes);
}
// now build the output mesh list
// now build the output mesh list. remove dummies
pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mMeshes[i] = avOutMeshes[i];
aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (std::vector<aiMesh*>::const_iterator
i = avOutMeshes.begin();
i != avOutMeshes.end();++i)
{
if (!(*i)->mNumFaces)continue;
*pp++ = *i;
}
pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
// buil final material indices (remove submaterials and make the final list)
this->BuildMaterialIndices(pScene);
this->BuildMaterialIndices();
// build the final node graph
this->BuildNodes(pScene);
this->BuildNodes();
// build output animations
this->BuildAnimations();
// delete the ASE parser
delete this->mParser;
@@ -187,28 +194,120 @@ void ASEImporter::GenerateDefaultMaterial()
{
ai_assert(NULL != this->mParser);
// add a simple material without sub materials to the parser's list
this->mParser->m_vMaterials.push_back ( ASE::Material() );
ASE::Material& mat = this->mParser->m_vMaterials.back();
bool bHas = false;
for (std::vector<ASE::Mesh>::iterator
i = this->mParser->m_vMeshes.begin();
i != this->mParser->m_vMeshes.end();++i)
{
if ((*i).bSkip)continue;
if (ASE::Face::DEFAULT_MATINDEX == (*i).iMaterialIndex)
{
(*i).iMaterialIndex = (unsigned int)this->mParser->m_vMaterials.size();
bHas = true;
}
}
if (bHas || this->mParser->m_vMaterials.empty())
{
// add a simple material without sub materials to the parser's list
this->mParser->m_vMaterials.push_back ( ASE::Material() );
ASE::Material& mat = this->mParser->m_vMaterials.back();
mat.mDiffuse = aiColor3D(0.5f,0.5f,0.5f);
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
mat.mShading = Dot3DSFile::Gouraud;
mat.mName = AI_DEFAULT_MATERIAL_NAME;
mat.mDiffuse = aiColor3D(0.5f,0.5f,0.5f);
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
mat.mShading = Dot3DSFile::Gouraud;
mat.mName = AI_DEFAULT_MATERIAL_NAME;
}
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
const char* szName)
void ASEImporter::BuildAnimations()
{
// check whether we have at least one mesh which has animations
std::vector<ASE::Mesh>::iterator i = this->mParser->m_vMeshes.begin();
unsigned int iNum = 0;
for (;i != this->mParser->m_vMeshes.end();++i)
{
if ((*i).bSkip)continue;
if ((*i).mAnim.akeyPositions.size() > 1 || (*i).mAnim.akeyRotations.size() > 1)
++iNum;
}
if (iNum)
{
this->pcScene->mNumAnimations = 1;
this->pcScene->mAnimations = new aiAnimation*[1];
aiAnimation* pcAnim = this->pcScene->mAnimations[0] = new aiAnimation();
pcAnim->mNumBones = iNum;
pcAnim->mBones = new aiBoneAnim*[iNum];
pcAnim->mTicksPerSecond = this->mParser->iFrameSpeed * this->mParser->iTicksPerFrame;
iNum = 0;
i = this->mParser->m_vMeshes.begin();
for (;i != this->mParser->m_vMeshes.end();++i)
{
if ((*i).bSkip)continue;
if ((*i).mAnim.akeyPositions.size() > 1 || (*i).mAnim.akeyRotations.size() > 1)
{
aiBoneAnim* pcBoneAnim = pcAnim->mBones[iNum++] = new aiBoneAnim();
pcBoneAnim->mBoneName.Set((*i).mName);
// copy position keys
if ((*i).mAnim.akeyPositions.size() > 1 )
{
pcBoneAnim->mNumPositionKeys = (unsigned int) (*i).mAnim.akeyPositions.size();
pcBoneAnim->mPositionKeys = new aiVectorKey[pcBoneAnim->mNumPositionKeys];
::memcpy(pcBoneAnim->mPositionKeys,&(*i).mAnim.akeyPositions[0],
pcBoneAnim->mNumPositionKeys * sizeof(aiVectorKey));
for (unsigned int qq = 0; qq < pcBoneAnim->mNumPositionKeys;++qq)
{
double dTime = pcBoneAnim->mPositionKeys[qq].mTime;
pcAnim->mDuration = std::max(pcAnim->mDuration,dTime);
}
}
// copy rotation keys
if ((*i).mAnim.akeyRotations.size() > 1 )
{
pcBoneAnim->mNumRotationKeys = (unsigned int) (*i).mAnim.akeyPositions.size();
pcBoneAnim->mRotationKeys = new aiQuatKey[pcBoneAnim->mNumPositionKeys];
::memcpy(pcBoneAnim->mRotationKeys,&(*i).mAnim.akeyRotations[0],
pcBoneAnim->mNumRotationKeys * sizeof(aiQuatKey));
for (unsigned int qq = 0; qq < pcBoneAnim->mNumRotationKeys;++qq)
{
double dTime = pcBoneAnim->mRotationKeys[qq].mTime;
pcAnim->mDuration = std::max(pcAnim->mDuration,dTime);
}
}
}
}
}
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::AddNodes(aiNode* pcParent,const char* szName)
{
aiMatrix4x4 m;
ASE::DecompTransform dec(m);
this->AddNodes(pcParent,szName,dec);
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::AddNodes(aiNode* pcParent,const char* szName,
const ASE::DecompTransform& decompTrafo)
{
const size_t len = szName ? strlen(szName) : 0;
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
std::vector<aiNode*> apcNodes;
aiMesh** pcMeshes = pcScene->mMeshes;
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
{
// get the name of the mesh ([0] = name, [1] = parent)
std::string* szMyName = (std::string*)pcScene->mMeshes[i]->mColors[1];
// get the name of the mesh
aiMesh* pcMesh = *pcMeshes++;
const ASE::Mesh& mesh = *((const ASE::Mesh*)pcMesh->mColors[2]);
// TODO: experimental quick'n'dirty, clean this up ...
std::string szMyName[2] = {mesh.mName,mesh.mParent} ;
if (!szMyName)
{
continue;
@@ -226,25 +325,39 @@ void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
apcNodes.push_back(new aiNode());
aiNode* node = apcNodes.back();
// get the transformation matrix of the mesh
aiMatrix4x4* pmTransform = (aiMatrix4x4*)pcScene->mMeshes[i]->mColors[2];
node->mName.Set(szMyName[0]);
node->mNumMeshes = 1;
node->mMeshes = new unsigned int[1];
node->mMeshes[0] = i;
node->mParent = pcParent;
node->mTransformation = *pmTransform;
// delete the matrix (a mesh is always the child of ONE node, so this is safe)
delete pmTransform;
pcScene->mMeshes[i]->mColors[2] = NULL;
delete[] szMyName;
pcScene->mMeshes[i]->mColors[1] = NULL;
aiMatrix4x4 mParentAdjust = decompTrafo.mMatrix;
mParentAdjust.Inverse();
//if(ComputeLocalToWorldShift(mParentAdjust, decompTrafo, mesh.inherit))
{
node->mTransformation = mParentAdjust*mesh.mTransform;
}
//else node->mTransformation = mesh.mTransform;
// Transform all vertices of the mesh back into their local space ->
// at the moment they are pretransformed
aiMatrix4x4 mInverse = mesh.mTransform;
mInverse.Inverse();
aiVector3D* pvCurPtr = pcMesh->mVertices;
const aiVector3D* const pvEndPtr = pcMesh->mVertices + pcMesh->mNumVertices;
while (pvCurPtr != pvEndPtr)
{
*pvCurPtr = mInverse * (*pvCurPtr);
pvCurPtr++;
}
//pcMesh->mColors[2] = NULL;
// add sub nodes
this->AddNodes(pcScene,node,node->mName.data);
aiMatrix4x4 mNewAbs = decompTrafo.mMatrix * node->mTransformation;
ASE::DecompTransform dec( mNewAbs);
this->AddNodes(node,node->mName.data,dec);
}
// allocate enough space for the child nodes
@@ -259,7 +372,7 @@ void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
return;
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::BuildNodes(aiScene* pcScene)
void ASEImporter::BuildNodes()
{
ai_assert(NULL != pcScene);
@@ -270,15 +383,18 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
pcScene->mRootNode->mName.Set("<root>");
// add all nodes
this->AddNodes(pcScene,pcScene->mRootNode,NULL);
this->AddNodes(pcScene->mRootNode,NULL);
// now iterate through al meshes and find those that have not yet
// been added to the nodegraph (= their parent could not be recognized)
std::vector<unsigned int> aiList;
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
{
// get the name of the mesh ([0] = name, [1] = parent)
std::string* szMyName = (std::string*)pcScene->mMeshes[i]->mColors[1];
// get the name of the mesh
const ASE::Mesh& mesh = *((const ASE::Mesh*)pcScene->mMeshes[i]->mColors[2]);
// TODO: experimental quick'n'dirty, clean this up ...
std::string szMyName[2] = {mesh.mName,mesh.mParent} ;
if (!szMyName)
{
continue;
@@ -289,8 +405,9 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
for (unsigned int i2 = 0; i2 < pcScene->mNumMeshes;++i2)
{
if (i2 == i)continue;
// get the name of the mesh ([0] = name, [1] = parent)
std::string* szMyName2 = (std::string*)pcScene->mMeshes[i2]->mColors[1];
const ASE::Mesh& mesh2 = *((const ASE::Mesh*)pcScene->mMeshes[i2]->mColors[2]);
// TODO: experimental quick'n'dirty, clean this up ...
std::string szMyName2[2] = {mesh2.mName,mesh2.mParent} ;
if (!szMyName2)
{
continue;
@@ -328,7 +445,7 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
aiNode* pcNode = new aiNode();
pcNode->mParent = pcScene->mRootNode;
pcNode->mName.Set(szMyName[1]);
this->AddNodes(pcScene,pcNode,szMyName[1].c_str());
this->AddNodes(pcNode,szMyName[1].c_str());
apcNodes.push_back(pcNode);
}
pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
@@ -338,6 +455,9 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size();
}
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
pcScene->mMeshes[i]->mColors[2] = NULL;
// if there is only one subnode, set it as root node
if (1 == pcScene->mRootNode->mNumChildren)
{
@@ -456,15 +576,15 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
// now need to transform all vertices with the inverse of their
// transformation matrix ...
aiMatrix4x4 mInverse = mesh.mTransform;
mInverse.Inverse();
//aiMatrix4x4 mInverse = mesh.mTransform;
//mInverse.Inverse();
for (std::vector<aiVector3D>::iterator
i = mesh.mPositions.begin();
i != mesh.mPositions.end();++i)
{
(*i) = mInverse * (*i);
}
//for (std::vector<aiVector3D>::iterator
// i = mesh.mPositions.begin();
// i != mesh.mPositions.end();++i)
//{
// (*i) = mInverse * (*i);
//}
return;
}
@@ -669,15 +789,8 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
// store the real index here ... color channel 3
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
// store the real transformation matrix in color channel 2
p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
// store the name of the mesh and the
// name of its parent in color channel 1
p_pcOut->mColors[1] = (aiColor4D*) new std::string[2];
((std::string*)p_pcOut->mColors[1])[0] = mesh.mName;
((std::string*)p_pcOut->mColors[1])[1] = mesh.mParent;
// store a pointer to the mesh in color channel 2
p_pcOut->mColors[2] = (aiColor4D*) &mesh;
avOutMeshes.push_back(p_pcOut);
// convert vertices
@@ -821,15 +934,17 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
// store the real index here ... in color channel 3
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
// store the transformation matrix in color channel 2
p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
// store a pointer to the mesh in color channel 2
p_pcOut->mColors[2] = (aiColor4D*) &mesh;
avOutMeshes.push_back(p_pcOut);
// store the name of the mesh and the
// name of its parent in color channel 1
p_pcOut->mColors[1] = (aiColor4D*) new std::string[2];
((std::string*)p_pcOut->mColors[1])[0] = mesh.mName;
((std::string*)p_pcOut->mColors[1])[1] = mesh.mParent;
// if the mesh hasn't faces or vertices, there are two cases
// possible: 1. the model is invalid. 2. This is a dummy
// helper object which we are going to remove later ...
if (mesh.mFaces.empty() || mesh.mPositions.empty())
{
return;
}
// convert vertices
p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
@@ -951,7 +1066,7 @@ void ComputeBounds(ASE::Mesh& mesh,aiVector3D& minVec, aiVector3D& maxVec,
return;
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::BuildMaterialIndices(aiScene* pcScene)
void ASEImporter::BuildMaterialIndices()
{
ai_assert(NULL != pcScene);
@@ -1033,7 +1148,7 @@ void ASEImporter::BuildMaterialIndices(aiScene* pcScene)
}
}
// prepare for the next step
for (unsigned int hans = 0; hans < pcScene->mNumMaterials;++hans)
for (unsigned int hans = 0; hans < this->mParser->m_vMaterials.size();++hans)
{
TextureTransform::ApplyScaleNOffset(this->mParser->m_vMaterials[hans]);
}
+14 -7
View File
@@ -130,24 +130,28 @@ protected:
// -------------------------------------------------------------------
/** Setup the final material indices for each mesh
* \param pcScene Scene object to be filled
*/
void BuildMaterialIndices(aiScene* pcScene);
void BuildMaterialIndices();
// -------------------------------------------------------------------
/** Build the node graph
* \param pcScene Scene object to be filled
*/
void BuildNodes(aiScene* pcScene);
void BuildNodes();
// -------------------------------------------------------------------
/** Build output animations
*/
void BuildAnimations();
// -------------------------------------------------------------------
/** Add sub nodes to a node
* \param pcScene Scene object to be filled
* \param pcParent parent node to be filled
* \param szName Name of the parent node
* \param decompTrafo Decomposed absolute parent transformation mat
*/
void AddNodes(aiScene* pcScene,aiNode* pcParent,
const char* szName);
void AddNodes(aiNode* pcParent,const char* szName);
void AddNodes(aiNode* pcParent,const char* szName,
const ASE::DecompTransform& decompTrafo);
// -------------------------------------------------------------------
/** Generate a default material and add it to the parser's list
@@ -166,6 +170,9 @@ protected:
/** true if this is an .ask file */
bool mIsAsk;
/** Scene to be filled */
aiScene* pcScene;
};
} // end of namespace Assimp
+249 -296
View File
@@ -67,6 +67,44 @@ using namespace Assimp::ASE;
#define BLUBB(_message_) \
{this->LogError(_message_);return;}
#define AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth) \
else if ('{' == *this->m_szFile)iDepth++; \
else if ('}' == *this->m_szFile) \
{ \
if (0 == --iDepth) \
{ \
++this->m_szFile; \
this->SkipToNextToken(); \
return; \
} \
} \
else if ('\0' == *this->m_szFile) \
{ \
return; \
} \
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber; \
++this->m_szFile;
#define AI_ASE_HANDLE_SECTION(iDepth, level, msg) \
else if ('{' == *this->m_szFile)iDepth++; \
else if ('}' == *this->m_szFile) \
{ \
if (0 == --iDepth) \
{ \
++this->m_szFile; \
this->SkipToNextToken(); \
return; \
} \
} \
else if ('\0' == *this->m_szFile) \
{ \
this->LogError("Encountered unexpected EOL while parsing a " msg \
" chunk (Level " level ")"); \
} \
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber; \
++this->m_szFile;
// ------------------------------------------------------------------------------------------------
Parser::Parser (const char* szFile)
{
@@ -78,6 +116,10 @@ Parser::Parser (const char* szFile)
this->m_clrAmbient.r = std::numeric_limits<float>::quiet_NaN();
this->iLineNumber = 0;
this->iFirstFrame = 0;
this->iLastFrame = 0;
this->iFrameSpeed = 30; // use 30 as default value for this property
this->iTicksPerFrame = 1; // use 1 as default value for this property
}
// ------------------------------------------------------------------------------------------------
void Parser::LogWarning(const char* szWarn)
@@ -234,6 +276,15 @@ void Parser::Parse()
this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back());
continue;
}
// helper object = dummy in the hierarchy
if (0 == strncmp(this->m_szFile,"*HELPEROBJECT",13) &&
IsSpaceOrNewLine(*(this->m_szFile+13)))
{
this->m_szFile+=14;
this->m_vMeshes.push_back(Mesh());
this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back());
continue;
}
// ignore comments, lights and cameras
// (display comments on the console)
if (0 == strncmp(this->m_szFile,"*LIGHTOBJECT",12) &&
@@ -260,18 +311,7 @@ void Parser::Parse()
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... why not?
return;
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
@@ -301,19 +341,36 @@ void Parser::ParseLV1SceneBlock()
this->ParseLV4MeshFloatTriple( &this->m_clrAmbient.r );
continue;
}
if (0 == strncmp(this->m_szFile,"*SCENE_FIRSTFRAME",17) &&
IsSpaceOrNewLine(*(this->m_szFile+17)))
{
this->m_szFile+=18;
this->ParseLV4MeshLong(this->iFirstFrame);
continue;
}
if (0 == strncmp(this->m_szFile,"*SCENE_LASTFRAME",16) &&
IsSpaceOrNewLine(*(this->m_szFile+16)))
{
this->m_szFile+=17;
this->ParseLV4MeshLong(this->iLastFrame);
continue;
}
if (0 == strncmp(this->m_szFile,"*SCENE_FRAMESPEED",17) &&
IsSpaceOrNewLine(*(this->m_szFile+17)))
{
this->m_szFile+=18;
this->ParseLV4MeshLong(this->iFrameSpeed);
continue;
}
if (0 == strncmp(this->m_szFile,"*SCENE_TICKSPERFRAME",20) &&
IsSpaceOrNewLine(*(this->m_szFile+20)))
{
this->m_szFile+=21;
this->ParseLV4MeshLong(this->iTicksPerFrame);
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... why not?
return;
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
@@ -361,18 +418,7 @@ void Parser::ParseLV1MaterialListBlock()
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... why not?
return;
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
@@ -594,18 +640,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level2 block, this can't be
BLUBB("Unable to finish parsing a lv2 material block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"2","*MATERIAL");
}
return;
}
@@ -669,18 +704,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
this->ParseLV4MeshFloat(map.mTextureBlend);continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing a lv3 map block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MAP_XXXXXX");
}
return;
}
@@ -788,23 +812,99 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
this->m_szFile+=14;
this->ParseLV4MeshLong(mesh.iMaterialIndex);continue;
}
// animation data of the node
if (0 == strncmp(this->m_szFile,"*TM_ANIMATION" ,13) &&
IsSpaceOrNewLine(*(this->m_szFile+13)))
{
this->m_szFile+=14;
this->ParseLV2AnimationBlock(mesh);continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level1 block, this can be
return;
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_TOP_LEVEL_SECTION(iDepth);
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV2AnimationBlock(ASE::Mesh& mesh)
{
int iDepth = 0;
while (true)
{
if ('*' == *this->m_szFile)
{
// position keyframes
if (0 == strncmp(this->m_szFile,"*CONTROL_POS_TRACK" ,18) &&
IsSpaceOrNewLine(*(this->m_szFile+18)))
{
this->m_szFile+=19;
this->ParseLV3PosAnimationBlock(mesh);continue;
}
// rotation keyframes
if (0 == strncmp(this->m_szFile,"*CONTROL_ROT_TRACK" ,18) &&
IsSpaceOrNewLine(*(this->m_szFile+18)))
{
this->m_szFile+=19;
this->ParseLV3RotAnimationBlock(mesh);continue;
}
}
AI_ASE_HANDLE_SECTION(iDepth,"2","TM_ANIMATION");
}
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3PosAnimationBlock(ASE::Mesh& mesh)
{
int iDepth = 0;
while (true)
{
if ('*' == *this->m_szFile)
{
// position keyframe
if (0 == strncmp(this->m_szFile,"*CONTROL_POS_SAMPLE" ,19) &&
IsSpaceOrNewLine(*(this->m_szFile+19)))
{
this->m_szFile+=20;
unsigned int iIndex;
mesh.mAnim.akeyPositions.push_back(aiVectorKey());
aiVectorKey& key = mesh.mAnim.akeyPositions.back();
this->ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
key.mTime = (double)iIndex;
}
}
AI_ASE_HANDLE_SECTION(iDepth,"3","*CONTROL_POS_TRACK");
}
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3RotAnimationBlock(ASE::Mesh& mesh)
{
int iDepth = 0;
while (true)
{
if ('*' == *this->m_szFile)
{
// rotation keyframe
if (0 == strncmp(this->m_szFile,"*CONTROL_ROT_SAMPLE" ,19) &&
IsSpaceOrNewLine(*(this->m_szFile+19)))
{
this->m_szFile+=20;
unsigned int iIndex;
mesh.mAnim.akeyRotations.push_back(aiQuatKey());
aiQuatKey& key = mesh.mAnim.akeyRotations.back();
// first read the axis, then the angle in radians
aiVector3D v;float f;
this->ParseLV4MeshFloatTriple(&v.x,iIndex);
this->ParseLV4MeshFloat(f);
key.mTime = (double)iIndex;
key.mValue = aiQuaternion(v,f);
}
}
AI_ASE_HANDLE_SECTION(iDepth,"3","*CONTROL_ROT_TRACK");
}
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
{
int iDepth = 0;
@@ -840,19 +940,44 @@ void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
this->m_szFile+=9;
this->ParseLV4MeshFloatTriple(mesh.mTransform[3]);continue;
}
// inherited position axes
if (0 == strncmp(this->m_szFile,"*INHERIT_POS" ,12) &&
IsSpaceOrNewLine(*(this->m_szFile+12)))
{
this->m_szFile+=13;
unsigned int aiVal[3];
this->ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
continue;
}
// inherited rotation axes
if (0 == strncmp(this->m_szFile,"*INHERIT_ROT" ,12) &&
IsSpaceOrNewLine(*(this->m_szFile+12)))
{
this->m_szFile+=13;
unsigned int aiVal[3];
this->ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
continue;
}
// inherited scaling axes
if (0 == strncmp(this->m_szFile,"*INHERIT_SCL" ,12) &&
IsSpaceOrNewLine(*(this->m_szFile+12)))
{
this->m_szFile+=13;
unsigned int aiVal[3];
this->ParseLV4MeshLongTriple(aiVal);
for (unsigned int i = 0; i < 3;++i)
mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level2 block, this can't be
BLUBB("Unable to finish parsing a lv2 node transform block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"2","*NODE_TM");
}
return;
}
@@ -1015,18 +1140,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
this->ParseLV3MeshWeightsBlock(mesh);continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level2 block, this can't be
BLUBB("Unable to finish parsing a lv2 mesh block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"2","*MESH");
}
return;
}
@@ -1072,18 +1186,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level2 block, this can't be
BLUBB("Unable to finish parsing a lv2 *MESH_WEIGHTS block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_WEIGHTS");
}
return;
}
@@ -1118,18 +1221,7 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
}
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level4 block, this can't be
BLUBB("Unable to finish parsing a lv4 *MESH_BONE_LIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_BONE_LIST");
}
}
// ------------------------------------------------------------------------------------------------
@@ -1183,18 +1275,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level4 block, this can't be
BLUBB("Unable to finish parsing a lv4 *MESH_BONE_VERTEX_LIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"4","*MESH_BONE_VERTEX");
}
return;
}
@@ -1227,18 +1308,7 @@ void Parser::ParseLV3MeshVertexListBlock(
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing a lv3 vertex list block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_VERTEX_LIST");
}
return;
}
@@ -1269,18 +1339,7 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing LV3 *MESH_FACE_LIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_FACE_LIST");
}
return;
}
@@ -1319,18 +1378,7 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing LV3 *MESH_VERTEX_LIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_TVERT_LIST");
}
return;
}
@@ -1367,18 +1415,7 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing LV3 *MESH_TFACELIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_TFACE_LIST");
}
return;
}
@@ -1426,18 +1463,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level2 block, this can't be
BLUBB("Unable to finish parsing a LV3 *MESH_MAPPINGCHANNEL block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_MAPPING_CHANNEL");
}
return;
}
@@ -1470,18 +1496,7 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
continue;
}
}
if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing LV3 *MESH_CVERTLIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_CVERTEX_LIST");
}
return;
}
@@ -1517,18 +1532,7 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
else if ('\0' == *this->m_szFile)
{
// END OF FILE ... this is a level3 block, this can't be
BLUBB("Unable to finish parsing LV3 *MESH_CFACELIST block. Unexpected EOF")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
++this->m_szFile;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_CFACE_LIST");
}
return;
}
@@ -1545,7 +1549,8 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
{
if ('*' == *this->m_szFile)
{
if (0 == strncmp(this->m_szFile,"*MESH_VERTEXNORMAL",18) && IsSpaceOrNewLine(*(this->m_szFile+18)))
if (0 == strncmp(this->m_szFile,"*MESH_VERTEXNORMAL",18) &&
IsSpaceOrNewLine(*(this->m_szFile+18)))
{
this->m_szFile += 19;
@@ -1565,18 +1570,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
continue;
}
}
else if ('{' == *this->m_szFile)iDepth++;
else if ('}' == *this->m_szFile)
{
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
}
// seems we have reached the end of the file ...
else if ('\0' == *this->m_szFile)
{
BLUBB("Unable to parse *MESH_NORMALS Element: Unexpected EOL [#1]")
}
else if(IsLineEnd(*this->m_szFile))++this->iLineNumber;
this->m_szFile++;
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_NORMALS");
}
return;
}
@@ -1729,40 +1723,19 @@ void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
{
ai_assert(NULL != apOut);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
for (unsigned int i = 0; i < 3;++i)
{
// LOG
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#1]");
++this->iLineNumber;
apOut[0] = apOut[1] = apOut[2] = 0;
return;
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#1]");
++this->iLineNumber;
apOut[0] = apOut[1] = apOut[2] = 0;
return;
}
apOut[i] = strtol10(this->m_szFile,&this->m_szFile);
}
apOut[0] = strtol10(this->m_szFile,&this->m_szFile);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#2]");
++this->iLineNumber;
apOut[1] = apOut[2] = 0;
return;
}
apOut[1] = strtol10(this->m_szFile,&this->m_szFile);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#3]");
apOut[2] = 0;
++this->iLineNumber;
return;
}
apOut[2] = strtol10(this->m_szFile,&this->m_szFile);
// go to the next valid sequence
//SkipSpacesAndLineEnd(this->m_szFile,&this->m_szFile);
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut)
@@ -1773,7 +1746,7 @@ void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#4]");
this->LogWarning("Unable to parse indexed long triple: unexpected EOL [#4]");
rIndexOut = 0;
apOut[0] = apOut[1] = apOut[2] = 0;
++this->iLineNumber;
@@ -1795,7 +1768,7 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse indexable float triple: unexpected EOL [#1]");
this->LogWarning("Unable to parse indexed float triple: unexpected EOL [#1]");
rIndexOut = 0;
apOut[0] = apOut[1] = apOut[2] = 0.0f;
++this->iLineNumber;
@@ -1812,41 +1785,21 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
void Parser::ParseLV4MeshFloatTriple(float* apOut)
{
ai_assert(NULL != apOut);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
for (unsigned int i = 0; i < 3;++i)
{
// LOG
this->LogWarning("Unable to parse float triple: unexpected EOL [#5]");
apOut[0] = apOut[1] = apOut[2] = 0.0f;
++this->iLineNumber;
return;
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse float triple: unexpected EOL [#5]");
apOut[0] = apOut[1] = apOut[2] = 0.0f;
++this->iLineNumber;
return;
}
// parse the float
this->m_szFile = fast_atof_move(this->m_szFile,apOut[i]);
}
// parse the first float
this->m_szFile = fast_atof_move(this->m_szFile,apOut[0]);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse float triple: unexpected EOL [#6]");
apOut[1] = apOut[2] = 0.0f;
++this->iLineNumber;
return;
}
// parse the second float
this->m_szFile = fast_atof_move(this->m_szFile,apOut[1]);
// skip spaces and tabs
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
{
// LOG
this->LogWarning("Unable to parse float triple: unexpected EOL [#7]");
apOut[2] = 0.0f;
++this->iLineNumber;
return;
}
// parse the third float
this->m_szFile = fast_atof_move(this->m_szFile,apOut[2]);
// go to the next valid sequence
//this->SkipToNextToken();
return;
}
// ------------------------------------------------------------------------------------------------
+104 -7
View File
@@ -43,17 +43,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_ASEFILEHELPER_H_INC
#define AI_ASEFILEHELPER_H_INC
// STL/CRT headers
#include <string>
#include <vector>
#include <list>
#include <sstream>
// public ASSIMP headers
#include "../include/aiTypes.h"
#include "../include/aiMesh.h"
#include "../include/aiAnim.h"
// for some helper routines like IsSpace()
#include "PlyParser.h"
#include "qnan.h"
// ASE is quite similar to 3ds. We can reuse some structures
#include "3DSLoader.h"
@@ -130,9 +132,10 @@ struct Bone
Bone()
{
static int iCnt = 0;
std::stringstream ss(mName);
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
ss.flush();
char szTemp[128];
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
mName = szTemp;
}
//! Name of the bone
@@ -152,6 +155,73 @@ struct BoneVertex
//aiVector3D mPosition;
};
// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file animation */
struct Animation
{
//! List of rotation keyframes
std::vector< aiQuatKey > akeyRotations;
//! List of position keyframes
std::vector< aiVectorKey > akeyPositions;
};
// ---------------------------------------------------------------------------
/** Helper structure to represent the inheritance information of an ASE node */
struct InheritanceInfo
{
//! Default constructor
InheritanceInfo()
{
// set the inheritance flag for all axes by default to true
for (unsigned int i = 0; i < 3;++i)
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
}
//! Inherit the parent's position?, axis order is x,y,z
bool abInheritPosition[3];
//! Inherit the parent's rotation?, axis order is x,y,z
bool abInheritRotation[3];
//! Inherit the parent's scaling?, axis order is x,y,z
bool abInheritScaling[3];
};
// ---------------------------------------------------------------------------
/** Stores a decomposed transformation matrix */
struct DecompTransform
{
//! Construction from a reference to an existing matrix
DecompTransform(aiMatrix4x4& ref)
: vScaling(1.0f,1.0f,1.0f)
, vPosition(std::numeric_limits<float>::quiet_NaN(),0.0f,0.0f)
, mMatrix(ref)
{}
//! Translational component
mutable aiVector3D vPosition;
//! Rotational component
mutable aiQuaternion qRotation;
//! Scaling component
mutable aiVector3D vScaling;
//! Reference to the matrix being decomposed
const aiMatrix4x4& mMatrix;
//! Decomposes the matrix if this has not yet been done
inline void NeedDecomposedMatrixNOW() const
{
if (is_qnan(vPosition.x))
{
mMatrix.Decompose(vScaling,qRotation,vPosition);
}
}
};
// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file mesh */
struct Mesh
@@ -160,9 +230,9 @@ struct Mesh
Mesh() : bSkip(false)
{
static int iCnt = 0;
std::stringstream ss(mName);
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
ss.flush();
char szTemp[128];
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
mName = szTemp;
// use 2 texture vertex components by default
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
@@ -203,6 +273,9 @@ struct Mesh
//! Transformation matrix of the mesh
aiMatrix4x4 mTransform;
//! Animation channels for the node
Animation mAnim;
//! Material index of the mesh
unsigned int iMaterialIndex;
@@ -211,6 +284,10 @@ struct Mesh
//! used internally
bool bSkip;
//! Specifies which axes transformations a node inherits
//! from its parent ...
InheritanceInfo inherit;
};
// ---------------------------------------------------------------------------------
@@ -259,6 +336,13 @@ private:
//! \param mesh Mesh object to be filled
void ParseLV2NodeTransformBlock(Mesh& mesh);
// -------------------------------------------------------------------
//! Parse a *TM_ANIMATION block in a file
//! \param mesh Mesh object to be filled
void ParseLV2AnimationBlock(Mesh& mesh);
void ParseLV3PosAnimationBlock(Mesh& mesh);
void ParseLV3RotAnimationBlock(Mesh& mesh);
// -------------------------------------------------------------------
//! Parse a *MESH block in a file
//! \param mesh Mesh object to be filled
@@ -453,6 +537,19 @@ public:
//! Current line in the file
unsigned int iLineNumber;
//! First frame
unsigned int iFirstFrame;
//! Last frame
unsigned int iLastFrame;
//! Frame speed - frames per second
unsigned int iFrameSpeed;
//! Ticks per frame
unsigned int iTicksPerFrame;
};
+1 -2
View File
@@ -110,8 +110,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh)
// what we can check, though, is if the mesh has normals and texture coord. That's a requirement
if( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL)
{
DefaultLogger::get()->error("Normal vectors and at least one "
"texture coordinate set are required to calculate tangents. ");
DefaultLogger::get()->error("Unable to compute tangents: UV0 and normals must be there ");
return false;
}
+10 -4
View File
@@ -42,20 +42,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the post processing step to validate
* the data structure returned by Assimp
*/
// STL headers
#include <vector>
#include <assert.h>
// internal headers
#include "ValidateDataStructure.h"
#include "BaseImporter.h"
#include "StringComparison.h"
#include "fast_atof.h"
// public ASSIMP headers
#include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
#include "../include/aiAssert.h"
// CRT headers
#include <stdarg.h>
using namespace Assimp;
@@ -128,7 +133,7 @@ void ValidateDSProcess::ReportWarning(const char* msg,...)
throw new ImportErrorException("Idiot ... learn coding!");
}
va_end(args);
DefaultLogger::get()->warn("Validation failed: " + std::string(szBuffer,iLen));
DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
@@ -286,7 +291,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
{
if (face.mIndices[a] >= pMesh->mNumVertices)
{
this->ReportError("aiMesh::mFaces[%i]::mIndices[%a] is out of range",i,a);
this->ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
}
if (abRefList[face.mIndices[a]])
{
@@ -636,6 +641,7 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
{
this->Validate(&pBoneAnim->mBoneName);
#if 0
// check whether there is a bone with this name ...
unsigned int i = 0;
for (; i < this->mScene->mNumMeshes;++i)
@@ -650,14 +656,14 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
__break_out:
if (i == this->mScene->mNumMeshes)
{
this->ReportWarning("aiBoneAnim::mBoneName is %s. However, no bone with this name was found",
this->ReportWarning("aiBoneAnim::mBoneName is \"%s\". However, no bone with this name was found",
pBoneAnim->mBoneName.data);
}
if (!pBoneAnim->mNumPositionKeys && !pBoneAnim->mNumRotationKeys && !pBoneAnim->mNumScalingKeys)
{
this->ReportWarning("A bone animation channel has no keys");
}
#endif
// otherwise check whether one of the keys exceeds the total duration of the animation
if (pBoneAnim->mNumPositionKeys)
{