From c8cb0ee93978dd8b4646cb4cb37e5fb397fcabd3 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 9 Dec 2015 11:58:49 +0100 Subject: [PATCH 01/13] Grab all materials --- tools/MayaExporter/MayaExporter/Material.cpp | 239 ++++++++++++++++++ tools/MayaExporter/MayaExporter/Material.h | 46 ++++ .../MayaExporter/MayaExporter.vcxproj | 2 + .../MayaExporter/MayaExporter.vcxproj.filters | 6 + .../MayaExporter/MayaExporter/MayaIncludes.h | 1 + tools/MayaExporter/MayaExporter/Menu.cpp | 14 +- tools/MayaExporter/MayaExporter/Menu.h | 4 +- 7 files changed, 307 insertions(+), 5 deletions(-) create mode 100644 tools/MayaExporter/MayaExporter/Material.cpp create mode 100644 tools/MayaExporter/MayaExporter/Material.h diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp new file mode 100644 index 00000000..53d029dc --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -0,0 +1,239 @@ +#include "Material.h" + +void Material::grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node) +{ + material_node.Name = node.name().asChar(); + + if (findColorTexture(material_node, node)) { + material_node.Color.fill(1.0f); + } + else { + m_Plug = node.findPlug("colorR"); + m_Plug.getValue(material_node.Color[0]); + m_Plug = node.findPlug("colorG"); + m_Plug.getValue(material_node.Color[1]); + m_Plug = node.findPlug("colorB"); + m_Plug.getValue(material_node.Color[2]); + + float TempTransp[3]; + m_Plug = node.findPlug("transparencyR"); + m_Plug.getValue(TempTransp[0]); + m_Plug = node.findPlug("transparencyG"); + m_Plug.getValue(TempTransp[1]); + m_Plug = node.findPlug("transparencyB"); + m_Plug.getValue(TempTransp[2]); + + MColor TranspNode(TempTransp[0], TempTransp[1], TempTransp[2]); + float DummyH, DummyS; + TranspNode.get(MColor::kHSV, DummyH, DummyS, material_node.Color[3]); + } + + if (findIncandescenceTexture(material_node, node)) { + material_node.Incandescence.fill(1.0f); + } + else { + m_Plug = node.findPlug("incandescenceR"); + m_Plug.getValue(material_node.Incandescence[0]); + m_Plug = node.findPlug("incandescenceG"); + m_Plug.getValue(material_node.Incandescence[1]); + m_Plug = node.findPlug("incandescenceB"); + m_Plug.getValue(material_node.Incandescence[2]); + } + + findNormalTexture(material_node, node); +} + +void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node) +{ + if (findSpecularTexture(material_node, node)) { + material_node.Specular.fill(1.0f); + } + else { + m_Plug = node.findPlug("specularColorR"); + m_Plug.getValue(material_node.Specular[0]); + m_Plug = node.findPlug("specularColorG"); + m_Plug.getValue(material_node.Specular[1]); + m_Plug = node.findPlug("specularColorB"); + m_Plug.getValue(material_node.Specular[2]); + } + + m_Plug = node.findPlug("reflectivity"); + m_Plug.getValue(material_node.ReflectionFactor); + + m_Plug = node.findPlug("eccentricity"); + float TempEccent; + m_Plug.getValue(TempEccent); + + // Blinn works differently from Phong which is used in-game. + // This is some magic numbers and math to make a conversion estimate between the two. + // There is no exact conversion between the two, so there are errors. + + // Phong min/max is around Blinn 0.7/0.1 + TempEccent = std::max(std::min(TempEccent, 0.7f), 0.1f); + + material_node.SpecularExponent = std::max(std::min(((2.66f) + (427.0f) * exp((-14.8f) * TempEccent)), 100.0f), 2.0f); +} + +void Material::grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node) +{ + if (findSpecularTexture(material_node, node)) { + material_node.Specular.fill(1.0f); + } + else { + m_Plug = node.findPlug("specularColorR"); + m_Plug.getValue(material_node.Specular[0]); + m_Plug = node.findPlug("specularColorG"); + m_Plug.getValue(material_node.Specular[1]); + m_Plug = node.findPlug("specularColorB"); + m_Plug.getValue(material_node.Specular[2]); + } + + m_Plug = node.findPlug("reflectivity"); + m_Plug.getValue(material_node.ReflectionFactor); + + m_Plug = node.findPlug("cosinePower "); + m_Plug.getValue(material_node.SpecularExponent); +} + +bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& node) +{ + MPlugArray AllConnections; + + m_Plug = node.findPlug("color", true); + m_Plug.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllConnections[i].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + material_node.ColorMapFile = FullPath.substr(FullPath.find_last_of("/")); + + return true; + } + } + + return false; +} + +bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node) +{ + MPlugArray AllConnections; + MPlugArray AllBumpConnections; + + m_Plug = node.findPlug("normalCamera", true); + m_Plug.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().apiType() == MFn::kBump) { + MFnDependencyNode BumpNode(AllConnections[i].node()); + + BumpNode.findPlug("bumpValue").connectedTo(AllBumpConnections, true, false); + for (int j = 0; j < AllBumpConnections.length(); j++) { + if (AllBumpConnections[j].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllBumpConnections[j].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + material_node.NormalMapFile = FullPath.substr(FullPath.find_last_of("/")); + + return true; + } + } + } + } + + return false; +} + +bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node) +{ + MPlugArray AllConnections; + + m_Plug = node.findPlug("specularColor", true); + m_Plug.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllConnections[i].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/")); + + return true; + } + } + return false; +} + +bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node) +{ + MPlugArray AllConnections; + + m_Plug = node.findPlug("incandescence", true); + m_Plug.connectedTo(AllConnections, true, false); + + for (int i = 0; i < AllConnections.length(); i++) { + if (AllConnections[i].node().hasFn(MFn::kFileTexture)) { + MFnDependencyNode TextureNode(AllConnections[i].node()); + + std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); + m_TexturePaths.push_back(FullPath); + + material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/")); + + return true; + } + } + return false; +} + +// Returns the absolute path for all textures. Use for copying texture files. +std::vector* Material::TexturePaths() +{ + return &m_TexturePaths; +} + +// Traverse the DAG and grab all the materials +std::vector* Material::DoIt() +{ + // All materials we care about inherit from Lambert + MItDependencyNodes matIt(MFn::kLambert); + + while (!matIt.isDone()) { + MFnDependencyNode MaterialFnDN(matIt.thisNode()); + MaterialNode MaterialStorage; + + if (matIt.thisNode().hasFn(MFn::kPhong)) { + grabLambertProperties(MaterialStorage, MaterialFnDN); + grabPhongProperties(MaterialStorage, MaterialFnDN); + + m_AllMaterials.push_back(MaterialStorage); + } + else if (matIt.thisNode().hasFn(MFn::kBlinn)) { + grabLambertProperties(MaterialStorage, MaterialFnDN); + grabBlinnProperties(MaterialStorage, MaterialFnDN); + + m_AllMaterials.push_back(MaterialStorage); + } + else if (matIt.thisNode().hasFn(MFn::kLambert)) { + grabLambertProperties(MaterialStorage, MaterialFnDN); + + m_AllMaterials.push_back(MaterialStorage); + + MaterialStorage.Specular.fill(0.0f); + MaterialStorage.ReflectionFactor = 0.0f; + MaterialStorage.SpecularExponent = 0.0f; + } + + matIt.next(); + } + + return &m_AllMaterials; +} + diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h new file mode 100644 index 00000000..1685453d --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -0,0 +1,46 @@ +#ifndef Material_Material_h__ +#define Material_Material_h__ + +#include +#include +#include +#include +#include "MayaIncludes.h" + +struct MaterialNode +{ + std::string Name; + std::array Color; + std::array Incandescence; + std::array Specular; + float ReflectionFactor; + float SpecularExponent; + std::string ColorMapFile; + std::string SpecularMapFile; + std::string NormalMapFile; + std::string IncandescenceMapFile; +}; + +class Material +{ +public: + Material() {}; + ~Material() {}; + std::vector* DoIt(); + std::vector* TexturePaths(); +private: + MPlug m_Plug; + + std::vector m_AllMaterials; + std::vector m_TexturePaths; + + bool findColorTexture(MaterialNode& material_node, MFnDependencyNode& node); + bool findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node); + bool findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node); + bool findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node); + void grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node); + void grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node); + void grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node); +}; + +#endif // Material_Material_h__ \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index 42b1b45a..c8ce591c 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -152,6 +152,7 @@ + true @@ -213,6 +214,7 @@ $(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath) + diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index d5bcfd00..4719620b 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -50,6 +50,9 @@ Source Files + + Source Files + @@ -69,5 +72,8 @@ Generated Files + + Header Files + \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 3573d30d..6c092052 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -30,6 +30,7 @@ #include #include #include +#include // Wrappers diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 6af300aa..5d8af1d4 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -141,9 +141,9 @@ void Menu::CancelClicked(bool) void Menu::Button1Clicked(bool) { if(exportAnimationsButton->isChecked()) - cout << "1 checked!" << endl; + MGlobal::displayInfo("1 checked!"); else - cout << "1 unchecked!" << endl; + MGlobal::displayInfo("1 unchecked!"); } void Menu::Button2Clicked(bool) @@ -222,11 +222,16 @@ void Menu::GetMeshData(MObject object) } -void Menu::exportMaterial(MObject object) +void Menu::GetMaterialData() { - MItDependencyNodes matIt(MFn::kLambert); + this->MaterialHandler = new Material(); + // Traverse scene and return vector with all materials + std::vector* AllMaterials = MaterialHandler->DoIt(); + // Access the colorR component of one material (example) + cout << AllMaterials->at(0).Color[0] << endl; + MGlobal::displayInfo(MString() + AllMaterials->at(0).Color[0]); } Menu::~Menu() @@ -236,4 +241,5 @@ Menu::~Menu() //delete exportPath; //delete fileDialog; fileDialog->~QFileDialog(); + delete MaterialHandler; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 44eca702..b2731c0a 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -5,6 +5,7 @@ #include #include "MayaIncludes.h" +#include "Material.h" // Qt #pragma comment(lib, "QtCore4") #pragma comment(lib, "QtGui4") @@ -46,7 +47,7 @@ public: ~Menu(); void GetMeshData(MObject object); - void exportMaterial(MObject object); + void GetMaterialData(); private slots: void ExportSelected(bool checked); @@ -74,6 +75,7 @@ private: QFileDialog* fileDialog; QDialog* dialogPointer; + Material* MaterialHandler; }; #endif \ No newline at end of file From 74c1beed2036e5629a36f3b273c0f91144ecee25 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 9 Dec 2015 12:03:01 +0100 Subject: [PATCH 02/13] gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 1774c281..d43dd612 100755 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ bin/ lib/ # Because apparently nobody has any self control *.orig + +*.suo +*.sdf +tools/MayaExporter/MayaExporter/x64/Debug/ +tools/MayaExporter/x64/Debug/ From a22d086e60ad9861c47ff592c0fae9c482b26b00 Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 10 Dec 2015 11:18:34 +0100 Subject: [PATCH 03/13] Tested some of the Material Code. Seems to work. The project should now be following the code standard properly (hopefully). --- .gitignore | 3 + tools/MayaExporter/MayaExporter/Material.cpp | 2 + tools/MayaExporter/MayaExporter/Material.h | 1 + .../MayaExporter/MayaExporter.vcxproj | 2 + .../MayaExporter/MayaExporter.vcxproj.filters | 6 + tools/MayaExporter/MayaExporter/Menu.cpp | 181 +++++++----------- tools/MayaExporter/MayaExporter/Menu.h | 38 ++-- tools/MayaExporter/MayaExporter/Mesh.cpp | 70 +++++++ tools/MayaExporter/MayaExporter/Mesh.h | 24 +++ 9 files changed, 189 insertions(+), 138 deletions(-) create mode 100644 tools/MayaExporter/MayaExporter/Mesh.cpp create mode 100644 tools/MayaExporter/MayaExporter/Mesh.h diff --git a/.gitignore b/.gitignore index d43dd612..0df2db42 100755 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ lib/ *.sdf tools/MayaExporter/MayaExporter/x64/Debug/ tools/MayaExporter/x64/Debug/ + +tools/MayaExporter/MayaExporter/Debug/ +tools/MayaExporter/MayaExporter/GeneratedFiles/ diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 53d029dc..2bc084dc 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -111,6 +111,8 @@ bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& material_node.ColorMapFile = FullPath.substr(FullPath.find_last_of("/")); + // Test + MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str()); return true; } } diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index 1685453d..c5d57529 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -5,6 +5,7 @@ #include #include #include + #include "MayaIncludes.h" struct MaterialNode diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index c8ce591c..ffc93c0f 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -173,6 +173,7 @@ true + @@ -195,6 +196,7 @@ + Moc%27ing Menu.h... .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index 4719620b..70af7805 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -53,6 +53,9 @@ Source Files + + Source Files + @@ -75,5 +78,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 5d8af1d4..3fc760e6 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -10,39 +10,39 @@ Menu::Menu() Menu::Menu(QDialog* dialog) { // Save the dialog pointer. Needed when the application gets destroyed - dialogPointer = dialog; + m_DialogPointer = dialog; // Create QpushButtons & give them names - exportSelectedButton = new QPushButton("&Export Selected", this); - browseButton = new QPushButton("&...", this); - exportAllButton = new QPushButton("&Export All", this); - cancelButton = new QPushButton("&Cancel", this); + m_ExportSelectedButton = new QPushButton("&Export Selected", this); + m_BrowseButton = new QPushButton("&...", this); + m_ExportAllButton = new QPushButton("&Export All", this); + m_CancelButton = new QPushButton("&Cancel", this); // Option box and checkboxes QGroupBox *optionsBox = new QGroupBox(tr("Options")); - exportAnimationsButton = new QCheckBox(tr("&Export Animations")); - copyTexturesButton = new QCheckBox(tr("&Copy Textures")); - button3 = new QCheckBox(tr("option3")); + m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations")); + m_CopyTexturesButton = new QCheckBox(tr("&Copy Textures")); + m_Button3 = new QCheckBox(tr("Test Materials")); - exportAnimationsButton->setChecked(true); - copyTexturesButton->setChecked(true); + m_ExportAnimationsButton->setChecked(true); + m_CopyTexturesButton->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; - vbox->addWidget(exportAnimationsButton); - vbox->addWidget(copyTexturesButton); - vbox->addWidget(button3); + vbox->addWidget(m_ExportAnimationsButton); + vbox->addWidget(m_CopyTexturesButton); + vbox->addWidget(m_Button3); vbox->addStretch(1); optionsBox->setLayout(vbox); // Connect the buttons with signals & functions - connect(exportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(ExportSelected(bool))); - connect(browseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool))); - connect(exportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool))); - connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool))); + connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(ExportSelected(bool))); + connect(m_BrowseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool))); + connect(m_ExportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool))); + connect(m_CancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool))); - connect(exportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool))); - connect(copyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool))); - connect(button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool))); + connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool))); + connect(m_CopyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool))); + connect(m_Button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool))); // Creating several layouts, adding widgets & adding them to one layout in the end QHBoxLayout* topLayout = new QHBoxLayout; @@ -50,8 +50,8 @@ Menu::Menu(QDialog* dialog) QHBoxLayout* botLayout = new QHBoxLayout; QVBoxLayout* baseLayout = new QVBoxLayout; - exportPath = new QLineEdit; - fileDialog = new QFileDialog; + m_ExportPath = new QLineEdit; + m_FileDialog = new QFileDialog; QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); @@ -59,12 +59,12 @@ Menu::Menu(QDialog* dialog) midLayout->addWidget(optionsBox); topLayout->addWidget(exportLabel); - topLayout->addWidget(exportPath); - topLayout->addWidget(browseButton); + topLayout->addWidget(m_ExportPath); + topLayout->addWidget(m_BrowseButton); - botLayout->addWidget(exportSelectedButton); - botLayout->addWidget(exportAllButton); - botLayout->addWidget(cancelButton); + botLayout->addWidget(m_ExportSelectedButton); + botLayout->addWidget(m_ExportAllButton); + botLayout->addWidget(m_CancelButton); baseLayout->addLayout(topLayout); baseLayout->addLayout(midLayout); @@ -86,28 +86,30 @@ void Menu::ExportSelected(bool checked) MGlobal::getActiveSelectionList(selected); // Loop through or list of selection(s) - for (unsigned int i = 0; i < selected.length();i++) - { + for (unsigned int i = 0; i < selected.length();i++) { MObject object; selected.getDependNode(i, object); MFnDependencyNode thisNode(object); cout << thisNode.name().asChar() << endl; - GetMeshData(object); + Mesh mesh; + mesh.GetMeshData(object); } - if (exportPath->text().isEmpty()) + if (m_ExportPath->text().isEmpty()) { cout << "Please select a folder." << endl; - else - cout << exportPath->text().toLocal8Bit().constData() << endl; + } + else { + cout << m_ExportPath->text().toLocal8Bit().constData() << endl; + } } void Menu::ExportPathClicked(bool) { // Opens up a file dialog. Save/Changes the name in the exportPath - fileDialog->setFileMode(QFileDialog::Directory); - fileDialog->setOption(QFileDialog::ShowDirsOnly); - QString fileName = fileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly); - exportPath->setText(fileName); + m_FileDialog->setFileMode(QFileDialog::Directory); + m_FileDialog->setOption(QFileDialog::ShowDirsOnly); + QString fileName = m_FileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly); + m_ExportPath->setText(fileName); } void Menu::ExportAll(bool) @@ -116,118 +118,65 @@ void Menu::ExportAll(bool) // Loop through all nodes in the scene MItDependencyNodes it(MFn::kInvalid); - for (;!it.isDone();it.next()) - { + for (;!it.isDone();it.next()) { MObject node = it.thisNode(); - if (node.hasFn(MFn::kMesh)) - { + if (node.hasFn(MFn::kMesh)) { MFnDependencyNode thisNode(node); cout << thisNode.name().asChar() << endl; - GetMeshData(node); + Mesh mesh; + mesh.GetMeshData(node); } } - if (exportPath->text().isEmpty()) + if (m_ExportPath->text().isEmpty()) { cout << "Please select a folder." << endl; - else - cout << exportPath->text().toLocal8Bit().constData() << endl; + } + else { + cout << m_ExportPath->text().toLocal8Bit().constData() << endl; + } } void Menu::CancelClicked(bool) { - dialogPointer->close(); + m_DialogPointer->close(); } void Menu::Button1Clicked(bool) { - if(exportAnimationsButton->isChecked()) + if (m_ExportAnimationsButton->isChecked()) { MGlobal::displayInfo("1 checked!"); - else + } + else { MGlobal::displayInfo("1 unchecked!"); + } } void Menu::Button2Clicked(bool) { - if (copyTexturesButton->isChecked()) + if (m_CopyTexturesButton->isChecked()) { cout << "2 checked!" << endl; - else + } + else { cout << "2 unchecked!" << endl; + } } void Menu::Button3Clicked(bool) { - if (button3->isChecked()) + if (m_Button3->isChecked()) { cout << "3 checked!" << endl; - else - cout << "3 unchecked!" << endl; -} - -void Menu::GetMeshData(MObject object) -{ - // In here, we retrieve triangulated polygons from the mesh - MFnMesh mesh(object); - - map> vertexToIndex; - - vector verticesData; - vectorindexArray; - - MIntArray intdexOffsetVertexCount, vertices, triangleList; - MPointArray dummy; - - UINT vertexIndex; - MVector normal; - MPoint pos; - float2 UV; - VertexLayout thisVertex; - - for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) - { - vector localVertexToGlobalIndex; - meshPolyIter.getVertices(vertices); - - meshPolyIter.getTriangles(dummy, triangleList); - UINT indexOffset = verticesData.size(); - - for (UINT i = 0; i < vertices.length(); i++) - { - vertexIndex = meshPolyIter.vertexIndex(i); - pos = meshPolyIter.point(i); - pos.get(thisVertex.pos); - - meshPolyIter.getNormal(i, normal); - thisVertex.normal[0] = normal[0]; - thisVertex.normal[1] = normal[1]; - thisVertex.normal[2] = normal[2]; - - meshPolyIter.getUV(i, UV); - thisVertex.uv[0] = UV[0]; - thisVertex.uv[1] = UV[1]; - - verticesData.push_back(thisVertex); - localVertexToGlobalIndex.push_back(vertexIndex); - - 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 << "UV: " << thisVertex.uv[0] << "/" << thisVertex.uv[1] << endl; - } - for (UINT i = 0; i < triangleList.length(); i++) - { - UINT k = 0; - while (localVertexToGlobalIndex[k] != triangleList[i]) - k++; - indexArray.push_back(indexOffset + k); - } } - + else { + cout << "3 unchecked!" << endl; + } } void Menu::GetMaterialData() { - this->MaterialHandler = new Material(); + this->m_MaterialHandler = new Material(); // Traverse scene and return vector with all materials - std::vector* AllMaterials = MaterialHandler->DoIt(); + std::vector* AllMaterials = m_MaterialHandler->DoIt(); // Access the colorR component of one material (example) cout << AllMaterials->at(0).Color[0] << endl; @@ -240,6 +189,6 @@ Menu::~Menu() //delete browseButton; //delete exportPath; //delete fileDialog; - fileDialog->~QFileDialog(); - delete MaterialHandler; + m_FileDialog->~QFileDialog(); + //delete MaterialHandler; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index b2731c0a..e58c86fb 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -1,11 +1,9 @@ -#ifndef BUTTONS_H -#define BUTTONS_H +#ifndef Menu_Menu_h__ +#define Menu_Menu_h__ #include #include -#include "MayaIncludes.h" -#include "Material.h" // Qt #pragma comment(lib, "QtCore4") #pragma comment(lib, "QtGui4") @@ -32,12 +30,9 @@ #include #include -struct VertexLayout -{ - float pos[3]; - float normal[3]; - float uv[2]; -}; +#include "MayaIncludes.h" +#include "Material.h" +#include "Mesh.h" class Menu : public QWidget { @@ -46,7 +41,6 @@ public: Menu(QDialog* dialog); ~Menu(); - void GetMeshData(MObject object); void GetMaterialData(); private slots: @@ -62,20 +56,20 @@ private slots: private: Menu(); - QPushButton* exportSelectedButton; - QPushButton* browseButton; - QPushButton* exportAllButton; - QPushButton* cancelButton; + QPushButton* m_ExportSelectedButton = nullptr; + QPushButton* m_BrowseButton = nullptr; + QPushButton* m_ExportAllButton = nullptr; + QPushButton* m_CancelButton = nullptr; - QCheckBox* exportAnimationsButton; - QCheckBox* copyTexturesButton; - QCheckBox* button3; + QCheckBox* m_ExportAnimationsButton = nullptr; + QCheckBox* m_CopyTexturesButton = nullptr; + QCheckBox* m_Button3 = nullptr; - QLineEdit* exportPath; - QFileDialog* fileDialog; - QDialog* dialogPointer; + QLineEdit* m_ExportPath = nullptr; + QFileDialog* m_FileDialog = nullptr; + QDialog* m_DialogPointer = nullptr; - Material* MaterialHandler; + Material* m_MaterialHandler = nullptr; }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp new file mode 100644 index 00000000..fa52fc8e --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -0,0 +1,70 @@ +#pragma once +#include "Mesh.h" + +using namespace std; + +Mesh::Mesh() +{ + +} + +void Mesh::GetMeshData(MObject object) +{ + // In here, we retrieve triangulated polygons from the mesh + MFnMesh mesh(object); + + map> vertexToIndex; + + vector verticesData; + vectorindexArray; + + MIntArray intdexOffsetVertexCount, vertices, triangleList; + MPointArray dummy; + + UINT vertexIndex; + MVector normal; + MPoint pos; + float2 UV; + VertexLayout thisVertex; + + for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) { + vector localVertexToGlobalIndex; + meshPolyIter.getVertices(vertices); + + meshPolyIter.getTriangles(dummy, triangleList); + UINT indexOffset = verticesData.size(); + + for (UINT i = 0; i < vertices.length(); i++) { + vertexIndex = meshPolyIter.vertexIndex(i); + pos = meshPolyIter.point(i); + pos.get(thisVertex.Pos); + + meshPolyIter.getNormal(i, normal); + thisVertex.Normal[0] = normal[0]; + thisVertex.Normal[1] = normal[1]; + thisVertex.Normal[2] = normal[2]; + + meshPolyIter.getUV(i, UV); + thisVertex.Uv[0] = UV[0]; + thisVertex.Uv[1] = UV[1]; + + verticesData.push_back(thisVertex); + localVertexToGlobalIndex.push_back(vertexIndex); + + 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 << "UV: " << thisVertex.Uv[0] << "/" << thisVertex.Uv[1] << endl; + } + for (UINT i = 0; i < triangleList.length(); i++) { + UINT k = 0; + while (localVertexToGlobalIndex[k] != triangleList[i]) + k++; + indexArray.push_back(indexOffset + k); + } + } +} + +Mesh::~Mesh() +{ + +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h new file mode 100644 index 00000000..0ba9624d --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -0,0 +1,24 @@ +#ifndef Mesh_Mesh_h__ +#define Mesh_Mesh_h__ + +#include +#include + +#include "MayaIncludes.h" + +struct VertexLayout +{ + float Pos[3]; + float Normal[3]; + float Uv[2]; +}; + +class Mesh +{ +public: + Mesh(); + void GetMeshData(MObject Object); + ~Mesh(); +}; + +#endif \ No newline at end of file From 60b3ce89b22889fdf0a9aa3635fee711a3dd3744 Mon Sep 17 00:00:00 2001 From: antc13 Date: Mon, 14 Dec 2015 12:59:54 +0100 Subject: [PATCH 04/13] Skeleton/Joints WIP --- assets | 2 +- .../MayaExporter/MayaExporter.vcxproj | 2 ++ .../MayaExporter/MayaExporter.vcxproj.filters | 6 +++++ tools/MayaExporter/MayaExporter/Menu.cpp | 5 ++++ tools/MayaExporter/MayaExporter/Menu.h | 1 + tools/MayaExporter/MayaExporter/Skeleton.cpp | 11 ++++++++ tools/MayaExporter/MayaExporter/Skeleton.h | 27 +++++++++++++++++++ 7 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tools/MayaExporter/MayaExporter/Skeleton.cpp create mode 100644 tools/MayaExporter/MayaExporter/Skeleton.h diff --git a/assets b/assets index 4bd902b6..56305dcc 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4bd902b697b8eef063da800102e6e9c3b29353eb +Subproject commit 56305dcca629b8adaf57efc4e6a853b6c5f345f8 diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index ffc93c0f..50577919 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -174,6 +174,7 @@ + @@ -197,6 +198,7 @@ + Moc%27ing Menu.h... .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index 70af7805..cf4a5a35 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -56,6 +56,9 @@ Source Files + + Source Files + @@ -81,5 +84,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 3fc760e6..fc3808f6 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -183,6 +183,11 @@ void Menu::GetMaterialData() MGlobal::displayInfo(MString() + AllMaterials->at(0).Color[0]); } +void Menu::GetSkeletonData() +{ + +} + Menu::~Menu() { //delete exportSelectedButton; diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index e58c86fb..6f766025 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -42,6 +42,7 @@ public: ~Menu(); void GetMaterialData(); + void GetSkeletonData(); private slots: void ExportSelected(bool checked); diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp new file mode 100644 index 00000000..28f56563 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -0,0 +1,11 @@ +#include "Skeleton.h" + +//std::vector* Skeleton::DoIt() +//{ +// MItDependencyNodes jointIt(MFn::kJoint); +// +// for (; !jointIt.isDone(); jointIt.next()) +// { +// //MFnDependencyNode +// } +//} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h new file mode 100644 index 00000000..8b111490 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -0,0 +1,27 @@ +#ifndef Skeleton_Skeleton_h__ +#define Skeleton_Skeleton_h__ + +#include +#include +#include "MayaIncludes.h" + +struct Joint { + int ParentIndex; + std::array Rotation; + std::array Translation; + std::array Scale; +}; + +struct SkeletonNode { + std::string Name; + std::vector joints; +}; + +class Skeleton { +public: + //std::vector* DoIt(); +private: + //std::vector m_AllSkeletons; +}; + +#endif //Skeleton_Skeleton_h__ \ No newline at end of file From 168937035669ea3cb958284ce29f02004f950594 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Tue, 15 Dec 2015 11:49:59 +0100 Subject: [PATCH 05/13] Export the skeletons Not really tested though --- tools/MayaExporter/MayaExporter/Menu.cpp | 14 +++++ tools/MayaExporter/MayaExporter/Menu.h | 2 + tools/MayaExporter/MayaExporter/Skeleton.cpp | 62 +++++++++++++++++--- tools/MayaExporter/MayaExporter/Skeleton.h | 16 +++-- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index fc3808f6..8eb245e2 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -145,6 +145,7 @@ void Menu::Button1Clicked(bool) { if (m_ExportAnimationsButton->isChecked()) { MGlobal::displayInfo("1 checked!"); + this->GetSkeletonData(); } else { MGlobal::displayInfo("1 unchecked!"); @@ -185,7 +186,20 @@ void Menu::GetMaterialData() void Menu::GetSkeletonData() { + this->m_SkeletonHandler = new Skeleton(); + // Traverse scene and return vector with all materials + std::vector* AllMaterials = m_SkeletonHandler->DoIt(); + + MGlobal::displayInfo(MString() + AllMaterials->size()); + + for (int i = 0; i < AllMaterials->size(); i++) + { + for (int j = 0; j < AllMaterials->at(i).Joints.size(); j++) + { + MGlobal::displayInfo(MString() + AllMaterials->at(i).Joints.at(j).Name.c_str()); + } + } } Menu::~Menu() diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 6f766025..a0fe93f6 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -33,6 +33,7 @@ #include "MayaIncludes.h" #include "Material.h" #include "Mesh.h" +#include "Skeleton.h" class Menu : public QWidget { @@ -71,6 +72,7 @@ private: QDialog* m_DialogPointer = nullptr; Material* m_MaterialHandler = nullptr; + Skeleton* m_SkeletonHandler = nullptr; }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 28f56563..3e95b817 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -1,11 +1,55 @@ #include "Skeleton.h" -//std::vector* Skeleton::DoIt() -//{ -// MItDependencyNodes jointIt(MFn::kJoint); -// -// for (; !jointIt.isDone(); jointIt.next()) -// { -// //MFnDependencyNode -// } -//} \ No newline at end of file +std::vector* Skeleton::DoIt() +{ + MItDependencyNodes jointIt(MFn::kJoint); + SkeletonNode SkeletonStorage; + + while (!jointIt.isDone()) { + MFnDependencyNode SkeletonFnDN(jointIt.thisNode()); + MFnTransform TransformNode(SkeletonFnDN.object()); + Joint NewJoint; + + if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") { + if (SkeletonStorage.Joints.size() != 0) { + m_AllSkeletons.push_back(SkeletonStorage); + + SkeletonStorage.Joints.clear(); + SkeletonStorage.Name.clear(); + } + + SkeletonStorage.Name = TransformNode.name().asChar(); + + NewJoint.ParentIndex = -1; // This joint is root + } + else { + auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), TransformNode.parent(0)); + if (it != m_Hierarchy.end()) { + NewJoint.ParentIndex = it - m_Hierarchy.begin(); + } + else { + MGlobal::displayError(MString() + "Could not find joint parent for: " + TransformNode.name()); + } + } + + m_Hierarchy.push_back(TransformNode.object()); + + NewJoint.Name = TransformNode.name().asChar(); + + MMatrix Matrix = TransformNode.transformationMatrix(); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; + } + } + + SkeletonStorage.Joints.push_back(NewJoint); + + jointIt.next(); + } + + m_AllSkeletons.push_back(SkeletonStorage); + + return &m_AllSkeletons; +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 8b111490..26e99d4b 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -3,25 +3,29 @@ #include #include +#include #include "MayaIncludes.h" struct Joint { int ParentIndex; - std::array Rotation; - std::array Translation; - std::array Scale; + //std::array Rotation; + //std::array Translation; + //std::array Scale; + std::array, 4> OffsetMatrix; + std::string Name; }; struct SkeletonNode { std::string Name; - std::vector joints; + std::vector Joints; }; class Skeleton { public: - //std::vector* DoIt(); + std::vector* DoIt(); private: - //std::vector m_AllSkeletons; + std::vector m_AllSkeletons; + std::vector m_Hierarchy; }; #endif //Skeleton_Skeleton_h__ \ No newline at end of file From 4e535c110293b527fe112c8e52a76ed5f3660145 Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 15 Dec 2015 15:24:46 +0100 Subject: [PATCH 06/13] =?UTF-8?q?File=20Writer=20WIP.=20Rework=20soon?= =?UTF-8?q?=E2=84=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MayaExporter/MayaExporter.vcxproj | 2 + .../MayaExporter/MayaExporter.vcxproj.filters | 6 ++ tools/MayaExporter/MayaExporter/Menu.h | 1 + tools/MayaExporter/MayaExporter/Var.cpp | 70 +++++++++++++++++++ tools/MayaExporter/MayaExporter/Var.h | 32 +++++++++ 5 files changed, 111 insertions(+) create mode 100644 tools/MayaExporter/MayaExporter/Var.cpp create mode 100644 tools/MayaExporter/MayaExporter/Var.h diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index 50577919..b04d032f 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -175,6 +175,7 @@ + @@ -199,6 +200,7 @@ + Moc%27ing Menu.h... .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index cf4a5a35..6f836155 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -59,6 +59,9 @@ Source Files + + Source Files + @@ -87,5 +90,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 6f766025..bf77e59f 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -33,6 +33,7 @@ #include "MayaIncludes.h" #include "Material.h" #include "Mesh.h" +#include "Var.h" class Menu : public QWidget { diff --git a/tools/MayaExporter/MayaExporter/Var.cpp b/tools/MayaExporter/MayaExporter/Var.cpp new file mode 100644 index 00000000..adfcb212 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Var.cpp @@ -0,0 +1,70 @@ +#include "Var.h" +#include "MayaIncludes.h" +#include + +Var::Var(Var::Type type, unsigned int numElements) +{ + m_Type = type; + m_NumElements = numElements; + + switch (m_Type) + { + case Var::Type::Int: + m_Data = new int[m_NumElements]; + break; + case Var::Type::Float: + m_Data = new float[m_NumElements]; + break; + case Var::Type::String: + m_Data = new std::string[m_NumElements]; + break; + default: + MGlobal::displayError("Var is an invalid type"); + assert(0); + break; + } +} + +Var& Var::operator=(const int& other) +{ + assert(m_Type == Type::Int); + *(int*)m_Data = other; + return *this; +} + +Var& Var::operator=(const float& other) +{ + assert(m_Type == Type::Float); + *(float*)m_Data = other; + return *this; +} + +Var& Var::operator=(const std::string& other) +{ + assert(m_Type == Type::String); + std::string tmp(other); + (*(std::string*)m_Data).swap(tmp); + return *this; +} + +//Var& Var::operator=(const Var& other) +//{ +// m_Data = other.m_Data; +// m_Type = other.m_Type; +// return *this; +//} + +Var::Type Var::isType() const +{ + return m_Type; +} + +unsigned int Var::NumElements() const +{ + return m_NumElements; +} + +void* Var::Data() +{ + return m_Data; +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Var.h b/tools/MayaExporter/MayaExporter/Var.h new file mode 100644 index 00000000..b0ec66dd --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Var.h @@ -0,0 +1,32 @@ +#ifndef Var_Var_h__ +#define Var_Var_h__ + +#include + +class Var +{ +public: + enum class Type + { + Int, + Float, + String + }; + + Var(Var::Type type, unsigned int numElements = 1); + ~Var() { delete[] m_Data; }; + + Var& operator=(const int& other); + Var& operator=(const float& other); + Var& operator=(const std::string& other); + //Var& operator=(const Var& other); + Type isType() const; + unsigned int NumElements() const; + void* Data(); +private: + Type m_Type; + unsigned int m_NumElements; + void* m_Data; +}; + +#endif \ No newline at end of file From 67017fcaf47a9a72fc9c8b7379d3c8aeb0f548f9 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 16 Dec 2015 11:33:42 +0100 Subject: [PATCH 07/13] Stepping through the timeline. --- .../MayaExporter/MayaExporter.vcxproj | 2 - .../MayaExporter/MayaExporter.vcxproj.filters | 6 -- .../MayaExporter/MayaExporter/MayaIncludes.h | 3 + tools/MayaExporter/MayaExporter/Menu.cpp | 26 +++++-- tools/MayaExporter/MayaExporter/Var.cpp | 70 ------------------- tools/MayaExporter/MayaExporter/Var.h | 32 --------- 6 files changed, 22 insertions(+), 117 deletions(-) delete mode 100644 tools/MayaExporter/MayaExporter/Var.cpp delete mode 100644 tools/MayaExporter/MayaExporter/Var.h diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index b04d032f..50577919 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -175,7 +175,6 @@ - @@ -200,7 +199,6 @@ - Moc%27ing Menu.h... .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index 6f836155..cf4a5a35 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -59,9 +59,6 @@ Source Files - - Source Files - @@ -90,8 +87,5 @@ Header Files - - Header Files - \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 6c092052..9186bfe6 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include // Wrappers @@ -59,5 +61,6 @@ #pragma comment(lib,"Foundation.lib") #pragma comment(lib,"OpenMaya.lib") #pragma comment(lib,"OpenMayaUI.lib") +#pragma comment (lib, "OpenMayaAnim.lib") #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 8eb245e2..06c115c8 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -187,17 +187,29 @@ void Menu::GetMaterialData() void Menu::GetSkeletonData() { this->m_SkeletonHandler = new Skeleton(); + MTime startFrame = MAnimControl::animationStartTime(); + MTime endFrame = MAnimControl::animationEndTime(); - // Traverse scene and return vector with all materials - std::vector* AllMaterials = m_SkeletonHandler->DoIt(); + std::vector*> AllSkeletons; - MGlobal::displayInfo(MString() + AllMaterials->size()); - - for (int i = 0; i < AllMaterials->size(); i++) + for (int i = startFrame.value(); i < endFrame.value();i++) { - for (int j = 0; j < AllMaterials->at(i).Joints.size(); j++) + MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); + // Traverse scene and return vector with all materials + AllSkeletons.push_back(m_SkeletonHandler->DoIt()); + } + + MGlobal::displayInfo(MString() + AllSkeletons.size()); + + for (int i = 0; i < AllSkeletons.size(); i++) + { + std::vector*& thisSkeleton = AllSkeletons.at(i); + for (int k = 0; k < thisSkeleton->size(); k++) { - MGlobal::displayInfo(MString() + AllMaterials->at(i).Joints.at(j).Name.c_str()); + for (int j = 0; j < thisSkeleton->at(k).Joints.size(); j++) + { + MGlobal::displayInfo(MString() + thisSkeleton->at(k).Joints.at(j).Name.c_str()); + } } } } diff --git a/tools/MayaExporter/MayaExporter/Var.cpp b/tools/MayaExporter/MayaExporter/Var.cpp deleted file mode 100644 index adfcb212..00000000 --- a/tools/MayaExporter/MayaExporter/Var.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "Var.h" -#include "MayaIncludes.h" -#include - -Var::Var(Var::Type type, unsigned int numElements) -{ - m_Type = type; - m_NumElements = numElements; - - switch (m_Type) - { - case Var::Type::Int: - m_Data = new int[m_NumElements]; - break; - case Var::Type::Float: - m_Data = new float[m_NumElements]; - break; - case Var::Type::String: - m_Data = new std::string[m_NumElements]; - break; - default: - MGlobal::displayError("Var is an invalid type"); - assert(0); - break; - } -} - -Var& Var::operator=(const int& other) -{ - assert(m_Type == Type::Int); - *(int*)m_Data = other; - return *this; -} - -Var& Var::operator=(const float& other) -{ - assert(m_Type == Type::Float); - *(float*)m_Data = other; - return *this; -} - -Var& Var::operator=(const std::string& other) -{ - assert(m_Type == Type::String); - std::string tmp(other); - (*(std::string*)m_Data).swap(tmp); - return *this; -} - -//Var& Var::operator=(const Var& other) -//{ -// m_Data = other.m_Data; -// m_Type = other.m_Type; -// return *this; -//} - -Var::Type Var::isType() const -{ - return m_Type; -} - -unsigned int Var::NumElements() const -{ - return m_NumElements; -} - -void* Var::Data() -{ - return m_Data; -} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Var.h b/tools/MayaExporter/MayaExporter/Var.h deleted file mode 100644 index b0ec66dd..00000000 --- a/tools/MayaExporter/MayaExporter/Var.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef Var_Var_h__ -#define Var_Var_h__ - -#include - -class Var -{ -public: - enum class Type - { - Int, - Float, - String - }; - - Var(Var::Type type, unsigned int numElements = 1); - ~Var() { delete[] m_Data; }; - - Var& operator=(const int& other); - Var& operator=(const float& other); - Var& operator=(const std::string& other); - //Var& operator=(const Var& other); - Type isType() const; - unsigned int NumElements() const; - void* Data(); -private: - Type m_Type; - unsigned int m_NumElements; - void* m_Data; -}; - -#endif \ No newline at end of file From 73708ec7066fd0305363e3844c35903b8edf3fa1 Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 17 Dec 2015 14:58:46 +0100 Subject: [PATCH 08/13] You can now add/remove animation clips. --- tools/MayaExporter/MayaExporter/Menu.cpp | 144 +++++++++++++++++++---- tools/MayaExporter/MayaExporter/Menu.h | 13 ++ 2 files changed, 134 insertions(+), 23 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 06c115c8..591c15fa 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -17,6 +17,8 @@ Menu::Menu(QDialog* dialog) m_BrowseButton = new QPushButton("&...", this); m_ExportAllButton = new QPushButton("&Export All", this); m_CancelButton = new QPushButton("&Cancel", this); + m_AddClipsButton = new QPushButton("&Add Clips", this); + m_RemoveClipsButton = new QPushButton("&Remove Latest Clip", this); // Option box and checkboxes QGroupBox *optionsBox = new QGroupBox(tr("Options")); @@ -39,6 +41,8 @@ Menu::Menu(QDialog* dialog) connect(m_BrowseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool))); connect(m_ExportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool))); connect(m_CancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool))); + connect(m_AddClipsButton, SIGNAL(clicked(bool)), this, SLOT(AddClipClicked(bool))); + connect(m_RemoveClipsButton, SIGNAL(clicked(bool)), this, SLOT(RemoveClipClicked(bool))); connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool))); connect(m_CopyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool))); @@ -49,12 +53,25 @@ Menu::Menu(QDialog* dialog) QVBoxLayout* midLayout = new QVBoxLayout; QHBoxLayout* botLayout = new QHBoxLayout; QVBoxLayout* baseLayout = new QVBoxLayout; + QHBoxLayout* clipButtonLayout = new QHBoxLayout; + QHBoxLayout* startEndLabelLayout = new QHBoxLayout; + m_ClipLayout = new QVBoxLayout; + + m_ExportPath = new QLineEdit; m_FileDialog = new QFileDialog; QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); + QLabel* nameLabel = new QLabel; + nameLabel->setText("Name:"); + QLabel* startLabel = new QLabel; + startLabel->setText("Start:"); + QLabel* endLabel = new QLabel; + endLabel->setText("End:"); + + //exportLabel->setText("Export Path:"); midLayout->addWidget(optionsBox); @@ -66,19 +83,35 @@ Menu::Menu(QDialog* dialog) botLayout->addWidget(m_ExportAllButton); botLayout->addWidget(m_CancelButton); + startEndLabelLayout->addWidget(nameLabel); + startEndLabelLayout->addWidget(startLabel); + startEndLabelLayout->addWidget(endLabel); + + clipButtonLayout->addWidget(m_AddClipsButton); + clipButtonLayout->addWidget(m_RemoveClipsButton); + baseLayout->addLayout(topLayout); baseLayout->addLayout(midLayout); baseLayout->addSpacing(10); - baseLayout->addLayout(botLayout); + + baseLayout->addSpacing(10); + baseLayout->addLayout(clipButtonLayout); + baseLayout->addLayout(startEndLabelLayout); + baseLayout->addLayout(m_ClipLayout); baseLayout->addStretch(); // Set the layout for our window dialog->setLayout(baseLayout); + for (unsigned int i = 0; i < 3; i++) { + this->AddClipClicked(true); + } + } + void Menu::ExportSelected(bool checked) { // Retrieving the objects we currently have selected @@ -101,6 +134,11 @@ void Menu::ExportSelected(bool checked) else { cout << m_ExportPath->text().toLocal8Bit().constData() << endl; } + + if (m_ExportAnimationsButton->isChecked()) { + GetSkeletonData(); + } + } void Menu::ExportPathClicked(bool) @@ -112,6 +150,48 @@ void Menu::ExportPathClicked(bool) m_ExportPath->setText(fileName); } +void Menu::AddClipClicked(bool) +{ + QHBoxLayout* tempLayout = new QHBoxLayout; + + QLineEdit* nameLineEdit = new QLineEdit; + QLineEdit* startLineEdit = new QLineEdit; + QLineEdit* endLineEdit = new QLineEdit; + + m_AnimationClipName.push_back(nameLineEdit); + m_StartFrameLines.push_back(startLineEdit); + m_EndFrameLines.push_back(endLineEdit); + + tempLayout->addWidget(nameLineEdit); + tempLayout->addWidget(startLineEdit); + tempLayout->addWidget(endLineEdit); + + m_ClipLayout->addLayout(tempLayout); + //m_ClipLayout->update(); + layouts.push_back(tempLayout); +} + +void Menu::RemoveClipClicked(bool) +{ + if (m_StartFrameLines.size() > 0) { + QLayoutItem* tempWidget;// = m_ClipLayout->itemAt(0); + + for (unsigned int i = 0; i < layouts.size(); i++) { + while ((tempWidget = layouts[layouts.size()-1]->takeAt(0)) != 0) { + delete tempWidget->widget(); + delete tempWidget; + } + } + + m_ClipLayout->removeItem(tempWidget); + m_ClipLayout->update(); + + layouts.pop_back(); + m_StartFrameLines.pop_back(); + m_EndFrameLines.pop_back(); + } +} + void Menu::ExportAll(bool) { MDagPath path; @@ -134,6 +214,9 @@ void Menu::ExportAll(bool) else { cout << m_ExportPath->text().toLocal8Bit().constData() << endl; } + + if(m_ExportAnimationsButton->isChecked()) + GetSkeletonData(); } void Menu::CancelClicked(bool) @@ -145,7 +228,6 @@ void Menu::Button1Clicked(bool) { if (m_ExportAnimationsButton->isChecked()) { MGlobal::displayInfo("1 checked!"); - this->GetSkeletonData(); } else { MGlobal::displayInfo("1 unchecked!"); @@ -186,31 +268,46 @@ void Menu::GetMaterialData() void Menu::GetSkeletonData() { - this->m_SkeletonHandler = new Skeleton(); - MTime startFrame = MAnimControl::animationStartTime(); - MTime endFrame = MAnimControl::animationEndTime(); + if (MAnimControl::currentTime().unit() != MTime::kNTSCField) { + MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!"); + return; + } + + this->m_SkeletonHandler = new Skeleton(); std::vector*> AllSkeletons; - for (int i = startFrame.value(); i < endFrame.value();i++) - { - MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); - // Traverse scene and return vector with all materials - AllSkeletons.push_back(m_SkeletonHandler->DoIt()); - } - - MGlobal::displayInfo(MString() + AllSkeletons.size()); - - for (int i = 0; i < AllSkeletons.size(); i++) - { - std::vector*& thisSkeleton = AllSkeletons.at(i); - for (int k = 0; k < thisSkeleton->size(); k++) - { - for (int j = 0; j < thisSkeleton->at(k).Joints.size(); j++) - { - MGlobal::displayInfo(MString() + thisSkeleton->at(k).Joints.at(j).Name.c_str()); - } + for (unsigned int j = 0; j < m_StartFrameLines.size(); j++) { + if (m_StartFrameLines[j]->text().isEmpty() == true || m_StartFrameLines[j]->text().isEmpty() == true) { + MGlobal::displayError(MString() + "Empty Animation Clip(s)"); + return; } + + int startFrame = m_StartFrameLines[j]->text().toInt(); + int endFrame = m_EndFrameLines[j]->text().toInt(); + + for (int i = startFrame; i < endFrame;++i) + { + MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); + MTime time = MAnimControl::currentTime(); + + // Traverse scene and return vector with all materials + AllSkeletons.push_back(m_SkeletonHandler->DoIt()); + } + + //MGlobal::displayInfo(MString() + AllSkeletons.size()); + + /*for (int i = 0; i < AllSkeletons.size(); i++) + { + std::vector*& thisSkeleton = AllSkeletons.at(i); + for (int k = 0; k < thisSkeleton->size(); k++) + { + for (int j = 0; j < thisSkeleton->at(k).Joints.size(); j++) + { + MGlobal::displayInfo(MString() + thisSkeleton->at(k).Joints.at(j).Name.c_str()); + } + } + }*/ } } @@ -221,5 +318,6 @@ Menu::~Menu() //delete exportPath; //delete fileDialog; m_FileDialog->~QFileDialog(); + //delete MaterialHandler; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index a0fe93f6..81ec2834 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -29,6 +29,9 @@ #include #include #include +#include +#include + #include "MayaIncludes.h" #include "Material.h" @@ -48,6 +51,8 @@ public: private slots: void ExportSelected(bool checked); void ExportPathClicked(bool); + void AddClipClicked(bool); + void RemoveClipClicked(bool); void ExportAll(bool); void CancelClicked(bool); @@ -58,10 +63,18 @@ private slots: private: Menu(); + std::vector m_AnimationClipName; + std:: vector m_StartFrameLines; + std::vector m_EndFrameLines; + std::vector layouts; + QVBoxLayout* m_ClipLayout; + QPushButton* m_ExportSelectedButton = nullptr; QPushButton* m_BrowseButton = nullptr; QPushButton* m_ExportAllButton = nullptr; QPushButton* m_CancelButton = nullptr; + QPushButton* m_AddClipsButton = nullptr; + QPushButton* m_RemoveClipsButton = nullptr; QCheckBox* m_ExportAnimationsButton = nullptr; QCheckBox* m_CopyTexturesButton = nullptr; From bc4cc5db548eeeb76391f1cd5f263e5aedd611e9 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Fri, 18 Dec 2015 10:03:00 +0100 Subject: [PATCH 09/13] Changed how we get skeletons. Made so that we could get the bind pose for each skeleton in the scene --- .../MayaExporter/MayaExporter/MayaIncludes.h | 3 + tools/MayaExporter/MayaExporter/Menu.cpp | 37 ++++-- tools/MayaExporter/MayaExporter/Skeleton.cpp | 114 +++++++++++++++--- tools/MayaExporter/MayaExporter/Skeleton.h | 13 +- 4 files changed, 135 insertions(+), 32 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 9186bfe6..4a810787 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -33,6 +33,9 @@ #include #include #include +#include +#include +#include // Wrappers diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 06c115c8..410e0fa3 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -190,25 +190,44 @@ void Menu::GetSkeletonData() MTime startFrame = MAnimControl::animationStartTime(); MTime endFrame = MAnimControl::animationEndTime(); - std::vector*> AllSkeletons; + std::vector> allSkeletons; + + std::vector allBindPoses; + allBindPoses = m_SkeletonHandler->GetBindPoses(); for (int i = startFrame.value(); i < endFrame.value();i++) { MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); // Traverse scene and return vector with all materials - AllSkeletons.push_back(m_SkeletonHandler->DoIt()); + allSkeletons.push_back(m_SkeletonHandler->DoIt()); + } + + //print out all bind poses + for (auto aBindPose : allBindPoses) + { + MGlobal::displayInfo(MString() + "BindPose Skeleton name: " + aBindPose.Name.c_str()); + for (int i = 0; i < aBindPose.Joints.size(); i++) + { + //MGlobal::displayInfo(MString() + aBindPose.JointNames[i].c_str()); + //MGlobal::displayInfo(MString() + aBindPose.ParentIDs[i]); + //MGlobal::displayInfo(MString() + aBindPose.Joints[i].Translation[0] + " " + aBindPose.Joints[i].Translation[1] + " " + aBindPose.Joints[i].Translation[2]); + //MGlobal::displayInfo(MString() + aBindPose.Joints[i].Rotation[0] + " " + aBindPose.Joints[i].Rotation[1] + " " + aBindPose.Joints[i].Rotation[2]); + //MGlobal::displayInfo(MString() + aBindPose.Joints[i].Scale[0] + " " + aBindPose.Joints[i].Scale[1] + " " + aBindPose.Joints[i].Scale[2]); + } } - MGlobal::displayInfo(MString() + AllSkeletons.size()); - - for (int i = 0; i < AllSkeletons.size(); i++) + //Print out all skeletons for all frames + MGlobal::displayInfo(MString() + allSkeletons.size()); + for (auto frameSkeletons : allSkeletons) { - std::vector*& thisSkeleton = AllSkeletons.at(i); - for (int k = 0; k < thisSkeleton->size(); k++) + for (auto aSkeleton : frameSkeletons) { - for (int j = 0; j < thisSkeleton->at(k).Joints.size(); j++) + MGlobal::displayInfo(MString() + aSkeleton.Name.c_str()); + for (auto joint : aSkeleton.Joints) { - MGlobal::displayInfo(MString() + thisSkeleton->at(k).Joints.at(j).Name.c_str()); + //MGlobal::displayInfo(MString() + joint.Translation[0] + " " + joint.Translation[1] + " " + joint.Translation[2]); + //MGlobal::displayInfo(MString() + joint.Rotation[0] + " " + joint.Rotation[1] + " " + joint.Rotation[2]); + //MGlobal::displayInfo(MString() + joint.Scale[0] + " " + joint.Scale[1] + " " + joint.Scale[2]); } } } diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 3e95b817..030c17dd 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -1,13 +1,14 @@ #include "Skeleton.h" -std::vector* Skeleton::DoIt() +std::vector Skeleton::DoIt() { - MItDependencyNodes jointIt(MFn::kJoint); + std::vector m_AllSkeletons; + + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); SkeletonNode SkeletonStorage; while (!jointIt.isDone()) { - MFnDependencyNode SkeletonFnDN(jointIt.thisNode()); - MFnTransform TransformNode(SkeletonFnDN.object()); + MFnTransform TransformNode(jointIt.currentItem()); Joint NewJoint; if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") { @@ -20,24 +21,27 @@ std::vector* Skeleton::DoIt() SkeletonStorage.Name = TransformNode.name().asChar(); - NewJoint.ParentIndex = -1; // This joint is root - } - else { - auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), TransformNode.parent(0)); - if (it != m_Hierarchy.end()) { - NewJoint.ParentIndex = it - m_Hierarchy.begin(); - } - else { - MGlobal::displayError(MString() + "Could not find joint parent for: " + TransformNode.name()); - } + //NewJoint.ParentIndex = -1; // This joint is root } - m_Hierarchy.push_back(TransformNode.object()); - - NewJoint.Name = TransformNode.name().asChar(); + //NewJoint.Name = TransformNode.name().asChar(); MMatrix Matrix = TransformNode.transformationMatrix(); + //double tmp[3]; + //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); + //NewJoint.Rotation[0] = tmp[0]; + //NewJoint.Rotation[1] = tmp[1]; + //NewJoint.Rotation[2] = tmp[2]; + //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); + //NewJoint.Scale[0] = tmp[0]; + //NewJoint.Scale[1] = tmp[1]; + //NewJoint.Scale[2] = tmp[2]; + //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); + //NewJoint.Translation[0] = tmp[0]; + //NewJoint.Translation[1] = tmp[1]; + //NewJoint.Translation[2] = tmp[2]; + for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; @@ -51,5 +55,79 @@ std::vector* Skeleton::DoIt() m_AllSkeletons.push_back(SkeletonStorage); - return &m_AllSkeletons; + return m_AllSkeletons; +} + +std::vector Skeleton::GetBindPoses() +{ + std::vector m_AllSkeletons; + std::vector m_Hierarchy; + + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + BindPoseSkeletonNode SkeletonStorage; + + while (!jointIt.isDone()) { + MFnTransform MayaJoint(jointIt.currentItem()); + + if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") { + if (SkeletonStorage.Joints.size() != 0) { + m_AllSkeletons.push_back(SkeletonStorage); + + SkeletonStorage.Joints.clear(); + SkeletonStorage.Name.clear(); + SkeletonStorage.ParentIDs.clear(); + SkeletonStorage.Name.clear(); + } + + SkeletonStorage.Name = MayaJoint.name().asChar(); + SkeletonStorage.ParentIDs.push_back(-1); // This joint is root + } + else { + auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0)); + if (it != m_Hierarchy.end()) { + SkeletonStorage.ParentIDs.push_back(it - m_Hierarchy.begin()); + } + else { + MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name()); + } + } + m_Hierarchy.push_back(MayaJoint.object()); + + Joint NewJoint; + + MPlug BindPose = MayaJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix Matrix = MartixFn.matrix(); + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; + } + } + + /*double tmp[3]; + ((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); + NewJoint.Rotation[0] = tmp[0]; + NewJoint.Rotation[1] = tmp[1]; + NewJoint.Rotation[2] = tmp[2]; + ((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); + NewJoint.Scale[0] = tmp[0]; + NewJoint.Scale[1] = tmp[1]; + NewJoint.Scale[2] = tmp[2]; + ((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); + NewJoint.Translation[0] = tmp[0]; + NewJoint.Translation[1] = tmp[1]; + NewJoint.Translation[2] = tmp[2];*/ + + SkeletonStorage.Joints.push_back(NewJoint); + SkeletonStorage.JointNames.push_back(MayaJoint.name().asChar()); + + jointIt.next(); + } + + m_AllSkeletons.push_back(SkeletonStorage); + + return m_AllSkeletons; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 26e99d4b..3ee01224 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -7,12 +7,11 @@ #include "MayaIncludes.h" struct Joint { - int ParentIndex; + //int ParentIndex; //std::array Rotation; //std::array Translation; //std::array Scale; std::array, 4> OffsetMatrix; - std::string Name; }; struct SkeletonNode { @@ -20,12 +19,16 @@ struct SkeletonNode { std::vector Joints; }; +struct BindPoseSkeletonNode : SkeletonNode { + std::vector ParentIDs; + std::vector JointNames; +}; + class Skeleton { public: - std::vector* DoIt(); + std::vector DoIt(); + std::vector GetBindPoses(); private: - std::vector m_AllSkeletons; - std::vector m_Hierarchy; }; #endif //Skeleton_Skeleton_h__ \ No newline at end of file From c9db46564f1394978bf75e88d5b18bce0e0d3908 Mon Sep 17 00:00:00 2001 From: antc13 Date: Fri, 18 Dec 2015 16:21:07 +0100 Subject: [PATCH 10/13] Spitting out files WIP --- .../MayaExporter/MayaExporter.vcxproj | 3 + .../MayaExporter/MayaExporter.vcxproj.filters | 9 +++ .../MayaExporter/MayaExporter/MayaIncludes.h | 1 + tools/MayaExporter/MayaExporter/Menu.cpp | 12 +++- tools/MayaExporter/MayaExporter/Menu.h | 3 + tools/MayaExporter/MayaExporter/Mesh.cpp | 52 ++++++++++---- tools/MayaExporter/MayaExporter/Mesh.h | 14 +++- tools/MayaExporter/MayaExporter/OutputData.h | 23 ++++++ tools/MayaExporter/MayaExporter/Skeleton.cpp | 3 + tools/MayaExporter/MayaExporter/Skeleton.h | 70 +++++++++++++++++-- .../MayaExporter/MayaExporter/WriteToFile.cpp | 38 ++++++++++ tools/MayaExporter/MayaExporter/WriteToFile.h | 49 +++++++++++++ 12 files changed, 257 insertions(+), 20 deletions(-) create mode 100644 tools/MayaExporter/MayaExporter/OutputData.h create mode 100644 tools/MayaExporter/MayaExporter/WriteToFile.cpp create mode 100644 tools/MayaExporter/MayaExporter/WriteToFile.h diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index 50577919..a9154ac7 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -175,6 +175,7 @@ + @@ -198,7 +199,9 @@ + + Moc%27ing Menu.h... .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index cf4a5a35..be5b36b1 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -59,6 +59,9 @@ Source Files + + Source Files + @@ -87,5 +90,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 4a810787..0e490208 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -36,6 +36,7 @@ #include #include #include +#include // Wrappers diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index ae5b1732..ed09ec25 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -215,8 +215,12 @@ 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(); + } void Menu::CancelClicked(bool) @@ -298,8 +302,10 @@ void Menu::GetSkeletonData() } //print out all bind poses + m_File.OpenFiles(); for (auto aBindPose : allBindPoses) { + m_File.writeToFiles(&aBindPose); MGlobal::displayInfo(MString() + "BindPose Skeleton name: " + aBindPose.Name.c_str()); for (int i = 0; i < aBindPose.Joints.size(); i++) { @@ -312,21 +318,25 @@ void Menu::GetSkeletonData() } //Print out all skeletons for all frames + MGlobal::displayInfo(MString() + allSkeletons.size()); for (auto frameSkeletons : allSkeletons) { for (auto aSkeleton : frameSkeletons) { MGlobal::displayInfo(MString() + aSkeleton.Name.c_str()); + //m_File.writeToFiles(&aSkeleton); for (auto joint : aSkeleton.Joints) { + //m_File.writeToFiles(&joint); //MGlobal::displayInfo(MString() + joint.Translation[0] + " " + joint.Translation[1] + " " + joint.Translation[2]); //MGlobal::displayInfo(MString() + joint.Rotation[0] + " " + joint.Rotation[1] + " " + joint.Rotation[2]); //MGlobal::displayInfo(MString() + joint.Scale[0] + " " + joint.Scale[1] + " " + joint.Scale[2]); } } - }*/ + } } + m_File.CloseFiles(); } Menu::~Menu() diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 81ec2834..0174cbc3 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -37,6 +37,7 @@ #include "Material.h" #include "Mesh.h" #include "Skeleton.h" +#include "WriteToFile.h" class Menu : public QWidget { @@ -86,6 +87,8 @@ private: Material* m_MaterialHandler = nullptr; Skeleton* m_SkeletonHandler = nullptr; + + WriteToFile m_File; }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index fa52fc8e..3965daf8 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -25,26 +25,48 @@ void Mesh::GetMeshData(MObject object) MVector normal; MPoint pos; float2 UV; + double biTangent[3]; + double biNormal[3]; VertexLayout thisVertex; + MFloatVectorArray biTangents; + MFloatVectorArray biNormals; + mesh.getTangents(biTangents, MSpace::kObject, NULL); + mesh.getBinormals(biNormals, MSpace::kObject, NULL); + + MGlobal::displayInfo("Befor Loop"); + 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++) { - vertexIndex = meshPolyIter.vertexIndex(i); - pos = meshPolyIter.point(i); - pos.get(thisVertex.Pos); - - meshPolyIter.getNormal(i, normal); + 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]; - meshPolyIter.getUV(i, UV); + 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]; + + MFloatVector biNormal = biNormals[faceVert.tangentId()]; + //faceVert.getBinormal().get(biNormal); + thisVertex.BiNormal[0] = biNormal[0]; + thisVertex.BiNormal[1] = biNormal[1]; + thisVertex.BiNormal[2] = biNormal[2]; + + faceVert.getUV(UV); thisVertex.Uv[0] = UV[0]; thisVertex.Uv[1] = UV[1]; @@ -53,14 +75,18 @@ void Mesh::GetMeshData(MObject object) 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; } - for (UINT i = 0; i < triangleList.length(); i++) { - UINT k = 0; - while (localVertexToGlobalIndex[k] != triangleList[i]) - k++; - indexArray.push_back(indexOffset + k); - } + MGlobal::displayInfo("Befor Third Loop"); + + //for (UINT i = 0; i < triangleList.length(); i++) { + // UINT k = 0; + // while (localVertexToGlobalIndex[k] != triangleList[i]) + // k++; + // indexArray.push_back(indexOffset + k); + //} } } diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 0ba9624d..00b88654 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -4,13 +4,25 @@ #include #include +#include "OutputData.h" #include "MayaIncludes.h" -struct VertexLayout +class VertexLayout : public OutputData { +public: + float Pos[3]; float Normal[3]; + float BiNormal[3]; + float BiTangent[3]; float Uv[2]; + + virtual void WriteBinary(std::ostream& out) { + + } + virtual void WriteASCII(std::ostream& out) const { + + } }; class Mesh diff --git a/tools/MayaExporter/MayaExporter/OutputData.h b/tools/MayaExporter/MayaExporter/OutputData.h new file mode 100644 index 00000000..60159340 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/OutputData.h @@ -0,0 +1,23 @@ +#ifndef OutputData_OutputData_h__ +#define OutputData_OutputData_h__ +#include +//template +class OutputData +{ +public://std::ostream& out, const OutputData& obj + //OutputData(T& object) + // : m_Object(object) + //{}; + + friend std::ostream& operator<<(std::ostream& out, const OutputData& obj) + { + obj.WriteASCII(out); + return out; + }; + virtual void WriteBinary(std::ostream& out) = 0; + virtual void WriteASCII(std::ostream& out) const = 0; + + //T& m_Object = nullptr; +}; + +#endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 030c17dd..3bba4c0a 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -1,5 +1,8 @@ #include "Skeleton.h" + + + std::vector Skeleton::DoIt() { std::vector m_AllSkeletons; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 3ee01224..2d363cf8 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -5,23 +5,83 @@ #include #include #include "MayaIncludes.h" - -struct Joint { +#include "OutputData.h" +class Joint : public OutputData{ +public: + //Joint() : OutputData((Joint)*this) + //{}; //int ParentIndex; //std::array Rotation; //std::array Translation; //std::array Scale; - std::array, 4> OffsetMatrix; + //std::array, 4> OffsetMatrix; + float OffsetMatrix[4][4]; + + virtual void WriteBinary(std::ostream& out) + { + out.write((char*)OffsetMatrix, 4 * 4 * sizeof(float)); + } + + virtual void WriteASCII(std::ostream& out) const + { + for (int i = 0; i < 4; i++) + { + for (int k = 0; k < 4; k++) + out << this->OffsetMatrix[i][k] << " "; + out << endl; + } + }; }; -struct SkeletonNode { +class SkeletonNode : public OutputData { +public: std::string Name; std::vector Joints; + + virtual void WriteBinary(std::ostream& out) + { + out.write(Name.c_str(), Name.size()); + for (auto aJoint : Joints) + { + aJoint.WriteBinary(out); + } + } + virtual void WriteASCII(std::ostream& out) const + { + out << "Skeleton: " << Name << endl; + for (auto aJoint : Joints) + { + aJoint.WriteASCII(out); + } + }; }; -struct BindPoseSkeletonNode : SkeletonNode { +class BindPoseSkeletonNode : public SkeletonNode { +public: std::vector ParentIDs; std::vector JointNames; + virtual void WriteBinary(std::ostream& out) + { + out.write(Name.c_str(), Name.size()); + for (int i = 0; i < Joints.size(); i++) + { + out.write((char*)&ParentIDs[i],sizeof(int)); + Joints[i].WriteBinary(out); + out.write(JointNames[i].c_str(), JointNames[i].size()); + } + + } + + virtual void WriteASCII(std::ostream& out) const + { + out << "Bind Pose: " << Name << endl; + for (int i = 0; i < Joints.size(); i++) + { + out << ParentIDs[i] << endl; + Joints[i].WriteASCII(out); + out << JointNames[i] << endl; + } + }; }; class Skeleton { diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.cpp b/tools/MayaExporter/MayaExporter/WriteToFile.cpp new file mode 100644 index 00000000..10883416 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/WriteToFile.cpp @@ -0,0 +1,38 @@ +#include "WriteToFile.h" + +WriteToFile::~WriteToFile() +{ + CloseFiles(); +} + +bool WriteToFile::binaryFilePath(string filePathAndFileName) +{ + binFileName = filePathAndFileName; + ofstream binFile(filePathAndFileName, ofstream::binary); + if (!binFile) + return false; + return true; +} + +bool WriteToFile::ASCIIFilePath(string filePathAndFileName) +{ + ASCIIFileName = filePathAndFileName; + ofstream ASCIIFile(filePathAndFileName); + if (!ASCIIFile) + return false; + return true; +} + +void WriteToFile::OpenFiles() +{ + if (binFile) + binFile.open(binFileName, ofstream::binary); + if (ASCIIFile) + ASCIIFile.open(ASCIIFileName); +} + +void WriteToFile::CloseFiles() +{ + binFile.close(); + ASCIIFile.close(); +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.h b/tools/MayaExporter/MayaExporter/WriteToFile.h new file mode 100644 index 00000000..f0c066d4 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/WriteToFile.h @@ -0,0 +1,49 @@ +#ifndef WriteToFile_WriteToFile_h__ +#define WriteToFile_WriteToFile_h__ + +#include "MayaIncludes.h" +#include "OutputData.h" +#include +#include + +using namespace std; + +class WriteToFile +{ +public: + ~WriteToFile(); + bool binaryFilePath(string filePathAndFileName); + bool ASCIIFilePath(string filePathAndFileName); + + void writeToFiles(OutputData* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0) + { + 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 OpenFiles(); + void CloseFiles(); + +private: + string binFileName; + string ASCIIFileName; + ofstream binFile; + ofstream ASCIIFile; +}; + + + +#endif \ No newline at end of file From eb5fca898ff4b092a93c1209a798824e1f796f1b Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Mon, 21 Dec 2015 12:55:25 +0100 Subject: [PATCH 11/13] Fix small bug with push_back order Commited directly from GitHub. Blame it if something explodes. --- tools/MayaExporter/MayaExporter/Material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 2bc084dc..ac9c46ea 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -226,11 +226,11 @@ std::vector* Material::DoIt() else if (matIt.thisNode().hasFn(MFn::kLambert)) { grabLambertProperties(MaterialStorage, MaterialFnDN); - m_AllMaterials.push_back(MaterialStorage); - MaterialStorage.Specular.fill(0.0f); MaterialStorage.ReflectionFactor = 0.0f; MaterialStorage.SpecularExponent = 0.0f; + + m_AllMaterials.push_back(MaterialStorage); } matIt.next(); From 1667358e0c3a59ee50b317bac75b85b8b35d5b2b Mon Sep 17 00:00:00 2001 From: antc13 Date: Fri, 8 Jan 2016 16:47:04 +0100 Subject: [PATCH 12/13] We now export animations. --- .../GeneratedFiles/Debug/moc_Menu.cpp | 31 +- tools/MayaExporter/MayaExporter/Menu.cpp | 63 ++-- tools/MayaExporter/MayaExporter/Mesh.cpp | 17 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 296 ++++++++++++------ tools/MayaExporter/MayaExporter/Skeleton.h | 117 ++++--- 5 files changed, 318 insertions(+), 206 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp b/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp index aef8d533..a375ed53 100644 --- a/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp +++ b/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp @@ -22,7 +22,7 @@ static const uint qt_meta_data_Menu[] = { 6, // revision 0, // classname 0, 0, // classinfo - 7, 14, // methods + 9, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors @@ -33,17 +33,20 @@ static const uint qt_meta_data_Menu[] = { 14, 6, 5, 5, 0x08, 35, 5, 5, 5, 0x08, 59, 5, 5, 5, 0x08, - 75, 5, 5, 5, 0x08, - 95, 5, 5, 5, 0x08, - 116, 5, 5, 5, 0x08, - 137, 5, 5, 5, 0x08, + 80, 5, 5, 5, 0x08, + 104, 5, 5, 5, 0x08, + 120, 5, 5, 5, 0x08, + 140, 5, 5, 5, 0x08, + 161, 5, 5, 5, 0x08, + 182, 5, 5, 5, 0x08, 0 // eod }; static const char qt_meta_stringdata_Menu[] = { "Menu\0\0checked\0ExportSelected(bool)\0" - "ExportPathClicked(bool)\0ExportAll(bool)\0" + "ExportPathClicked(bool)\0AddClipClicked(bool)\0" + "RemoveClipClicked(bool)\0ExportAll(bool)\0" "CancelClicked(bool)\0Button1Clicked(bool)\0" "Button2Clicked(bool)\0Button3Clicked(bool)\0" }; @@ -56,11 +59,13 @@ void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void * switch (_id) { case 0: _t->ExportSelected((*reinterpret_cast< bool(*)>(_a[1]))); break; case 1: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; - case 2: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break; - case 3: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; - case 4: _t->Button1Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; - case 5: _t->Button2Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; - case 6: _t->Button3Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 2: _t->AddClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 3: _t->RemoveClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 4: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 5: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 6: _t->Button1Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 7: _t->Button2Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 8: _t->Button3Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; default: ; } } @@ -98,9 +103,9 @@ int Menu::qt_metacall(QMetaObject::Call _c, int _id, void **_a) if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 7) + if (_id < 9) qt_static_metacall(this, _c, _id, _a); - _id -= 7; + _id -= 9; } return _id; } diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index ed09ec25..77241cad 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -72,7 +72,7 @@ Menu::Menu(QDialog* dialog) endLabel->setText("End:"); //exportLabel->setText("Export Path:"); - + midLayout->addWidget(optionsBox); topLayout->addWidget(exportLabel); @@ -119,7 +119,7 @@ void Menu::ExportSelected(bool checked) MGlobal::getActiveSelectionList(selected); // Loop through or list of selection(s) - for (unsigned int i = 0; i < selected.length();i++) { + for (unsigned int i = 0; i < selected.length(); i++) { MObject object; selected.getDependNode(i, object); MFnDependencyNode thisNode(object); @@ -177,7 +177,7 @@ void Menu::RemoveClipClicked(bool) QLayoutItem* tempWidget;// = m_ClipLayout->itemAt(0); for (unsigned int i = 0; i < layouts.size(); i++) { - while ((tempWidget = layouts[layouts.size()-1]->takeAt(0)) != 0) { + while ((tempWidget = layouts[layouts.size() - 1]->takeAt(0)) != 0) { delete tempWidget->widget(); delete tempWidget; } @@ -185,7 +185,7 @@ void Menu::RemoveClipClicked(bool) m_ClipLayout->removeItem(tempWidget); m_ClipLayout->update(); - + layouts.pop_back(); m_StartFrameLines.pop_back(); m_EndFrameLines.pop_back(); @@ -195,10 +195,10 @@ void Menu::RemoveClipClicked(bool) void Menu::ExportAll(bool) { MDagPath path; - + // Loop through all nodes in the scene MItDependencyNodes it(MFn::kInvalid); - for (;!it.isDone();it.next()) { + for (; !it.isDone(); it.next()) { MObject node = it.thisNode(); if (node.hasFn(MFn::kMesh)) { MFnDependencyNode thisNode(node); @@ -218,7 +218,7 @@ void Menu::ExportAll(bool) m_File.ASCIIFilePath("C:/Users/Nickelodion/Desktop/coolASCII.txt"); m_File.binaryFilePath("C:/Users/Nickelodion/Desktop/coolSoptunz.bin"); - if(m_ExportAnimationsButton->isChecked()) + if (m_ExportAnimationsButton->isChecked()) GetSkeletonData(); } @@ -267,7 +267,7 @@ void Menu::GetMaterialData() // Access the colorR component of one material (example) cout << AllMaterials->at(0).Color[0] << endl; - MGlobal::displayInfo(MString() + AllMaterials->at(0).Color[0]); + MGlobal::displayInfo(MString() + AllMaterials->at(0).Color[0]); } void Menu::GetSkeletonData() @@ -277,10 +277,10 @@ void Menu::GetSkeletonData() MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!"); return; } - - std::vector> allSkeletons; std::vector allBindPoses; + std::vector allAnimations; + allBindPoses = m_SkeletonHandler->GetBindPoses(); for (unsigned int j = 0; j < m_StartFrameLines.size(); j++) { @@ -291,24 +291,19 @@ void Menu::GetSkeletonData() int startFrame = m_StartFrameLines[j]->text().toInt(); int endFrame = m_EndFrameLines[j]->text().toInt(); + std::string animationName = m_AnimationClipName[j]->text().toAscii().constData(); - for (int i = startFrame; i < endFrame;++i) - { - MAnimControl::setCurrentTime(MTime(i, MTime::kNTSCField)); - MTime time = MAnimControl::currentTime(); + allAnimations.push_back(m_SkeletonHandler->GetAnimData(animationName, startFrame, endFrame)); + } + + m_File.OpenFiles(); - // Traverse scene and return vector with all materials - allSkeletons.push_back(m_SkeletonHandler->DoIt()); - } - //print out all bind poses - m_File.OpenFiles(); - for (auto aBindPose : allBindPoses) - { + for (auto aBindPose : allBindPoses){ m_File.writeToFiles(&aBindPose); MGlobal::displayInfo(MString() + "BindPose Skeleton name: " + aBindPose.Name.c_str()); - for (int i = 0; i < aBindPose.Joints.size(); i++) - { + + for (int i = 0; i < aBindPose.Joints.size(); i++){ //MGlobal::displayInfo(MString() + aBindPose.JointNames[i].c_str()); //MGlobal::displayInfo(MString() + aBindPose.ParentIDs[i]); //MGlobal::displayInfo(MString() + aBindPose.Joints[i].Translation[0] + " " + aBindPose.Joints[i].Translation[1] + " " + aBindPose.Joints[i].Translation[2]); @@ -316,25 +311,9 @@ void Menu::GetSkeletonData() //MGlobal::displayInfo(MString() + aBindPose.Joints[i].Scale[0] + " " + aBindPose.Joints[i].Scale[1] + " " + aBindPose.Joints[i].Scale[2]); } } - - //Print out all skeletons for all frames - - MGlobal::displayInfo(MString() + allSkeletons.size()); - for (auto frameSkeletons : allSkeletons) - { - for (auto aSkeleton : frameSkeletons) - { - MGlobal::displayInfo(MString() + aSkeleton.Name.c_str()); - //m_File.writeToFiles(&aSkeleton); - for (auto joint : aSkeleton.Joints) - { - //m_File.writeToFiles(&joint); - //MGlobal::displayInfo(MString() + joint.Translation[0] + " " + joint.Translation[1] + " " + joint.Translation[2]); - //MGlobal::displayInfo(MString() + joint.Rotation[0] + " " + joint.Rotation[1] + " " + joint.Rotation[2]); - //MGlobal::displayInfo(MString() + joint.Scale[0] + " " + joint.Scale[1] + " " + joint.Scale[2]); - } - } - } + //print out all animations + for (auto aAnimation : allAnimations) { + m_File.writeToFiles(&aAnimation); } m_File.CloseFiles(); } diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 3965daf8..58a7fbe4 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -34,7 +34,6 @@ void Mesh::GetMeshData(MObject object) mesh.getTangents(biTangents, MSpace::kObject, NULL); mesh.getBinormals(biNormals, MSpace::kObject, NULL); - MGlobal::displayInfo("Befor Loop"); MItMeshFaceVertex faceVert(object); int intDummy = 0; for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) { @@ -43,10 +42,10 @@ void Mesh::GetMeshData(MObject object) meshPolyIter.getTriangles(dummy, triangleList); UINT indexOffset = verticesData.size(); - MGlobal::displayInfo("Befor Second Loop"); + //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"); + //MGlobal::displayInfo("In Second Loop"); faceVert.position().get(thisVertex.Pos); faceVert.getNormal(normal); thisVertex.Normal[0] = normal[0]; @@ -73,13 +72,13 @@ void Mesh::GetMeshData(MObject object) verticesData.push_back(thisVertex); localVertexToGlobalIndex.push_back(vertexIndex); - 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; + //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("Befor Third Loop"); //for (UINT i = 0; i < triangleList.length(); i++) { // UINT k = 0; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 3bba4c0a..394f548b 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -3,33 +3,225 @@ -std::vector Skeleton::DoIt() +//std::vector Skeleton::DoIt() +//{ +// std::vector m_AllSkeletons; +// +// MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); +// SkeletonNode SkeletonStorage; +// +// while (!jointIt.isDone()) { +// MFnTransform TransformNode(jointIt.currentItem()); +// Joint NewJoint; +// +// if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") { +// if (SkeletonStorage.Joints.size() != 0) { +// m_AllSkeletons.push_back(SkeletonStorage); +// +// SkeletonStorage.Joints.clear(); +// SkeletonStorage.Name.clear(); +// } +// +// SkeletonStorage.Name = TransformNode.name().asChar(); +// +// //NewJoint.ParentIndex = -1; // This joint is root +// } +// +// //NewJoint.Name = TransformNode.name().asChar(); +// +// MMatrix Matrix = TransformNode.transformationMatrix(); +// +// //double tmp[3]; +// //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); +// //NewJoint.Rotation[0] = tmp[0]; +// //NewJoint.Rotation[1] = tmp[1]; +// //NewJoint.Rotation[2] = tmp[2]; +// //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); +// //NewJoint.Scale[0] = tmp[0]; +// //NewJoint.Scale[1] = tmp[1]; +// //NewJoint.Scale[2] = tmp[2]; +// //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); +// //NewJoint.Translation[0] = tmp[0]; +// //NewJoint.Translation[1] = tmp[1]; +// //NewJoint.Translation[2] = tmp[2]; +// +// for (int i = 0; i < 4; i++) { +// for (int j = 0; j < 4; j++) { +// NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; +// } +// } +// +// SkeletonStorage.Joints.push_back(NewJoint); +// +// jointIt.next(); +// } +// +// m_AllSkeletons.push_back(SkeletonStorage); +// +// return m_AllSkeletons; +//} +std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ" }; + +Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame) { - std::vector m_AllSkeletons; + Animation returnData; + double oneDivSixty = 1 / 60.0; + returnData.Name = animationName; + returnData.Duration = (endFrame - startFrame) * oneDivSixty; + std::vector animatedJoints; + std::vector m_Hierarchy; MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - SkeletonNode SkeletonStorage; + while (!jointIt.isDone()) + { + m_Hierarchy.push_back(jointIt.item()); + + MFnDependencyNode depNode(jointIt.item()); + for (int i = 0; i < 9; i++) + { + MStatus tmp; + MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp); + + MPlugArray connections; + plug.connectedTo(connections, true, false, 0); + for (int j = 0; j != connections.length(); j++) { + MObject connected = connections[j].node(); + + if (connected.hasFn(MFn::kAnimCurve)) { + + MFnAnimCurve jointAnim(connected); + + unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp); + + if (tmp == MStatus::kFailure) + MGlobal::displayInfo(MString() + "Fail :c"); + + if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } + + unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField)); + MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex); + + if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) { + animatedJoints.push_back(jointIt.item()); + i = 9; + break; + } + + MFnTransform MayaJoint(jointIt.item()); + + MPlug BindPose = MayaJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix BindPoseMatrix = MartixFn.matrix(); + + if (BindPoseMatrix != MayaJoint.transformationMatrix()) + { + MGlobal::displayError(MString() + animationName.c_str() + " is using a joint that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya"); + } + } + } + } + + jointIt.next(); + } + + int currentFrame = startFrame; + while (currentFrame != endFrame) { + Animation::Keyframe thisKeyFrame; + thisKeyFrame.Index = currentFrame - startFrame; + thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; + + MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField)); + MTime time = MAnimControl::currentTime(); + + for (auto aJoint : animatedJoints){ + MFnTransform thisJoint(aJoint); + Animation::Keyframe::JointProperty joint; + + auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), thisJoint.object()); + if (it != m_Hierarchy.end()) { + joint.ID = it - m_Hierarchy.begin(); + } + else { + MGlobal::displayError(MString() + "Could not find joint ID for: " + thisJoint.name()); + } + + MMatrix Matrix = thisJoint.transformationMatrix(); + + double tmp[4]; + thisJoint.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + joint.Rotation[0] = tmp[0]; + joint.Rotation[1] = tmp[1]; + joint.Rotation[2] = tmp[2]; + joint.Rotation[3] = tmp[3]; + thisJoint.getTranslation(MSpace::kPreTransform).get(tmp); + joint.Position[0] = tmp[0]; + joint.Position[1] = tmp[1]; + joint.Position[2] = tmp[2]; + thisJoint.getScale(tmp); + joint.Scale[0] = tmp[0]; + joint.Scale[1] = tmp[1]; + joint.Scale[2] = tmp[2]; + + thisKeyFrame.JointProperties.push_back(joint); + } + returnData.Keyframes.push_back(thisKeyFrame); + currentFrame++; + } + return returnData; +} + +std::vector Skeleton::GetBindPoses() +{ + std::vector m_AllSkeletons; + std::vector m_Hierarchy; + + MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); + BindPoseSkeletonNode SkeletonStorage; while (!jointIt.isDone()) { - MFnTransform TransformNode(jointIt.currentItem()); - Joint NewJoint; + MFnTransform MayaJoint(jointIt.currentItem()); + BindPoseSkeletonNode::BindPoseJoint NewJoint; - if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") { + if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") { if (SkeletonStorage.Joints.size() != 0) { m_AllSkeletons.push_back(SkeletonStorage); SkeletonStorage.Joints.clear(); SkeletonStorage.Name.clear(); } + SkeletonStorage.Name = std::string(MayaJoint.name().asChar()); + NewJoint.ParentID = -1; // This joint is root + } + else { + auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0)); + if (it != m_Hierarchy.end()) { + NewJoint.ParentID = it - m_Hierarchy.begin(); + } + else { + MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name()); + } + } + m_Hierarchy.push_back(MayaJoint.object()); - SkeletonStorage.Name = TransformNode.name().asChar(); + MPlug BindPose = MayaJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix Matrix = MartixFn.matrix(); - //NewJoint.ParentIndex = -1; // This joint is root + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; + } } - //NewJoint.Name = TransformNode.name().asChar(); - - MMatrix Matrix = TransformNode.transformationMatrix(); + NewJoint.Name = MayaJoint.name().asChar(); //double tmp[3]; //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); @@ -44,89 +236,7 @@ std::vector Skeleton::DoIt() //NewJoint.Translation[0] = tmp[0]; //NewJoint.Translation[1] = tmp[1]; //NewJoint.Translation[2] = tmp[2]; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; - } - } - SkeletonStorage.Joints.push_back(NewJoint); - - jointIt.next(); - } - - m_AllSkeletons.push_back(SkeletonStorage); - - return m_AllSkeletons; -} - -std::vector Skeleton::GetBindPoses() -{ - std::vector m_AllSkeletons; - std::vector m_Hierarchy; - - MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); - BindPoseSkeletonNode SkeletonStorage; - - while (!jointIt.isDone()) { - MFnTransform MayaJoint(jointIt.currentItem()); - - if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") { - if (SkeletonStorage.Joints.size() != 0) { - m_AllSkeletons.push_back(SkeletonStorage); - - SkeletonStorage.Joints.clear(); - SkeletonStorage.Name.clear(); - SkeletonStorage.ParentIDs.clear(); - SkeletonStorage.Name.clear(); - } - - SkeletonStorage.Name = MayaJoint.name().asChar(); - SkeletonStorage.ParentIDs.push_back(-1); // This joint is root - } - else { - auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0)); - if (it != m_Hierarchy.end()) { - SkeletonStorage.ParentIDs.push_back(it - m_Hierarchy.begin()); - } - else { - MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name()); - } - } - m_Hierarchy.push_back(MayaJoint.object()); - - Joint NewJoint; - - MPlug BindPose = MayaJoint.findPlug("bindPose"); - MDataHandle DataHandle; - BindPose.getValue(DataHandle); - MFnMatrixData MartixFn(DataHandle.data()); - MMatrix Matrix = MartixFn.matrix(); - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; - } - } - - /*double tmp[3]; - ((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); - NewJoint.Rotation[0] = tmp[0]; - NewJoint.Rotation[1] = tmp[1]; - NewJoint.Rotation[2] = tmp[2]; - ((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform); - NewJoint.Scale[0] = tmp[0]; - NewJoint.Scale[1] = tmp[1]; - NewJoint.Scale[2] = tmp[2]; - ((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp); - NewJoint.Translation[0] = tmp[0]; - NewJoint.Translation[1] = tmp[1]; - NewJoint.Translation[2] = tmp[2];*/ - - SkeletonStorage.Joints.push_back(NewJoint); - SkeletonStorage.JointNames.push_back(MayaJoint.name().asChar()); - jointIt.next(); } diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 2d363cf8..0b0c2a60 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -6,68 +6,81 @@ #include #include "MayaIncludes.h" #include "OutputData.h" -class Joint : public OutputData{ + +class Animation : public OutputData { public: - //Joint() : OutputData((Joint)*this) - //{}; - //int ParentIndex; - //std::array Rotation; - //std::array Translation; - //std::array Scale; - //std::array, 4> OffsetMatrix; - float OffsetMatrix[4][4]; - - virtual void WriteBinary(std::ostream& out) + struct Keyframe { - out.write((char*)OffsetMatrix, 4 * 4 * sizeof(float)); - } - - virtual void WriteASCII(std::ostream& out) const - { - for (int i = 0; i < 4; i++) + struct JointProperty { - for (int k = 0; k < 4; k++) - out << this->OffsetMatrix[i][k] << " "; - out << endl; - } - }; -}; + int ID; + float Position[3]; + float Rotation[4]; + float Scale[3]; + }; + + int Index; + double Time; + std::vector JointProperties; + }; -class SkeletonNode : public OutputData { -public: std::string Name; - std::vector Joints; + double Duration; + std::vector Keyframes; virtual void WriteBinary(std::ostream& out) { - out.write(Name.c_str(), Name.size()); - for (auto aJoint : Joints) - { - aJoint.WriteBinary(out); + out.write(Name.c_str(), Name.size() + 1); + out.write((char*)&Duration, sizeof(double)); + for (auto aKeyframe : Keyframes) { + out.write((char*)&aKeyframe.Index, sizeof(int)); + out.write((char*)&aKeyframe.Time, sizeof(double)); + for (auto aJoint : aKeyframe.JointProperties) { + out.write((char*)&aJoint.ID, sizeof(int)); + out.write((char*)aJoint.Position, sizeof(float) * 3); + out.write((char*)aJoint.Rotation, sizeof(float) * 4); + out.write((char*)aJoint.Scale, sizeof(float) * 3); + } } } + virtual void WriteASCII(std::ostream& out) const { - out << "Skeleton: " << Name << endl; - for (auto aJoint : Joints) - { - aJoint.WriteASCII(out); + out << "Animation Name: " << Name << endl; + out << "Duration: " << Duration << endl; + for (auto aKeyframe : Keyframes) { + out << "Frame: " << aKeyframe.Index << endl; + out << "Time: " << aKeyframe.Time << endl; + for (auto aJoint : aKeyframe.JointProperties) { + out << "Joint ID: " << aJoint.ID << endl; + out << aJoint.Position[0] << " " << aJoint.Position[1] << " " << aJoint.Position[2] << endl; + out << aJoint.Rotation[0] << " " << aJoint.Rotation[1] << " " << aJoint.Rotation[2] << " " << aJoint.Rotation[3] << endl; + out << aJoint.Scale[0] << " " << aJoint.Scale[1] << " " << aJoint.Scale[2] << endl; + } } - }; + + } }; -class BindPoseSkeletonNode : public SkeletonNode { +class BindPoseSkeletonNode : public OutputData { public: - std::vector ParentIDs; - std::vector JointNames; + struct BindPoseJoint + { + int ParentID; + std::string Name; + float OffsetMatrix[4][4]; + }; + + std::string Name; + std::vector Joints; virtual void WriteBinary(std::ostream& out) { - out.write(Name.c_str(), Name.size()); - for (int i = 0; i < Joints.size(); i++) - { - out.write((char*)&ParentIDs[i],sizeof(int)); - Joints[i].WriteBinary(out); - out.write(JointNames[i].c_str(), JointNames[i].size()); + out.write(Name.c_str(), Name.size() + 1); + for (auto Joint:Joints) + { + out.write(Joint.Name.c_str(), Joint.Name.size() + 1); + out.write((char*)&Joint.OffsetMatrix, sizeof(float) * 4 * 4); + out.write((char*)&Joint.ParentID, sizeof(int)); } } @@ -75,18 +88,24 @@ public: virtual void WriteASCII(std::ostream& out) const { out << "Bind Pose: " << Name << endl; - for (int i = 0; i < Joints.size(); i++) + for (auto Joint : Joints) { - out << ParentIDs[i] << endl; - Joints[i].WriteASCII(out); - out << JointNames[i] << endl; + out << Joint.Name << endl; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++){ + out << Joint.OffsetMatrix[i][j] << " "; + } + out << endl; + } + out << Joint.ParentID << endl; } }; }; class Skeleton { public: - std::vector DoIt(); + //std::vector DoIt(); + Animation GetAnimData(std::string animationName, int startFrame, int endFrame); std::vector GetBindPoses(); private: }; From 7b62dc19bf0e5f85ec1dc7dc2f3d69a0d18d22ef Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 12 Jan 2016 15:39:29 +0100 Subject: [PATCH 13/13] 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();