ase/ask loader is quite stable now, loads most models correctly
added pretransformvertices postprocess step bugfixes in the 3ds material system. transparency is now displayed correctly Node view in the viewer display the local transformation matrix now Fixed wrong directory name. "unused" renamed to "extra" ---> all is WIP ... git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@50 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
@@ -1091,9 +1091,9 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining)
|
||||
pcf = &this->mScene->mMaterials.back().mTransparency;
|
||||
*pcf = this->ParsePercentageChunk();
|
||||
// NOTE: transparency, not opacity
|
||||
*pcf = 1.0f - *pcf;
|
||||
if (is_qnan(*pcf))
|
||||
*pcf = 0.0f;
|
||||
*pcf = 1.0f;
|
||||
else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f;
|
||||
break;
|
||||
|
||||
case Dot3DSFile::CHUNK_MAT_SHADING:
|
||||
@@ -1121,10 +1121,12 @@ void Dot3DSImporter::ParseMaterialChunk(int* piRemaining)
|
||||
break;
|
||||
|
||||
case Dot3DSFile::CHUNK_MAT_SELF_ILPCT:
|
||||
// TODO: need to multiply with emissive base color?
|
||||
pcf = &this->mScene->mMaterials.back().sTexEmissive.mTextureBlend;
|
||||
*pcf = this->ParsePercentageChunk();
|
||||
if (is_qnan(*pcf))
|
||||
*pcf = 1.0f;
|
||||
*pcf = 0.0f;
|
||||
else *pcf = *pcf * (float)0xFFFF / 100.0f;
|
||||
break;
|
||||
|
||||
// parse texture chunks
|
||||
|
||||
@@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "ASELoader.h"
|
||||
#include "3DSSpatialSort.h"
|
||||
#include "MaterialSystem.h"
|
||||
#include "fast_atof.h"
|
||||
|
||||
#include "../include/IOStream.h"
|
||||
#include "../include/IOSystem.h"
|
||||
@@ -126,11 +127,23 @@ void ASEImporter::InternReadFile(
|
||||
this->mParser = new ASE::Parser((const char*)this->mBuffer);
|
||||
this->mParser->Parse();
|
||||
|
||||
// the .ask file format contains normally three LODs of
|
||||
// a single object. Named <name>n, where n = 1 designates
|
||||
// the highest level of detail.
|
||||
if (this->mIsAsk)
|
||||
{
|
||||
this->AskFilterLOD(this->mParser->m_vMeshes);
|
||||
}
|
||||
|
||||
// process all meshes
|
||||
std::vector<aiMesh*> avOutMeshes;
|
||||
avOutMeshes.reserve(this->mParser->m_vMeshes.size()*2);
|
||||
for (std::vector<ASE::Mesh>::iterator
|
||||
i = this->mParser->m_vMeshes.begin();
|
||||
i != this->mParser->m_vMeshes.end();++i)
|
||||
{
|
||||
if ((*i).bSkip)continue;
|
||||
|
||||
// transform all vertices into worldspace
|
||||
// world2obj transform is specified in the
|
||||
// transformation matrix of a scenegraph node
|
||||
@@ -144,8 +157,15 @@ void ASEImporter::InternReadFile(
|
||||
this->GenerateNormals(*i);
|
||||
|
||||
// convert all meshes to aiMesh objects
|
||||
this->ConvertMeshes(*i,pScene);
|
||||
this->ConvertMeshes(*i,avOutMeshes);
|
||||
}
|
||||
|
||||
// now build the output mesh list
|
||||
pScene->mNumMeshes = avOutMeshes.size();
|
||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
pScene->mMeshes[i] = avOutMeshes[i];
|
||||
|
||||
// buil final material indices (remove submaterials and make the final list)
|
||||
this->BuildMaterialIndices(pScene);
|
||||
|
||||
@@ -158,69 +178,87 @@ void ASEImporter::InternReadFile(
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::AddNodes(aiScene* pcScene,aiNode* pcParent,
|
||||
const char* szName)
|
||||
{
|
||||
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
|
||||
std::vector<aiNode*> apcNodes;
|
||||
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];
|
||||
if (!szMyName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (szName)
|
||||
{
|
||||
if(0 != ASSIMP_stricmp ( szName, szMyName[1].c_str() ))
|
||||
continue;
|
||||
}
|
||||
else if ('\0' != szMyName[1].c_str()[0])continue;
|
||||
|
||||
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;
|
||||
|
||||
// add sub nodes
|
||||
this->AddNodes(pcScene,node,node->mName.data);
|
||||
}
|
||||
|
||||
// allocate enough space for the child nodes
|
||||
pcParent->mNumChildren = apcNodes.size();
|
||||
pcParent->mChildren = new aiNode*[apcNodes.size()];
|
||||
|
||||
// now build all nodes
|
||||
for (unsigned int p = 0; p < apcNodes.size();++p)
|
||||
{
|
||||
pcParent->mChildren[p] = apcNodes[p];
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::BuildNodes(aiScene* pcScene)
|
||||
{
|
||||
ai_assert(NULL != pcScene);
|
||||
|
||||
// allocate the root node
|
||||
pcScene->mRootNode = new aiNode();
|
||||
pcScene->mRootNode->mNumMeshes = 0;
|
||||
pcScene->mRootNode->mMeshes = 0;
|
||||
pcScene->mRootNode->mName.Set("<root>");
|
||||
|
||||
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
|
||||
std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > > stack;
|
||||
stack.reserve(pcScene->mNumMeshes);
|
||||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||
// add all nodes
|
||||
this->AddNodes(pcScene,pcScene->mRootNode,NULL);
|
||||
|
||||
// if there is only one subnode, set it as root node
|
||||
if (1 == pcScene->mRootNode->mNumChildren)
|
||||
{
|
||||
// get the transformation matrix of the node
|
||||
aiMatrix4x4* pmTransform = (aiMatrix4x4*)pcScene->mMeshes[i]->mColors[2];
|
||||
|
||||
// search for an identical matrix in our list
|
||||
for (std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > >::iterator
|
||||
a = stack.begin();
|
||||
a != stack.end();++a)
|
||||
{
|
||||
if ((*a).first == *pmTransform)
|
||||
{
|
||||
(*a).second.push_back(i);
|
||||
pmTransform->a1 = std::numeric_limits<float>::quiet_NaN();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_not_qnan(pmTransform->a1))
|
||||
{
|
||||
// add a new entry ...
|
||||
stack.push_back(std::pair<aiMatrix4x4,std::list<unsigned int> >(
|
||||
*pmTransform,std::list<unsigned int>()));
|
||||
stack.back().second.push_back(i);
|
||||
}
|
||||
// delete the matrix
|
||||
delete pmTransform;
|
||||
pcScene->mMeshes[i]->mColors[2] = NULL;
|
||||
aiNode* pc = pcScene->mRootNode;
|
||||
pcScene->mRootNode = pcScene->mRootNode->mChildren[0];
|
||||
pcScene->mRootNode->mParent = NULL;
|
||||
delete pc;
|
||||
}
|
||||
|
||||
// allocate enough space for the child nodes
|
||||
pcScene->mRootNode->mNumChildren = stack.size();
|
||||
pcScene->mRootNode->mChildren = new aiNode*[stack.size()];
|
||||
|
||||
// now build all nodes
|
||||
for (std::vector<std::pair<aiMatrix4x4,std::list<unsigned int> > >::iterator
|
||||
a = stack.begin();
|
||||
a != stack.end();++a)
|
||||
else if (0 == pcScene->mRootNode->mNumChildren)
|
||||
{
|
||||
aiNode* pcNode = new aiNode();
|
||||
pcNode->mNumMeshes = (*a).second.size();
|
||||
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
|
||||
for (std::list<unsigned int>::const_iterator
|
||||
i = (*a).second.begin();
|
||||
i != (*a).second.end();++i)
|
||||
{
|
||||
*pcNode->mMeshes++ = *i;
|
||||
}
|
||||
pcNode->mMeshes -= pcNode->mNumMeshes;
|
||||
pcNode->mTransformation = (*a).first;
|
||||
*pcScene->mRootNode->mChildren++ = pcNode;
|
||||
throw new ImportErrorException("No nodes loaded. The ASE/ASK file is either empty or corrupt");
|
||||
}
|
||||
pcScene->mRootNode->mChildren -= stack.size();
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -229,16 +267,6 @@ void ASEImporter::TransformVertices(ASE::Mesh& mesh)
|
||||
// the matrix data is stored in column-major format,
|
||||
// but we need row major
|
||||
mesh.mTransform.Transpose();
|
||||
|
||||
aiMatrix4x4 m = mesh.mTransform;
|
||||
m.Inverse();
|
||||
|
||||
for (std::vector<aiVector3D>::iterator
|
||||
i = mesh.mPositions.begin();
|
||||
i != mesh.mPositions.end();++i)
|
||||
{
|
||||
(*i) = m * (*i);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
||||
@@ -315,10 +343,11 @@ void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh)
|
||||
// will fix that again ...)
|
||||
mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]];
|
||||
}
|
||||
|
||||
// assign a new valid index to the face
|
||||
(*i).mIndices[n] = iCurrent;
|
||||
}
|
||||
// we need to flip the order of the indices
|
||||
(*i).mIndices[0] = iCurrent-1;
|
||||
(*i).mIndices[1] = iCurrent-2;
|
||||
(*i).mIndices[2] = iCurrent-3;
|
||||
}
|
||||
|
||||
// replace the old arrays
|
||||
@@ -373,7 +402,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
||||
}
|
||||
// if there is no shininess, we can disable phong lighting
|
||||
else if (Dot3DS::Dot3DSFile::Metal == mat.mShading ||
|
||||
Dot3DS::Dot3DSFile::Phong == mat.mShading)
|
||||
Dot3DS::Dot3DSFile::Phong == mat.mShading ||
|
||||
Dot3DS::Dot3DSFile::Blinn == mat.mShading)
|
||||
{
|
||||
mat.mShading = Dot3DS::Dot3DSFile::Gouraud;
|
||||
}
|
||||
@@ -390,6 +420,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
||||
eShading = aiShadingMode_Flat; break;
|
||||
case Dot3DS::Dot3DSFile::Phong :
|
||||
eShading = aiShadingMode_Phong; break;
|
||||
case Dot3DS::Dot3DSFile::Blinn :
|
||||
eShading = aiShadingMode_Blinn; break;
|
||||
|
||||
// I don't know what "Wire" shading should be,
|
||||
// assume it is simple lambertian diffuse (L dot N) shading
|
||||
@@ -490,10 +522,8 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMeshes)
|
||||
{
|
||||
ai_assert(NULL != pcScene);
|
||||
|
||||
// validate the material index of the mesh
|
||||
if (mesh.iMaterialIndex >= this->mParser->m_vMaterials.size())
|
||||
{
|
||||
@@ -501,8 +531,6 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
LOGOUT_WARN("Material index is out of range");
|
||||
}
|
||||
|
||||
// List of all output meshes
|
||||
std::vector<aiMesh*> avOutMeshes;
|
||||
|
||||
// if the material the mesh is assigned to is consisting of submeshes
|
||||
// we'll need to split it ... Quak.
|
||||
@@ -544,8 +572,16 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
|
||||
// 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;
|
||||
|
||||
avOutMeshes.push_back(p_pcOut);
|
||||
|
||||
// convert vertices
|
||||
@@ -647,24 +683,24 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++;
|
||||
|
||||
p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ];
|
||||
aiBone** pcBone = &p_pcOut->mBones[0];
|
||||
aiBone** pcBone = p_pcOut->mBones;
|
||||
for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
|
||||
{
|
||||
if (!avOutputBones[mrspock].empty())
|
||||
{
|
||||
// we will need this bone. add it to the output mesh and
|
||||
// add all per-vertex weights
|
||||
*pcBone = new aiBone();
|
||||
(**pcBone).mName.Set(mesh.mBones[mrspock].mName);
|
||||
aiBone* pc = *pcBone = new aiBone();
|
||||
pc->mName.Set(mesh.mBones[mrspock].mName);
|
||||
|
||||
(**pcBone).mNumWeights = avOutputBones[mrspock].size();
|
||||
(**pcBone).mWeights = new aiVertexWeight[(**pcBone).mNumWeights];
|
||||
pc->mNumWeights = avOutputBones[mrspock].size();
|
||||
pc->mWeights = new aiVertexWeight[pc->mNumWeights];
|
||||
|
||||
for (unsigned int captainkirk = 0; captainkirk < (**pcBone).mNumWeights;++captainkirk)
|
||||
for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk)
|
||||
{
|
||||
const std::pair<unsigned int,float>& ref = avOutputBones[mrspock][captainkirk];
|
||||
(**pcBone).mWeights[captainkirk].mVertexId = ref.first;
|
||||
(**pcBone).mWeights[captainkirk].mWeight = ref.second;
|
||||
pc->mWeights[captainkirk].mVertexId = ref.first;
|
||||
pc->mWeights[captainkirk].mWeight = ref.second;
|
||||
}
|
||||
++pcBone;
|
||||
}
|
||||
@@ -688,10 +724,17 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
|
||||
// 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);
|
||||
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;
|
||||
|
||||
// convert vertices
|
||||
p_pcOut->mNumVertices = mesh.mPositions.size();
|
||||
p_pcOut->mNumFaces = mesh.mFaces.size();
|
||||
@@ -772,29 +815,59 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene)
|
||||
if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++;
|
||||
|
||||
p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones];
|
||||
aiBone** pcBone = &p_pcOut->mBones[0];
|
||||
aiBone** pcBone = p_pcOut->mBones;
|
||||
for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy)
|
||||
{
|
||||
if (!avBonesOut[jfkennedy].empty())
|
||||
{
|
||||
*pcBone = new aiBone();
|
||||
(**pcBone).mName.Set(mesh.mBones[jfkennedy].mName);
|
||||
(**pcBone).mNumWeights = avBonesOut[jfkennedy].size();
|
||||
(**pcBone).mWeights = new aiVertexWeight[(**pcBone).mNumWeights];
|
||||
memcpy((**pcBone).mWeights,&avBonesOut[jfkennedy][0],
|
||||
sizeof(aiVertexWeight) * (**pcBone).mNumWeights);
|
||||
aiBone* pc = *pcBone = new aiBone();
|
||||
pc->mName.Set(mesh.mBones[jfkennedy].mName);
|
||||
pc->mNumWeights = avBonesOut[jfkennedy].size();
|
||||
pc->mWeights = new aiVertexWeight[pc->mNumWeights];
|
||||
memcpy(pc->mWeights,&avBonesOut[jfkennedy][0],
|
||||
sizeof(aiVertexWeight) * pc->mNumWeights);
|
||||
++pcBone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ASEImporter::AskFilterLOD(std::vector<ASE::Mesh>& meshes)
|
||||
{
|
||||
for (std::vector<ASE::Mesh>::iterator
|
||||
i = meshes.begin();
|
||||
i != meshes.end();++i)
|
||||
{
|
||||
if ((*i).bSkip)continue;
|
||||
|
||||
// now build the output mesh list
|
||||
pcScene->mNumMeshes = avOutMeshes.size();
|
||||
pcScene->mMeshes = new aiMesh*[pcScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
|
||||
pcScene->mMeshes[i] = avOutMeshes[i];
|
||||
|
||||
// search for a number in the name of the node
|
||||
const char* sz = (*i).mName.c_str();
|
||||
while (*sz)
|
||||
{
|
||||
if (*sz >= '0' && *sz <= '9')
|
||||
{
|
||||
// check whether there is another mesh with exactly
|
||||
// the same name, but a lower number out there ...
|
||||
unsigned int iLen = (unsigned int)(sz - (*i).mName.c_str());
|
||||
unsigned int iMyNum = strtol10(sz,NULL);
|
||||
for (std::vector<ASE::Mesh>::iterator
|
||||
f = meshes.begin();
|
||||
f != meshes.end();++f)
|
||||
{
|
||||
const char* sz = (*f).mName.c_str();
|
||||
if (i != f && !(*f).bSkip &&
|
||||
0 == memcmp(sz,(*i).mName.c_str(),iLen) &&
|
||||
iMyNum > strtol10(sz))
|
||||
{
|
||||
(*f).bSkip = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}++sz;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -889,9 +962,9 @@ void ASEImporter::GenerateNormals(ASE::Mesh& mesh)
|
||||
const ASE::Face& face = mesh.mFaces[a];
|
||||
|
||||
// assume it is a triangle
|
||||
aiVector3D* pV1 = &mesh.mPositions[face.mIndices[0]];
|
||||
aiVector3D* pV1 = &mesh.mPositions[face.mIndices[2]];
|
||||
aiVector3D* pV2 = &mesh.mPositions[face.mIndices[1]];
|
||||
aiVector3D* pV3 = &mesh.mPositions[face.mIndices[2]];
|
||||
aiVector3D* pV3 = &mesh.mPositions[face.mIndices[0]];
|
||||
|
||||
aiVector3D pDelta1 = *pV2 - *pV1;
|
||||
aiVector3D pDelta2 = *pV3 - *pV1;
|
||||
|
||||
@@ -115,12 +115,19 @@ protected:
|
||||
*/
|
||||
void TransformVertices(ASE::Mesh& mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** The ASK file format contains LOD nodes.
|
||||
* We do only use the highest level of detail, all others
|
||||
* are skipped.
|
||||
*/
|
||||
void AskFilterLOD(std::vector<ASE::Mesh>& meshes);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Create one-material-per-mesh meshes ;-)
|
||||
* \param mesh Mesh to work with
|
||||
* \param pcScene Scene object to be filled
|
||||
* \param Receives the list of all created meshes
|
||||
*/
|
||||
void ConvertMeshes(ASE::Mesh& mesh, aiScene* pcScene);
|
||||
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Convert a material to a MaterialHelper object
|
||||
@@ -140,6 +147,15 @@ protected:
|
||||
*/
|
||||
void BuildNodes(aiScene* pcScene);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** 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
|
||||
*/
|
||||
void AddNodes(aiScene* pcScene,aiNode* pcParent,
|
||||
const char* szName);
|
||||
|
||||
protected:
|
||||
|
||||
/** Parser instance */
|
||||
|
||||
@@ -175,6 +175,7 @@ void Parser::Parse()
|
||||
this->LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
|
||||
be 200. Continuing happily ...");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// main scene information
|
||||
if (0 == strncmp(this->m_szFile,"*SCENE",6) &&
|
||||
@@ -182,6 +183,7 @@ void Parser::Parse()
|
||||
{
|
||||
this->m_szFile+=7;
|
||||
this->ParseLV1SceneBlock();
|
||||
continue;
|
||||
}
|
||||
// material list
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_LIST",14) &&
|
||||
@@ -189,24 +191,25 @@ void Parser::Parse()
|
||||
{
|
||||
this->m_szFile+=15;
|
||||
this->ParseLV1MaterialListBlock();
|
||||
continue;
|
||||
}
|
||||
// geometric object (mesh)
|
||||
if (0 == strncmp(this->m_szFile,"*GEOMOBJECT",11) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+11)))
|
||||
{
|
||||
this->m_szFile+=12;
|
||||
|
||||
this->m_vMeshes.push_back(Mesh());
|
||||
this->ParseLV1GeometryObjectBlock(this->m_vMeshes.back());
|
||||
continue;
|
||||
}
|
||||
// ignore comments, lights and cameras
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
if ('\0' == *this->m_szFile)
|
||||
else if ('\0' == *this->m_szFile)
|
||||
{
|
||||
// END OF FILE ... why not?
|
||||
return;
|
||||
@@ -231,6 +234,7 @@ void Parser::ParseLV1SceneBlock()
|
||||
|
||||
// parse a color triple and assume it is really the bg color
|
||||
this->ParseLV4MeshFloatTriple( &this->m_clrBackground.r );
|
||||
continue;
|
||||
}
|
||||
if (0 == strncmp(this->m_szFile,"*SCENE_AMBIENT_STATIC",21) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+21)))
|
||||
@@ -239,10 +243,11 @@ void Parser::ParseLV1SceneBlock()
|
||||
|
||||
// parse a color triple and assume it is really the bg color
|
||||
this->ParseLV4MeshFloatTriple( &this->m_clrAmbient.r );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -261,6 +266,7 @@ void Parser::ParseLV1MaterialListBlock()
|
||||
{
|
||||
int iDepth = 0;
|
||||
unsigned int iMaterialCount = 0;
|
||||
unsigned int iOldMaterialCount = this->m_vMaterials.size();
|
||||
while (true)
|
||||
{
|
||||
if ('*' == *this->m_szFile)
|
||||
@@ -272,7 +278,8 @@ void Parser::ParseLV1MaterialListBlock()
|
||||
this->ParseLV4MeshLong(iMaterialCount);
|
||||
|
||||
// now allocate enough storage to hold all materials
|
||||
this->m_vMaterials.resize(iMaterialCount);
|
||||
this->m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
|
||||
continue;
|
||||
}
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL",9) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+9)))
|
||||
@@ -288,17 +295,18 @@ void Parser::ParseLV1MaterialListBlock()
|
||||
}
|
||||
|
||||
// get a reference to the material
|
||||
Material& sMat = this->m_vMaterials[iIndex];
|
||||
Material& sMat = this->m_vMaterials[iIndex+iOldMaterialCount];
|
||||
|
||||
// skip the '{'
|
||||
this->SkipOpeningBracket();
|
||||
|
||||
// parse the material block
|
||||
this->ParseLV2MaterialBlock(sMat);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -326,36 +334,29 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
{
|
||||
this->m_szFile+=15;
|
||||
|
||||
// NOTE: The name could also be the texture in some cases
|
||||
// be prepared that this might occur ...
|
||||
if (!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||
BLUBB("Unable to parse *MATERIAL_NAME block: Unexpected EOL")
|
||||
|
||||
const char* sz = this->m_szFile;
|
||||
while (!IsSpaceOrNewLine(*sz))sz++;
|
||||
mat.mName = std::string(this->m_szFile,(uintptr_t)sz-(uintptr_t)this->m_szFile);
|
||||
this->m_szFile = sz;
|
||||
if (!this->ParseString(mat.mName,"*MATERIAL_NAME"))this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
// ambient material color
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_AMBIENT",17) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+17)))
|
||||
{
|
||||
this->m_szFile+=18;
|
||||
this->ParseLV4MeshFloatTriple(&mat.mAmbient.r);
|
||||
this->ParseLV4MeshFloatTriple(&mat.mAmbient.r);continue;
|
||||
}
|
||||
// diffuse material color
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_DIFFUSE",17) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+17)))
|
||||
{
|
||||
this->m_szFile+=18;
|
||||
this->ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
|
||||
this->ParseLV4MeshFloatTriple(&mat.mDiffuse.r);continue;
|
||||
}
|
||||
// specular material color
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_SPECULAR",18) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+18)))
|
||||
{
|
||||
this->m_szFile+=19;
|
||||
this->ParseLV4MeshFloatTriple(&mat.mSpecular.r);
|
||||
this->ParseLV4MeshFloatTriple(&mat.mSpecular.r);continue;
|
||||
}
|
||||
// material shading type
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_SHADING",17) &&
|
||||
@@ -393,6 +394,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
mat.mShading = Dot3DSFile::Gouraud;
|
||||
this->SkipToNextToken();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// material transparency
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_TRANSPARENCY",22) &&
|
||||
@@ -400,7 +402,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
{
|
||||
this->m_szFile+=23;
|
||||
this->ParseLV4MeshFloat(mat.mTransparency);
|
||||
mat.mTransparency = 1.0f - mat.mTransparency;
|
||||
mat.mTransparency = 1.0f - mat.mTransparency;continue;
|
||||
}
|
||||
// material self illumination
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_SELFILLUM",19) &&
|
||||
@@ -413,6 +415,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
mat.mEmissive.r = f;
|
||||
mat.mEmissive.g = f;
|
||||
mat.mEmissive.b = f;
|
||||
continue;
|
||||
}
|
||||
// material shininess
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINE",15) &&
|
||||
@@ -420,14 +423,14 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->ParseLV4MeshFloat(mat.mSpecularExponent);
|
||||
mat.mSpecularExponent *= 15;
|
||||
mat.mSpecularExponent *= 15;continue;
|
||||
}
|
||||
// material shininess strength
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_SHINESTRENGTH",23) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+23)))
|
||||
{
|
||||
this->m_szFile+=24;
|
||||
this->ParseLV4MeshFloat(mat.mShininessStrength);
|
||||
this->ParseLV4MeshFloat(mat.mShininessStrength);continue;
|
||||
}
|
||||
// diffuse color map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_DIFFUSE",12) &&
|
||||
@@ -437,7 +440,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexDiffuse);
|
||||
this->ParseLV3MapBlock(mat.sTexDiffuse);continue;
|
||||
}
|
||||
// ambient color map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_AMBIENT",12) &&
|
||||
@@ -447,7 +450,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexAmbient);
|
||||
this->ParseLV3MapBlock(mat.sTexAmbient);continue;
|
||||
}
|
||||
// specular color map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_SPECULAR",13) &&
|
||||
@@ -457,7 +460,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexSpecular);
|
||||
this->ParseLV3MapBlock(mat.sTexSpecular);continue;
|
||||
}
|
||||
// opacity map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_OPACITY",12) &&
|
||||
@@ -467,7 +470,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexOpacity);
|
||||
this->ParseLV3MapBlock(mat.sTexOpacity);continue;
|
||||
}
|
||||
// emissive map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_SELFILLUM",14) &&
|
||||
@@ -477,7 +480,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexEmissive);
|
||||
this->ParseLV3MapBlock(mat.sTexEmissive);continue;
|
||||
}
|
||||
// bump map
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_BUMP",9) &&
|
||||
@@ -497,7 +500,7 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
// skip the opening bracket
|
||||
this->SkipOpeningBracket();
|
||||
// parse the texture block
|
||||
this->ParseLV3MapBlock(mat.sTexShininess);
|
||||
this->ParseLV3MapBlock(mat.sTexShininess);continue;
|
||||
}
|
||||
// number of submaterials
|
||||
if (0 == strncmp(this->m_szFile,"*NUMSUBMTLS",11) &&
|
||||
@@ -532,11 +535,11 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||
|
||||
// parse the material block
|
||||
this->ParseLV2MaterialBlock(sMat);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -564,77 +567,54 @@ void Parser::ParseLV3MapBlock(Texture& map)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+7)))
|
||||
{
|
||||
this->m_szFile+=8;
|
||||
|
||||
// NOTE: The name could also be the texture in some cases
|
||||
// be prepared that this might occur ...
|
||||
if (!SkipSpaces(this->m_szFile,&this->m_szFile))
|
||||
BLUBB("Unable to parse *BITMAP block: Unexpected EOL")
|
||||
|
||||
// there must be "
|
||||
if ('\"' != *this->m_szFile)
|
||||
BLUBB("Unable to parse *BITMAP block: Path is expected to be enclosed in double quotation marks")
|
||||
|
||||
++this->m_szFile;
|
||||
const char* sz = this->m_szFile;
|
||||
while (true)
|
||||
{
|
||||
if ('\"' == *sz)break;
|
||||
else if ('\0' == sz)
|
||||
{
|
||||
BLUBB("Unable to parse *BITMAP block: Path is expected to be enclosed in double quotation marks \
|
||||
but EOF was reached before a closing quotation mark was found")
|
||||
}
|
||||
sz++;
|
||||
}
|
||||
|
||||
map.mMapName = std::string(this->m_szFile,(uintptr_t)sz-(uintptr_t)this->m_szFile);
|
||||
this->m_szFile = sz;
|
||||
if(!this->ParseString(map.mMapName,"*BITMAP"))SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
// offset on the u axis
|
||||
if (0 == strncmp(this->m_szFile,"*UVW_U_OFFSET" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshFloat(map.mOffsetU);
|
||||
this->ParseLV4MeshFloat(map.mOffsetU);continue;
|
||||
}
|
||||
// offset on the v axis
|
||||
if (0 == strncmp(this->m_szFile,"*UVW_V_OFFSET" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshFloat(map.mOffsetV);
|
||||
this->ParseLV4MeshFloat(map.mOffsetV);continue;
|
||||
}
|
||||
// tiling on the u axis
|
||||
if (0 == strncmp(this->m_szFile,"*UVW_U_TILING" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshFloat(map.mScaleU);
|
||||
this->ParseLV4MeshFloat(map.mScaleU);continue;
|
||||
}
|
||||
// tiling on the v axis
|
||||
if (0 == strncmp(this->m_szFile,"*UVW_V_TILING" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshFloat(map.mScaleV);
|
||||
this->ParseLV4MeshFloat(map.mScaleV);continue;
|
||||
}
|
||||
// rotation around the z-axis
|
||||
if (0 == strncmp(this->m_szFile,"*UVW_ANGLE" ,10) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+10)))
|
||||
{
|
||||
this->m_szFile+=11;
|
||||
this->ParseLV4MeshFloat(map.mRotation);
|
||||
this->ParseLV4MeshFloat(map.mRotation);continue;
|
||||
}
|
||||
// map blending factor
|
||||
if (0 == strncmp(this->m_szFile,"*MAP_AMOUNT" ,11) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+11)))
|
||||
{
|
||||
this->m_szFile+=12;
|
||||
this->ParseLV4MeshFloat(map.mTextureBlend);
|
||||
this->ParseLV4MeshFloat(map.mTextureBlend);continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -652,7 +632,7 @@ void Parser::ParseLV3MapBlock(Texture& map)
|
||||
bool Parser::ParseString(std::string& out,const char* szName)
|
||||
{
|
||||
char szBuffer[1024];
|
||||
ai_assert(strlen(szName < 750));
|
||||
ai_assert(strlen(szName) < 750);
|
||||
|
||||
// NOTE: The name could also be the texture in some cases
|
||||
// be prepared that this might occur ...
|
||||
@@ -702,47 +682,41 @@ void Parser::ParseLV1GeometryObjectBlock(ASE::Mesh& mesh)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+10)))
|
||||
{
|
||||
this->m_szFile+=11;
|
||||
if(!this->ParseString(mesh.mName,"*NODE_NAME"))
|
||||
{
|
||||
this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
if(!this->ParseString(mesh.mName,"*NODE_NAME"))this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
// name of the parent of the node
|
||||
if (0 == strncmp(this->m_szFile,"*NODE_PARENT" ,12) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+12)))
|
||||
{
|
||||
this->m_szFile+=13;
|
||||
if(!this->ParseString(mesh.mParent,"*NODE_PARENT"))
|
||||
{
|
||||
this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
if(!this->ParseString(mesh.mParent,"*NODE_PARENT"))this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
// transformation matrix of the node
|
||||
if (0 == strncmp(this->m_szFile,"*NODE_TM" ,8) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+8)))
|
||||
{
|
||||
this->m_szFile+=9;
|
||||
this->ParseLV2NodeTransformBlock(mesh);
|
||||
this->ParseLV2NodeTransformBlock(mesh);continue;
|
||||
}
|
||||
// mesh data
|
||||
if (0 == strncmp(this->m_szFile,"*MESH" ,5) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+5)))
|
||||
{
|
||||
this->m_szFile+=6;
|
||||
this->ParseLV2MeshBlock(mesh);
|
||||
this->ParseLV2MeshBlock(mesh);continue;
|
||||
}
|
||||
// mesh material index
|
||||
else if (0 == strncmp(this->m_szFile,"*MATERIAL_REF" ,13) &&
|
||||
if (0 == strncmp(this->m_szFile,"*MATERIAL_REF" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshLong(mesh.iMaterialIndex);
|
||||
this->ParseLV4MeshLong(mesh.iMaterialIndex);continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -769,32 +743,32 @@ void Parser::ParseLV2NodeTransformBlock(ASE::Mesh& mesh)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+8)))
|
||||
{
|
||||
this->m_szFile+=9;
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[0]);
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[0]);continue;
|
||||
}
|
||||
// second row of the transformation matrix
|
||||
if (0 == strncmp(this->m_szFile,"*TM_ROW1" ,8) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+8)))
|
||||
{
|
||||
this->m_szFile+=9;
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[1]);
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[1]);continue;
|
||||
}
|
||||
// third row of the transformation matrix
|
||||
if (0 == strncmp(this->m_szFile,"*TM_ROW2" ,8) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+8)))
|
||||
{
|
||||
this->m_szFile+=9;
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[2]);
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[2]);continue;
|
||||
}
|
||||
// fourth row of the transformation matrix
|
||||
if (0 == strncmp(this->m_szFile,"*TM_ROW3" ,8) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+8)))
|
||||
{
|
||||
this->m_szFile+=9;
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[3]);
|
||||
this->ParseLV4MeshFloatTriple(mesh.mTransform[3]);continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -827,42 +801,44 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+15)))
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->ParseLV4MeshLong(iNumVertices);
|
||||
this->ParseLV4MeshLong(iNumVertices);continue;
|
||||
}
|
||||
// Number of texture coordinates in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMTVERTEX" ,16) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumTVertices);
|
||||
this->ParseLV4MeshLong(iNumTVertices);continue;
|
||||
}
|
||||
// Number of vertex colors in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMCVERTEX" ,16) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumCVertices);
|
||||
this->ParseLV4MeshLong(iNumCVertices);continue;
|
||||
}
|
||||
// Number of regular faces in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMFACES" ,14) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+14)))
|
||||
{
|
||||
this->m_szFile+=15;
|
||||
this->ParseLV4MeshLong(iNumFaces);
|
||||
this->ParseLV4MeshLong(iNumFaces);continue;
|
||||
// fix ...
|
||||
//mesh.mFaces.resize(iNumFaces);
|
||||
}
|
||||
// Number of UVWed faces in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumTFaces);
|
||||
this->ParseLV4MeshLong(iNumTFaces);continue;
|
||||
}
|
||||
// Number of colored faces in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMCVFACES" ,16) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumCFaces);
|
||||
this->ParseLV4MeshLong(iNumCFaces);continue;
|
||||
}
|
||||
// mesh vertex list block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_VERTEX_LIST" ,17) &&
|
||||
@@ -870,6 +846,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=18;
|
||||
this->ParseLV3MeshVertexListBlock(iNumVertices,mesh);
|
||||
continue;
|
||||
}
|
||||
// mesh face list block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_FACE_LIST" ,15) &&
|
||||
@@ -877,7 +854,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshFaceListBlock(iNumFaces,mesh);
|
||||
this->ParseLV3MeshFaceListBlock(iNumFaces,mesh);continue;
|
||||
}
|
||||
// mesh texture vertex list block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
|
||||
@@ -885,7 +862,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshTListBlock(iNumTVertices,mesh);
|
||||
this->ParseLV3MeshTListBlock(iNumTVertices,mesh);continue;
|
||||
}
|
||||
// mesh texture face block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
|
||||
@@ -893,7 +870,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
|
||||
this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);continue;
|
||||
}
|
||||
// mesh color vertex list block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_CVERTLIST" ,15) &&
|
||||
@@ -901,7 +878,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshCListBlock(iNumCVertices,mesh);
|
||||
this->ParseLV3MeshCListBlock(iNumCVertices,mesh);continue;
|
||||
}
|
||||
// mesh color face block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_CFACELIST" ,15) &&
|
||||
@@ -909,7 +886,7 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
|
||||
this->ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);continue;
|
||||
}
|
||||
// another mesh UV channel ...
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_MAPPINGCHANNEL" ,20) &&
|
||||
@@ -942,9 +919,10 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
// parse the mapping channel
|
||||
this->ParseLV3MappingChannel(iIndex-1,mesh);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// mesh animation keyframe. Not supported
|
||||
else if (0 == strncmp(this->m_szFile,"*MESH_ANIMATION" ,15) &&
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_ANIMATION" ,15) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+15)))
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
@@ -952,17 +930,18 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||
this->LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. "
|
||||
"Keyframe animation is not supported by Assimp, this element "
|
||||
"will be ignored");
|
||||
continue;
|
||||
}
|
||||
// mesh animation keyframe. Not supported
|
||||
else if (0 == strncmp(this->m_szFile,"*MESH_WEIGHTS" ,13) &&
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_WEIGHTS" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV3MeshWeightsBlock(mesh);
|
||||
this->ParseLV3MeshWeightsBlock(mesh);continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -991,14 +970,14 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+15)))
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->ParseLV4MeshLong(iNumVertices);
|
||||
this->ParseLV4MeshLong(iNumVertices);continue;
|
||||
}
|
||||
// Number of bones
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMBONE" ,13) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+13)))
|
||||
{
|
||||
this->m_szFile+=14;
|
||||
this->ParseLV4MeshLong(iNumBones);
|
||||
this->ParseLV4MeshLong(iNumBones);continue;
|
||||
}
|
||||
// parse the list of bones
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_BONE_LIST" ,15) &&
|
||||
@@ -1006,7 +985,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
|
||||
{
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV4MeshBones(iNumBones,mesh);
|
||||
this->ParseLV4MeshBones(iNumBones,mesh);continue;
|
||||
}
|
||||
// parse the list of bones vertices
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_BONE_VERTEX_LIST" ,22) &&
|
||||
@@ -1015,10 +994,11 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
|
||||
this->m_szFile+=23;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV4MeshBonesVertices(iNumVertices,mesh);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1058,14 +1038,12 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
|
||||
"bone index instead");
|
||||
}
|
||||
if (!this->ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
|
||||
{
|
||||
this->SkipToNextToken();
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
@@ -1127,9 +1105,10 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh
|
||||
mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
@@ -1170,9 +1149,10 @@ void Parser::ParseLV3MeshVertexListBlock(
|
||||
this->LogWarning("Vertex has an invalid index. It will be ignored");
|
||||
}
|
||||
else mesh.mPositions[iIndex] = vTemp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
@@ -1211,10 +1191,11 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
|
||||
this->LogWarning("Face has an invalid index. It will be ignored");
|
||||
}
|
||||
else mesh.mFaces[mFace.iFace] = mFace;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1260,10 +1241,11 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||
// we need 3 coordinate channels
|
||||
mesh.mNumUVComponents[iChannel] = 3;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1307,10 +1289,11 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||
mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1];
|
||||
mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1340,14 +1323,14 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumTVertices);
|
||||
this->ParseLV4MeshLong(iNumTVertices);continue;
|
||||
}
|
||||
// Number of UVWed faces in the mesh
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_NUMTVFACES" ,16) &&
|
||||
IsSpaceOrNewLine(*(this->m_szFile+16)))
|
||||
{
|
||||
this->m_szFile+=17;
|
||||
this->ParseLV4MeshLong(iNumTFaces);
|
||||
this->ParseLV4MeshLong(iNumTFaces);continue;
|
||||
}
|
||||
// mesh texture vertex list block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_TVERTLIST" ,15) &&
|
||||
@@ -1356,6 +1339,7 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
|
||||
continue;
|
||||
}
|
||||
// mesh texture face block
|
||||
if (0 == strncmp(this->m_szFile,"*MESH_TFACELIST" ,15) &&
|
||||
@@ -1364,10 +1348,11 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
|
||||
this->m_szFile+=16;
|
||||
this->SkipOpeningBracket();
|
||||
this->ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1407,10 +1392,11 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
|
||||
this->LogWarning("Vertex color has an invalid index. It will be ignored");
|
||||
}
|
||||
else mesh.mVertexColors[iIndex] = vTemp;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1453,10 +1439,11 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
|
||||
mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1];
|
||||
mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
@@ -1500,10 +1487,11 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
|
||||
|
||||
// important: this->m_szFile might now point to '}' ...
|
||||
sMesh.mNormals[iIndex] = vNormal;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ('{' == *this->m_szFile)iDepth++;
|
||||
if ('}' == *this->m_szFile)
|
||||
else if ('{' == *this->m_szFile)iDepth++;
|
||||
else if ('}' == *this->m_szFile)
|
||||
{
|
||||
if (0 == --iDepth){++this->m_szFile;this->SkipToNextToken();return;}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ struct BoneVertex
|
||||
struct Mesh
|
||||
{
|
||||
//! Constructor. Creates a default name for the mesh
|
||||
Mesh()
|
||||
Mesh() : bSkip(false)
|
||||
{
|
||||
static int iCnt = 0;
|
||||
std::stringstream ss(mName);
|
||||
@@ -211,6 +211,9 @@ struct Mesh
|
||||
|
||||
//! Number of vertex components for each UVW set
|
||||
unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||
|
||||
//! used internally
|
||||
bool bSkip;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
@@ -24,7 +24,7 @@ const aiMatrix3x3 Assimp::ConvertToLHProcess::sToDXTransform(
|
||||
// Constructor to be privately used by Importer
|
||||
ConvertToLHProcess::ConvertToLHProcess()
|
||||
{
|
||||
// nothing to do here
|
||||
bTransformVertices = false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -38,7 +38,13 @@ ConvertToLHProcess::~ConvertToLHProcess()
|
||||
// Returns whether the processing step is present in the given flag field.
|
||||
bool ConvertToLHProcess::IsActive( unsigned int pFlags) const
|
||||
{
|
||||
return (pFlags & aiProcess_ConvertToLeftHanded) != 0;
|
||||
if (pFlags & aiProcess_ConvertToLeftHanded)
|
||||
{
|
||||
if (pFlags & aiProcess_PreTransformVertices)
|
||||
this->bTransformVertices = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -54,8 +60,34 @@ void ConvertToLHProcess::Execute( aiScene* pScene)
|
||||
|
||||
DefaultLogger::get()->debug("ConvertToLHProcess begin");
|
||||
|
||||
// transform the root node of the scene, the other nodes will follow then
|
||||
ConvertToDX( pScene->mRootNode->mTransformation);
|
||||
// transform vertex by vertex or change the root transform?
|
||||
if (this->bTransformVertices)
|
||||
{
|
||||
this->bTransformVertices = false;
|
||||
aiMatrix4x4 mTransform;
|
||||
this->ConvertToDX(mTransform);
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
{
|
||||
aiMesh* pcMesh = pScene->mMeshes[i];
|
||||
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
||||
{
|
||||
pcMesh->mVertices[n] = mTransform * pcMesh->mVertices[n];
|
||||
}
|
||||
if (pcMesh->HasNormals())
|
||||
{
|
||||
mTransform.Inverse().Transpose();
|
||||
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
||||
{
|
||||
pcMesh->mNormals[n] = mTransform * pcMesh->mNormals[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// transform the root node of the scene, the other nodes will follow then
|
||||
ConvertToDX( pScene->mRootNode->mTransformation);
|
||||
}
|
||||
|
||||
// transform all meshes accordingly
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
|
||||
|
||||
@@ -116,6 +116,10 @@ protected:
|
||||
*/
|
||||
void ProcessAnimation( aiBoneAnim* pAnim);
|
||||
|
||||
//! true if the transformation matrix for the OGL-to-DX is
|
||||
//! directly used to transform all vertices.
|
||||
mutable bool bTransformVertices;
|
||||
|
||||
public:
|
||||
/** The transformation matrix to convert from DirectX coordinates to OpenGL coordinates. */
|
||||
static const aiMatrix3x3 sToOGLTransform;
|
||||
|
||||
161
code/HalfLifeFileData.h
Normal file
161
code/HalfLifeFileData.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
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 Definition of in-memory structures for the HL2 MDL file format
|
||||
// and for the HalfLife text format (SMD)
|
||||
//
|
||||
// The specification has been taken from various sources on the internet.
|
||||
|
||||
|
||||
#ifndef AI_MDLFILEHELPER2_H_INC
|
||||
#define AI_MDLFILEHELPER2_H_INC
|
||||
|
||||
|
||||
// ugly compiler dependent packing stuff
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||
# pragma pack(push,1)
|
||||
# define PACK_STRUCT
|
||||
#elif defined( __GNUC__ )
|
||||
# define PACK_STRUCT __attribute__((packed))
|
||||
#else
|
||||
# error Compiler not supported. Never do this again.
|
||||
#endif
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace MDL
|
||||
{
|
||||
|
||||
// magic bytes used in Half Life 2 MDL models
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2a 'IDST'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2a 'TSDI'
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2b 'IDSQ'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2b 'QSDI'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \struct Header_HL2
|
||||
* \brief Data structure for the HL2 main header
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Header_HL2
|
||||
{
|
||||
//! magic number: "IDST"/"IDSQ"
|
||||
char ident[4];
|
||||
|
||||
//! Version number
|
||||
int32_t version;
|
||||
|
||||
//! Original file name in pak ?
|
||||
char name[64];
|
||||
|
||||
//! Length of file name/length of file?
|
||||
int32_t length;
|
||||
|
||||
//! For viewer, ignored
|
||||
aiVector3D eyeposition;
|
||||
aiVector3D min;
|
||||
aiVector3D max;
|
||||
|
||||
//! AABB of the model
|
||||
aiVector3D bbmin;
|
||||
aiVector3D bbmax;
|
||||
|
||||
// File flags
|
||||
int32_t flags;
|
||||
|
||||
//! NUmber of bones contained in the file
|
||||
int32_t numbones;
|
||||
int32_t boneindex;
|
||||
|
||||
//! Number of bone controllers for bone animation
|
||||
int32_t numbonecontrollers;
|
||||
int32_t bonecontrollerindex;
|
||||
|
||||
//! More bounding boxes ...
|
||||
int32_t numhitboxes;
|
||||
int32_t hitboxindex;
|
||||
|
||||
//! Animation sequences in the file
|
||||
int32_t numseq;
|
||||
int32_t seqindex;
|
||||
|
||||
//! Loaded sequences. Ignored
|
||||
int32_t numseqgroups;
|
||||
int32_t seqgroupindex;
|
||||
|
||||
//! Raw texture data
|
||||
int32_t numtextures;
|
||||
int32_t textureindex;
|
||||
int32_t texturedataindex;
|
||||
|
||||
//! Number of skins (=textures?)
|
||||
int32_t numskinref;
|
||||
int32_t numskinfamilies;
|
||||
int32_t skinindex;
|
||||
|
||||
//! Number of parts
|
||||
int32_t numbodyparts;
|
||||
int32_t bodypartindex;
|
||||
|
||||
//! attachable points for gameplay and physics
|
||||
int32_t numattachments;
|
||||
int32_t attachmentindex;
|
||||
|
||||
//! Table of sound effects associated with the model
|
||||
int32_t soundtable;
|
||||
int32_t soundindex;
|
||||
int32_t soundgroups;
|
||||
int32_t soundgroupindex;
|
||||
|
||||
//! Number of animation transitions
|
||||
int32_t numtransitions;
|
||||
int32_t transitionindex;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// reset packing to the original value
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
|
||||
# pragma pack( pop )
|
||||
#endif
|
||||
#undef PACK_STRUCT
|
||||
|
||||
};}; // end namespaces
|
||||
#endif // ! AI_MDLFILEHELPER2_H_INC
|
||||
@@ -88,6 +88,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "GenVertexNormalsProcess.h"
|
||||
#include "KillNormalsProcess.h"
|
||||
#include "SplitLargeMeshes.h"
|
||||
#include "PretransformVertices.h"
|
||||
#include "../include/DefaultLogger.h"
|
||||
|
||||
using namespace Assimp;
|
||||
@@ -133,6 +134,7 @@ Importer::Importer() :
|
||||
|
||||
// add an instance of each post processing step here in the order of sequence it is executed
|
||||
mPostProcessingSteps.push_back( new TriangulateProcess());
|
||||
mPostProcessingSteps.push_back( new PretransformVertices());
|
||||
mPostProcessingSteps.push_back( new SplitLargeMeshesProcess_Triangle());
|
||||
mPostProcessingSteps.push_back( new KillNormalsProcess());
|
||||
mPostProcessingSteps.push_back( new GenFaceNormalsProcess());
|
||||
|
||||
@@ -67,7 +67,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# error Compiler not supported. Never do this again.
|
||||
#endif
|
||||
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace MDL
|
||||
@@ -95,11 +94,6 @@ namespace MDL
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_GS7 'MDL7'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_GS7 '7LDM'
|
||||
|
||||
// magic bytes used in Half Life 2 MDL models
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2a 'IDST'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2a 'TSDI'
|
||||
#define AI_MDL_MAGIC_NUMBER_BE_HL2b 'IDSQ'
|
||||
#define AI_MDL_MAGIC_NUMBER_LE_HL2b 'QSDI'
|
||||
|
||||
// common limitations for Quake1 meshes. The loader does not check them,
|
||||
// but models should not exceed these limits.
|
||||
@@ -217,86 +211,6 @@ struct Header_MDL7
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \struct Header_HL2
|
||||
* \brief Data structure for the HL2 main header
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct Header_HL2
|
||||
{
|
||||
//! magic number: "IDST"/"IDSQ"
|
||||
char ident[4];
|
||||
|
||||
//! Version number
|
||||
int32_t version;
|
||||
|
||||
//! Original file name in pak ?
|
||||
char name[64];
|
||||
|
||||
//! Length of file name/length of file?
|
||||
int32_t length;
|
||||
|
||||
//! For viewer, ignored
|
||||
aiVector3D eyeposition;
|
||||
aiVector3D min;
|
||||
aiVector3D max;
|
||||
|
||||
//! AABB of the model
|
||||
aiVector3D bbmin;
|
||||
aiVector3D bbmax;
|
||||
|
||||
// File flags
|
||||
int32_t flags;
|
||||
|
||||
//! NUmber of bones contained in the file
|
||||
int32_t numbones;
|
||||
int32_t boneindex;
|
||||
|
||||
//! Number of bone controllers for bone animation
|
||||
int32_t numbonecontrollers;
|
||||
int32_t bonecontrollerindex;
|
||||
|
||||
//! More bounding boxes ...
|
||||
int32_t numhitboxes;
|
||||
int32_t hitboxindex;
|
||||
|
||||
//! Animation sequences in the file
|
||||
int32_t numseq;
|
||||
int32_t seqindex;
|
||||
|
||||
//! Loaded sequences. Ignored
|
||||
int32_t numseqgroups;
|
||||
int32_t seqgroupindex;
|
||||
|
||||
//! Raw texture data
|
||||
int32_t numtextures;
|
||||
int32_t textureindex;
|
||||
int32_t texturedataindex;
|
||||
|
||||
//! Number of skins (=textures?)
|
||||
int32_t numskinref;
|
||||
int32_t numskinfamilies;
|
||||
int32_t skinindex;
|
||||
|
||||
//! Number of parts
|
||||
int32_t numbodyparts;
|
||||
int32_t bodypartindex;
|
||||
|
||||
//! attachable points for gameplay and physics
|
||||
int32_t numattachments;
|
||||
int32_t attachmentindex;
|
||||
|
||||
//! Table of sound effects associated with the model
|
||||
int32_t soundtable;
|
||||
int32_t soundindex;
|
||||
int32_t soundgroups;
|
||||
int32_t soundgroupindex;
|
||||
|
||||
//! Number of animation transitions
|
||||
int32_t numtransitions;
|
||||
int32_t transitionindex;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define AI_MDL7_MAX_BONENAMESIZE 20
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -372,6 +286,12 @@ struct Deformer_MDL7
|
||||
int32_t deformerdata_size;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \struct DeformerElement_MDL7
|
||||
* \brief Deformer element in a MDL7 file
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct DeformerElement_MDL7
|
||||
{
|
||||
//! bei deformer_typ==0 (==bones) element_index == bone index
|
||||
@@ -380,6 +300,12 @@ struct DeformerElement_MDL7
|
||||
int32_t weights;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** \struct DeformerWeight_MDL7
|
||||
* \brief Deformer weight in a MDL7 file
|
||||
*/
|
||||
// ---------------------------------------------------------------------------
|
||||
struct DeformerWeight_MDL7
|
||||
{
|
||||
//! for deformer_typ==0 (==bones) index == vertex index
|
||||
@@ -387,8 +313,11 @@ struct DeformerWeight_MDL7
|
||||
float weight;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// maximum length of texture file name
|
||||
#define AI_MDL7_MAX_TEXNAMESIZE 0x10
|
||||
|
||||
// don't know why this was in the original headers ...
|
||||
// to be removed in future versions
|
||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiNode;
|
||||
#include "MDLFileData.h"
|
||||
#include "HalfLifeFileData.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
378
code/PretransformVertices.cpp
Normal file
378
code/PretransformVertices.cpp
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (ASSIMP)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the ASSIMP team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the ASSIMP Development Team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file Implementation of the "PretransformVertices" post processing step
|
||||
*/
|
||||
#include "PretransformVertices.h"
|
||||
#include "../include/DefaultLogger.h"
|
||||
#include "../include/aiPostProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
#include "../include/aiScene.h"
|
||||
#include "../include/aiAssert.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
// Constructor to be privately used by Importer
|
||||
PretransformVertices::PretransformVertices()
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor, private as well
|
||||
PretransformVertices::~PretransformVertices()
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the processing step is present in the given flag field.
|
||||
bool PretransformVertices::IsActive( unsigned int pFlags) const
|
||||
{
|
||||
return (pFlags & aiProcess_PreTransformVertices) != 0;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Count the number of nodes
|
||||
unsigned int CountNodes( aiNode* pcNode )
|
||||
{
|
||||
unsigned int iRet = 1;
|
||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||
{
|
||||
iRet += CountNodes(pcNode->mChildren[i]);
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Get a bitwise combination identifying the vertex format of a mesh
|
||||
unsigned int GetMeshVFormat(aiMesh* pcMesh)
|
||||
{
|
||||
if (0xdeadbeef == pcMesh->mNumUVComponents[0])
|
||||
return pcMesh->mNumUVComponents[1];
|
||||
|
||||
unsigned int iRet = 0;
|
||||
|
||||
// normals
|
||||
if (pcMesh->HasNormals())iRet |= 0x1;
|
||||
// tangents and bitangents
|
||||
if (pcMesh->HasTangentsAndBitangents())iRet |= 0x2;
|
||||
|
||||
// texture coordinates
|
||||
unsigned int p = 0;
|
||||
ai_assert(4 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
||||
while (pcMesh->HasTextureCoords(p))
|
||||
{
|
||||
iRet |= (0x100 << p++);
|
||||
if (3 == pcMesh->mNumUVComponents[p])
|
||||
iRet |= (0x1000 << p++);
|
||||
}
|
||||
// vertex colors
|
||||
p = 0;
|
||||
while (pcMesh->HasVertexColors(p))iRet |= (0x10000 << p++);
|
||||
|
||||
// store the value for later use
|
||||
pcMesh->mNumUVComponents[0] = 0xdeadbeef;
|
||||
pcMesh->mNumUVComponents[1] = iRet;
|
||||
|
||||
return iRet;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Count the number of vertices in the whole scene and a given
|
||||
// material index
|
||||
void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||
unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices)
|
||||
{
|
||||
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
|
||||
{
|
||||
aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
|
||||
if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
|
||||
{
|
||||
*piVertices += pcMesh->mNumVertices;
|
||||
*piFaces += pcMesh->mNumFaces;
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||
{
|
||||
CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
|
||||
iVFormat,piFaces,piVertices);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#define AI_PTVS_VERTEX 0x0
|
||||
#define AI_PTVS_FACE 0x1
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Collect vertex/face data
|
||||
void CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||
unsigned int iVFormat, aiMesh* pcMeshOut,
|
||||
unsigned int aiCurrent[2])
|
||||
{
|
||||
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
|
||||
{
|
||||
aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
|
||||
if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
|
||||
{
|
||||
// copy positions, transform them to worldspace
|
||||
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
||||
{
|
||||
pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] =
|
||||
pcNode->mTransformation * pcMesh->mVertices[n];
|
||||
}
|
||||
if (iVFormat & 0x1)
|
||||
{
|
||||
aiMatrix4x4 mWorldIT = pcNode->mTransformation;
|
||||
mWorldIT.Inverse().Transpose();
|
||||
|
||||
// copy normals, transform them to worldspace
|
||||
for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)
|
||||
{
|
||||
pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] =
|
||||
mWorldIT * pcMesh->mNormals[n];
|
||||
}
|
||||
}
|
||||
if (iVFormat & 0x2)
|
||||
{
|
||||
// copy tangents
|
||||
memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
|
||||
pcMesh->mTangents,
|
||||
pcMesh->mNumVertices * sizeof(aiVector3D));
|
||||
// copy bitangents
|
||||
memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX],
|
||||
pcMesh->mBitangents,
|
||||
pcMesh->mNumVertices * sizeof(aiVector3D));
|
||||
}
|
||||
unsigned int p = 0;
|
||||
while (iVFormat & (0x100 << p))
|
||||
{
|
||||
// copy texture coordinates
|
||||
memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX],
|
||||
pcMesh->mTextureCoords[p],
|
||||
pcMesh->mNumVertices * sizeof(aiVector3D));
|
||||
++p;
|
||||
}
|
||||
p = 0;
|
||||
while (iVFormat & (0x10000 << p))
|
||||
{
|
||||
// copy vertex colors
|
||||
memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX],
|
||||
pcMesh->mColors[p],
|
||||
pcMesh->mNumVertices * sizeof(aiColor4D));
|
||||
++p;
|
||||
}
|
||||
// now we need to copy all faces
|
||||
// since we will delete the source mesh afterwards,
|
||||
// we don't need to reallocate the array of indices
|
||||
for (unsigned int planck = 0;planck<pcMesh->mNumFaces;++planck)
|
||||
{
|
||||
pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck].mNumIndices =
|
||||
pcMesh->mFaces[planck].mNumIndices;
|
||||
|
||||
unsigned int* pi = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck].
|
||||
mIndices = pcMesh->mFaces[planck].mIndices;
|
||||
|
||||
// offset all vrtex indices
|
||||
for (unsigned int hahn = 0; hahn < pcMesh->mFaces[planck].mNumIndices;++hahn)
|
||||
{
|
||||
pi[hahn] += aiCurrent[AI_PTVS_VERTEX];
|
||||
}
|
||||
|
||||
// just make sure the array won't be deleted by the
|
||||
// aiFace destructor ...
|
||||
pcMesh->mFaces[planck].mIndices = NULL;
|
||||
}
|
||||
aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
|
||||
aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces;
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||
{
|
||||
CollectData(pcScene,pcNode->mChildren[i],iMat,
|
||||
iVFormat,pcMeshOut,aiCurrent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Get a list of all vertex formats that occur for a given material index
|
||||
// The output list contains duplicate elements
|
||||
void GetVFormatList( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
|
||||
std::list<unsigned int>& aiOut)
|
||||
{
|
||||
for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
|
||||
{
|
||||
aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
|
||||
if (iMat == pcMesh->mMaterialIndex)
|
||||
{
|
||||
aiOut.push_back(GetMeshVFormat(pcMesh));
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||
{
|
||||
GetVFormatList(pcScene,pcNode->mChildren[i],iMat,aiOut);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Compute the absolute transformation matrices of each node
|
||||
void ComputeAbsoluteTransform( aiNode* pcNode )
|
||||
{
|
||||
if (pcNode->mParent)
|
||||
{
|
||||
pcNode->mTransformation = pcNode->mTransformation*pcNode->mParent->mTransformation;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
|
||||
{
|
||||
ComputeAbsoluteTransform(pcNode->mChildren[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported data.
|
||||
void PretransformVertices::Execute( aiScene* pScene)
|
||||
{
|
||||
DefaultLogger::get()->debug("PretransformVerticesProcess begin");
|
||||
|
||||
// first compute absolute transformation matrices for all nodes
|
||||
ComputeAbsoluteTransform(pScene->mRootNode);
|
||||
|
||||
// now build a list of output meshes
|
||||
std::vector<aiMesh*> apcOutMeshes;
|
||||
apcOutMeshes.reserve(pScene->mNumMaterials*2);
|
||||
std::list<unsigned int> aiVFormats;
|
||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||
{
|
||||
// get the list of all vertex formats for this material
|
||||
aiVFormats.clear();
|
||||
GetVFormatList(pScene,pScene->mRootNode,i,aiVFormats);
|
||||
aiVFormats.sort(std::less<unsigned int>());
|
||||
aiVFormats.unique();
|
||||
for (std::list<unsigned int>::const_iterator
|
||||
j = aiVFormats.begin();
|
||||
j != aiVFormats.end();++j)
|
||||
{
|
||||
unsigned int iVertices = 0;
|
||||
unsigned int iFaces = 0;
|
||||
CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices);
|
||||
if (iFaces && iVertices)
|
||||
{
|
||||
apcOutMeshes.push_back(new aiMesh());
|
||||
aiMesh* pcMesh = apcOutMeshes.back();
|
||||
pcMesh->mNumFaces = iFaces;
|
||||
pcMesh->mNumVertices = iVertices;
|
||||
pcMesh->mFaces = new aiFace[iFaces];
|
||||
pcMesh->mVertices = new aiVector3D[iVertices];
|
||||
pcMesh->mMaterialIndex = i;
|
||||
if ((*j) & 0x1)pcMesh->mNormals = new aiVector3D[iVertices];
|
||||
if ((*j) & 0x2)
|
||||
{
|
||||
pcMesh->mTangents = new aiVector3D[iVertices];
|
||||
pcMesh->mBitangents = new aiVector3D[iVertices];
|
||||
}
|
||||
iFaces = 0;
|
||||
while ((*j) & (0x100 << iFaces))
|
||||
{
|
||||
pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
|
||||
if ((*j) & (0x1000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3;
|
||||
else pcMesh->mNumUVComponents[iFaces] = 2;
|
||||
iFaces++;
|
||||
}
|
||||
iFaces = 0;
|
||||
while ((*j) & (0x10000 << iFaces))
|
||||
pcMesh->mColors[iFaces] = new aiColor4D[iVertices];
|
||||
|
||||
// fill the mesh ...
|
||||
unsigned int aiTemp[2] = {0,0};
|
||||
CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove all animations from the scene
|
||||
for (unsigned int i = 0; i < pScene->mNumAnimations;++i)
|
||||
delete pScene->mAnimations[i];
|
||||
pScene->mAnimations = NULL;
|
||||
pScene->mNumAnimations = 0;
|
||||
|
||||
// now delete all meshes in the scene and build a new mesh list
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
delete pScene->mMeshes[i];
|
||||
if (apcOutMeshes.size() != pScene->mNumMeshes)
|
||||
{
|
||||
delete[] pScene->mMeshes;
|
||||
pScene->mNumMeshes = apcOutMeshes.size();
|
||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
}
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
pScene->mMeshes[i] = apcOutMeshes[i];
|
||||
|
||||
// now delete all nodes in the scene and build a new
|
||||
// flat node graph with a root node and some level 1 children
|
||||
delete pScene->mRootNode;
|
||||
pScene->mRootNode = new aiNode();
|
||||
pScene->mRootNode->mName.Set("<dummy_root>");
|
||||
|
||||
if (1 == pScene->mNumMeshes)
|
||||
{
|
||||
pScene->mRootNode->mNumMeshes = 1;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||
pScene->mRootNode->mMeshes[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
|
||||
pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||
{
|
||||
aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||
pcNode->mName.length = sprintf(pcNode->mName.data,"dummy_%i",i);
|
||||
|
||||
pcNode->mNumMeshes = 1;
|
||||
pcNode->mMeshes = new unsigned int[1];
|
||||
pcNode->mMeshes[0] = i;
|
||||
pcNode->mParent = pScene->mRootNode;
|
||||
}
|
||||
}
|
||||
|
||||
DefaultLogger::get()->debug("PretransformVerticesProcess finished. All "
|
||||
"vertices are in worldspace now");
|
||||
return;
|
||||
}
|
||||
|
||||
88
code/PretransformVertices.h
Normal file
88
code/PretransformVertices.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 Defines a post processing step to pretransform all
|
||||
vertices in the scenegraph */
|
||||
#ifndef AI_PRETRANSFORMVERTICES_H_INC
|
||||
#define AI_PRETRANSFORMVERTICES_H_INC
|
||||
|
||||
#include "BaseProcess.h"
|
||||
#include "../include/aiMesh.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The PretransformVertices pretransforms all vertices in the nodegraph
|
||||
* and removes the whole graph. The output is a list of meshes, one for
|
||||
* each material.
|
||||
*/
|
||||
class PretransformVertices : public BaseProcess
|
||||
{
|
||||
friend class Importer;
|
||||
|
||||
protected:
|
||||
/** Constructor to be privately used by Importer */
|
||||
PretransformVertices ();
|
||||
|
||||
/** Destructor, private as well */
|
||||
~PretransformVertices ();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the processing step is present in the given flag field.
|
||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||
* combination of #aiPostProcessSteps.
|
||||
* @return true if the process is present in this flag fields, false if not.
|
||||
*/
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Executes the post processing step on the given imported data.
|
||||
* At the moment a process is not supposed to fail.
|
||||
* @param pScene The imported data to work at.
|
||||
*/
|
||||
void Execute( aiScene* pScene);
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // !!AI_GENFACENORMALPROCESS_H_INC
|
||||
Reference in New Issue
Block a user