From 7b62dc19bf0e5f85ec1dc7dc2f3d69a0d18d22ef Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 12 Jan 2016 15:39:29 +0100 Subject: [PATCH] Spitting out Meshes & Animation Data to file. --- .../MayaExporter/MayaExporter.vcxproj | 1 + .../MayaExporter/MayaExporter/MayaIncludes.h | 5 + tools/MayaExporter/MayaExporter/Menu.cpp | 46 +++-- tools/MayaExporter/MayaExporter/Menu.h | 1 + tools/MayaExporter/MayaExporter/Mesh.cpp | 193 +++++++++++++----- tools/MayaExporter/MayaExporter/Mesh.h | 53 ++++- tools/MayaExporter/MayaExporter/WriteToFile.h | 16 +- 7 files changed, 242 insertions(+), 73 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index a9154ac7..701b39cf 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -140,6 +140,7 @@ MultiThreadedDLL true + Disabled Windows diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 0e490208..66527470 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -37,6 +37,11 @@ #include #include #include +#include +#include +#include +#include +#include // Wrappers diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 77241cad..7e1e6cde 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -125,8 +125,7 @@ void Menu::ExportSelected(bool checked) MFnDependencyNode thisNode(object); cout << thisNode.name().asChar() << endl; - Mesh mesh; - mesh.GetMeshData(object); + GetMeshData(object); } if (m_ExportPath->text().isEmpty()) { cout << "Please select a folder." << endl; @@ -195,17 +194,32 @@ void Menu::RemoveClipClicked(bool) void Menu::ExportAll(bool) { MDagPath path; + m_File.ASCIIFilePath("C:/Users/Nickelodion/Desktop/coolASCII.txt"); + m_File.binaryFilePath("C:/Users/Nickelodion/Desktop/coolSoptunz.bin"); + m_File.OpenFiles(); // Loop through all nodes in the scene - MItDependencyNodes it(MFn::kInvalid); + MItDependencyNodes it(MFn::kMesh); for (; !it.isDone(); it.next()) { MObject node = it.thisNode(); if (node.hasFn(MFn::kMesh)) { MFnDependencyNode thisNode(node); + MPlugArray connections; - cout << thisNode.name().asChar() << endl; - Mesh mesh; - mesh.GetMeshData(node); + thisNode.findPlug("inMesh").connectedTo(connections, true, true); + bool next = false; + for (unsigned int i = 0; i < connections.length(); i++) { + if(connections[i].node().apiType() == MFn::kSkinClusterFilter){ + next = true; + break; + } + } + if (next) + continue; + + cout << thisNode.name().asChar() << endl; + MGlobal::displayInfo("EXPORT ALL FUNCTION: " + thisNode.name() + " " + thisNode.findPlug("inMesh").asMObject().apiTypeStr()); + GetMeshData(node); } } if (m_ExportPath->text().isEmpty()) { @@ -215,12 +229,9 @@ void Menu::ExportAll(bool) cout << m_ExportPath->text().toLocal8Bit().constData() << endl; } - m_File.ASCIIFilePath("C:/Users/Nickelodion/Desktop/coolASCII.txt"); - m_File.binaryFilePath("C:/Users/Nickelodion/Desktop/coolSoptunz.bin"); - if (m_ExportAnimationsButton->isChecked()) GetSkeletonData(); - + m_File.CloseFiles(); } void Menu::CancelClicked(bool) @@ -257,7 +268,19 @@ void Menu::Button3Clicked(bool) cout << "3 unchecked!" << endl; } } +void Menu::GetMeshData(MObject object) +{ + std::vector vertexList; + std::vector indexList; + Mesh mesh; + mesh.GetMeshData(object, vertexList, indexList); + + for (auto aVertex : vertexList) { + m_File.writeToFiles(&aVertex); + } + m_File.writeToFiles(indexList.data(), indexList.size()); +} void Menu::GetMaterialData() { this->m_MaterialHandler = new Material(); @@ -296,8 +319,6 @@ void Menu::GetSkeletonData() allAnimations.push_back(m_SkeletonHandler->GetAnimData(animationName, startFrame, endFrame)); } - m_File.OpenFiles(); - //print out all bind poses for (auto aBindPose : allBindPoses){ m_File.writeToFiles(&aBindPose); @@ -315,7 +336,6 @@ void Menu::GetSkeletonData() for (auto aAnimation : allAnimations) { m_File.writeToFiles(&aAnimation); } - m_File.CloseFiles(); } Menu::~Menu() diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 0174cbc3..9f3492ab 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -46,6 +46,7 @@ public: Menu(QDialog* dialog); ~Menu(); + void GetMeshData(MObject object); void GetMaterialData(); void GetSkeletonData(); diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 58a7fbe4..0ac66b33 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -7,21 +7,80 @@ Mesh::Mesh() { } +std::map Mesh::GetWeightData() +{ + map weightMap; -void Mesh::GetMeshData(MObject object) + MItDependencyNodes it(MFn::kSkinClusterFilter); + + while (!it.isDone()) { + + MObject object = it.item(); + MFnSkinCluster skinCluster(object); + MDagPathArray influences; + + unsigned int nrOfInfluences = skinCluster.influenceObjects(influences); + + unsigned int index; + index = skinCluster.indexForOutputConnection(0); + MDagPath skinPath; + skinCluster.getPathAtIndex(index, skinPath); + + MItGeometry geomIter(skinPath); + //for (unsigned int i = 0; i < nrOfInfluences; i++) { + // MGlobal::displayInfo(MString() + " Influence object name: " + influences[i].partialPathName().asChar()); + //} + WeightInfo weightInfo; + + while (!geomIter.isDone()) { + MObject comp = geomIter.component(); + MFloatArray weights; + unsigned int influenceCount; + skinCluster.getWeights(skinPath, comp, weights, influenceCount); + MFnDependencyNode test(comp); + + unsigned int nrOfWeights = 0; + + for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) { + if (weights[j] > 0.00001) { + weightInfo.BoneWeights[nrOfWeights] = weights[j]; + weightInfo.BoneIndices[nrOfWeights] = j; + nrOfWeights++; + } + } + + float totalWeight = 0.0f; + for (unsigned int i = 0; i < 4; i++) { + totalWeight += weightInfo.BoneWeights[i]; + } + for (unsigned int i = 0; i < 4; i++) { + weightInfo.BoneWeights[i] /= totalWeight; + } + weightMap[geomIter.index()] = weightInfo; + + + for (unsigned int k = 0; k!=nrOfWeights; k++) { + //MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]); + } + geomIter.next(); + + + } + + it.next(); + } + return weightMap; +} + +void Mesh::GetMeshData(MObject object, std::vector& vertexList, std::vector& indexList) { // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object); - - map> vertexToIndex; - - vector verticesData; - vectorindexArray; + map> vertexToIndex;; MIntArray intdexOffsetVertexCount, vertices, triangleList; MPointArray dummy; - - UINT vertexIndex; + unsigned int vertexIndex; MVector normal; MPoint pos; float2 UV; @@ -31,62 +90,92 @@ void Mesh::GetMeshData(MObject object) MFloatVectorArray biTangents; MFloatVectorArray biNormals; + std::map vertexWeights = GetWeightData(); + mesh.getTangents(biTangents, MSpace::kObject, NULL); mesh.getBinormals(biNormals, MSpace::kObject, NULL); MItMeshFaceVertex faceVert(object); + int intDummy = 0; - for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) { - vector localVertexToGlobalIndex; - meshPolyIter.getVertices(vertices); - meshPolyIter.getTriangles(dummy, triangleList); - UINT indexOffset = verticesData.size(); - //MGlobal::displayInfo("Befor Second Loop"); - for (UINT i = 0; i < vertices.length(); i++) { - faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); - //MGlobal::displayInfo("In Second Loop"); - faceVert.position().get(thisVertex.Pos); - faceVert.getNormal(normal); - thisVertex.Normal[0] = normal[0]; - thisVertex.Normal[1] = normal[1]; - thisVertex.Normal[2] = normal[2]; + for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) { - MFloatVector biTangent = biTangents[faceVert.tangentId()]; - //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); - //tmp.get(biTangent); - thisVertex.BiTangent[0] = biTangent[0]; - thisVertex.BiTangent[1] = biTangent[1]; - thisVertex.BiTangent[2] = biTangent[2]; + vector localVertexToGlobalIndex; + unsigned int indexOffset = vertexList.size(); - MFloatVector biNormal = biNormals[faceVert.tangentId()]; - //faceVert.getBinormal().get(biNormal); - thisVertex.BiNormal[0] = biNormal[0]; - thisVertex.BiNormal[1] = biNormal[1]; - thisVertex.BiNormal[2] = biNormal[2]; + meshPolyIter.getVertices(vertices); + meshPolyIter.getTriangles(dummy, triangleList); + MGlobal::displayInfo(MString() + "vertices.length(): " + vertices.length()); + //MGlobal::displayInfo("Befor Second Loop"); + for (unsigned int i = 0; i < vertices.length(); i++) { + vertexIndex = meshPolyIter.vertexIndex(i); + faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); + //MGlobal::displayInfo("In Second Loop"); + faceVert.position().get(thisVertex.Pos); + faceVert.getNormal(normal); + thisVertex.Normal[0] = normal[0]; + thisVertex.Normal[1] = normal[1]; + thisVertex.Normal[2] = normal[2]; - faceVert.getUV(UV); - thisVertex.Uv[0] = UV[0]; - thisVertex.Uv[1] = UV[1]; + MFloatVector biTangent = biTangents[faceVert.tangentId()]; + //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); + //tmp.get(biTangent); + thisVertex.BiTangent[0] = biTangent[0]; + thisVertex.BiTangent[1] = biTangent[1]; + thisVertex.BiTangent[2] = biTangent[2]; - verticesData.push_back(thisVertex); - localVertexToGlobalIndex.push_back(vertexIndex); + MFloatVector biNormal = biNormals[faceVert.tangentId()]; + //faceVert.getBinormal().get(biNormal); + thisVertex.BiNormal[0] = biNormal[0]; + thisVertex.BiNormal[1] = biNormal[1]; + thisVertex.BiNormal[2] = biNormal[2]; - //cout << "Pos: " << thisVertex.Pos[0] << "/" << thisVertex.Pos[1] << "/" << thisVertex.Pos[2] << endl; - //cout << "Normals: " << thisVertex.Normal[0] << "/" << thisVertex.Normal[1] << "/" << thisVertex.Normal[2] << endl; - //cout << "Bi-Normals: " << thisVertex.BiNormal[0] << "/" << thisVertex.BiNormal[1] << "/" << thisVertex.BiNormal[2] << endl; - //cout << "Bi-Tangents: " << thisVertex.BiTangent[0] << "/" << thisVertex.BiTangent[1] << "/" << thisVertex.BiTangent[2] << endl; - //cout << "UV: " << thisVertex.Uv[0] << "/" << thisVertex.Uv[1] << endl; - } - //MGlobal::displayInfo("Befor Third Loop"); + faceVert.getUV(UV); + thisVertex.Uv[0] = UV[0]; + thisVertex.Uv[1] = UV[1]; - //for (UINT i = 0; i < triangleList.length(); i++) { - // UINT k = 0; - // while (localVertexToGlobalIndex[k] != triangleList[i]) - // k++; - // indexArray.push_back(indexOffset + k); - //} - } + thisVertex.BoneIndices[0] = vertexWeights[faceVert.vertId()].BoneIndices[0]; + thisVertex.BoneIndices[1] = vertexWeights[faceVert.vertId()].BoneIndices[1]; + thisVertex.BoneIndices[2] = vertexWeights[faceVert.vertId()].BoneIndices[2]; + thisVertex.BoneIndices[3] = vertexWeights[faceVert.vertId()].BoneIndices[3]; + + thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; + thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1]; + thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2]; + thisVertex.BoneWeights[3] = vertexWeights[faceVert.vertId()].BoneWeights[3]; + + std::vector::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex); + + if (it != vertexList.end()) { + localVertexToGlobalIndex.push_back(vertexIndex); + } else { + localVertexToGlobalIndex.push_back(vertexIndex); + vertexList.push_back(thisVertex); + } + + //cout << "Pos: " << thisVertex.Pos[0] << "/" << thisVertex.Pos[1] << "/" << thisVertex.Pos[2] << endl; + //cout << "Normals: " << thisVertex.Normal[0] << "/" << thisVertex.Normal[1] << "/" << thisVertex.Normal[2] << endl; + //cout << "Bi-Normals: " << thisVertex.BiNormal[0] << "/" << thisVertex.BiNormal[1] << "/" << thisVertex.BiNormal[2] << endl; + //cout << "Bi-Tangents: " << thisVertex.BiTangent[0] << "/" << thisVertex.BiTangent[1] << "/" << thisVertex.BiTangent[2] << endl; + //cout << "UV: " << thisVertex.Uv[0] << "/" << thisVertex.Uv[1] << endl; + } + //MGlobal::displayInfo("Befor Third Loop"); + MGlobal::displayInfo(MString() + "localVertexToGlobalIndex.size(): " + localVertexToGlobalIndex.size()); + MGlobal::displayInfo(MString() + "vertexList.size(): " + vertexList.size()); + + for (unsigned int i = 0; i < triangleList.length(); i++) { + unsigned int k = 0; + MGlobal::displayInfo(MString() + "triangleList[i]: " + triangleList[i]); + if (localVertexToGlobalIndex.size() > 0) { + while (localVertexToGlobalIndex[k] != triangleList[i] && k < localVertexToGlobalIndex.size()) { + MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k]: " + localVertexToGlobalIndex[k]); + k++; + } + indexList.push_back(indexOffset + k); + } + } + } } Mesh::~Mesh() diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 00b88654..6fab0536 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -16,21 +16,62 @@ public: float BiNormal[3]; float BiTangent[3]; float Uv[2]; + float BoneIndices[4]; + float BoneWeights[4]; - virtual void WriteBinary(std::ostream& out) { + virtual void WriteBinary(std::ostream& out) + { + out.write((char*)&Pos, sizeof(float) * 3); + out.write((char*)&Normal, sizeof(float) * 3); + out.write((char*)&BiNormal, sizeof(float) * 3); + out.write((char*)&BiTangent, sizeof(float) * 3); + out.write((char*)&Uv, sizeof(float) * 2); + out.write((char*)&BoneIndices, sizeof(float) * 4); + out.write((char*)&BoneWeights, sizeof(float) * 4); + } - } - virtual void WriteASCII(std::ostream& out) const { + virtual void WriteASCII(std::ostream& out) const + { + out << "New Vertex: " << endl; + out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl; + out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl; + out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl; + out << BiTangent[0] << " " << BiTangent[1] << " " << BiTangent[2] << endl; + out << Uv[0] << " " << Uv[1] << endl; + out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl; + out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl; - } + } + bool operator==(const VertexLayout& right) + { + return + this->Pos[0] == right.Pos[0] && this->Pos[1] == right.Pos[1] && this->Pos[2] == right.Pos[2] && + this->Normal[0] == right.Normal[0] && this->Normal[1] == right.Normal[1] && this->Normal[2] == right.Normal[2] && + this->BiNormal[0] == right.BiNormal[0] && this->BiNormal[1] == right.BiNormal[1] && this->BiNormal[2] == right.BiNormal[2] && + this->BiTangent[0] == right.BiTangent[0] && this->BiTangent[1] == right.BiTangent[1] && this->BiTangent[2] == right.BiTangent[2] && + this->Uv[0] == right.Uv[0] && this->Uv[1] == right.Uv[1] && + this->BoneIndices[0] == right.BoneIndices[0] && this->BoneIndices[1] == right.BoneIndices[1] && this->BoneIndices[2] == right.BoneIndices[2] && this->BoneIndices[3] == right.BoneIndices[3] && + this->BoneWeights[0] == right.BoneWeights[0] && this->BoneWeights[1] == right.BoneWeights[1] && this->BoneWeights[2] == right.BoneWeights[2] && this->BoneWeights[3] == right.BoneWeights[3] + ; + } }; + + + class Mesh { public: Mesh(); - void GetMeshData(MObject Object); - ~Mesh(); + void GetMeshData(MObject Object, std::vector& vertexList, std::vector& indexList); + ~Mesh(); +private: + struct WeightInfo { + float BoneIndices[4] = { 0 }; + float BoneWeights[4] = { 0 }; + }; + std::map GetWeightData(); + }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.h b/tools/MayaExporter/MayaExporter/WriteToFile.h index f0c066d4..3d6cc078 100644 --- a/tools/MayaExporter/MayaExporter/WriteToFile.h +++ b/tools/MayaExporter/MayaExporter/WriteToFile.h @@ -20,20 +20,32 @@ public: MGlobal::displayInfo("WriteToFile::writeToFiles()"); if (ASCIIFile.is_open()) { - MGlobal::displayInfo("Writing to ASCIIfile"); for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++) ASCIIFile << toWrite[i] << endl; } if (binFile.is_open()) { - MGlobal::displayInfo("Writing to binaryfile"); for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++) toWrite[i].WriteBinary(binFile); } } + void writeToFiles(unsigned int* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0) + { + MGlobal::displayInfo("WriteToFile::writeToFiles()"); + if (ASCIIFile.is_open()) { + for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++) + ASCIIFile << toWrite[i] << endl; + } + + if (binFile.is_open()) { + binFile.write((char*)toWrite, numOfElementToWrite * sizeof(int)); + } + + } + void OpenFiles(); void CloseFiles();