- Multiple Submeshes are loaded now
- In standard materials the colors are now loaded - not excessively tested, but it should work git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@704 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
0695775bc4
commit
a85b851442
|
@ -70,40 +70,35 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------Read the submesh:-----------------------
|
//-------------------Read the submeshs and materials:-----------------------
|
||||||
SubMesh theSubMesh;
|
std::list<shared_ptr<SubMesh> > SubMeshes;
|
||||||
|
vector<aiMaterial*> Materials;
|
||||||
XmlRead(MeshFile);
|
XmlRead(MeshFile);
|
||||||
if(MeshFile->getNodeName()==string("submesh"))
|
while(MeshFile->getNodeName()==string("submesh"))
|
||||||
{
|
{
|
||||||
theSubMesh.MaterialName=GetAttribute<string>(MeshFile, "material");
|
SubMesh* theSubMesh=new SubMesh();
|
||||||
DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh.MaterialName);
|
theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material");
|
||||||
ReadSubMesh(theSubMesh, MeshFile);
|
DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
|
||||||
|
ReadSubMesh(*theSubMesh, MeshFile);
|
||||||
|
|
||||||
|
//just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
|
||||||
|
//so it is important to do this before pushing the mesh in the vector!
|
||||||
|
theSubMesh->MaterialIndex=SubMeshes.size();
|
||||||
|
|
||||||
|
SubMeshes.push_back(shared_ptr<SubMesh>(theSubMesh));
|
||||||
|
|
||||||
//Load the Material:
|
//Load the Material:
|
||||||
aiMaterial* MeshMat=LoadMaterial(theSubMesh.MaterialName);
|
aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName);
|
||||||
|
|
||||||
//Set the Material:
|
//Set the Material:
|
||||||
if(m_CurrentScene->mMaterials)
|
Materials.push_back(MeshMat);
|
||||||
throw DeadlyImportError("only 1 material supported at this time!");
|
|
||||||
m_CurrentScene->mMaterials=new aiMaterial*[1];
|
|
||||||
m_CurrentScene->mNumMaterials=1;
|
|
||||||
m_CurrentScene->mMaterials[0]=MeshMat;
|
|
||||||
theSubMesh.MaterialIndex=0;
|
|
||||||
}
|
}
|
||||||
//check for second root node:
|
|
||||||
if(MeshFile->getNodeName()==string("submesh"))
|
|
||||||
throw DeadlyImportError("more than one submesh in the file, abording!");
|
|
||||||
|
|
||||||
//____________________________________________________________
|
if(SubMeshes.empty())
|
||||||
|
throw DeadlyImportError("no submesh loaded!");
|
||||||
|
if(SubMeshes.size()!=Materials.size())
|
||||||
|
throw DeadlyImportError("materialcount doesn't match mesh count!");
|
||||||
|
|
||||||
|
|
||||||
//-----------------Create the root node-----------------------
|
|
||||||
pScene->mRootNode=new aiNode("root");
|
|
||||||
|
|
||||||
//link the mesh with the root node:
|
|
||||||
pScene->mRootNode->mMeshes=new unsigned int[1];
|
|
||||||
pScene->mRootNode->mMeshes[0]=0;
|
|
||||||
pScene->mRootNode->mNumMeshes=1;
|
|
||||||
//____________________________________________________________
|
//____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,8 +117,39 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
|
||||||
}
|
}
|
||||||
//__________________________________________________________________
|
//__________________________________________________________________
|
||||||
|
|
||||||
CreateAssimpSubMesh(theSubMesh, Bones);
|
|
||||||
|
//----------------- Now fill the Assimp scene ---------------------------
|
||||||
|
|
||||||
|
//put the aiMaterials in the scene:
|
||||||
|
m_CurrentScene->mMaterials=new aiMaterial*[Materials.size()];
|
||||||
|
m_CurrentScene->mNumMaterials=Materials.size();
|
||||||
|
for(unsigned int i=0; i<Materials.size(); ++i)
|
||||||
|
m_CurrentScene->mMaterials[i]=Materials[i];
|
||||||
|
|
||||||
|
//create the aiMehs...
|
||||||
|
vector<aiMesh*> aiMeshes;
|
||||||
|
BOOST_FOREACH(shared_ptr<SubMesh> theSubMesh, SubMeshes)
|
||||||
|
{
|
||||||
|
aiMeshes.push_back(CreateAssimpSubMesh(*theSubMesh, Bones));
|
||||||
|
}
|
||||||
|
//... and put them in the scene:
|
||||||
|
m_CurrentScene->mNumMeshes=aiMeshes.size();
|
||||||
|
m_CurrentScene->mMeshes=new aiMesh*[aiMeshes.size()];
|
||||||
|
memcpy(m_CurrentScene->mMeshes, &(aiMeshes[0]), sizeof(aiMeshes[0])*aiMeshes.size());
|
||||||
|
|
||||||
|
//Create the root node
|
||||||
|
m_CurrentScene->mRootNode=new aiNode("root");
|
||||||
|
|
||||||
|
//link the meshs with the root node:
|
||||||
|
m_CurrentScene->mRootNode->mMeshes=new unsigned int[SubMeshes.size()];
|
||||||
|
m_CurrentScene->mRootNode->mNumMeshes=SubMeshes.size();
|
||||||
|
for(unsigned int i=0; i<SubMeshes.size(); ++i)
|
||||||
|
m_CurrentScene->mRootNode->mMeshes[i]=i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CreateAssimpSkeleton(Bones, Animations);
|
CreateAssimpSkeleton(Bones, Animations);
|
||||||
|
//___________________________________________________________
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,20 +357,12 @@ void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& Bones)
|
aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<Bone>& Bones) const
|
||||||
{
|
{
|
||||||
//Mesh is fully loaded, copy it into the aiScene:
|
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
||||||
if(m_CurrentScene->mNumMeshes!=0)
|
|
||||||
throw DeadlyImportError("Currently only one mesh per File is allowed!!");
|
|
||||||
|
|
||||||
aiMesh* NewAiMesh=new aiMesh();
|
aiMesh* NewAiMesh=new aiMesh();
|
||||||
|
|
||||||
//Attach the mesh to the scene:
|
|
||||||
m_CurrentScene->mNumMeshes=1;
|
|
||||||
m_CurrentScene->mMeshes=new aiMesh*;
|
|
||||||
m_CurrentScene->mMeshes[0]=NewAiMesh;
|
|
||||||
|
|
||||||
|
|
||||||
//Positions
|
//Positions
|
||||||
NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()];
|
NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()];
|
||||||
memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D));
|
memcpy(NewAiMesh->mVertices, &theSubMesh.Positions[0], theSubMesh.Positions.size()*sizeof(aiVector3D));
|
||||||
|
@ -426,11 +444,16 @@ void OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vector<B
|
||||||
|
|
||||||
//Link the material:
|
//Link the material:
|
||||||
NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh
|
NewAiMesh->mMaterialIndex=theSubMesh.MaterialIndex;//the index is set by the function who called ReadSubMesh
|
||||||
|
|
||||||
|
return NewAiMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations)
|
void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations) const
|
||||||
{
|
{
|
||||||
|
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
||||||
|
|
||||||
|
|
||||||
//most likely the skeleton file will only end with .skeleton
|
//most likely the skeleton file will only end with .skeleton
|
||||||
//But this is a xml reader, so we need: .skeleton.xml
|
//But this is a xml reader, so we need: .skeleton.xml
|
||||||
FileName+=".xml";
|
FileName+=".xml";
|
||||||
|
@ -500,6 +523,7 @@ void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vecto
|
||||||
}
|
}
|
||||||
//The bones in the file a not neccesarly ordered by there id's so we do it now:
|
//The bones in the file a not neccesarly ordered by there id's so we do it now:
|
||||||
std::sort(Bones.begin(), Bones.end());
|
std::sort(Bones.begin(), Bones.end());
|
||||||
|
|
||||||
//now the id of each bone should be equal to its position in the vector:
|
//now the id of each bone should be equal to its position in the vector:
|
||||||
//so we do a simple check:
|
//so we do a simple check:
|
||||||
{
|
{
|
||||||
|
@ -633,8 +657,10 @@ void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vecto
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations)
|
void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations) const
|
||||||
{
|
{
|
||||||
|
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
||||||
|
|
||||||
//-----------------skeleton is completly loaded, now put it in the assimp scene:-------------------------------
|
//-----------------skeleton is completly loaded, now put it in the assimp scene:-------------------------------
|
||||||
|
|
||||||
if(!m_CurrentScene->mRootNode)
|
if(!m_CurrentScene->mRootNode)
|
||||||
|
@ -657,8 +683,11 @@ void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const st
|
||||||
m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()];
|
m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()];
|
||||||
memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size());
|
memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size());
|
||||||
//_______________________________________________________________
|
//_______________________________________________________________
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OgreImporter::PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations)
|
||||||
|
{
|
||||||
//-----------------Create the Assimp Animations --------------------
|
//-----------------Create the Assimp Animations --------------------
|
||||||
if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have benn called
|
if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have benn called
|
||||||
{
|
{
|
||||||
|
@ -739,8 +768,10 @@ void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const st
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode)
|
aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode) const
|
||||||
{
|
{
|
||||||
|
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
||||||
|
|
||||||
//----Create the node for this bone and set its values-----
|
//----Create the node for this bone and set its values-----
|
||||||
aiNode* NewNode=new aiNode(Bones[BoneId].Name);
|
aiNode* NewNode=new aiNode(Bones[BoneId].Name);
|
||||||
NewNode->mParent=ParentNode;
|
NewNode->mParent=ParentNode;
|
||||||
|
|
|
@ -32,14 +32,23 @@ private:
|
||||||
|
|
||||||
/// Helper Functions to read parts of the XML File
|
/// Helper Functions to read parts of the XML File
|
||||||
void ReadSubMesh(SubMesh& theSubMesh, XmlReader* Reader);//the submesh reference is the result value
|
void ReadSubMesh(SubMesh& theSubMesh, XmlReader* Reader);//the submesh reference is the result value
|
||||||
void LoadSkeleton(std::string FileName, std::vector<Bone> &Bones, std::vector<Animation> &Animations);///< writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
|
|
||||||
void CreateAssimpSubMesh(const SubMesh &theSubMesh, const std::vector<Bone>& Bones);
|
|
||||||
void CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
|
|
||||||
|
|
||||||
aiMaterial* LoadMaterial(const std::string MaterialName);
|
/// writes the results in Bones and Animations, Filename is not const, because its call-by-value and the function will change it!
|
||||||
|
void LoadSkeleton(std::string FileName, std::vector<Bone> &Bones, std::vector<Animation> &Animations) const;
|
||||||
|
|
||||||
|
/// converts the animations in aiAnimations and puts them into the scene
|
||||||
|
void PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations);
|
||||||
|
|
||||||
|
/// uses the bone data to convert a SubMesh into a aiMesh which will be created and returned
|
||||||
|
aiMesh* CreateAssimpSubMesh(const SubMesh &theSubMesh, const std::vector<Bone>& Bones) const;
|
||||||
|
|
||||||
|
|
||||||
|
void CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations) const;
|
||||||
|
|
||||||
|
aiMaterial* LoadMaterial(const std::string MaterialName) const;
|
||||||
|
|
||||||
///Recursivly creates a filled aiNode from a given root bone
|
///Recursivly creates a filled aiNode from a given root bone
|
||||||
aiNode* CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode);
|
aiNode* CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode) const;
|
||||||
|
|
||||||
//Now we don't have to give theses parameters to all functions
|
//Now we don't have to give theses parameters to all functions
|
||||||
std::string m_CurrentFilename;
|
std::string m_CurrentFilename;
|
||||||
|
|
|
@ -26,8 +26,10 @@ namespace Ogre
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName)
|
aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
|
||||||
{
|
{
|
||||||
|
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
|
||||||
|
|
||||||
MaterialHelper *NewMaterial=new MaterialHelper();
|
MaterialHelper *NewMaterial=new MaterialHelper();
|
||||||
|
|
||||||
aiString ts(MaterialName.c_str());
|
aiString ts(MaterialName.c_str());
|
||||||
|
@ -70,7 +72,7 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName)
|
||||||
MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
|
MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
|
||||||
if(NULL==MatFilePtr)
|
if(NULL==MatFilePtr)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opned, Material will not be loaded!");
|
DefaultLogger::get()->error(m_MaterialLibFilename+" and "+MaterialFileName + " could not be opened, Material will not be loaded!");
|
||||||
return NewMaterial;
|
return NewMaterial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,16 +120,27 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName)
|
||||||
ss >> Line;
|
ss >> Line;
|
||||||
if(Line=="ambient")
|
if(Line=="ambient")
|
||||||
{
|
{
|
||||||
//read the ambient light values:
|
aiColor3D Color;
|
||||||
|
ss >> Color.r >> Color.g >> Color.b;
|
||||||
|
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||||
}
|
}
|
||||||
else if(Line=="diffuse")
|
else if(Line=="diffuse")
|
||||||
{
|
{
|
||||||
|
aiColor3D Color;
|
||||||
|
ss >> Color.r >> Color.g >> Color.b;
|
||||||
|
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
}
|
}
|
||||||
else if(Line=="specular")
|
else if(Line=="specular")
|
||||||
{
|
{
|
||||||
|
aiColor3D Color;
|
||||||
|
ss >> Color.r >> Color.g >> Color.b;
|
||||||
|
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_SPECULAR);
|
||||||
}
|
}
|
||||||
else if(Line=="emmisive")
|
else if(Line=="emmisive")
|
||||||
{
|
{
|
||||||
|
aiColor3D Color;
|
||||||
|
ss >> Color.r >> Color.g >> Color.b;
|
||||||
|
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE);
|
||||||
}
|
}
|
||||||
else if(Line=="texture_unit")
|
else if(Line=="texture_unit")
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue