OgreImporter: One more function cleanup.

pull/266/head
Jonne Nauha 2014-05-02 00:56:35 +03:00
parent 283394d695
commit 409c2cf332
2 changed files with 75 additions and 90 deletions

View File

@ -200,9 +200,9 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
ReadBoneWeights(m_SharedGeometry, reader.get()); ReadBoneWeights(m_SharedGeometry, reader.get());
// -------------------- Process Results -------------------- // -------------------- Process Results --------------------
BOOST_FOREACH(boost::shared_ptr<SubMesh> theSubMesh, subMeshes) BOOST_FOREACH(boost::shared_ptr<SubMesh> submesh, subMeshes)
{ {
ProcessSubMesh(*theSubMesh, m_SharedGeometry); ProcessSubMesh(*submesh.get(), m_SharedGeometry);
} }
// -------------------- Apply to aiScene -------------------- // -------------------- Apply to aiScene --------------------

View File

@ -324,123 +324,108 @@ void OgreImporter::ReadBoneWeights(SubMesh &submesh, XmlReader *reader)
void OgreImporter::ProcessSubMesh(SubMesh &submesh, SubMesh &sharedGeometry) void OgreImporter::ProcessSubMesh(SubMesh &submesh, SubMesh &sharedGeometry)
{ {
//---------------Make all Vertexes unique: (this is required by assimp)----------------------- // Make all vertexes unique. Required by Assimp.
vector<Face> UniqueFaceList(submesh.Faces.size()); vector<Face> uniqueFaceList(submesh.Faces.size());
unsigned int UniqueVertexCount=submesh.Faces.size()*3;//*3 because each face consists of 3 vertexes, because we only support triangles^^ unsigned int uniqueVertexCount = submesh.Faces.size() * 3;
vector<aiVector3D> UniquePositions(UniqueVertexCount); vector<aiVector3D> uniquePositions(uniqueVertexCount);
vector<aiVector3D> uniqueNormals(uniqueVertexCount);
vector<aiVector3D> uniqueTangents(uniqueVertexCount);
vector<aiVector3D> UniqueNormals(UniqueVertexCount); vector<vector<BoneWeight> > uniqueWeights(uniqueVertexCount);
vector<vector<aiVector3D> > uniqueUvs(submesh.UseSharedGeometry ? sharedGeometry.Uvs.size() : submesh.Uvs.size());
vector<aiVector3D> UniqueTangents(UniqueVertexCount); for(size_t uvi=0; uvi<uniqueUvs.size(); ++uvi)
uniqueUvs[uvi].resize(uniqueVertexCount);
vector< vector<BoneWeight> > UniqueWeights(UniqueVertexCount); /* Support for shared geometry.
We can use this loop to copy vertex informations from the shared data pool. In order to do so
vector< vector<aiVector3D> > UniqueUvs(submesh.Uvs.size());
for(unsigned int i=0; i<UniqueUvs.size(); ++i) UniqueUvs[i].resize(UniqueVertexCount);
//Support for shared data:
/*We can use this loop to copy vertex informations from the shared data pool. In order to do so
we just use a reference to a submodel instead of our submodel itself */ we just use a reference to a submodel instead of our submodel itself */
SubMesh &vertexSource = (submesh.UseSharedGeometry ? sharedGeometry : submesh);
SubMesh& VertexSource= submesh.UseSharedGeometry ? sharedGeometry : submesh; if (submesh.UseSharedGeometry)
if(submesh.UseSharedGeometry)//copy vertexinformations to our mesh:
{ {
submesh.HasPositions = sharedGeometry.HasPositions; submesh.HasPositions = sharedGeometry.HasPositions;
submesh.HasNormals = sharedGeometry.HasNormals; submesh.HasNormals = sharedGeometry.HasNormals;
submesh.HasTangents = sharedGeometry.HasTangents; submesh.HasTangents = sharedGeometry.HasTangents;
submesh.BonesUsed = sharedGeometry.BonesUsed; submesh.BonesUsed = sharedGeometry.BonesUsed;
UniqueUvs.resize(sharedGeometry.Uvs.size());
for(unsigned int i=0; i<UniqueUvs.size(); ++i) UniqueUvs[i].resize(UniqueVertexCount);
} }
for(unsigned int i=0; i<submesh.Faces.size(); ++i) for (size_t i=0, flen=submesh.Faces.size(); i<flen; ++i)
{ {
//We precalculate the index vlaues her, because we need them in all vertex attributes const Face &face = submesh.Faces[i];
unsigned int Vertex1=submesh.Faces[i].VertexIndices[0];
unsigned int Vertex2=submesh.Faces[i].VertexIndices[1];
unsigned int Vertex3=submesh.Faces[i].VertexIndices[2];
UniquePositions[3*i+0]=VertexSource.Positions[Vertex1]; // We pre calculate the index values here,
UniquePositions[3*i+1]=VertexSource.Positions[Vertex2]; // because we need them in all vertex attributes.
UniquePositions[3*i+2]=VertexSource.Positions[Vertex3]; unsigned int v1 = face.VertexIndices[0];
unsigned int v2 = face.VertexIndices[1];
unsigned int v3 = face.VertexIndices[2];
if(VertexSource.HasNormals) size_t pos = i*3;
uniqueFaceList[i].VertexIndices[0] = pos;
uniqueFaceList[i].VertexIndices[1] = pos + 1;
uniqueFaceList[i].VertexIndices[2] = pos + 2;
uniquePositions[pos] = vertexSource.Positions[v1];
uniquePositions[pos+1] = vertexSource.Positions[v2];
uniquePositions[pos+2] = vertexSource.Positions[v3];
if (vertexSource.HasNormals)
{ {
UniqueNormals[3*i+0]=VertexSource.Normals[Vertex1]; uniqueNormals[pos ] = vertexSource.Normals[v1];
UniqueNormals[3*i+1]=VertexSource.Normals[Vertex2]; uniqueNormals[pos+1] = vertexSource.Normals[v2];
UniqueNormals[3*i+2]=VertexSource.Normals[Vertex3]; uniqueNormals[pos+2] = vertexSource.Normals[v3];
} }
if(VertexSource.HasTangents) if (vertexSource.HasTangents)
{ {
UniqueTangents[3*i+0]=VertexSource.Tangents[Vertex1]; uniqueTangents[pos] = vertexSource.Tangents[v1];
UniqueTangents[3*i+1]=VertexSource.Tangents[Vertex2]; uniqueTangents[pos+1] = vertexSource.Tangents[v2];
UniqueTangents[3*i+2]=VertexSource.Tangents[Vertex3]; uniqueTangents[pos+2] = vertexSource.Tangents[v3];
} }
if(UniqueUvs.size()>0) for(size_t uvi=0; uvi<uniqueUvs.size(); ++uvi)
{ {
for(unsigned int j=0; j<UniqueUvs.size(); ++j) const std::vector<aiVector3D> &uv = vertexSource.Uvs[uvi];
uniqueUvs[uvi][pos] = uv[v1];
uniqueUvs[uvi][pos+1] = uv[v2];
uniqueUvs[uvi][pos+2] = uv[v3];
}
if (!vertexSource.Weights.empty())
{ {
UniqueUvs[j][3*i+0]=VertexSource.Uvs[j][Vertex1]; uniqueWeights[pos] = vertexSource.Weights[v1];
UniqueUvs[j][3*i+1]=VertexSource.Uvs[j][Vertex2]; uniqueWeights[pos+1] = vertexSource.Weights[v2];
UniqueUvs[j][3*i+2]=VertexSource.Uvs[j][Vertex3]; uniqueWeights[pos+2] = vertexSource.Weights[v3];
} }
} }
if(VertexSource.Weights.size() > 0) // Now we have the unique data, but want them in the SubMesh, so we swap all the containers.
// If we don't have one of them, we just swap empty containers, so everything is ok.
submesh.Faces.swap(uniqueFaceList);
submesh.Positions.swap(uniquePositions);
submesh.Normals.swap(uniqueNormals);
submesh.Tangents.swap(uniqueTangents);
submesh.Uvs.swap(uniqueUvs);
submesh.Weights.swap(uniqueWeights);
// Normalize bone weights
// For example the Blender exporter doesn't care about whether the sum of all bone
// weights for a single vertex equals 1 or not, so validate here.
for(size_t vertexId=0, wlen=submesh.Weights.size(); vertexId<wlen; ++vertexId)
{ {
UniqueWeights[3*i+0]=VertexSource.Weights[Vertex1]; std::vector<BoneWeight> &weights = submesh.Weights[vertexId];
UniqueWeights[3*i+1]=VertexSource.Weights[Vertex2];
UniqueWeights[3*i+2]=VertexSource.Weights[Vertex3];
}
//The indexvalues a just continuous numbers (0, 1, 2, 3, 4, 5, 6...) float sum = 0.0f;
UniqueFaceList[i].VertexIndices[0]=3*i+0; for(size_t boneId=0, blen=weights.size(); boneId<blen; ++boneId)
UniqueFaceList[i].VertexIndices[1]=3*i+1; sum += weights[boneId].Value;
UniqueFaceList[i].VertexIndices[2]=3*i+2;
}
//_________________________________________________________________________________________
//now we have the unique datas, but want them in the SubMesh, so we swap all the containers:
//if we don't have one of them, we just swap empty containers, so everything is ok
submesh.Faces.swap(UniqueFaceList);
submesh.Positions.swap(UniquePositions);
submesh.Normals.swap(UniqueNormals);
submesh.Tangents.swap(UniqueTangents);
submesh.Uvs.swap(UniqueUvs);
submesh.Weights.swap(UniqueWeights);
//------------- normalize weights -----------------------------
//The Blender exporter doesn't care about whether the sum of all boneweights for a single vertex equals 1 or not,
//so we have to make this sure:
for(unsigned int VertexId=0; VertexId<submesh.Weights.size(); ++VertexId)//iterate over all vertices
{
float WeightSum=0.0f;
for(unsigned int BoneId=0; BoneId<submesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
{
WeightSum+=submesh.Weights[VertexId][BoneId].Value;
}
//check if the sum is too far away from 1 //check if the sum is too far away from 1
if(WeightSum<1.0f-0.05f || WeightSum>1.0f+0.05f) if ((sum < (1.0f - 0.05f)) || (sum > (1.0f + 0.05f)))
{ for(size_t boneId=0, blen=weights.size(); boneId<blen; ++boneId)
//normalize all weights: weights[boneId].Value /= sum;
for(unsigned int BoneId=0; BoneId<submesh.Weights[VertexId].size(); ++BoneId)//iterate over all bones
{
submesh.Weights[VertexId][BoneId].Value/=WeightSum;
} }
} }
}
//_________________________________________________________
}
aiMesh *OgreImporter::CreateAssimpSubMesh(aiScene *pScene, const SubMesh& submesh, const vector<Bone>& bones) const aiMesh *OgreImporter::CreateAssimpSubMesh(aiScene *pScene, const SubMesh& submesh, const vector<Bone>& bones) const
{ {