Small update to the ASE loader.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@64 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
fc8a8b54f9
commit
6ad0892396
|
@ -126,6 +126,7 @@ void ASEImporter::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 unsigned char[fileSize+1];
|
this->mBuffer = new unsigned char[fileSize+1];
|
||||||
|
this->pcScene = pScene;
|
||||||
file->Read( (void*)mBuffer, 1, fileSize);
|
file->Read( (void*)mBuffer, 1, fileSize);
|
||||||
this->mBuffer[fileSize] = '\0';
|
this->mBuffer[fileSize] = '\0';
|
||||||
|
|
||||||
|
@ -135,10 +136,7 @@ void ASEImporter::InternReadFile(
|
||||||
|
|
||||||
// if absolutely no material has been loaded from the file
|
// if absolutely no material has been loaded from the file
|
||||||
// we need to generate a default material
|
// we need to generate a default material
|
||||||
if (this->mParser->m_vMaterials.empty())
|
this->GenerateDefaultMaterial();
|
||||||
{
|
|
||||||
this->GenerateDefaultMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
// process all meshes
|
// process all meshes
|
||||||
std::vector<aiMesh*> avOutMeshes;
|
std::vector<aiMesh*> avOutMeshes;
|
||||||
|
@ -165,17 +163,26 @@ void ASEImporter::InternReadFile(
|
||||||
this->ConvertMeshes(*i,avOutMeshes);
|
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->mNumMeshes = (unsigned int)avOutMeshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (std::vector<aiMesh*>::const_iterator
|
||||||
pScene->mMeshes[i] = avOutMeshes[i];
|
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)
|
// buil final material indices (remove submaterials and make the final list)
|
||||||
this->BuildMaterialIndices(pScene);
|
this->BuildMaterialIndices();
|
||||||
|
|
||||||
// build the final node graph
|
// build the final node graph
|
||||||
this->BuildNodes(pScene);
|
this->BuildNodes();
|
||||||
|
|
||||||
|
// build output animations
|
||||||
|
this->BuildAnimations();
|
||||||
|
|
||||||
// delete the ASE parser
|
// delete the ASE parser
|
||||||
delete this->mParser;
|
delete this->mParser;
|
||||||
|
@ -187,28 +194,120 @@ void ASEImporter::GenerateDefaultMaterial()
|
||||||
{
|
{
|
||||||
ai_assert(NULL != this->mParser);
|
ai_assert(NULL != this->mParser);
|
||||||
|
|
||||||
// add a simple material without sub materials to the parser's list
|
bool bHas = false;
|
||||||
this->mParser->m_vMaterials.push_back ( ASE::Material() );
|
for (std::vector<ASE::Mesh>::iterator
|
||||||
ASE::Material& mat = this->mParser->m_vMaterials.back();
|
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.mDiffuse = aiColor3D(0.5f,0.5f,0.5f);
|
||||||
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
|
mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
|
||||||
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
|
mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
|
||||||
mat.mShading = Dot3DSFile::Gouraud;
|
mat.mShading = Dot3DSFile::Gouraud;
|
||||||
mat.mName = AI_DEFAULT_MATERIAL_NAME;
|
mat.mName = AI_DEFAULT_MATERIAL_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
|
void ASEImporter::BuildAnimations()
|
||||||
const char* szName)
|
{
|
||||||
|
// 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;
|
const size_t len = szName ? strlen(szName) : 0;
|
||||||
|
|
||||||
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
|
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
|
||||||
std::vector<aiNode*> apcNodes;
|
std::vector<aiNode*> apcNodes;
|
||||||
|
aiMesh** pcMeshes = pcScene->mMeshes;
|
||||||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
// get the name of the mesh ([0] = name, [1] = parent)
|
// get the name of the mesh
|
||||||
std::string* szMyName = (std::string*)pcScene->mMeshes[i]->mColors[1];
|
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)
|
if (!szMyName)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -226,25 +325,39 @@ void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
|
||||||
apcNodes.push_back(new aiNode());
|
apcNodes.push_back(new aiNode());
|
||||||
aiNode* node = apcNodes.back();
|
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->mName.Set(szMyName[0]);
|
||||||
node->mNumMeshes = 1;
|
node->mNumMeshes = 1;
|
||||||
node->mMeshes = new unsigned int[1];
|
node->mMeshes = new unsigned int[1];
|
||||||
node->mMeshes[0] = i;
|
node->mMeshes[0] = i;
|
||||||
node->mParent = pcParent;
|
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;
|
aiMatrix4x4 mParentAdjust = decompTrafo.mMatrix;
|
||||||
pcScene->mMeshes[i]->mColors[1] = NULL;
|
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
|
// 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
|
// allocate enough space for the child nodes
|
||||||
|
@ -259,7 +372,7 @@ void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ASEImporter::BuildNodes(aiScene* pcScene)
|
void ASEImporter::BuildNodes()
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcScene);
|
ai_assert(NULL != pcScene);
|
||||||
|
|
||||||
|
@ -270,15 +383,18 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
|
||||||
pcScene->mRootNode->mName.Set("<root>");
|
pcScene->mRootNode->mName.Set("<root>");
|
||||||
|
|
||||||
// add all nodes
|
// 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
|
// now iterate through al meshes and find those that have not yet
|
||||||
// been added to the nodegraph (= their parent could not be recognized)
|
// been added to the nodegraph (= their parent could not be recognized)
|
||||||
std::vector<unsigned int> aiList;
|
std::vector<unsigned int> aiList;
|
||||||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||||
{
|
{
|
||||||
// get the name of the mesh ([0] = name, [1] = parent)
|
// get the name of the mesh
|
||||||
std::string* szMyName = (std::string*)pcScene->mMeshes[i]->mColors[1];
|
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)
|
if (!szMyName)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -289,8 +405,9 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
|
||||||
for (unsigned int i2 = 0; i2 < pcScene->mNumMeshes;++i2)
|
for (unsigned int i2 = 0; i2 < pcScene->mNumMeshes;++i2)
|
||||||
{
|
{
|
||||||
if (i2 == i)continue;
|
if (i2 == i)continue;
|
||||||
// get the name of the mesh ([0] = name, [1] = parent)
|
const ASE::Mesh& mesh2 = *((const ASE::Mesh*)pcScene->mMeshes[i2]->mColors[2]);
|
||||||
std::string* szMyName2 = (std::string*)pcScene->mMeshes[i2]->mColors[1];
|
// TODO: experimental quick'n'dirty, clean this up ...
|
||||||
|
std::string szMyName2[2] = {mesh2.mName,mesh2.mParent} ;
|
||||||
if (!szMyName2)
|
if (!szMyName2)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -328,7 +445,7 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
|
||||||
aiNode* pcNode = new aiNode();
|
aiNode* pcNode = new aiNode();
|
||||||
pcNode->mParent = pcScene->mRootNode;
|
pcNode->mParent = pcScene->mRootNode;
|
||||||
pcNode->mName.Set(szMyName[1]);
|
pcNode->mName.Set(szMyName[1]);
|
||||||
this->AddNodes(pcScene,pcNode,szMyName[1].c_str());
|
this->AddNodes(pcNode,szMyName[1].c_str());
|
||||||
apcNodes.push_back(pcNode);
|
apcNodes.push_back(pcNode);
|
||||||
}
|
}
|
||||||
pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
|
pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
|
||||||
|
@ -338,6 +455,9 @@ void ASEImporter::BuildNodes(aiScene* pcScene)
|
||||||
pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size();
|
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 there is only one subnode, set it as root node
|
||||||
if (1 == pcScene->mRootNode->mNumChildren)
|
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
|
// now need to transform all vertices with the inverse of their
|
||||||
// transformation matrix ...
|
// transformation matrix ...
|
||||||
aiMatrix4x4 mInverse = mesh.mTransform;
|
//aiMatrix4x4 mInverse = mesh.mTransform;
|
||||||
mInverse.Inverse();
|
//mInverse.Inverse();
|
||||||
|
|
||||||
for (std::vector<aiVector3D>::iterator
|
//for (std::vector<aiVector3D>::iterator
|
||||||
i = mesh.mPositions.begin();
|
// i = mesh.mPositions.begin();
|
||||||
i != mesh.mPositions.end();++i)
|
// i != mesh.mPositions.end();++i)
|
||||||
{
|
//{
|
||||||
(*i) = mInverse * (*i);
|
// (*i) = mInverse * (*i);
|
||||||
}
|
//}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -669,15 +789,8 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
|
||||||
// store the real index here ... color channel 3
|
// store the real index here ... color channel 3
|
||||||
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
|
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
|
||||||
|
|
||||||
// store the real transformation matrix in color channel 2
|
// store a pointer to the mesh in color channel 2
|
||||||
p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
|
p_pcOut->mColors[2] = (aiColor4D*) &mesh;
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
avOutMeshes.push_back(p_pcOut);
|
avOutMeshes.push_back(p_pcOut);
|
||||||
|
|
||||||
// convert vertices
|
// 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
|
// store the real index here ... in color channel 3
|
||||||
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
|
p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
|
||||||
|
|
||||||
// store the transformation matrix in color channel 2
|
// store a pointer to the mesh in color channel 2
|
||||||
p_pcOut->mColors[2] = (aiColor4D*) new aiMatrix4x4(mesh.mTransform);
|
p_pcOut->mColors[2] = (aiColor4D*) &mesh;
|
||||||
avOutMeshes.push_back(p_pcOut);
|
avOutMeshes.push_back(p_pcOut);
|
||||||
|
|
||||||
// store the name of the mesh and the
|
// if the mesh hasn't faces or vertices, there are two cases
|
||||||
// name of its parent in color channel 1
|
// possible: 1. the model is invalid. 2. This is a dummy
|
||||||
p_pcOut->mColors[1] = (aiColor4D*) new std::string[2];
|
// helper object which we are going to remove later ...
|
||||||
((std::string*)p_pcOut->mColors[1])[0] = mesh.mName;
|
if (mesh.mFaces.empty() || mesh.mPositions.empty())
|
||||||
((std::string*)p_pcOut->mColors[1])[1] = mesh.mParent;
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// convert vertices
|
// convert vertices
|
||||||
p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
|
p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
|
||||||
|
@ -951,7 +1066,7 @@ void ComputeBounds(ASE::Mesh& mesh,aiVector3D& minVec, aiVector3D& maxVec,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ASEImporter::BuildMaterialIndices(aiScene* pcScene)
|
void ASEImporter::BuildMaterialIndices()
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcScene);
|
ai_assert(NULL != pcScene);
|
||||||
|
|
||||||
|
@ -1033,7 +1148,7 @@ void ASEImporter::BuildMaterialIndices(aiScene* pcScene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prepare for the next step
|
// 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]);
|
TextureTransform::ApplyScaleNOffset(this->mParser->m_vMaterials[hans]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,24 +130,28 @@ protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Setup the final material indices for each mesh
|
/** 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
|
/** 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
|
/** Add sub nodes to a node
|
||||||
* \param pcScene Scene object to be filled
|
|
||||||
* \param pcParent parent node to be filled
|
* \param pcParent parent node to be filled
|
||||||
* \param szName Name of the parent node
|
* \param szName Name of the parent node
|
||||||
|
* \param decompTrafo Decomposed absolute parent transformation mat
|
||||||
*/
|
*/
|
||||||
void AddNodes(aiScene* pcScene,aiNode* pcParent,
|
void AddNodes(aiNode* pcParent,const char* szName);
|
||||||
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
|
/** Generate a default material and add it to the parser's list
|
||||||
|
@ -166,6 +170,9 @@ protected:
|
||||||
|
|
||||||
/** true if this is an .ask file */
|
/** true if this is an .ask file */
|
||||||
bool mIsAsk;
|
bool mIsAsk;
|
||||||
|
|
||||||
|
/** Scene to be filled */
|
||||||
|
aiScene* pcScene;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -67,6 +67,44 @@ using namespace Assimp::ASE;
|
||||||
#define BLUBB(_message_) \
|
#define BLUBB(_message_) \
|
||||||
{this->LogError(_message_);return;}
|
{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)
|
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->m_clrAmbient.r = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
|
||||||
this->iLineNumber = 0;
|
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)
|
void Parser::LogWarning(const char* szWarn)
|
||||||
|
@ -234,6 +276,15 @@ void Parser::Parse()
|
||||||
this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back());
|
this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back());
|
||||||
continue;
|
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
|
// ignore comments, lights and cameras
|
||||||
// (display comments on the console)
|
// (display comments on the console)
|
||||||
if (0 == strncmp(this->m_szFile,"*LIGHTOBJECT",12) &&
|
if (0 == strncmp(this->m_szFile,"*LIGHTOBJECT",12) &&
|
||||||
|
@ -260,18 +311,7 @@ void Parser::Parse()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION(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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -301,19 +341,36 @@ void Parser::ParseLV1SceneBlock()
|
||||||
this->ParseLV4MeshFloatTriple( &this->m_clrAmbient.r );
|
this->ParseLV4MeshFloatTriple( &this->m_clrAmbient.r );
|
||||||
continue;
|
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++;
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION(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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -361,18 +418,7 @@ void Parser::ParseLV1MaterialListBlock()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION(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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -594,18 +640,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"2","*MATERIAL");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -669,18 +704,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
|
||||||
this->ParseLV4MeshFloat(map.mTextureBlend);continue;
|
this->ParseLV4MeshFloat(map.mTextureBlend);continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MAP_XXXXXX");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -788,23 +812,99 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
|
||||||
this->m_szFile+=14;
|
this->m_szFile+=14;
|
||||||
this->ParseLV4MeshLong(mesh.iMaterialIndex);continue;
|
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++;
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION(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;
|
|
||||||
}
|
}
|
||||||
return;
|
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)
|
void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
|
||||||
{
|
{
|
||||||
int iDepth = 0;
|
int iDepth = 0;
|
||||||
|
@ -840,19 +940,44 @@ void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
|
||||||
this->m_szFile+=9;
|
this->m_szFile+=9;
|
||||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[3]);continue;
|
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++;
|
AI_ASE_HANDLE_SECTION(iDepth,"2","*NODE_TM");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1015,18 +1140,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||||
this->ParseLV3MeshWeightsBlock(mesh);continue;
|
this->ParseLV3MeshWeightsBlock(mesh);continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"2","*MESH");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1072,18 +1186,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_WEIGHTS");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1118,18 +1221,7 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_BONE_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1183,18 +1275,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"4","*MESH_BONE_VERTEX");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1227,18 +1308,7 @@ void Parser::ParseLV3MeshVertexListBlock(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_VERTEX_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1269,18 +1339,7 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_FACE_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1319,18 +1378,7 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_TVERT_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1367,18 +1415,7 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_TFACE_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1426,18 +1463,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_MAPPING_CHANNEL");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1470,18 +1496,7 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_CVERTEX_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1517,18 +1532,7 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_CFACE_LIST");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1545,7 +1549,8 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
|
||||||
{
|
{
|
||||||
if ('*' == *this->m_szFile)
|
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;
|
this->m_szFile += 19;
|
||||||
|
|
||||||
|
@ -1565,18 +1570,7 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ('{' == *this->m_szFile)iDepth++;
|
AI_ASE_HANDLE_SECTION(iDepth,"3","*MESH_NORMALS");
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1729,40 +1723,19 @@ void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != apOut);
|
ai_assert(NULL != apOut);
|
||||||
|
|
||||||
// skip spaces and tabs
|
for (unsigned int i = 0; i < 3;++i)
|
||||||
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
|
||||||
{
|
{
|
||||||
// LOG
|
// skip spaces and tabs
|
||||||
this->LogWarning("Unable to parse indexable long triple: unexpected EOL [#1]");
|
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||||
++this->iLineNumber;
|
{
|
||||||
apOut[0] = apOut[1] = apOut[2] = 0;
|
// LOG
|
||||||
return;
|
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)
|
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))
|
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||||
{
|
{
|
||||||
// LOG
|
// 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;
|
rIndexOut = 0;
|
||||||
apOut[0] = apOut[1] = apOut[2] = 0;
|
apOut[0] = apOut[1] = apOut[2] = 0;
|
||||||
++this->iLineNumber;
|
++this->iLineNumber;
|
||||||
|
@ -1795,7 +1768,7 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
|
||||||
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||||
{
|
{
|
||||||
// LOG
|
// 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;
|
rIndexOut = 0;
|
||||||
apOut[0] = apOut[1] = apOut[2] = 0.0f;
|
apOut[0] = apOut[1] = apOut[2] = 0.0f;
|
||||||
++this->iLineNumber;
|
++this->iLineNumber;
|
||||||
|
@ -1812,41 +1785,21 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
|
||||||
void Parser::ParseLV4MeshFloatTriple(float* apOut)
|
void Parser::ParseLV4MeshFloatTriple(float* apOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != 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
|
// skip spaces and tabs
|
||||||
this->LogWarning("Unable to parse float triple: unexpected EOL [#5]");
|
if(!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||||
apOut[0] = apOut[1] = apOut[2] = 0.0f;
|
{
|
||||||
++this->iLineNumber;
|
// LOG
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
111
code/ASEParser.h
111
code/ASEParser.h
|
@ -43,17 +43,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_ASEFILEHELPER_H_INC
|
#ifndef AI_ASEFILEHELPER_H_INC
|
||||||
#define AI_ASEFILEHELPER_H_INC
|
#define AI_ASEFILEHELPER_H_INC
|
||||||
|
|
||||||
|
// STL/CRT headers
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
|
// public ASSIMP headers
|
||||||
#include "../include/aiTypes.h"
|
#include "../include/aiTypes.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiAnim.h"
|
#include "../include/aiAnim.h"
|
||||||
|
|
||||||
// for some helper routines like IsSpace()
|
// for some helper routines like IsSpace()
|
||||||
#include "PlyParser.h"
|
#include "PlyParser.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
|
||||||
// ASE is quite similar to 3ds. We can reuse some structures
|
// ASE is quite similar to 3ds. We can reuse some structures
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
|
@ -130,9 +132,10 @@ struct Bone
|
||||||
Bone()
|
Bone()
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
std::stringstream ss(mName);
|
|
||||||
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
|
char szTemp[128];
|
||||||
ss.flush();
|
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
||||||
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Name of the bone
|
//! Name of the bone
|
||||||
|
@ -152,6 +155,73 @@ struct BoneVertex
|
||||||
//aiVector3D mPosition;
|
//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 */
|
/** Helper structure to represent an ASE file mesh */
|
||||||
struct Mesh
|
struct Mesh
|
||||||
|
@ -160,9 +230,9 @@ struct Mesh
|
||||||
Mesh() : bSkip(false)
|
Mesh() : bSkip(false)
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
std::stringstream ss(mName);
|
char szTemp[128];
|
||||||
ss << "%%_UNNAMED_" << iCnt++ << "_%%";
|
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
||||||
ss.flush();
|
mName = szTemp;
|
||||||
|
|
||||||
// use 2 texture vertex components by default
|
// use 2 texture vertex components by default
|
||||||
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
|
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
|
||||||
|
@ -203,6 +273,9 @@ struct Mesh
|
||||||
//! Transformation matrix of the mesh
|
//! Transformation matrix of the mesh
|
||||||
aiMatrix4x4 mTransform;
|
aiMatrix4x4 mTransform;
|
||||||
|
|
||||||
|
//! Animation channels for the node
|
||||||
|
Animation mAnim;
|
||||||
|
|
||||||
//! Material index of the mesh
|
//! Material index of the mesh
|
||||||
unsigned int iMaterialIndex;
|
unsigned int iMaterialIndex;
|
||||||
|
|
||||||
|
@ -211,6 +284,10 @@ struct Mesh
|
||||||
|
|
||||||
//! used internally
|
//! used internally
|
||||||
bool bSkip;
|
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
|
//! \param mesh Mesh object to be filled
|
||||||
void ParseLV2NodeTransformBlock(Mesh& mesh);
|
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
|
//! Parse a *MESH block in a file
|
||||||
//! \param mesh Mesh object to be filled
|
//! \param mesh Mesh object to be filled
|
||||||
|
@ -453,6 +537,19 @@ public:
|
||||||
|
|
||||||
//! Current line in the file
|
//! Current line in the file
|
||||||
unsigned int iLineNumber;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
// 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)
|
if( pMesh->mNormals == NULL || pMesh->mTextureCoords[0] == NULL)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("Normal vectors and at least one "
|
DefaultLogger::get()->error("Unable to compute tangents: UV0 and normals must be there ");
|
||||||
"texture coordinate set are required to calculate tangents. ");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
/** @file Implementation of the post processing step to validate
|
||||||
* the data structure returned by Assimp
|
* the data structure returned by Assimp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// STL headers
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
// internal headers
|
||||||
#include "ValidateDataStructure.h"
|
#include "ValidateDataStructure.h"
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
|
||||||
|
// public ASSIMP headers
|
||||||
#include "../include/DefaultLogger.h"
|
#include "../include/DefaultLogger.h"
|
||||||
#include "../include/aiPostProcess.h"
|
#include "../include/aiPostProcess.h"
|
||||||
#include "../include/aiMesh.h"
|
#include "../include/aiMesh.h"
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
#include "../include/aiAssert.h"
|
#include "../include/aiAssert.h"
|
||||||
|
|
||||||
|
// CRT headers
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -128,7 +133,7 @@ void ValidateDSProcess::ReportWarning(const char* msg,...)
|
||||||
throw new ImportErrorException("Idiot ... learn coding!");
|
throw new ImportErrorException("Idiot ... learn coding!");
|
||||||
}
|
}
|
||||||
va_end(args);
|
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.
|
// 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)
|
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]])
|
if (abRefList[face.mIndices[a]])
|
||||||
{
|
{
|
||||||
|
@ -636,6 +641,7 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
|
||||||
{
|
{
|
||||||
this->Validate(&pBoneAnim->mBoneName);
|
this->Validate(&pBoneAnim->mBoneName);
|
||||||
|
|
||||||
|
#if 0
|
||||||
// check whether there is a bone with this name ...
|
// check whether there is a bone with this name ...
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (; i < this->mScene->mNumMeshes;++i)
|
for (; i < this->mScene->mNumMeshes;++i)
|
||||||
|
@ -650,14 +656,14 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
|
||||||
__break_out:
|
__break_out:
|
||||||
if (i == this->mScene->mNumMeshes)
|
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);
|
pBoneAnim->mBoneName.data);
|
||||||
}
|
}
|
||||||
if (!pBoneAnim->mNumPositionKeys && !pBoneAnim->mNumRotationKeys && !pBoneAnim->mNumScalingKeys)
|
if (!pBoneAnim->mNumPositionKeys && !pBoneAnim->mNumRotationKeys && !pBoneAnim->mNumScalingKeys)
|
||||||
{
|
{
|
||||||
this->ReportWarning("A bone animation channel has no keys");
|
this->ReportWarning("A bone animation channel has no keys");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// otherwise check whether one of the keys exceeds the total duration of the animation
|
// otherwise check whether one of the keys exceeds the total duration of the animation
|
||||||
if (pBoneAnim->mNumPositionKeys)
|
if (pBoneAnim->mNumPositionKeys)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,9 +66,12 @@ struct aiQuatKey
|
||||||
C_STRUCT aiQuaternion mValue; ///< The value of this key
|
C_STRUCT aiQuaternion mValue; ///< The value of this key
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Describes the animation of a single bone. The name specifies the bone which is affected by this
|
/** Describes the animation of a single node. The name specifies the bone/node which is affected by this
|
||||||
* animation channel. The keyframes are given in three separate series of values, one each for
|
* animation channel. The keyframes are given in three separate series of values, one each for
|
||||||
* position, rotation and scaling.
|
* position, rotation and scaling.
|
||||||
|
* <br>
|
||||||
|
* NOTE: The name "BoneAnim" is misleading. This structure is also used to describe
|
||||||
|
* the animation of regular nodes on the node graph. They needn't be nodes.
|
||||||
*/
|
*/
|
||||||
struct aiBoneAnim
|
struct aiBoneAnim
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,8 @@ struct aiMatrix4x4
|
||||||
aiMatrix4x4& Inverse();
|
aiMatrix4x4& Inverse();
|
||||||
float Determinant() const;
|
float Determinant() const;
|
||||||
|
|
||||||
|
inline bool IsIdentity() const;
|
||||||
|
|
||||||
float* operator[](unsigned int p_iIndex);
|
float* operator[](unsigned int p_iIndex);
|
||||||
const float* operator[](unsigned int p_iIndex) const;
|
const float* operator[](unsigned int p_iIndex) const;
|
||||||
|
|
||||||
|
@ -87,6 +89,37 @@ struct aiMatrix4x4
|
||||||
inline void FromEulerAngles(float x, float y, float z);
|
inline void FromEulerAngles(float x, float y, float z);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns a rotation matrix for a rotation around the x axis
|
||||||
|
* \param a Rotation angle, in radians
|
||||||
|
* \param out Receives the output matrix
|
||||||
|
* \return Reference to the output matrix
|
||||||
|
*/
|
||||||
|
static aiMatrix4x4& RotationX(float a, aiMatrix4x4& out);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns a rotation matrix for a rotation around the y axis
|
||||||
|
* \param a Rotation angle, in radians
|
||||||
|
* \param out Receives the output matrix
|
||||||
|
* \return Reference to the output matrix
|
||||||
|
*/
|
||||||
|
static aiMatrix4x4& RotationY(float a, aiMatrix4x4& out);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns a rotation matrix for a rotation around the z axis
|
||||||
|
* \param a Rotation angle, in radians
|
||||||
|
* \param out Receives the output matrix
|
||||||
|
* \return Reference to the output matrix
|
||||||
|
*/
|
||||||
|
static aiMatrix4x4& RotationZ(float a, aiMatrix4x4& out);
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Returns a translation matrix
|
||||||
|
* \param v Translation vector
|
||||||
|
* \param out Receives the output matrix
|
||||||
|
* \return Reference to the output matrix
|
||||||
|
*/
|
||||||
|
static aiMatrix4x4& Translation(aiVector3D v, aiMatrix4x4& out);
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
float a1, a2, a3, a4;
|
float a1, a2, a3, a4;
|
||||||
|
|
|
@ -237,6 +237,65 @@ inline void aiMatrix4x4::FromEulerAngles(float x, float y, float z)
|
||||||
_this.a4 = _this.b4 = _this.c4 = _this.d1 = _this.d2 = _this.d3 = 0.0f;
|
_this.a4 = _this.b4 = _this.c4 = _this.d1 = _this.d2 = _this.d3 = 0.0f;
|
||||||
_this.d4 = 1.0f;
|
_this.d4 = 1.0f;
|
||||||
}
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline bool aiMatrix4x4::IsIdentity() const
|
||||||
|
{
|
||||||
|
return !(a1 != 1.0f || a2 || a3 || a4 ||
|
||||||
|
b1 || b2 != 1.0f || b3 || b4 ||
|
||||||
|
c1 || c2 || c3 != 1.0f || a4 ||
|
||||||
|
d1 || d2 || d3 || d4 != 1.0f);
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiMatrix4x4& aiMatrix4x4::RotationX(float a, aiMatrix4x4& out)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
| 1 0 0 0 |
|
||||||
|
M = | 0 cos(A) -sin(A) 0 |
|
||||||
|
| 0 sin(A) cos(A) 0 |
|
||||||
|
| 0 0 0 1 | */
|
||||||
|
out.aiMatrix4x4::aiMatrix4x4();
|
||||||
|
out.b2 = out.c3 = cos(a);
|
||||||
|
out.b3 = -(out.c2 = sin(a));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiMatrix4x4& aiMatrix4x4::RotationY(float a, aiMatrix4x4& out)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
| cos(A) 0 sin(A) 0 |
|
||||||
|
M = | 0 1 0 0 |
|
||||||
|
| -sin(A) 0 cos(A) 0 |
|
||||||
|
| 0 0 0 1 |
|
||||||
|
*/
|
||||||
|
out.aiMatrix4x4::aiMatrix4x4();
|
||||||
|
out.a1 = out.c3 = cos(a);
|
||||||
|
out.c1 = -(out.a3 = sin(a));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiMatrix4x4& aiMatrix4x4::RotationZ(float a, aiMatrix4x4& out)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
| cos(A) -sin(A) 0 0 |
|
||||||
|
M = | sin(A) cos(A) 0 0 |
|
||||||
|
| 0 0 1 0 |
|
||||||
|
| 0 0 0 1 | */
|
||||||
|
out.aiMatrix4x4::aiMatrix4x4();
|
||||||
|
out.a1 = out.b2 = cos(a);
|
||||||
|
out.a2 = -(out.b1 = sin(a));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
inline aiMatrix4x4& aiMatrix4x4::Translation(aiVector3D v, aiMatrix4x4& out)
|
||||||
|
{
|
||||||
|
out.aiMatrix4x4::aiMatrix4x4();
|
||||||
|
out.d1 = v.x;
|
||||||
|
out.d2 = v.y;
|
||||||
|
out.d3 = v.z;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
#endif // AI_MATRIX4x4_INL_INC
|
#endif // AI_MATRIX4x4_INL_INC
|
||||||
|
|
|
@ -1,3 +1,43 @@
|
||||||
|
/*
|
||||||
|
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 Quaternion structure, including operators when compiling in C++ */
|
/** @file Quaternion structure, including operators when compiling in C++ */
|
||||||
#ifndef AI_QUATERNION_H_INC
|
#ifndef AI_QUATERNION_H_INC
|
||||||
#define AI_QUATERNION_H_INC
|
#define AI_QUATERNION_H_INC
|
||||||
|
@ -23,8 +63,12 @@ struct aiQuaternion
|
||||||
/** Construct from euler angles */
|
/** Construct from euler angles */
|
||||||
aiQuaternion( float rotx, float roty, float rotz);
|
aiQuaternion( float rotx, float roty, float rotz);
|
||||||
|
|
||||||
|
/** Construct from an axis angle pair */
|
||||||
|
aiQuaternion( aiVector3D axis, float angle);
|
||||||
|
|
||||||
/** Returns a matrix representation of the quaternion */
|
/** Returns a matrix representation of the quaternion */
|
||||||
aiMatrix3x3 GetMatrix() const;
|
aiMatrix3x3 GetMatrix() const;
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
//! w,x,y,z components of the quaternion
|
//! w,x,y,z components of the quaternion
|
||||||
|
@ -113,6 +157,21 @@ inline aiMatrix3x3 aiQuaternion::GetMatrix() const
|
||||||
return resMatrix;
|
return resMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Construction from an axis-angle pair
|
||||||
|
inline aiQuaternion::aiQuaternion( aiVector3D axis, float angle)
|
||||||
|
{
|
||||||
|
axis.Normalize();
|
||||||
|
|
||||||
|
const float sin_a = sin( angle / 2 );
|
||||||
|
const float cos_a = cos( angle / 2 );
|
||||||
|
x = axis.x * sin_a;
|
||||||
|
y = axis.y * sin_a;
|
||||||
|
z = axis.z * sin_a;
|
||||||
|
w = cos_a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end extern "C"
|
} // end extern "C"
|
||||||
|
|
|
@ -119,6 +119,7 @@ struct aiNode
|
||||||
//! and propably meshes with bones.
|
//! and propably meshes with bones.
|
||||||
#define AI_SCENE_FLAGS_ANIM_SKELETON_ONLY 0x1
|
#define AI_SCENE_FLAGS_ANIM_SKELETON_ONLY 0x1
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** The root structure of the imported data.
|
/** The root structure of the imported data.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue