diff --git a/code/OgreImporter.hpp b/code/OgreImporter.hpp index d9dd87e7b..80a12f28a 100644 --- a/code/OgreImporter.hpp +++ b/code/OgreImporter.hpp @@ -38,14 +38,14 @@ struct SubMesh std::vector Positions; bool HasPositions; std::vector Normals; bool HasNormals; std::vector Tangents; bool HasTangents; - std::vector Uvs; unsigned int NumUvs;//nearly always 2d, but assimp has always 3d texcoords + std::vector > Uvs;//arbitrary number of texcoords, they are nearly always 2d, but assimp has always 3d texcoords, n vectors(outer) with texcoords for each vertex(inner) - std::vector< std::vector > Weights;//a list of bones for each vertex + std::vector< std::vector > Weights;//a list(inner) of bones for each vertex(outer) int MaterialIndex;///< The Index in the Assimp Materialarray from the material witch is attached to this submesh unsigned int BonesUsed;//the highest index of a bone from a bone weight, this is needed to create the assimp bone structur (converting from Vertex-Bones to Bone-Vertices) SubMesh(): SharedData(false), HasPositions(false), HasNormals(false), HasTangents(false), - NumUvs(0), MaterialIndex(-1), BonesUsed(0) {}//initialize everything + MaterialIndex(-1), BonesUsed(0) {}//initialize everything }; diff --git a/code/OgreMaterial.cpp b/code/OgreMaterial.cpp index 177c8eac1..64de3a861 100644 --- a/code/OgreMaterial.cpp +++ b/code/OgreMaterial.cpp @@ -282,6 +282,9 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const void OgreImporter::ReadTechnique(stringstream &ss, aiMaterial* NewMaterial) { + unsigned int CurrentTextureId=0; + + string RestOfLine; getline(ss, RestOfLine);//ignore the rest of the line @@ -349,11 +352,33 @@ void OgreImporter::ReadTechnique(stringstream &ss, aiMaterial* NewMaterial) { ss >> Line; aiString ts(Line.c_str()); - NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + NewMaterial->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, CurrentTextureId)); } + else if(Line=="tex_coord_set") + { + int UvSet; + ss >> UvSet; + NewMaterial->AddProperty(&UvSet, 1, AI_MATKEY_UVWSRC(0, CurrentTextureId)); + } + else if(Line=="colour_op") + { + ss >> Line; + if("replace"==Line)//I don't think, assimp has something for this... + { + } + else if("modulate"==Line) + { + //TODO: set value + //NewMaterial->AddProperty(aiTextureOp_Multiply) + } + } + }//end of texture unit + Line="";//clear the } that would end the outer loop + CurrentTextureId++;//new Id for the next texture } } + Line="";//clear the } that would end the outer loop } }//end of technique } diff --git a/code/OgreMesh.cpp b/code/OgreMesh.cpp index 3035038aa..39278b1ec 100644 --- a/code/OgreMesh.cpp +++ b/code/OgreMesh.cpp @@ -111,8 +111,11 @@ void OgreImporter::ReadSubMesh(SubMesh &theSubMesh, XmlReader *Reader) if(theSubMesh.HasTangents && theSubMesh.Tangents.size() != NumVertices) throw DeadlyImportError("Wrong Number of Tangents loaded!"); - if(theSubMesh.NumUvs==1 && theSubMesh.Uvs.size() != NumVertices) - throw DeadlyImportError("Wrong Number of Uvs loaded!"); + for(unsigned int i=0; igetAttributeValue("positions") && GetAttribute(Reader, "positions")) @@ -161,26 +164,18 @@ void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsi DefaultLogger::get()->debug("reading tangents"); } - - //we can have 1 or 0 uv channels, and if the mesh has no uvs, it also doesn't have the attribute - if(!Reader->getAttributeValue("texture_coords")) - theSubMesh.NumUvs=0; - else + if(Reader->getAttributeValue("texture_coords")) { - ReadUvs=!!(theSubMesh.NumUvs=GetAttribute(Reader, "texture_coords")); - theSubMesh.Uvs.reserve(NumVertices); + NumUvs=GetAttribute(Reader, "texture_coords"); + theSubMesh.Uvs.resize(NumUvs); + for(unsigned int i=0; idebug("reading texture coords"); } - if(theSubMesh.NumUvs>1) - { - DefaultLogger::get()->warn("too many texcoords (just 1 supported!), just the first texcoords will be loaded!"); - theSubMesh.NumUvs=1; - } //___________________________________________________________________ //check if we will load anything - if(!(ReadPositions || ReadNormals || ReadTangents || ReadUvs)) + if(!( ReadPositions || ReadNormals || ReadTangents || (NumUvs>0) )) DefaultLogger::get()->warn("vertexbuffer seams to be empty!"); @@ -230,17 +225,21 @@ void OgreImporter::ReadVertexBuffer(SubMesh &theSubMesh, XmlReader *Reader, unsi } //Uv: - else if(ReadUvs && Reader->getNodeName()==string("texcoord")) + else if(NumUvs>0 && Reader->getNodeName()==string("texcoord")) { - aiVector3D NewUv; - NewUv.x=GetAttribute(Reader, "u"); - NewUv.y=GetAttribute(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so! - theSubMesh.Uvs.push_back(NewUv); - - //skip all the following texcoords: - while(Reader->getNodeName()==string("texcoord")) + for(unsigned int i=0; igetNodeName()!=string("texcoord")) + { + DefaultLogger::get()->warn(string("Not enough UVs in Vertex: ")+Reader->getNodeName()); + } + aiVector3D NewUv; + NewUv.x=GetAttribute(Reader, "u"); + NewUv.y=GetAttribute(Reader, "v")*(-1)+1;//flip the uv vertikal, blender exports them so! + theSubMesh.Uvs[i].push_back(NewUv); XmlRead(Reader); - continue;//don't read another line at the end of the loop + } + continue;//because we already read the next node... } //Color: @@ -284,12 +283,20 @@ void OgreImporter::ProcessSubMesh(SubMesh &theSubMesh, SubMesh &theSharedGeometr //---------------Make all Vertexes unique: (this is required by assimp)----------------------- vector UniqueFaceList(theSubMesh.FaceList.size()); unsigned int UniqueVertexCount=theSubMesh.FaceList.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^ + vector UniquePositions(UniqueVertexCount); + vector UniqueNormals(UniqueVertexCount); + vector UniqueTangents(UniqueVertexCount); - vector UniqueUvs(UniqueVertexCount); + vector< vector > UniqueWeights(UniqueVertexCount); + vector< vector > UniqueUvs(theSubMesh.Uvs.size()); + for(unsigned int i=0; i 0) - { - DefaultLogger::get()->error("Not all Uvs will be made unique!"); + UniqueUvs.resize(theSharedGeometry.Uvs.size()); + for(unsigned int i=0; i 0) + if(UniqueUvs.size()>0) { - UniqueUvs[3*i+0]=VertexSource.Uvs[Vertex1]; - UniqueUvs[3*i+1]=VertexSource.Uvs[Vertex2]; - UniqueUvs[3*i+2]=VertexSource.Uvs[Vertex3]; + for(unsigned int j=0; j 0) @@ -425,11 +432,14 @@ aiMesh* OgreImporter::CreateAssimpSubMesh(const SubMesh& theSubMesh, const vecto */ //Uvs - if(0!=theSubMesh.NumUvs) + if(theSubMesh.Uvs.size()>0) { - NewAiMesh->mNumUVComponents[0]=2; - NewAiMesh->mTextureCoords[0]= new aiVector3D[theSubMesh.Uvs.size()]; - memcpy(NewAiMesh->mTextureCoords[0], &theSubMesh.Uvs[0], theSubMesh.Uvs.size()*sizeof(aiVector3D)); + for(unsigned int i=0; imNumUVComponents[i]=2; + NewAiMesh->mTextureCoords[i]=new aiVector3D[theSubMesh.Uvs[i].size()]; + memcpy(NewAiMesh->mTextureCoords[i], &(theSubMesh.Uvs[i][0]), theSubMesh.Uvs[i].size()*sizeof(aiVector3D)); + } } diff --git a/code/OgreXmlHelper.hpp b/code/OgreXmlHelper.hpp index 34779a605..8a71a4be5 100644 --- a/code/OgreXmlHelper.hpp +++ b/code/OgreXmlHelper.hpp @@ -29,6 +29,15 @@ template<> inline int GetAttribute(XmlReader* Reader, std::string Name) throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str()); } +template<> inline unsigned int GetAttribute(XmlReader* Reader, std::string Name) +{ + const char* Value=Reader->getAttributeValue(Name.c_str()); + if(Value) + return static_cast(atoi(Value));//yes, ugly, but pfff + else + throw DeadlyImportError(std::string("Attribute "+Name+" does not exist in "+Reader->getNodeName()).c_str()); +} + template<> inline float GetAttribute(XmlReader* Reader, std::string Name) { const char* Value=Reader->getAttributeValue(Name.c_str());