- 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-9d2fd5bffc1f
pull/1/head
jonathanklein 2010-04-19 17:50:52 +00:00
parent 0695775bc4
commit a85b851442
3 changed files with 103 additions and 50 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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")
{ {