- 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:-----------------------
SubMesh theSubMesh;
//-------------------Read the submeshs and materials:-----------------------
std::list<shared_ptr<SubMesh> > SubMeshes;
vector<aiMaterial*> Materials;
XmlRead(MeshFile);
if(MeshFile->getNodeName()==string("submesh"))
while(MeshFile->getNodeName()==string("submesh"))
{
theSubMesh.MaterialName=GetAttribute<string>(MeshFile, "material");
DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh.MaterialName);
ReadSubMesh(theSubMesh, MeshFile);
SubMesh* theSubMesh=new SubMesh();
theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material");
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:
aiMaterial* MeshMat=LoadMaterial(theSubMesh.MaterialName);
aiMaterial* MeshMat=LoadMaterial(theSubMesh->MaterialName);
//Set the Material:
if(m_CurrentScene->mMaterials)
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;
Materials.push_back(MeshMat);
}
//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);
//___________________________________________________________
}
@ -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:
if(m_CurrentScene->mNumMeshes!=0)
throw DeadlyImportError("Currently only one mesh per File is allowed!!");
const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
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
NewAiMesh->mVertices=new aiVector3D[theSubMesh.Positions.size()];
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:
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
//But this is a xml reader, so we need: .skeleton.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:
std::sort(Bones.begin(), Bones.end());
//now the id of each bone should be equal to its position in the vector:
//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:-------------------------------
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()];
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 --------------------
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-----
aiNode* NewNode=new aiNode(Bones[BoneId].Name);
NewNode->mParent=ParentNode;

View File

@ -32,14 +32,23 @@ private:
/// Helper Functions to read parts of the XML File
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
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
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();
aiString ts(MaterialName.c_str());
@ -70,7 +72,7 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName)
MatFilePtr=m_CurrentIOHandler->Open(m_MaterialLibFilename);
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;
}
}
@ -118,16 +120,27 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName)
ss >> Line;
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")
{
aiColor3D Color;
ss >> Color.r >> Color.g >> Color.b;
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_DIFFUSE);
}
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")
{
aiColor3D Color;
ss >> Color.r >> Color.g >> Color.b;
NewMaterial->AddProperty(&Color, 1, AI_MATKEY_COLOR_EMISSIVE);
}
else if(Line=="texture_unit")
{