From c8cb0ee93978dd8b4646cb4cb37e5fb397fcabd3 Mon Sep 17 00:00:00 2001 From: FakeShemp Date: Wed, 9 Dec 2015 11:58:49 +0100 Subject: [PATCH 01/80] 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/80] 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/80] 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/80] 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/80] 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/80] =?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/80] 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/80] 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/80] 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/80] 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/80] 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/80] 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/80] 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(); From 24486c314dffcdf0294682cc3da0e6be1f559c56 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 13 Jan 2016 14:03:58 +0100 Subject: [PATCH 14/80] Reworked the Exporter. --- tools/MayaExporter/MayaExporter/Export.cpp | 172 ++++++++++++++ tools/MayaExporter/MayaExporter/Export.h | 54 +++++ .../GeneratedFiles/Debug/moc_Menu.cpp | 42 ++-- .../MayaExporter/MayaExporter.vcxproj | 2 + .../MayaExporter/MayaExporter.vcxproj.filters | 6 + tools/MayaExporter/MayaExporter/Menu.cpp | 213 ++++-------------- tools/MayaExporter/MayaExporter/Menu.h | 23 +- tools/MayaExporter/MayaExporter/Mesh.cpp | 26 ++- tools/MayaExporter/MayaExporter/Mesh.h | 45 +++- tools/MayaExporter/MayaExporter/Skeleton.cpp | 11 +- tools/MayaExporter/MayaExporter/Skeleton.h | 6 + tools/MayaExporter/MayaExporter/WriteToFile.h | 10 +- 12 files changed, 369 insertions(+), 241 deletions(-) create mode 100644 tools/MayaExporter/MayaExporter/Export.cpp create mode 100644 tools/MayaExporter/MayaExporter/Export.h diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp new file mode 100644 index 00000000..82c81cfa --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -0,0 +1,172 @@ +#include "Export.h" + +Export::Export() +{ + +} + +bool Export::Meshes(std::string pathName, bool selectedOnly) +{ + if (pathName.empty()) { + MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file"); + return false; + } + meshes.clear(); + + if (selectedOnly) { + // Retrieving the objects we currently have selected + MSelectionList selected; + MGlobal::getActiveSelectionList(selected); + + // Loop through or list of selection(s) + for (unsigned int i = 0; i < selected.length(); i++) { + MObject object; + selected.getDependNode(i, object); + + if (object.hasFn(MFn::kMesh)) { + MFnDependencyNode thisNode(object); + GetMeshData(object); + } + } + } else { + // Loop through all nodes in the scene + MItDependencyNodes it(MFn::kMesh); + for (; !it.isDone(); it.next()) { + MObject node = it.thisNode(); + MFnDependencyNode thisNode(node); + MPlugArray connections; + 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; + + GetMeshData(node); + } + } + MGlobal::displayInfo(MString() + "nrofmeshes: " + meshes.size()); + WriteMeshData(pathName); + return true; +} + +bool Export::Materials() +{ + return true; +} + +bool Export::Animations(std::string pathName, std::vector animInfo) +{ + if (MAnimControl::currentTime().unit() != MTime::kNTSCField) { + + MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!"); + return false; + } + + if (pathName.empty()) { + MGlobal::displayError(MString() + "Export::Animations() got no pathName. Do not know where to write file"); + return false; + } + MGlobal::displayInfo("HALLOOOO"); + allBindPoses = m_SkeletonHandler.GetBindPoses(); + + for (auto clip : animInfo) { + MGlobal::displayInfo("preben"); + if (!GetAnimationData(clip)) { + MGlobal::displayError(MString() + "Export::Animations() failed to export " + clip.Name.c_str()); + return false; + } + } + MGlobal::displayInfo("ghihgihi"); + WriteAnimData(pathName); + return true; +} + +bool Export::GetMeshData(MObject object) +{ + if (!object.hasFn(MFn::kMesh)) + return false; + + meshes.push_back(m_MeshHandler.GetMeshData(object)); + return true; +} + +bool Export::GetMaterialData() +{ + // Traverse scene and return vector with all materials + std::vector* AllMaterials = m_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]); + return true; +} + +bool Export::GetAnimationData(AnimationInfo animInfo) +{ + if (animInfo.Name.empty()) { + MGlobal::displayError(MString() + "A clip does not have a name"); + return false; + } + if (animInfo.End - animInfo.Start <= 0) { + MGlobal::displayError(MString() + "A clip ends before it starts or contains 0 frames"); + return false; + } + + allAnimations.push_back(m_SkeletonHandler.GetAnimData(animInfo.Name, animInfo.Start, animInfo.End)); + return true; +} + +void Export::WriteMeshData(std::string pathName) +{ + m_MeshFile.ASCIIFilePath(pathName +"_mesh.txt"); + m_MeshFile.binaryFilePath(pathName + ".mesh"); + + m_MeshFile.OpenFiles(); + + for (auto aMesh : meshes) { + m_MeshFile.writeToFiles((OutputData*)&aMesh); + } + + m_MeshFile.CloseFiles(); +} + +void Export::WriteAnimData(std::string pathName) +{ + if (allBindPoses.size() > 0) { + m_AnimFile.ASCIIFilePath(pathName + "_anim.txt"); + m_AnimFile.binaryFilePath(pathName + ".anim"); + + m_AnimFile.OpenFiles(); + int size = allBindPoses.size(); + m_AnimFile.writeToFiles(&size); + + size = allAnimations.size(); + m_AnimFile.writeToFiles(&size); + + //print out all bind poses + for (auto aBindPose : allBindPoses) { + m_AnimFile.writeToFiles((OutputData*)&aBindPose); + } + for (auto aAnimation : allAnimations) { + m_AnimFile.writeToFiles((OutputData*)&aAnimation); + } + + m_AnimFile.CloseFiles(); + } else + MGlobal::displayInfo("Export::WriteAnimData() got called when allBindPoses contained no data, did not write nor created them"); +} + +Export::~Export() +{ + /* delete m_MaterialHandler; + delete m_SkeletonHandler; + delete m_MeshHandler;*/ + +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Export.h b/tools/MayaExporter/MayaExporter/Export.h new file mode 100644 index 00000000..83d27459 --- /dev/null +++ b/tools/MayaExporter/MayaExporter/Export.h @@ -0,0 +1,54 @@ +#ifndef Export_Export_h__ +#define Export_Export_h__ + +#include +#include + +#include "MayaIncludes.h" +#include "Material.h" +#include "Mesh.h" +#include "Skeleton.h" +#include "WriteToFile.h" + +class Export { +public: + Export(); + + ~Export(); + + struct AnimationInfo { + std::string Name; + int Start; + int End; + }; + + bool Meshes(std::string pathName, bool selectedOnly = false); + bool Materials(); + bool Animations(std::string pathName, std::vector animInfo); + +private: + bool GetMeshData(MObject object); + bool GetMaterialData(); + bool GetAnimationData(AnimationInfo info); + + void WriteMeshData(std::string pathName); + void WriteAnimData(std::string pathName); + + Material m_MaterialHandler; + Skeleton m_SkeletonHandler; + MeshClass m_MeshHandler; + + + //File export + WriteToFile m_MeshFile; + WriteToFile m_AnimFile; + + //Mesh Data + std::vector meshes; + + //Animation Data + std::vector allBindPoses; + std::vector allAnimations; + +}; +#endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp b/tools/MayaExporter/MayaExporter/GeneratedFiles/Debug/moc_Menu.cpp index a375ed53..c7879431 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 - 9, 14, // methods + 5, 14, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors @@ -30,25 +30,19 @@ static const uint qt_meta_data_Menu[] = { 0, // signalCount // slots: signature, parameters, type, tag, flags - 14, 6, 5, 5, 0x08, - 35, 5, 5, 5, 0x08, - 59, 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, + 6, 5, 5, 5, 0x08, + 30, 5, 5, 5, 0x08, + 51, 5, 5, 5, 0x08, + 75, 5, 5, 5, 0x08, + 91, 5, 5, 5, 0x08, 0 // eod }; static const char qt_meta_stringdata_Menu[] = { - "Menu\0\0checked\0ExportSelected(bool)\0" - "ExportPathClicked(bool)\0AddClipClicked(bool)\0" - "RemoveClipClicked(bool)\0ExportAll(bool)\0" - "CancelClicked(bool)\0Button1Clicked(bool)\0" - "Button2Clicked(bool)\0Button3Clicked(bool)\0" + "Menu\0\0ExportPathClicked(bool)\0" + "AddClipClicked(bool)\0RemoveClipClicked(bool)\0" + "ExportAll(bool)\0CancelClicked(bool)\0" }; void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) @@ -57,15 +51,11 @@ void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void * Q_ASSERT(staticMetaObject.cast(_o)); Menu *_t = static_cast(_o); 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->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; + case 0: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 1: _t->AddClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 2: _t->RemoveClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 3: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break; + case 4: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; default: ; } } @@ -103,9 +93,9 @@ int Menu::qt_metacall(QMetaObject::Call _c, int _id, void **_a) if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { - if (_id < 9) + if (_id < 5) qt_static_metacall(this, _c, _id, _a); - _id -= 9; + _id -= 5; } return _id; } diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj index 701b39cf..4a7ac07e 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj @@ -153,6 +153,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters index be5b36b1..ae3d2478 100644 --- a/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters +++ b/tools/MayaExporter/MayaExporter/MayaExporter.vcxproj.filters @@ -62,6 +62,9 @@ Source Files + + Source Files + @@ -96,5 +99,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 7e1e6cde..1ff007b4 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -13,9 +13,8 @@ Menu::Menu(QDialog* dialog) m_DialogPointer = dialog; // Create QpushButtons & give them names - m_ExportSelectedButton = new QPushButton("&Export Selected", this); m_BrowseButton = new QPushButton("&...", this); - m_ExportAllButton = new QPushButton("&Export All", this); + m_ExportAllButton = new QPushButton("&Export", this); m_CancelButton = new QPushButton("&Cancel", this); m_AddClipsButton = new QPushButton("&Add Clips", this); m_RemoveClipsButton = new QPushButton("&Remove Latest Clip", this); @@ -23,6 +22,7 @@ Menu::Menu(QDialog* dialog) // Option box and checkboxes QGroupBox *optionsBox = new QGroupBox(tr("Options")); + m_ExportSelectedButton = new QCheckBox(tr("&Export Selected")); m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations")); m_CopyTexturesButton = new QCheckBox(tr("&Copy Textures")); m_Button3 = new QCheckBox(tr("Test Materials")); @@ -30,6 +30,7 @@ Menu::Menu(QDialog* dialog) m_ExportAnimationsButton->setChecked(true); m_CopyTexturesButton->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(m_ExportSelectedButton); vbox->addWidget(m_ExportAnimationsButton); vbox->addWidget(m_CopyTexturesButton); vbox->addWidget(m_Button3); @@ -37,16 +38,16 @@ Menu::Menu(QDialog* dialog) optionsBox->setLayout(vbox); // Connect the buttons with signals & functions - 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(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))); - connect(m_Button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool))); + connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); + connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); + connect(m_CopyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); + connect(m_Button3, SIGNAL(clicked(bool)), this, SLOT(NULL)); // Creating several layouts, adding widgets & adding them to one layout in the end QHBoxLayout* topLayout = new QHBoxLayout; @@ -61,7 +62,8 @@ Menu::Menu(QDialog* dialog) m_ExportPath = new QLineEdit; m_FileDialog = new QFileDialog; - + QString tmpPath("C:/Users/Nickelodion/Desktop/Baljj"); + m_ExportPath->setText(tmpPath); QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); QLabel* nameLabel = new QLabel; @@ -79,7 +81,6 @@ Menu::Menu(QDialog* dialog) topLayout->addWidget(m_ExportPath); topLayout->addWidget(m_BrowseButton); - botLayout->addWidget(m_ExportSelectedButton); botLayout->addWidget(m_ExportAllButton); botLayout->addWidget(m_CancelButton); @@ -111,35 +112,6 @@ Menu::Menu(QDialog* dialog) } - -void Menu::ExportSelected(bool checked) -{ - // Retrieving the objects we currently have selected - MSelectionList selected; - MGlobal::getActiveSelectionList(selected); - - // Loop through or list of selection(s) - 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); - } - if (m_ExportPath->text().isEmpty()) { - cout << "Please select a folder." << endl; - } - else { - cout << m_ExportPath->text().toLocal8Bit().constData() << endl; - } - - if (m_ExportAnimationsButton->isChecked()) { - GetSkeletonData(); - } - -} - void Menu::ExportPathClicked(bool) { // Opens up a file dialog. Save/Changes the name in the exportPath @@ -188,50 +160,45 @@ void Menu::RemoveClipClicked(bool) layouts.pop_back(); m_StartFrameLines.pop_back(); m_EndFrameLines.pop_back(); + m_AnimationClipName.pop_back(); } } 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(); + if (m_ExportPath->text().isEmpty()) { + MGlobal::displayError(MString() + "Please select a folder."); + return; + } - // Loop through all nodes in the scene - MItDependencyNodes it(MFn::kMesh); - for (; !it.isDone(); it.next()) { - MObject node = it.thisNode(); - if (node.hasFn(MFn::kMesh)) { - MFnDependencyNode thisNode(node); - MPlugArray connections; + //Export meshes + if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked())) { + MGlobal::displayError(MString() + "Could not export mesh"); + return; + } - 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; + std::vector animations; + MGlobal::displayInfo(MString() + "yeeehaa"); + for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { + Export::AnimationInfo thisClip; + MGlobal::displayInfo(MString() + "qwqw"); + thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData()); + MGlobal::displayInfo(MString() + "shizzzz"); + thisClip.Start = m_StartFrameLines[i]->text().toInt(); + MGlobal::displayInfo(MString() + "dsdsfg"); + thisClip.End = m_EndFrameLines[i]->text().toInt(); + MGlobal::displayInfo(MString() + "aaaaaaaaaaaaaaaaaaaa"); - cout << thisNode.name().asChar() << endl; - MGlobal::displayInfo("EXPORT ALL FUNCTION: " + thisNode.name() + " " + thisNode.findPlug("inMesh").asMObject().apiTypeStr()); - GetMeshData(node); - } - } - if (m_ExportPath->text().isEmpty()) { - cout << "Please select a folder." << endl; - } - else { - cout << m_ExportPath->text().toLocal8Bit().constData() << endl; - } - - if (m_ExportAnimationsButton->isChecked()) - GetSkeletonData(); - m_File.CloseFiles(); + animations.push_back(thisClip); + } + MGlobal::displayInfo(MString() + "asdf"); + if (m_ExportAnimationsButton->isChecked()) { + //Export Animations + if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) { + MGlobal::displayError(MString() + "Could not export animations"); + return; + } + } } void Menu::CancelClicked(bool) @@ -239,105 +206,6 @@ void Menu::CancelClicked(bool) m_DialogPointer->close(); } -void Menu::Button1Clicked(bool) -{ - if (m_ExportAnimationsButton->isChecked()) { - MGlobal::displayInfo("1 checked!"); - } - else { - MGlobal::displayInfo("1 unchecked!"); - } -} - -void Menu::Button2Clicked(bool) -{ - if (m_CopyTexturesButton->isChecked()) { - cout << "2 checked!" << endl; - } - else { - cout << "2 unchecked!" << endl; - } -} - -void Menu::Button3Clicked(bool) -{ - if (m_Button3->isChecked()) { - cout << "3 checked!" << endl; - } - else { - 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(); - - // Traverse scene and return vector with all materials - std::vector* AllMaterials = m_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]); -} - -void Menu::GetSkeletonData() -{ - if (MAnimControl::currentTime().unit() != MTime::kNTSCField) { - - MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!"); - return; - } - - std::vector allBindPoses; - std::vector allAnimations; - - allBindPoses = m_SkeletonHandler->GetBindPoses(); - - 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(); - std::string animationName = m_AnimationClipName[j]->text().toAscii().constData(); - - allAnimations.push_back(m_SkeletonHandler->GetAnimData(animationName, startFrame, endFrame)); - } - - //print out all bind poses - 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++){ - //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]); - } - } - //print out all animations - for (auto aAnimation : allAnimations) { - m_File.writeToFiles(&aAnimation); - } -} - Menu::~Menu() { //delete exportSelectedButton; @@ -346,5 +214,6 @@ Menu::~Menu() //delete fileDialog; m_FileDialog->~QFileDialog(); + //delete m_Export; //delete MaterialHandler; } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index 9f3492ab..a8b517bc 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -32,12 +32,8 @@ #include #include - #include "MayaIncludes.h" -#include "Material.h" -#include "Mesh.h" -#include "Skeleton.h" -#include "WriteToFile.h" +#include "Export.h" class Menu : public QWidget { @@ -46,23 +42,13 @@ public: Menu(QDialog* dialog); ~Menu(); - void GetMeshData(MObject object); - void GetMaterialData(); - void GetSkeletonData(); - private slots: - void ExportSelected(bool checked); void ExportPathClicked(bool); void AddClipClicked(bool); void RemoveClipClicked(bool); void ExportAll(bool); void CancelClicked(bool); - void Button1Clicked(bool); - void Button2Clicked(bool); - void Button3Clicked(bool); - - private: Menu(); std::vector m_AnimationClipName; @@ -71,13 +57,13 @@ private: 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_ExportSelectedButton = nullptr; QCheckBox* m_ExportAnimationsButton = nullptr; QCheckBox* m_CopyTexturesButton = nullptr; QCheckBox* m_Button3 = nullptr; @@ -86,10 +72,7 @@ private: QFileDialog* m_FileDialog = nullptr; QDialog* m_DialogPointer = nullptr; - Material* m_MaterialHandler = nullptr; - Skeleton* m_SkeletonHandler = nullptr; - - WriteToFile m_File; + Export m_Export; }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 0ac66b33..d9b47875 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -3,11 +3,12 @@ using namespace std; -Mesh::Mesh() +MeshClass::MeshClass() { } -std::map Mesh::GetWeightData() + +std::map MeshClass::GetWeightData() { map weightMap; @@ -72,10 +73,14 @@ std::map Mesh::GetWeightData() return weightMap; } -void Mesh::GetMeshData(MObject object, std::vector& vertexList, std::vector& indexList) +Mesh MeshClass::GetMeshData(MObject object) { + Mesh newMesh; + std::vector& vertexList = newMesh.Vertices; + std::vector& indexList = newMesh.Indices; // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object); + map> vertexToIndex;; MIntArray intdexOffsetVertexCount, vertices, triangleList; @@ -106,7 +111,7 @@ void Mesh::GetMeshData(MObject object, std::vector& vertexList, st 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); @@ -160,25 +165,26 @@ void Mesh::GetMeshData(MObject object, std::vector& vertexList, st //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); } } } + + newMesh.NumIndices = newMesh.Indices.size(); + newMesh.NumVertices = newMesh.Vertices.size(); + + return newMesh; } -Mesh::~Mesh() +MeshClass::~MeshClass() { } \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 6fab0536..c9445e4e 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -10,7 +10,6 @@ class VertexLayout : public OutputData { public: - float Pos[3]; float Normal[3]; float BiNormal[3]; @@ -32,7 +31,6 @@ public: 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; @@ -56,15 +54,50 @@ public: } }; +class Mesh : public OutputData { +public: + int NumVertices; + int NumIndices; + std::vector Vertices; + std::vector Indices; + + virtual void WriteBinary(std::ostream& out) + { + out.write((char*)&NumVertices, sizeof(int)); + out.write((char*)&NumIndices, sizeof(int)); + for (auto aVertex : Vertices) { + aVertex.WriteBinary(out); + } + for (auto aIndex : Indices) { + out.write((char*)&aIndex, sizeof(int)); + } + } + + virtual void WriteASCII(std::ostream& out) const + { + out << "New Mesh _ not in binary" << endl; + out << "Number of vertices: " << NumVertices << endl; + out << "number of indices: " << NumIndices << endl; + int vertexNumber = 0; + for (auto aVertex : Vertices) { + out << "New vertex number: " << vertexNumber << "_ not in binary" << endl; + aVertex.WriteASCII(out); + vertexNumber++; + } + for (int i = 0; i < NumIndices; i += 3) { + out << Indices[i] << " " << Indices[i+1] << " " << Indices[i + 2] << endl; + } + } +}; -class Mesh +class MeshClass { public: - Mesh(); - void GetMeshData(MObject Object, std::vector& vertexList, std::vector& indexList); - ~Mesh(); + MeshClass(); + Mesh GetMeshData(MObject Object); + ~MeshClass(); private: struct WeightInfo { float BoneIndices[4] = { 0 }; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 394f548b..0497aa31 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -64,12 +64,13 @@ std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY" Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame) { + std::vector animatedJoints; + std::vector m_Hierarchy; + 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); while (!jointIt.isDone()) @@ -121,7 +122,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e 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"); + MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " 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"); } } } @@ -173,6 +174,10 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e returnData.Keyframes.push_back(thisKeyFrame); currentFrame++; } + + returnData.NumKeyFrames = returnData.Keyframes.size(); + returnData.NumberOfJoints = animatedJoints.size(); + return returnData; } diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index 0b0c2a60..dda0cfea 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -26,12 +26,16 @@ public: std::string Name; double Duration; + int NumKeyFrames; + int NumberOfJoints; std::vector Keyframes; virtual void WriteBinary(std::ostream& out) { out.write(Name.c_str(), Name.size() + 1); out.write((char*)&Duration, sizeof(double)); + out.write((char*)&NumKeyFrames, sizeof(int)); + out.write((char*)&NumberOfJoints, sizeof(int)); for (auto aKeyframe : Keyframes) { out.write((char*)&aKeyframe.Index, sizeof(int)); out.write((char*)&aKeyframe.Time, sizeof(double)); @@ -48,6 +52,8 @@ public: { out << "Animation Name: " << Name << endl; out << "Duration: " << Duration << endl; + out << "Number of KeyFrames: " << NumKeyFrames << endl; + out << "Number of Joints: " << NumberOfJoints << endl; for (auto aKeyframe : Keyframes) { out << "Frame: " << aKeyframe.Index << endl; out << "Time: " << aKeyframe.Time << endl; diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.h b/tools/MayaExporter/MayaExporter/WriteToFile.h index 3d6cc078..91ca7103 100644 --- a/tools/MayaExporter/MayaExporter/WriteToFile.h +++ b/tools/MayaExporter/MayaExporter/WriteToFile.h @@ -17,7 +17,7 @@ public: void writeToFiles(OutputData* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0) { - MGlobal::displayInfo("WriteToFile::writeToFiles()"); + MGlobal::displayInfo("WriteToFile::writeToFiles(OutputData*)"); if (ASCIIFile.is_open()) { for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++) @@ -32,16 +32,18 @@ public: } - void writeToFiles(unsigned int* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0) + template + void writeToFiles(T* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0) { - MGlobal::displayInfo("WriteToFile::writeToFiles()"); + MGlobal::displayInfo("WriteToFile::writeToFiles(T*) - Template T"); 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)); + for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++) + binFile.write((char*)toWrite, sizeof(T)); } } From 8437b9c734a72fee32bd79d9a59b8db345d43ff2 Mon Sep 17 00:00:00 2001 From: antc13 Date: Fri, 15 Jan 2016 17:58:26 +0100 Subject: [PATCH 15/80] Commit for Pull --- include/Engine/Collision/Collision.h | 2 +- include/Engine/Rendering/Model.h | 2 +- .../{RawModel.h => RawModelAssimp.h} | 18 ++--- include/Engine/Rendering/RawModelCustom.h | 68 +++++++++++++++++++ src/Engine/Rendering/Model.cpp | 10 +-- .../{RawModel.cpp => RawModelAssimp.cpp} | 22 ++---- src/Engine/Rendering/RawModelCustom.cpp | 67 ++++++++++++++++++ tools/MayaExporter/MayaExporter/Mesh.cpp | 12 ++-- tools/MayaExporter/MayaExporter/Mesh.h | 8 +-- 9 files changed, 158 insertions(+), 51 deletions(-) rename include/Engine/Rendering/{RawModel.h => RawModelAssimp.h} (79%) create mode 100644 include/Engine/Rendering/RawModelCustom.h rename src/Engine/Rendering/{RawModel.cpp => RawModelAssimp.cpp} (92%) create mode 100644 src/Engine/Rendering/RawModelCustom.cpp diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 714cee3f..3ac43baf 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -9,7 +9,7 @@ #include "Core/Ray.h" #include "Core/AABB.h" -#include "Engine/Rendering/RawModel.h" +#include "Engine/Rendering/RawModelAssimp.h" #include "Core/Entity.h" class World; diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index 9cc145af..228e7acf 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -1,7 +1,7 @@ #ifndef Model_h__ #define Model_h__ -#include "RawModel.h" +#include "RawModelAssimp.h" #include "../OpenGL.h" class Model : public RawModel diff --git a/include/Engine/Rendering/RawModel.h b/include/Engine/Rendering/RawModelAssimp.h similarity index 79% rename from include/Engine/Rendering/RawModel.h rename to include/Engine/Rendering/RawModelAssimp.h index c8226168..5c96d946 100644 --- a/include/Engine/Rendering/RawModel.h +++ b/include/Engine/Rendering/RawModelAssimp.h @@ -1,5 +1,5 @@ -#ifndef RawModel_h__ -#define RawModel_h__ +#ifndef RawModelAssimp_h__ +#define RawModelAssimp_h__ #include #include @@ -23,7 +23,7 @@ class RawModel : public Resource friend class ResourceManager; protected: - RawModel(std::string fileName); + RawModel(std::string fileName); public: ~RawModel(); @@ -33,14 +33,10 @@ public: glm::vec3 Position; glm::vec3 Normal; glm::vec3 Tangent; - glm::vec3 BiTangent; + glm::vec3 BiNormal; glm::vec2 TextureCoords; - glm::vec4 DiffuseVertexColor; - glm::vec4 SpecularVertexColor; - glm::vec4 BoneIndices1; - glm::vec4 BoneIndices2; - glm::vec4 BoneWeights1; - glm::vec4 BoneWeights2; + glm::vec4 BoneIndices; + glm::vec4 BoneWeights; }; struct MaterialGroup @@ -64,8 +60,6 @@ private: std::vector BoneIndices; std::vector BoneWeights; std::vector Normals; - std::vector DiffuseVertexColor; - std::vector SpecularVertexColor; std::vector TangentNormals; std::vector BiTangentNormals; std::vector TextureCoords; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h new file mode 100644 index 00000000..c6e97242 --- /dev/null +++ b/include/Engine/Rendering/RawModelCustom.h @@ -0,0 +1,68 @@ +#ifndef RawModelCustom_h__ +#define RawModelCustom_h__ + +#include +#include +#include +#include +#include + +#include + +#include "../Common.h" +#include "../GLM.h" +#include "../Core/ResourceManager.h" +#include "Texture.h" +#include "Skeleton.h" + +#include "boost\endian\buffers.hpp" + +class RawModel : public Resource +{ + friend class ResourceManager; + +protected: + RawModel(std::string fileName); + +public: + ~RawModel(); + + struct Vertex + { + glm::vec3 Position; + glm::vec3 Normal; + glm::vec3 Tangent; + glm::vec3 BiNormal; + glm::vec2 TextureCoords; + glm::vec4 BoneIndices; + glm::vec4 BoneWeights; + }; + + struct MaterialGroup + { + float Shininess; + std::shared_ptr<::Texture> Texture; + std::shared_ptr<::Texture> NormalMap; + std::shared_ptr<::Texture> SpecularMap; + unsigned int StartIndex; + unsigned int EndIndex; + }; + + std::vector TextureGroups; + + std::vector m_Vertices; + std::vector m_Indices; + Skeleton* m_Skeleton = nullptr; + glm::mat4 m_Matrix; + +private: + + bool ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + bool ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + bool ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + bool ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + + //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); +}; + +#endif diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index f346d9e1..c7b5667b 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -18,7 +18,7 @@ Model::Model(std::string fileName) GLERROR("GLEW: BufferFail4"); glBindBuffer(GL_ARRAY_BUFFER, buffer); - std::vector structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 }; + std::vector structSizes = { 3, 3, 3, 3, 2, 4, 4 }; int stride = 0; for (int size : structSizes) { stride += size; @@ -34,10 +34,6 @@ Model::Model(std::string fileName) glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; - glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; - glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; - glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; - glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; } GLERROR("GLEW: BufferFail5"); @@ -48,10 +44,6 @@ Model::Model(std::string fileName) glEnableVertexAttribArray(4); glEnableVertexAttribArray(5); glEnableVertexAttribArray(6); - glEnableVertexAttribArray(7); - glEnableVertexAttribArray(8); - glEnableVertexAttribArray(9); - glEnableVertexAttribArray(10); GLERROR("GLEW: BufferFail5"); //CreateBuffers(); diff --git a/src/Engine/Rendering/RawModel.cpp b/src/Engine/Rendering/RawModelAssimp.cpp similarity index 92% rename from src/Engine/Rendering/RawModel.cpp rename to src/Engine/Rendering/RawModelAssimp.cpp index 95a75a15..68cbb23e 100644 --- a/src/Engine/Rendering/RawModel.cpp +++ b/src/Engine/Rendering/RawModelAssimp.cpp @@ -1,4 +1,4 @@ -#include "Rendering/RawModel.h" +#include "Rendering/RawModelAssimp.h" RawModel::RawModel(std::string fileName) { @@ -38,7 +38,7 @@ RawModel::RawModel(std::string fileName) //LOG_DEBUG("Index count %i", numIndices); //LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures); - + std::vector> boneInfo; std::map boneNameMapping; @@ -75,17 +75,6 @@ RawModel::RawModel(std::string fileName) desc.TextureCoords = glm::vec2(uv.x, uv.y); } - // Material diffuse color - aiColor3D diffuse; - material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); - float opacity; - material->Get(AI_MATKEY_OPACITY, opacity); - desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity); - // Material specular color - aiColor3D specular; - material->Get(AI_MATKEY_COLOR_SPECULAR, specular); - desc.SpecularVertexColor = glm::vec4(specular.r, specular.g, specular.b, 1.f); - m_Vertices.push_back(desc); } @@ -125,7 +114,7 @@ RawModel::RawModel(std::string fileName) } for (auto& vertex : m_Vertices) { vertex.Tangent = glm::normalize(vertex.Tangent); - vertex.BiTangent = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal))); + vertex.BiNormal = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal))); } // Material info @@ -203,10 +192,7 @@ RawModel::RawModel(std::string fileName) LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights); } for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) { - std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[weightIndex]) = weights[weightIndex]; - } - for (int weightIndex = 4; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 8; ++weightIndex) { - std::tie(desc.BoneIndices2[weightIndex - 4], desc.BoneWeights2[weightIndex - 4]) = weights[weightIndex]; + std::tie(desc.BoneIndices[weightIndex], desc.BoneWeights[weightIndex]) = weights[weightIndex]; } } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp new file mode 100644 index 00000000..a5493bd8 --- /dev/null +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -0,0 +1,67 @@ +#include "Rendering\RawModelCustom.h" + +RawModel::RawModel(std::string fileName) +{ + boost::endian::big_int16_buf_t* test; + int16_t tal; + test = &(boost::endian::big_int16_buf_t)tal; + + char* fileData; + std::ifstream in(fileName.c_str(), std::ios_base::binary | std::ios_base::ate); + + if (!in.is_open()) + LOG_ERROR("Failed to load custom binary model \"%s\"", fileName.c_str()); + + unsigned int fileByteSize = in.tellg(); + in.seekg(0, std::ios_base::beg); + + fileData = new char[fileByteSize]; + in.read(fileData, fileByteSize); + in.close(); + + unsigned int offset = 0; + ReadMeshFileHeader(offset, fileData, fileByteSize); + ReadMesh(offset, fileData, fileByteSize); + +} + +bool RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + m_Vertices.resize(*fileData); + offset += sizeof(unsigned int); + m_Indices.resize(*(fileData + offset)); + offset += sizeof(unsigned int); +#else +#endif +} + +bool RawModel::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +{ + ReadVertices(offset, fileData, fileByteSize); + ReadIndices(offset, fileData, fileByteSize); +} + +bool RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + memcpy(&m_Vertices[0], fileData, m_Vertices.size() * sizeof(Vertex)); + offset += m_Vertices.size() * sizeof(Vertex); +#else +#endif +} + +bool RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + memcpy(&m_Indices[0], fileData, m_Indices.size() * sizeof(unsigned int)); + offset += m_Indices.size() * sizeof(unsigned int); +#else +#endif +} + + +RawModel::~RawModel() +{ + +} \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index d9b47875..24e661ac 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -92,12 +92,12 @@ Mesh MeshClass::GetMeshData(MObject object) double biTangent[3]; double biNormal[3]; VertexLayout thisVertex; - MFloatVectorArray biTangents; + MFloatVectorArray Tangents; MFloatVectorArray biNormals; std::map vertexWeights = GetWeightData(); - mesh.getTangents(biTangents, MSpace::kObject, NULL); + mesh.getTangents(Tangents, MSpace::kObject, NULL); mesh.getBinormals(biNormals, MSpace::kObject, NULL); MItMeshFaceVertex faceVert(object); @@ -123,12 +123,12 @@ Mesh MeshClass::GetMeshData(MObject object) thisVertex.Normal[1] = normal[1]; thisVertex.Normal[2] = normal[2]; - MFloatVector biTangent = biTangents[faceVert.tangentId()]; + MFloatVector Tangent = Tangents[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]; + thisVertex.Tangent[0] = Tangent[0]; + thisVertex.Tangent[1] = Tangent[1]; + thisVertex.Tangent[2] = Tangent[2]; MFloatVector biNormal = biNormals[faceVert.tangentId()]; //faceVert.getBinormal().get(biNormal); diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index c9445e4e..ff7cc3b0 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -12,8 +12,8 @@ class VertexLayout : public OutputData public: float Pos[3]; float Normal[3]; + float Tangent[3]; float BiNormal[3]; - float BiTangent[3]; float Uv[2]; float BoneIndices[4]; float BoneWeights[4]; @@ -22,7 +22,7 @@ public: { out.write((char*)&Pos, sizeof(float) * 3); out.write((char*)&Normal, sizeof(float) * 3); - out.write((char*)&BiNormal, sizeof(float) * 3); + out.write((char*)&Tangent, sizeof(float) * 3); out.write((char*)&BiTangent, sizeof(float) * 3); out.write((char*)&Uv, sizeof(float) * 2); out.write((char*)&BoneIndices, sizeof(float) * 4); @@ -33,7 +33,7 @@ public: { 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 << Tangent[0] << " " << Tangent[1] << " " << Tangent[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; @@ -45,7 +45,7 @@ public: 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->Tangent[0] == right.Tangent[0] && this->Tangent[1] == right.Tangent[1] && this->Tangent[2] == right.Tangent[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] && From 2a3009212ae9b921a777941dfb8426c9c1349e8e Mon Sep 17 00:00:00 2001 From: antc13 Date: Mon, 18 Jan 2016 19:37:55 +0100 Subject: [PATCH 16/80] Importing custom mesh without material. --- include/Engine/Collision/Collision.h | 3 +- include/Engine/Core/ResourceManager.h | 8 +- include/Engine/Rendering/Model.h | 4 +- include/Engine/Rendering/RawModelCustom.h | 25 ++- resources/Schema/Entities/Model.xml | 30 +++ resources/Shaders/BasicForward.vert.glsl | 11 +- resources/Shaders/ForwardPlus.frag.glsl | 5 +- resources/Shaders/ForwardPlus.vert.glsl | 10 +- src/Engine/Editor/EditorSystem.cpp | 26 +-- src/Engine/Rendering/RawModelAssimp.cpp | 3 - src/Engine/Rendering/RawModelCustom.cpp | 54 +++-- src/Engine/Rendering/RenderSystem.cpp | 4 +- src/Engine/Rendering/Renderer.cpp | 4 +- tools/MayaExporter/MayaExporter/Export.cpp | 30 ++- tools/MayaExporter/MayaExporter/Export.h | 6 +- tools/MayaExporter/MayaExporter/Material.cpp | 85 +++----- tools/MayaExporter/MayaExporter/Material.h | 69 ++++++- tools/MayaExporter/MayaExporter/Menu.cpp | 25 ++- tools/MayaExporter/MayaExporter/Menu.h | 3 +- tools/MayaExporter/MayaExporter/Mesh.cpp | 206 +++++++++++++------ tools/MayaExporter/MayaExporter/Mesh.h | 39 ++-- 21 files changed, 402 insertions(+), 248 deletions(-) create mode 100644 resources/Schema/Entities/Model.xml diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 98ca1fb0..9777614f 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -9,7 +9,8 @@ #include "../Core/Ray.h" #include "../Core/AABB.h" -#include "Engine/Rendering/RawModelAssimp.h" +//#include "Engine/Rendering/RawModelAssimp.h" +#include "Engine/Rendering/RawModelCustom.h" #include "../Core/Entity.h" class World; diff --git a/include/Engine/Core/ResourceManager.h b/include/Engine/Core/ResourceManager.h index 15a551e7..10529819 100644 --- a/include/Engine/Core/ResourceManager.h +++ b/include/Engine/Core/ResourceManager.h @@ -32,10 +32,10 @@ public: }; struct FailedLoadingException : public std::exception { - virtual const char* what() const throw() - { - return "Resource is failed to load."; - } + FailedLoadingException(char const* const _Message) + : std::exception(_Message) + { } + FailedLoadingException() :std::exception("Resource failed to load.") { }; }; // Pretend that this is a pure virtual function that you have to implement diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index e99347c9..f79cacd5 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -1,7 +1,7 @@ #ifndef Model_h__ #define Model_h__ -#include "RawModelAssimp.h" +#include "RawModelCustom.h" #include "../OpenGL.h" class Model : public ThreadUnsafeResource @@ -23,8 +23,6 @@ public: private: RawModel* m_RawModel; GLuint VertexBuffer; - GLuint DiffuseVertexColorBuffer; - GLuint SpecularVertexColorBuffer; GLuint NormalBuffer; GLuint TangentNormalsBuffer; GLuint BiTangentNormalsBuffer; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index c6e97242..b5bf44cc 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -40,15 +40,22 @@ public: struct MaterialGroup { - float Shininess; - std::shared_ptr<::Texture> Texture; - std::shared_ptr<::Texture> NormalMap; - std::shared_ptr<::Texture> SpecularMap; + float SpecularExponent; + float ReflectionFactor; unsigned int StartIndex; unsigned int EndIndex; + //float Transparency; + std::string TexturePath; + std::shared_ptr<::Texture> Texture; + std::string NormalMapPath; + std::shared_ptr<::Texture> NormalMap; + std::string SpecularMapPath; + std::shared_ptr<::Texture> SpecularMap; + std::string IncandescenceMapPath; + std::shared_ptr<::Texture> IncandescenceMap; }; - std::vector TextureGroups; + std::vector MaterialGroups; std::vector m_Vertices; std::vector m_Indices; @@ -57,10 +64,10 @@ public: private: - bool ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize); - bool ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize); - bool ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); - bool ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + void ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + void ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + void ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/resources/Schema/Entities/Model.xml b/resources/Schema/Entities/Model.xml new file mode 100644 index 00000000..e4e60e4f --- /dev/null +++ b/resources/Schema/Entities/Model.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + models/coolTriangle.mesh + + + + + + + + diff --git a/resources/Shaders/BasicForward.vert.glsl b/resources/Shaders/BasicForward.vert.glsl index 96f081f4..cb231e45 100644 --- a/resources/Shaders/BasicForward.vert.glsl +++ b/resources/Shaders/BasicForward.vert.glsl @@ -9,18 +9,14 @@ layout(location = 1) in vec3 Normal; layout(location = 2) in vec3 Tangent; layout(location = 3) in vec3 BiTangent; layout(location = 4) in vec2 TextureCoords; -layout(location = 5) in vec4 DiffuseVertexColor; -layout(location = 6) in vec4 SpecularVertexColor; -layout(location = 7) in vec4 BoneIndices1; -layout(location = 8) in vec4 BoneIndices2; -layout(location = 9) in vec4 BoneWeights1; -layout(location = 10) in vec4 BoneWeights2; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; + out VertexData{ vec3 Position; vec3 Normal; vec2 TextureCoordinate; - vec4 DiffuseColor; }Output; void main() @@ -30,5 +26,4 @@ void main() Output.Position = Position; Output.TextureCoordinate = TextureCoords; Output.Normal = Normal; - Output.DiffuseColor = DiffuseVertexColor; } \ No newline at end of file diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 3d5b9bfd..450d8929 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -44,7 +44,6 @@ in VertexData{ vec3 Position; vec3 Normal; vec2 TextureCoordinate; - vec4 DiffuseColor; }Input; out vec4 fragmentColor; @@ -114,7 +113,7 @@ void main() totalLighting.Specular += result.Specular; } - fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; + //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1); //fragmentColor = texel * Input.DiffuseColor * Color; @@ -126,7 +125,7 @@ void main() } - + fragmentColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); } diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index 20ab9051..9ef20d5b 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -9,18 +9,13 @@ layout(location = 1) in vec3 Normal; layout(location = 2) in vec3 Tangent; layout(location = 3) in vec3 BiTangent; layout(location = 4) in vec2 TextureCoords; -layout(location = 5) in vec4 DiffuseVertexColor; -layout(location = 6) in vec4 SpecularVertexColor; -layout(location = 7) in vec4 BoneIndices1; -layout(location = 8) in vec4 BoneIndices2; -layout(location = 9) in vec4 BoneWeights1; -layout(location = 10) in vec4 BoneWeights2; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; out VertexData{ vec3 Position; vec3 Normal; vec2 TextureCoordinate; - vec4 DiffuseColor; }Output; void main() @@ -30,5 +25,4 @@ void main() Output.Position = Position; Output.TextureCoordinate = TextureCoords; Output.Normal = Normal; - Output.DiffuseColor = DiffuseVertexColor; } \ No newline at end of file diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 94e848c0..0f32a519 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -291,21 +291,21 @@ void EditorSystem::createWidget() m_WidgetPlaneX = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneX, "Transform"); m_World->AttachComponent(m_WidgetPlaneX, "Model"); - m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/WidgetPlaneX.obj"; + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube.mesh"; m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); m_World->AttachComponent(m_WidgetY, "Model"); m_WidgetPlaneY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneY, "Transform"); m_World->AttachComponent(m_WidgetPlaneY, "Model"); - m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/WidgetPlaneY.obj"; + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube.mesh"; m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); m_World->AttachComponent(m_WidgetZ, "Model"); m_WidgetPlaneZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneZ, "Transform"); m_World->AttachComponent(m_WidgetPlaneZ, "Model"); - m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube.mesh"; m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); m_World->AttachComponent(m_WidgetOrigin, "Model"); @@ -350,9 +350,9 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false; if (newMode == WidgetMode::Translate) { - m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; - m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj"; - m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; + //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj"; + //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj"; // Temporarily disabled for local space until I can figure out what's wrong with the math if (m_WidgetSpace != WidgetSpace::Local) { m_World->GetComponent(m_WidgetPlaneX, "Model")["Visible"] = true; @@ -366,19 +366,19 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) } } } else if (newMode == WidgetMode::Scale) { - m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; - m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj"; - m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; + //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj"; + //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj"; m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = true; - m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; + //m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; if (m_Selection != EntityID_Invalid) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); widgetTransform["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(m_World, m_Selection)); } } else if (newMode == WidgetMode::Rotate) { - m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; - m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj"; - m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; + //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj"; + //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj"; if (m_Selection != EntityID_Invalid) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); if (m_WidgetSpace == WidgetSpace::Local) { diff --git a/src/Engine/Rendering/RawModelAssimp.cpp b/src/Engine/Rendering/RawModelAssimp.cpp index 875bacbf..259eafc3 100644 --- a/src/Engine/Rendering/RawModelAssimp.cpp +++ b/src/Engine/Rendering/RawModelAssimp.cpp @@ -74,9 +74,6 @@ RawModel::RawModel(std::string fileName) auto uv = mesh->mTextureCoords[0][vertexIndex]; desc.TextureCoords = glm::vec2(uv.x, uv.y); } - - - desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity); m_Vertices.push_back(desc); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index a5493bd8..a165e1a4 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -2,16 +2,12 @@ RawModel::RawModel(std::string fileName) { - boost::endian::big_int16_buf_t* test; - int16_t tal; - test = &(boost::endian::big_int16_buf_t)tal; - char* fileData; std::ifstream in(fileName.c_str(), std::ios_base::binary | std::ios_base::ate); - if (!in.is_open()) - LOG_ERROR("Failed to load custom binary model \"%s\"", fileName.c_str()); - + if (!in.is_open()) { + throw Resource::FailedLoadingException("Open file failed"); + } unsigned int fileByteSize = in.tellg(); in.seekg(0, std::ios_base::beg); @@ -20,42 +16,64 @@ RawModel::RawModel(std::string fileName) in.close(); unsigned int offset = 0; - ReadMeshFileHeader(offset, fileData, fileByteSize); - ReadMesh(offset, fileData, fileByteSize); - + if (fileByteSize > 0) { + ReadMeshFileHeader(offset, fileData, fileByteSize); + ReadMesh(offset, fileData, fileByteSize); + } + delete fileData; + MaterialGroup mat; + mat.StartIndex = 0; + mat.EndIndex = m_Indices.size() - 1; + MaterialGroups.push_back(mat); } -bool RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - m_Vertices.resize(*fileData); + unsigned int test; + test = *(unsigned int*)fileData; + unsigned int* test2; + test2 = (unsigned int*)fileData; + + m_Vertices.resize(test); offset += sizeof(unsigned int); - m_Indices.resize(*(fileData + offset)); + test = *(unsigned int*)(fileData + offset); + m_Indices.resize(*(unsigned int*)(fileData + offset)); offset += sizeof(unsigned int); #else #endif } -bool RawModel::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModel::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { ReadVertices(offset, fileData, fileByteSize); ReadIndices(offset, fileData, fileByteSize); } -bool RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - memcpy(&m_Vertices[0], fileData, m_Vertices.size() * sizeof(Vertex)); + if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { + throw Resource::FailedLoadingException("Reading vertices failed"); + } + unsigned int i = sizeof(Vertex); + unsigned int ii = sizeof(unsigned int); + memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex)); offset += m_Vertices.size() * sizeof(Vertex); #else #endif } -bool RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - memcpy(&m_Indices[0], fileData, m_Indices.size() * sizeof(unsigned int)); + if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading indices failed"); + } + + memcpy(&m_Indices[0], fileData + offset, m_Indices.size() * sizeof(unsigned int)); offset += m_Indices.size() * sizeof(unsigned int); + #else #endif } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index c8def2b9..bc43a5a6 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -95,10 +95,10 @@ void RenderSystem::fillModels(std::list>& jobs, World model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; - model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj"); + model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); } catch (const std::exception&) { try { - model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); + model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); } catch (const std::exception&) { continue; } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 9ae317ca..983b0736 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -10,9 +10,9 @@ void Renderer::Initialize() InitializeShaders(); InitializeTextures(); - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + /* m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); - m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); + m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj");*/ m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index 82c81cfa..20b99e0f 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -51,13 +51,15 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) GetMeshData(node); } } - MGlobal::displayInfo(MString() + "nrofmeshes: " + meshes.size()); WriteMeshData(pathName); return true; } -bool Export::Materials() +bool Export::Materials(std::string pathName) { + if (!GetMaterialData()) + return false; + WriteMaterialData(pathName); return true; } @@ -73,17 +75,14 @@ bool Export::Animations(std::string pathName, std::vector animInf MGlobal::displayError(MString() + "Export::Animations() got no pathName. Do not know where to write file"); return false; } - MGlobal::displayInfo("HALLOOOO"); allBindPoses = m_SkeletonHandler.GetBindPoses(); for (auto clip : animInfo) { - MGlobal::displayInfo("preben"); if (!GetAnimationData(clip)) { MGlobal::displayError(MString() + "Export::Animations() failed to export " + clip.Name.c_str()); return false; } } - MGlobal::displayInfo("ghihgihi"); WriteAnimData(pathName); return true; } @@ -100,11 +99,8 @@ bool Export::GetMeshData(MObject object) bool Export::GetMaterialData() { // Traverse scene and return vector with all materials - std::vector* AllMaterials = m_MaterialHandler.DoIt(); + AllMaterials = m_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]); return true; } @@ -163,6 +159,22 @@ void Export::WriteAnimData(std::string pathName) MGlobal::displayInfo("Export::WriteAnimData() got called when allBindPoses contained no data, did not write nor created them"); } +void Export::WriteMaterialData(std::string pathName) +{ + m_MtrlFile.ASCIIFilePath(pathName +"_mtrl.txt"); + m_MtrlFile.binaryFilePath(pathName + ".mtrl"); + + m_MtrlFile.OpenFiles(); + + int size = (*AllMaterials).size(); + m_MtrlFile.writeToFiles(&size); + + for (auto aMaterial : *AllMaterials) { + m_MtrlFile.writeToFiles((OutputData*)&aMaterial); + } + m_MtrlFile.CloseFiles(); +} + Export::~Export() { /* delete m_MaterialHandler; diff --git a/tools/MayaExporter/MayaExporter/Export.h b/tools/MayaExporter/MayaExporter/Export.h index 83d27459..b05dee4e 100644 --- a/tools/MayaExporter/MayaExporter/Export.h +++ b/tools/MayaExporter/MayaExporter/Export.h @@ -23,7 +23,7 @@ public: }; bool Meshes(std::string pathName, bool selectedOnly = false); - bool Materials(); + bool Materials(std::string pathName); bool Animations(std::string pathName, std::vector animInfo); private: @@ -33,6 +33,7 @@ private: void WriteMeshData(std::string pathName); void WriteAnimData(std::string pathName); + void WriteMaterialData(std::string pathName); Material m_MaterialHandler; Skeleton m_SkeletonHandler; @@ -42,6 +43,7 @@ private: //File export WriteToFile m_MeshFile; WriteToFile m_AnimFile; + WriteToFile m_MtrlFile; //Mesh Data std::vector meshes; @@ -50,5 +52,7 @@ private: std::vector allBindPoses; std::vector allAnimations; + //Material Data + std::vector* AllMaterials; }; #endif \ No newline at end of file diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index ac9c46ea..8071efab 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -4,57 +4,24 @@ void Material::grabLambertProperties(MaterialNode& material_node, MFnDependencyN { 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]); + if (!findColorTexture(material_node, node)) { + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no color texture. Please apply a texture insted of using a value"); + } - 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]); + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no Incandescence texture. Please apply a texture insted of using value"); } - findNormalTexture(material_node, node); + if (findNormalTexture(material_node, node)) { + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no normal texture. Please apply a texture to it"); + } } 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]); + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no specular texture. Please apply a specular to it"); } m_Plug = node.findPlug("reflectivity"); @@ -76,17 +43,9 @@ void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNod 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]); - } + if (findSpecularTexture(material_node, node)) { + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no specular texture. Please apply a specular to it"); + } m_Plug = node.findPlug("reflectivity"); m_Plug.getValue(material_node.ReflectionFactor); @@ -109,8 +68,10 @@ bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - material_node.ColorMapFile = FullPath.substr(FullPath.find_last_of("/")); + FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + material_node.ColorMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + material_node.ColorMapFileLength = material_node.ColorMapFile.length() + 1; // Test MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str()); return true; @@ -140,8 +101,9 @@ bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - material_node.NormalMapFile = FullPath.substr(FullPath.find_last_of("/")); - + FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + material_node.NormalMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + material_node.NormalMapFileLength = material_node.NormalMapFile.length() + 1; return true; } } @@ -165,8 +127,9 @@ bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNod std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/")); - + FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + material_node.SpecularMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + material_node.SpecularMapFileLength = material_node.SpecularMapFile.length() + 1; return true; } } @@ -187,8 +150,9 @@ bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependen std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - material_node.SpecularMapFile = FullPath.substr(FullPath.find_last_of("/")); - + FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + material_node.IncandescenceMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); + material_node.IncandescenceMapFileLength = material_node.IncandescenceMapFile.length() + 1; return true; } } @@ -206,7 +170,7 @@ std::vector* Material::DoIt() { // All materials we care about inherit from Lambert MItDependencyNodes matIt(MFn::kLambert); - + m_AllMaterials.clear(); while (!matIt.isDone()) { MFnDependencyNode MaterialFnDN(matIt.thisNode()); MaterialNode MaterialStorage; @@ -226,7 +190,6 @@ std::vector* Material::DoIt() else if (matIt.thisNode().hasFn(MFn::kLambert)) { grabLambertProperties(MaterialStorage, MaterialFnDN); - MaterialStorage.Specular.fill(0.0f); MaterialStorage.ReflectionFactor = 0.0f; MaterialStorage.SpecularExponent = 0.0f; diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index c5d57529..9a6058f0 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -5,21 +5,80 @@ #include #include #include +#include #include "MayaIncludes.h" +#include "OutputData.h" +#include "Mesh.h" -struct MaterialNode +class MaterialNode : public OutputData { +public: std::string Name; - std::array Color; - std::array Incandescence; - std::array Specular; + float ReflectionFactor; - float SpecularExponent; + float SpecularExponent; + + unsigned int ColorMapFileLength = 0; std::string ColorMapFile; + + unsigned int SpecularMapFileLength = 0; std::string SpecularMapFile; + + unsigned int NormalMapFileLength = 0; std::string NormalMapFile; + + unsigned int IncandescenceMapFileLength = 0; std::string IncandescenceMapFile; + + unsigned int IndexStart; + unsigned int IndexEnd; + + virtual void WriteBinary(std::ostream& out) + { + out.write((char*)&ColorMapFileLength, sizeof(unsigned int)); + out.write((char*)&NormalMapFileLength, sizeof(unsigned int)); + out.write((char*)&SpecularMapFileLength, sizeof(unsigned int)); + out.write((char*)&IncandescenceMapFileLength, sizeof(unsigned int)); + + out.write((char*)&SpecularExponent, sizeof(float)); + out.write((char*)&ReflectionFactor, sizeof(float)); + out.write((char*)&IndexStart, sizeof(unsigned int)); + out.write((char*)&IndexEnd, sizeof(unsigned int)); + + out.write(ColorMapFile.c_str(), ColorMapFileLength); + out.write(NormalMapFile.c_str(), NormalMapFileLength); + out.write(SpecularMapFile.c_str(), SpecularMapFileLength); + out.write(IncandescenceMapFile.c_str(), IncandescenceMapFileLength); + } + + virtual void WriteASCII(std::ostream& out) const + { + out << "New Material _ not in binary" << endl; + out << "number of indices: " << Name << " _ not in binary" << endl; + + out << "ColorMapFile length: " << ColorMapFileLength << endl; + out << "NormalMapFile length: " << NormalMapFileLength << endl; + out << "SpecularMapFile length: " << SpecularMapFileLength << endl; + out << "IncandescenceMapFile length: " << IncandescenceMapFileLength << endl; + + out << "SpecularExponent: " << SpecularExponent << endl; + out << "ReflectionFactor: " << ReflectionFactor << endl; + out << "IndexStart: " << IndexStart << endl; + out << "IndexEnd: " << IndexEnd << endl; + + out << "ColorMapFile length: " << ColorMapFileLength << endl; + if (ColorMapFileLength > 0) + out << "ColorMapFile: " << ColorMapFile << endl; + if (NormalMapFileLength > 0) + out << "NormalMapFile: " << NormalMapFile << endl; + + if (SpecularMapFileLength > 0) + out << "SpecularMapFile: " << SpecularMapFile << endl; + + if (IncandescenceMapFileLength > 0) + out << "IncandescenceMapFile: " << IncandescenceMapFile << endl; + } }; class Material diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 1ff007b4..a03788a6 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -24,16 +24,15 @@ Menu::Menu(QDialog* dialog) m_ExportSelectedButton = new QCheckBox(tr("&Export Selected")); m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations")); - m_CopyTexturesButton = new QCheckBox(tr("&Copy Textures")); - m_Button3 = new QCheckBox(tr("Test Materials")); + m_ExportMaterialButton = new QCheckBox(tr("&Export Material"));; m_ExportAnimationsButton->setChecked(true); - m_CopyTexturesButton->setChecked(true); + m_ExportMaterialButton->setChecked(true); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(m_ExportSelectedButton); vbox->addWidget(m_ExportAnimationsButton); - vbox->addWidget(m_CopyTexturesButton); - vbox->addWidget(m_Button3); + vbox->addWidget(m_ExportMaterialButton); + vbox->addStretch(1); optionsBox->setLayout(vbox); @@ -46,8 +45,7 @@ Menu::Menu(QDialog* dialog) connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); - connect(m_CopyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); - connect(m_Button3, SIGNAL(clicked(bool)), this, SLOT(NULL)); + connect(m_ExportMaterialButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); // Creating several layouts, adding widgets & adding them to one layout in the end QHBoxLayout* topLayout = new QHBoxLayout; @@ -178,20 +176,14 @@ void Menu::ExportAll(bool) } std::vector animations; - MGlobal::displayInfo(MString() + "yeeehaa"); for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { Export::AnimationInfo thisClip; - MGlobal::displayInfo(MString() + "qwqw"); thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData()); - MGlobal::displayInfo(MString() + "shizzzz"); thisClip.Start = m_StartFrameLines[i]->text().toInt(); - MGlobal::displayInfo(MString() + "dsdsfg"); thisClip.End = m_EndFrameLines[i]->text().toInt(); - MGlobal::displayInfo(MString() + "aaaaaaaaaaaaaaaaaaaa"); animations.push_back(thisClip); } - MGlobal::displayInfo(MString() + "asdf"); if (m_ExportAnimationsButton->isChecked()) { //Export Animations if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) { @@ -199,6 +191,13 @@ void Menu::ExportAll(bool) return; } } + + if (m_ExportMaterialButton->isChecked()) { + if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())){ + MGlobal::displayError(MString() + "Could not export materials"); + return; + } + } } void Menu::CancelClicked(bool) diff --git a/tools/MayaExporter/MayaExporter/Menu.h b/tools/MayaExporter/MayaExporter/Menu.h index a8b517bc..fb95a953 100644 --- a/tools/MayaExporter/MayaExporter/Menu.h +++ b/tools/MayaExporter/MayaExporter/Menu.h @@ -65,8 +65,7 @@ private: QCheckBox* m_ExportSelectedButton = nullptr; QCheckBox* m_ExportAnimationsButton = nullptr; - QCheckBox* m_CopyTexturesButton = nullptr; - QCheckBox* m_Button3 = nullptr; + QCheckBox* m_ExportMaterialButton = nullptr; QLineEdit* m_ExportPath = nullptr; QFileDialog* m_FileDialog = nullptr; diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 24e661ac..c37a7bed 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -76,8 +76,8 @@ std::map MeshClass::GetWeightData() Mesh MeshClass::GetMeshData(MObject object) { Mesh newMesh; - std::vector& vertexList = newMesh.Vertices; - std::vector& indexList = newMesh.Indices; + vector& vertexList = newMesh.Vertices; + map>& indexLists = newMesh.Indices; // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object); @@ -91,11 +91,28 @@ Mesh MeshClass::GetMeshData(MObject object) float2 UV; double biTangent[3]; double biNormal[3]; - VertexLayout thisVertex; MFloatVectorArray Tangents; MFloatVectorArray biNormals; - std::map vertexWeights = GetWeightData(); + MObjectArray shaderList; + MIntArray shaderIndexList; + mesh.getConnectedShaders(0, shaderList, shaderIndexList); + + map> materialFaceIDs; + MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length()); + MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length()); + MPlugArray plugArray; + for (int i = 0; i < shaderIndexList.length(); i++) + { + MFnDependencyNode shader(shaderList[shaderIndexList[i]]); + MPlug p_Plug = shader.findPlug("surfaceShader"); + if (p_Plug.connectedTo(plugArray, true, false)) { + MFnDependencyNode node = plugArray[0].node(); + materialFaceIDs[node.name().asChar()].push_back(i); + } + } + + map vertexWeights = GetWeightData(); mesh.getTangents(Tangents, MSpace::kObject, NULL); mesh.getBinormals(biNormals, MSpace::kObject, NULL); @@ -103,82 +120,139 @@ Mesh MeshClass::GetMeshData(MObject object) MItMeshFaceVertex faceVert(object); int intDummy = 0; + + MItMeshPolygon meshPolyIter(object); - for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next()) { + for (auto aMaterial : materialFaceIDs) { + for (auto faceID : aMaterial.second) { - vector localVertexToGlobalIndex; - unsigned int indexOffset = vertexList.size(); + vector> localVertexToGlobalIndex; + meshPolyIter.setIndex(faceID, intDummy); - meshPolyIter.getVertices(vertices); - meshPolyIter.getTriangles(dummy, triangleList); + meshPolyIter.getVertices(vertices); + meshPolyIter.getTriangles(dummy, triangleList); + //MGlobal::displayInfo("Befor Second Loop"); + for (unsigned int i = 0; i < vertices.length(); i++) { + VertexLayout thisVertex; + vertexIndex = meshPolyIter.vertexIndex(i); + faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); + //MGlobal::displayInfo("In Second Loop"); + pos = faceVert.position(); + if (abs(pos.x) > 0.0001) + thisVertex.Pos[0] = pos.x; + if (abs(pos.y) > 0.0001) + thisVertex.Pos[1] = pos.y; + if (abs(pos.z) > 0.0001) + thisVertex.Pos[2] = pos.z; - //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.getNormal(normal); + if (abs(normal[0]) > 0.0001) + thisVertex.Normal[0] = normal[0]; + if (abs(normal[1]) > 0.0001) + thisVertex.Normal[1] = normal[1]; + if (abs(normal[2]) > 0.0001) + thisVertex.Normal[2] = normal[2]; - MFloatVector Tangent = Tangents[faceVert.tangentId()]; - //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); - //tmp.get(biTangent); - thisVertex.Tangent[0] = Tangent[0]; - thisVertex.Tangent[1] = Tangent[1]; - thisVertex.Tangent[2] = Tangent[2]; + MFloatVector Tangent = Tangents[faceVert.tangentId()]; + //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); + //tmp.get(biTangent); + if (abs(Tangent[0]) > 0.0001) + thisVertex.Tangent[0] = Tangent[0]; + if (abs(Tangent[1]) > 0.0001) + thisVertex.Tangent[1] = Tangent[1]; + if (abs(Tangent[2]) > 0.0001) + thisVertex.Tangent[2] = Tangent[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]; + MFloatVector biNormal = biNormals[faceVert.tangentId()]; + //faceVert.getBinormal().get(biNormal); + if (abs(biNormal[0]) > 0.0001) + thisVertex.BiNormal[0] = biNormal[0]; + if (abs(biNormal[1]) > 0.0001) + thisVertex.BiNormal[1] = biNormal[1]; + if (abs(biNormal[2]) > 0.0001) + thisVertex.BiNormal[2] = biNormal[2]; - faceVert.getUV(UV); - thisVertex.Uv[0] = UV[0]; - thisVertex.Uv[1] = UV[1]; + faceVert.getUV(UV); + thisVertex.Uv[0] = UV[0]; + thisVertex.Uv[1] = UV[1]; - 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.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]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[0]) > 0.0001) + thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[1]) > 0.0001) + thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[2]) > 0.0001) + thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[3]) > 0.0001) + 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; - } - - - for (unsigned int i = 0; i < triangleList.length(); i++) { - unsigned int k = 0; - if (localVertexToGlobalIndex.size() > 0) { - while (localVertexToGlobalIndex[k] != triangleList[i] && k < localVertexToGlobalIndex.size()) { - k++; + float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; + if (totalWeight < 1.00f && totalWeight > 0.01f) { + thisVertex.BoneWeights[0] /= totalWeight; + thisVertex.BoneWeights[1] /= totalWeight; + thisVertex.BoneWeights[2] /= totalWeight; + thisVertex.BoneWeights[3] /= totalWeight; } - indexList.push_back(indexOffset + k); - } + + std::vector::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex); + array tmp; + if (it != vertexList.end()) { + tmp[0] = vertexIndex; + tmp[1] = it - vertexList.begin(); + localVertexToGlobalIndex.push_back(tmp); + } else { + tmp[0] = vertexIndex; + tmp[1] = vertexList.size(); + localVertexToGlobalIndex.push_back(tmp); + vertexList.push_back(thisVertex); + } + //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1]: " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][0] + " " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][1]); + //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 (unsigned int i = 0; i < triangleList.length(); i++) { + unsigned int k = 0; + if (localVertexToGlobalIndex.size() > 0) { + //MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); + while (localVertexToGlobalIndex[k][0] != triangleList[i] && k < localVertexToGlobalIndex.size()) { + k++; + } + //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k][0] + " " + localVertexToGlobalIndex[k][1]); + indexLists[aMaterial.first.c_str()].push_back(localVertexToGlobalIndex[k][1]); + } + } } + // MGlobal::displayInfo( MString() + "localVertexToGlobalIndex.size(): " + localVertexToGlobalIndex.size()); + // if (localVertexToGlobalIndex.size() > 0) { + // MGlobal::displayInfo(MString() + "triangleList.length(): " + triangleList.length()); + // for (unsigned int i = triangleList.length() - 1; i >= 0; i--) { + // MGlobal::displayInfo(MString() + "i: " + i); + // unsigned int k = localVertexToGlobalIndex.size() - 1; + // MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); + // while (localVertexToGlobalIndex[k] != triangleList[i] && k >= 0) { + // MGlobal::displayInfo(MString() + "k: " + k); + // k--; + // } + // MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k]); + // indexList.push_back(indexOffset + k); + // } + // } } - newMesh.NumIndices = newMesh.Indices.size(); + + int totalIndecies = 0; + for (auto aList : newMesh.Indices) { + totalIndecies += aList.second.size(); + } + + newMesh.NumIndices = totalIndecies; newMesh.NumVertices = newMesh.Vertices.size(); return newMesh; diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index ff7cc3b0..15c16913 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -3,6 +3,7 @@ #include #include +#include #include "OutputData.h" #include "MayaIncludes.h" @@ -10,20 +11,20 @@ class VertexLayout : public OutputData { public: - float Pos[3]; - float Normal[3]; - float Tangent[3]; - float BiNormal[3]; - float Uv[2]; - float BoneIndices[4]; - float BoneWeights[4]; + float Pos[3]{ 0 }; + float Normal[3]{ 0 }; + float Tangent[3]{ 0 }; + float BiNormal[3]{ 0 }; + float Uv[2]{ 0 }; + float BoneIndices[4]{ 0 }; + float BoneWeights[4]{ 0 }; virtual void WriteBinary(std::ostream& out) { out.write((char*)&Pos, sizeof(float) * 3); out.write((char*)&Normal, sizeof(float) * 3); out.write((char*)&Tangent, sizeof(float) * 3); - out.write((char*)&BiTangent, sizeof(float) * 3); + out.write((char*)&BiNormal, sizeof(float) * 3); out.write((char*)&Uv, sizeof(float) * 2); out.write((char*)&BoneIndices, sizeof(float) * 4); out.write((char*)&BoneWeights, sizeof(float) * 4); @@ -34,7 +35,7 @@ public: out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl; out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl; out << Tangent[0] << " " << Tangent[1] << " " << Tangent[2] << endl; - out << BiTangent[0] << " " << BiTangent[1] << " " << BiTangent[2] << endl; + out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[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; @@ -46,7 +47,7 @@ public: 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->Tangent[0] == right.Tangent[0] && this->Tangent[1] == right.Tangent[1] && this->Tangent[2] == right.Tangent[2] && - this->BiTangent[0] == right.BiTangent[0] && this->BiTangent[1] == right.BiTangent[1] && this->BiTangent[2] == right.BiTangent[2] && + this->BiNormal[0] == right.BiNormal[0] && this->BiNormal[1] == right.BiNormal[1] && this->BiNormal[2] == right.BiNormal[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] @@ -56,10 +57,10 @@ public: class Mesh : public OutputData { public: - int NumVertices; - int NumIndices; + unsigned int NumVertices; + unsigned int NumIndices; std::vector Vertices; - std::vector Indices; + std::map> Indices; virtual void WriteBinary(std::ostream& out) { @@ -69,7 +70,7 @@ public: aVertex.WriteBinary(out); } for (auto aIndex : Indices) { - out.write((char*)&aIndex, sizeof(int)); + out.write((char*)aIndex.second.data(), sizeof(int) * aIndex.second.size()); } } @@ -80,12 +81,16 @@ public: out << "number of indices: " << NumIndices << endl; int vertexNumber = 0; for (auto aVertex : Vertices) { - out << "New vertex number: " << vertexNumber << "_ not in binary" << endl; + out << "New vertex number: " << vertexNumber << " _ not in binary" << endl; aVertex.WriteASCII(out); vertexNumber++; } - for (int i = 0; i < NumIndices; i += 3) { - out << Indices[i] << " " << Indices[i+1] << " " << Indices[i + 2] << endl; + out << "New vertex Triangels: " << NumIndices/3 << " _ not in binary" << endl; + for (auto aIndexList : Indices) { + out << "Using Material: " << aIndexList.first << " _ not in binary" << endl; + for (int i = 0; i < aIndexList.second.size(); i += 3) { + out << aIndexList.second[i] << " " << aIndexList.second[i+1] << " " << aIndexList.second[i + 2] << endl; + } } } }; From 3826142e94a6c7b98f69b702922a847de390c54c Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 19 Jan 2016 17:40:34 +0100 Subject: [PATCH 17/80] Now supporting multiple material per mesh. Simon changed glDrawElementsBaseVertex to glDrawElements in DrawFinalPass.cpp Hallelulijah! --- include/Engine/Rendering/Model.h | 3 +- include/Engine/Rendering/RawModelCustom.h | 8 +- resources/Schema/Entities/Model.xml | 2 +- src/Engine/Editor/EditorSystem.cpp | 6 +- src/Engine/Rendering/DrawFinalPass.cpp | 4 +- src/Engine/Rendering/DrawFinalPassState.cpp | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 136 +++++++- src/Engine/Rendering/RenderSystem.cpp | 4 +- src/Engine/Rendering/Renderer.cpp | 8 +- tools/MayaExporter/MayaExporter/Export.cpp | 20 +- tools/MayaExporter/MayaExporter/Export.h | 4 +- tools/MayaExporter/MayaExporter/Material.cpp | 44 +-- tools/MayaExporter/MayaExporter/Material.h | 4 +- tools/MayaExporter/MayaExporter/Mesh.cpp | 337 ++++++++++--------- tools/MayaExporter/MayaExporter/Mesh.h | 7 +- 15 files changed, 359 insertions(+), 230 deletions(-) diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index f79cacd5..4b83562c 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -19,9 +19,10 @@ public: GLuint VAO; GLuint ElementBuffer; + RawModel* m_RawModel; private: - RawModel* m_RawModel; + GLuint VertexBuffer; GLuint NormalBuffer; GLuint TangentNormalsBuffer; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index b5bf44cc..bc85e32c 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -22,7 +22,7 @@ class RawModel : public Resource friend class ResourceManager; protected: - RawModel(std::string fileName); + RawModel(std::string& fileName); public: ~RawModel(); @@ -63,12 +63,18 @@ public: glm::mat4 m_Matrix; private: + + void ReadMeshFile(std::string filePath); void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize); void ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize); void ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); void ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialFile(std::string filePath); + void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/resources/Schema/Entities/Model.xml b/resources/Schema/Entities/Model.xml index e4e60e4f..8962d7e1 100644 --- a/resources/Schema/Entities/Model.xml +++ b/resources/Schema/Entities/Model.xml @@ -19,7 +19,7 @@ - models/coolTriangle.mesh + models/Baljj diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 0f32a519..044c0cd7 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -291,21 +291,21 @@ void EditorSystem::createWidget() m_WidgetPlaneX = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneX, "Transform"); m_World->AttachComponent(m_WidgetPlaneX, "Model"); - m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube.mesh"; + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube"; m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); m_World->AttachComponent(m_WidgetY, "Model"); m_WidgetPlaneY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneY, "Transform"); m_World->AttachComponent(m_WidgetPlaneY, "Model"); - m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube.mesh"; + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube"; m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); m_World->AttachComponent(m_WidgetZ, "Model"); m_WidgetPlaneZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneZ, "Transform"); m_World->AttachComponent(m_WidgetPlaneZ, "Model"); - m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube.mesh"; + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube"; m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); m_World->AttachComponent(m_WidgetOrigin, "Model"); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index b0ca4afe..7093b00f 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -56,9 +56,7 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); - - continue; + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); } } GLERROR("DrawFinalPass::Draw: END"); diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index 1cb9d7da..5bafc294 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -7,7 +7,7 @@ DrawFinalPassState::DrawFinalPassState() Enable(GL_BLEND); BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Enable(GL_DEPTH_TEST); - Enable(GL_CULL_FACE); + Disable(GL_CULL_FACE); //Should be enabled, fix it johan and andreas. ClearColor(glm::vec4(200.f / 255, 0.f / 255, 200.f / 255, 0.f)); Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index a165e1a4..a749e1fd 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -1,12 +1,19 @@ -#include "Rendering\RawModelCustom.h" +#include "Rendering/RawModelCustom.h" -RawModel::RawModel(std::string fileName) +RawModel::RawModel(std::string& fileName) { + ReadMeshFile(fileName); + ReadMaterialFile(fileName); +} + +void RawModel::ReadMeshFile(std::string filePath) +{ char* fileData; - std::ifstream in(fileName.c_str(), std::ios_base::binary | std::ios_base::ate); + filePath += ".mesh"; + std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate); if (!in.is_open()) { - throw Resource::FailedLoadingException("Open file failed"); + throw Resource::FailedLoadingException("Open mesh file failed"); } unsigned int fileByteSize = in.tellg(); in.seekg(0, std::ios_base::beg); @@ -21,23 +28,13 @@ RawModel::RawModel(std::string fileName) ReadMesh(offset, fileData, fileByteSize); } delete fileData; - MaterialGroup mat; - mat.StartIndex = 0; - mat.EndIndex = m_Indices.size() - 1; - MaterialGroups.push_back(mat); } void RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN - unsigned int test; - test = *(unsigned int*)fileData; - unsigned int* test2; - test2 = (unsigned int*)fileData; - - m_Vertices.resize(test); + m_Vertices.resize(*(unsigned int*)(fileData + offset)); offset += sizeof(unsigned int); - test = *(unsigned int*)(fileData + offset); m_Indices.resize(*(unsigned int*)(fileData + offset)); offset += sizeof(unsigned int); #else @@ -78,6 +75,115 @@ void RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& f #endif } +void RawModel::ReadMaterialFile(std::string filePath) +{ + char* fileData; + filePath += ".mtrl"; + std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate); + + if (!in.is_open()) { + throw Resource::FailedLoadingException("Open material file failed"); + } + unsigned int fileByteSize = in.tellg(); + in.seekg(0, std::ios_base::beg); + + fileData = new char[fileByteSize]; + in.read(fileData, fileByteSize); + in.close(); + + unsigned int offset = 0; + if (fileByteSize > 0) { + ReadMaterials(offset, fileData, fileByteSize); + } + delete fileData; +} + +void RawModel::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + unsigned int* numMaterials = (unsigned int*)(fileData); + MaterialGroups.reserve(*numMaterials); + offset += sizeof(unsigned int); + + for (int i = 0; i < *numMaterials; i++) { + ReadMaterialSingle(offset, fileData, fileByteSize); + } +#else +#endif +} + +void RawModel::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ + MaterialGroup newMaterial; + +#ifdef BOOST_LITTLE_ENDIAN + + if (offset + sizeof(unsigned int) * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material texture names length failed"); + } + + unsigned int* nameLengths = (unsigned int*)(fileData + offset); + offset += sizeof(unsigned int) * 4; + + if (offset + sizeof(float) * 2 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material specular and reflection values failed"); + } + + newMaterial.SpecularExponent = *(float*)(fileData + offset); + offset += sizeof(float); + newMaterial.ReflectionFactor = *(float*)(fileData + offset); + offset += sizeof(float); + + if (offset + sizeof(unsigned int) * 2 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material start and end index values failed"); + } + + newMaterial.StartIndex = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + newMaterial.EndIndex = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (nameLengths[0] > 0) { + if (offset + nameLengths[0] > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material texture path failed"); + } + + newMaterial.TexturePath = (fileData + offset); + offset += nameLengths[0]; + } + + if (nameLengths[1] > 0) { + if (offset + nameLengths[1] > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material NormalMap path failed"); + } + + newMaterial.NormalMapPath = (fileData + offset); + offset += nameLengths[1]; + } + + if (nameLengths[2] > 0) { + if (offset + nameLengths[2] > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material SpecularMap path failed"); + } + + newMaterial.SpecularMapPath = (fileData + offset); + offset += nameLengths[2]; + } + + if (nameLengths[3] > 0) { + if (offset + nameLengths[3] > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material IncandescenceMap path failed"); + } + + newMaterial.IncandescenceMapPath = (fileData + offset); + offset += nameLengths[3]; + } + +#else +#endif + + MaterialGroups.push_back(newMaterial); +} RawModel::~RawModel() { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index bc43a5a6..42628ad1 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -95,10 +95,10 @@ void RenderSystem::fillModels(std::list>& jobs, World model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; - model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); + model = ResourceManager::Load<::Model>("Models/coolCube"); } catch (const std::exception&) { try { - model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); + model = ResourceManager::Load<::Model>("Models/coolCube"); } catch (const std::exception&) { continue; } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 983b0736..f86fea43 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -101,10 +101,10 @@ void Renderer::Draw(RenderFrame& frame) m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras. FillDepth(*scene); - m_PickingPass->Draw(*scene); - m_LightCullingPass->GenerateNewFrustum(*scene); - m_LightCullingPass->FillLightList(*scene); - m_LightCullingPass->CullLights(*scene); + //m_PickingPass->Draw(*scene); + //m_LightCullingPass->GenerateNewFrustum(*scene); + //m_LightCullingPass->FillLightList(*scene); + //m_LightCullingPass->CullLights(*scene); m_DrawFinalPass->Draw(*scene); //m_DrawScenePass->Draw(rq); diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index 20b99e0f..1db753d7 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -11,8 +11,8 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file"); return false; } - meshes.clear(); + MObjectArray Objects; if (selectedOnly) { // Retrieving the objects we currently have selected MSelectionList selected; @@ -25,7 +25,7 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) if (object.hasFn(MFn::kMesh)) { MFnDependencyNode thisNode(object); - GetMeshData(object); + Objects.append(object); } } } else { @@ -48,9 +48,10 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) if (next) continue; - GetMeshData(node); + Objects.append(node); } } + GetMeshData(Objects); WriteMeshData(pathName); return true; } @@ -87,19 +88,16 @@ bool Export::Animations(std::string pathName, std::vector animInf return true; } -bool Export::GetMeshData(MObject object) +bool Export::GetMeshData(MObjectArray object) { - if (!object.hasFn(MFn::kMesh)) - return false; - - meshes.push_back(m_MeshHandler.GetMeshData(object)); + meshes = m_MeshHandler.GetMeshData(object); return true; } bool Export::GetMaterialData() { // Traverse scene and return vector with all materials - AllMaterials = m_MaterialHandler.DoIt(); + AllMaterials = m_MaterialHandler.DoIt(meshes); return true; } @@ -126,9 +124,7 @@ void Export::WriteMeshData(std::string pathName) m_MeshFile.OpenFiles(); - for (auto aMesh : meshes) { - m_MeshFile.writeToFiles((OutputData*)&aMesh); - } + m_MeshFile.writeToFiles((OutputData*)&meshes); m_MeshFile.CloseFiles(); } diff --git a/tools/MayaExporter/MayaExporter/Export.h b/tools/MayaExporter/MayaExporter/Export.h index b05dee4e..42b40445 100644 --- a/tools/MayaExporter/MayaExporter/Export.h +++ b/tools/MayaExporter/MayaExporter/Export.h @@ -27,7 +27,7 @@ public: bool Animations(std::string pathName, std::vector animInfo); private: - bool GetMeshData(MObject object); + bool GetMeshData(MObjectArray object); bool GetMaterialData(); bool GetAnimationData(AnimationInfo info); @@ -46,7 +46,7 @@ private: WriteToFile m_MtrlFile; //Mesh Data - std::vector meshes; + Mesh meshes; //Animation Data std::vector allBindPoses; diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 8071efab..8f6b0a62 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -166,36 +166,42 @@ std::vector* Material::TexturePaths() } // Traverse the DAG and grab all the materials -std::vector* Material::DoIt() +std::vector* Material::DoIt(Mesh mesh) { // All materials we care about inherit from Lambert MItDependencyNodes matIt(MFn::kLambert); m_AllMaterials.clear(); + int totalIndices = 0; while (!matIt.isDone()) { MFnDependencyNode MaterialFnDN(matIt.thisNode()); MaterialNode MaterialStorage; + bool meshHasMaterial = false; + //Mesh Indices is a map with : indices> + for (auto aMeshMaterial : mesh.Indices) { + if (aMeshMaterial.first.compare(MaterialFnDN.name().asChar()) == 0) { + meshHasMaterial = true; + MaterialStorage.IndexStart = totalIndices; + MaterialStorage.IndexEnd = totalIndices + aMeshMaterial.second.size() - 1; + totalIndices += aMeshMaterial.second.size(); + break; + } + } + if (meshHasMaterial) { + grabLambertProperties(MaterialStorage, MaterialFnDN); - if (matIt.thisNode().hasFn(MFn::kPhong)) { - grabLambertProperties(MaterialStorage, MaterialFnDN); - grabPhongProperties(MaterialStorage, MaterialFnDN); + if (matIt.thisNode().hasFn(MFn::kPhong)) { + grabPhongProperties(MaterialStorage, MaterialFnDN); - m_AllMaterials.push_back(MaterialStorage); - } - else if (matIt.thisNode().hasFn(MFn::kBlinn)) { - grabLambertProperties(MaterialStorage, MaterialFnDN); - grabBlinnProperties(MaterialStorage, MaterialFnDN); + } else if (matIt.thisNode().hasFn(MFn::kBlinn)) { + grabBlinnProperties(MaterialStorage, MaterialFnDN); - m_AllMaterials.push_back(MaterialStorage); - } - else if (matIt.thisNode().hasFn(MFn::kLambert)) { - grabLambertProperties(MaterialStorage, MaterialFnDN); - - MaterialStorage.ReflectionFactor = 0.0f; - MaterialStorage.SpecularExponent = 0.0f; - - m_AllMaterials.push_back(MaterialStorage); - } + } else if (matIt.thisNode().hasFn(MFn::kLambert)) { + MaterialStorage.ReflectionFactor = 0.0f; + MaterialStorage.SpecularExponent = 0.0f; + } + m_AllMaterials.push_back(MaterialStorage); + } matIt.next(); } diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index 9a6058f0..4b567d8b 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -67,9 +67,9 @@ public: out << "IndexStart: " << IndexStart << endl; out << "IndexEnd: " << IndexEnd << endl; - out << "ColorMapFile length: " << ColorMapFileLength << endl; if (ColorMapFileLength > 0) out << "ColorMapFile: " << ColorMapFile << endl; + if (NormalMapFileLength > 0) out << "NormalMapFile: " << NormalMapFile << endl; @@ -86,7 +86,7 @@ class Material public: Material() {}; ~Material() {}; - std::vector* DoIt(); + std::vector* DoIt(Mesh mesh); std::vector* TexturePaths(); private: MPlug m_Plug; diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index c37a7bed..0f99533c 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -73,186 +73,201 @@ std::map MeshClass::GetWeightData() return weightMap; } -Mesh MeshClass::GetMeshData(MObject object) +Mesh MeshClass::GetMeshData(MObjectArray object) { Mesh newMesh; vector& vertexList = newMesh.Vertices; map>& indexLists = newMesh.Indices; - // In here, we retrieve triangulated polygons from the mesh - MFnMesh mesh(object); + for (int ObjectID = 0; ObjectID < object.length(); ObjectID++) { + if (!object[ObjectID].hasFn(MFn::kMesh)) + continue; - map> vertexToIndex;; + // In here, we retrieve triangulated polygons from the mesh + MFnMesh mesh(object[ObjectID]); + MDagPathArray dagPaths; + MDagPath::getAllPathsTo(object[ObjectID], dagPaths); + for (int pathID = 0; pathID < dagPaths.length(); pathID++) { + MGlobal::displayInfo(dagPaths[pathID].fullPathName()); + MDagPath thisMeshPath(dagPaths[pathID]); + MMatrix transformMatrix = thisMeshPath.inclusiveMatrix(); - MIntArray intdexOffsetVertexCount, vertices, triangleList; - MPointArray dummy; - unsigned int vertexIndex; - MVector normal; - MPoint pos; - float2 UV; - double biTangent[3]; - double biNormal[3]; - MFloatVectorArray Tangents; - MFloatVectorArray biNormals; + map> vertexToIndex;; - MObjectArray shaderList; - MIntArray shaderIndexList; - mesh.getConnectedShaders(0, shaderList, shaderIndexList); + MIntArray intdexOffsetVertexCount, vertices, triangleList; + MPointArray dummy; + unsigned int vertexIndex; + MVector normal; + MPoint pos; + float2 UV; + double biTangent[3]; + double biNormal[3]; + MFloatVectorArray Tangents; + MFloatVectorArray biNormals; - map> materialFaceIDs; - MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length()); - MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length()); - MPlugArray plugArray; - for (int i = 0; i < shaderIndexList.length(); i++) - { - MFnDependencyNode shader(shaderList[shaderIndexList[i]]); - MPlug p_Plug = shader.findPlug("surfaceShader"); - if (p_Plug.connectedTo(plugArray, true, false)) { - MFnDependencyNode node = plugArray[0].node(); - materialFaceIDs[node.name().asChar()].push_back(i); - } - } - - map vertexWeights = GetWeightData(); + MObjectArray shaderList; + MIntArray shaderIndexList; + mesh.getConnectedShaders(0, shaderList, shaderIndexList); - mesh.getTangents(Tangents, MSpace::kObject, NULL); - mesh.getBinormals(biNormals, MSpace::kObject, NULL); - - MItMeshFaceVertex faceVert(object); - - int intDummy = 0; - - MItMeshPolygon meshPolyIter(object); - - for (auto aMaterial : materialFaceIDs) { - for (auto faceID : aMaterial.second) { - - vector> localVertexToGlobalIndex; - meshPolyIter.setIndex(faceID, intDummy); - - meshPolyIter.getVertices(vertices); - meshPolyIter.getTriangles(dummy, triangleList); - //MGlobal::displayInfo("Befor Second Loop"); - for (unsigned int i = 0; i < vertices.length(); i++) { - VertexLayout thisVertex; - vertexIndex = meshPolyIter.vertexIndex(i); - faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); - //MGlobal::displayInfo("In Second Loop"); - pos = faceVert.position(); - if (abs(pos.x) > 0.0001) - thisVertex.Pos[0] = pos.x; - if (abs(pos.y) > 0.0001) - thisVertex.Pos[1] = pos.y; - if (abs(pos.z) > 0.0001) - thisVertex.Pos[2] = pos.z; - - faceVert.getNormal(normal); - if (abs(normal[0]) > 0.0001) - thisVertex.Normal[0] = normal[0]; - if (abs(normal[1]) > 0.0001) - thisVertex.Normal[1] = normal[1]; - if (abs(normal[2]) > 0.0001) - thisVertex.Normal[2] = normal[2]; - - MFloatVector Tangent = Tangents[faceVert.tangentId()]; - //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); - //tmp.get(biTangent); - if (abs(Tangent[0]) > 0.0001) - thisVertex.Tangent[0] = Tangent[0]; - if (abs(Tangent[1]) > 0.0001) - thisVertex.Tangent[1] = Tangent[1]; - if (abs(Tangent[2]) > 0.0001) - thisVertex.Tangent[2] = Tangent[2]; - - MFloatVector biNormal = biNormals[faceVert.tangentId()]; - //faceVert.getBinormal().get(biNormal); - if (abs(biNormal[0]) > 0.0001) - thisVertex.BiNormal[0] = biNormal[0]; - if (abs(biNormal[1]) > 0.0001) - thisVertex.BiNormal[1] = biNormal[1]; - if (abs(biNormal[2]) > 0.0001) - thisVertex.BiNormal[2] = biNormal[2]; - - faceVert.getUV(UV); - thisVertex.Uv[0] = UV[0]; - thisVertex.Uv[1] = UV[1]; - - 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]; - - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[0]) > 0.0001) - thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[1]) > 0.0001) - thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[2]) > 0.0001) - thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[3]) > 0.0001) - thisVertex.BoneWeights[3] = vertexWeights[faceVert.vertId()].BoneWeights[3]; - - float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; - if (totalWeight < 1.00f && totalWeight > 0.01f) { - thisVertex.BoneWeights[0] /= totalWeight; - thisVertex.BoneWeights[1] /= totalWeight; - thisVertex.BoneWeights[2] /= totalWeight; - thisVertex.BoneWeights[3] /= totalWeight; + map> materialFaceIDs; + MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length()); + MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length()); + MPlugArray plugArray; + for (int i = 0; i < shaderIndexList.length(); i++) { + MFnDependencyNode shader(shaderList[shaderIndexList[i]]); + MPlug p_Plug = shader.findPlug("surfaceShader"); + if (p_Plug.connectedTo(plugArray, true, false)) { + MFnDependencyNode node = plugArray[0].node(); + materialFaceIDs[node.name().asChar()].push_back(i); } - - std::vector::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex); - array tmp; - if (it != vertexList.end()) { - tmp[0] = vertexIndex; - tmp[1] = it - vertexList.begin(); - localVertexToGlobalIndex.push_back(tmp); - } else { - tmp[0] = vertexIndex; - tmp[1] = vertexList.size(); - localVertexToGlobalIndex.push_back(tmp); - vertexList.push_back(thisVertex); - } - //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1]: " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][0] + " " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][1]); - //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 (unsigned int i = 0; i < triangleList.length(); i++) { - unsigned int k = 0; - if (localVertexToGlobalIndex.size() > 0) { - //MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); - while (localVertexToGlobalIndex[k][0] != triangleList[i] && k < localVertexToGlobalIndex.size()) { - k++; + + map vertexWeights = GetWeightData(); + + mesh.getTangents(Tangents, MSpace::kTransform, NULL); + mesh.getBinormals(biNormals, MSpace::kTransform, NULL); + + MItMeshFaceVertex faceVert(object[ObjectID]); + + int intDummy = 0; + + MItMeshPolygon meshPolyIter(object[ObjectID]); + MFloatPointArray positions; + + mesh.getPoints(positions); + + for (auto aMaterial : materialFaceIDs) { + for (auto faceID : aMaterial.second) { + + vector> localVertexToGlobalIndex; + meshPolyIter.setIndex(faceID, intDummy); + + meshPolyIter.getVertices(vertices); + meshPolyIter.getTriangles(dummy, triangleList); + //MGlobal::displayInfo("Befor Second Loop"); + for (unsigned int i = 0; i < vertices.length(); i++) { + VertexLayout thisVertex; + vertexIndex = meshPolyIter.vertexIndex(i); + faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); + //MGlobal::displayInfo("In Second Loop"); + //pos = faceVert.position(MSpace::kTransform); + //mesh.getPoint(vertexIndex, pos, MSpace::kPostTransform); + pos = positions[vertexIndex]; + pos = pos * transformMatrix; + if (abs(pos.x) > 0.0001) + thisVertex.Pos[0] = pos.x; + if (abs(pos.y) > 0.0001) + thisVertex.Pos[1] = pos.y; + if (abs(pos.z) > 0.0001) + thisVertex.Pos[2] = pos.z; + + faceVert.getNormal(normal, MSpace::kTransform); + if (abs(normal[0]) > 0.0001) + thisVertex.Normal[0] = normal[0]; + if (abs(normal[1]) > 0.0001) + thisVertex.Normal[1] = normal[1]; + if (abs(normal[2]) > 0.0001) + thisVertex.Normal[2] = normal[2]; + + MFloatVector Tangent = Tangents[faceVert.tangentId()]; + //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); + //tmp.get(biTangent); + if (abs(Tangent[0]) > 0.0001) + thisVertex.Tangent[0] = Tangent[0]; + if (abs(Tangent[1]) > 0.0001) + thisVertex.Tangent[1] = Tangent[1]; + if (abs(Tangent[2]) > 0.0001) + thisVertex.Tangent[2] = Tangent[2]; + + MFloatVector biNormal = biNormals[faceVert.tangentId()]; + //faceVert.getBinormal().get(biNormal); + if (abs(biNormal[0]) > 0.0001) + thisVertex.BiNormal[0] = biNormal[0]; + if (abs(biNormal[1]) > 0.0001) + thisVertex.BiNormal[1] = biNormal[1]; + if (abs(biNormal[2]) > 0.0001) + thisVertex.BiNormal[2] = biNormal[2]; + + faceVert.getUV(UV); + thisVertex.Uv[0] = UV[0]; + thisVertex.Uv[1] = UV[1]; + + 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]; + + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[0]) > 0.0001) + thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[1]) > 0.0001) + thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[2]) > 0.0001) + thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2]; + if (abs(vertexWeights[faceVert.vertId()].BoneWeights[3]) > 0.0001) + thisVertex.BoneWeights[3] = vertexWeights[faceVert.vertId()].BoneWeights[3]; + + float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; + if (totalWeight < 1.00f && totalWeight > 0.01f) { + thisVertex.BoneWeights[0] /= totalWeight; + thisVertex.BoneWeights[1] /= totalWeight; + thisVertex.BoneWeights[2] /= totalWeight; + thisVertex.BoneWeights[3] /= totalWeight; + } + + std::vector::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex); + array tmp; + if (it != vertexList.end()) { + tmp[0] = vertexIndex; + tmp[1] = it - vertexList.begin(); + localVertexToGlobalIndex.push_back(tmp); + } else { + tmp[0] = vertexIndex; + tmp[1] = vertexList.size(); + localVertexToGlobalIndex.push_back(tmp); + vertexList.push_back(thisVertex); + } + //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1]: " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][0] + " " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][1]); + //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 (unsigned int i = 0; i < triangleList.length(); i++) { + unsigned int k = 0; + if (localVertexToGlobalIndex.size() > 0) { + //MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); + while (localVertexToGlobalIndex[k][0] != triangleList[i] && k < localVertexToGlobalIndex.size()) { + k++; + } + //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k][0] + " " + localVertexToGlobalIndex[k][1]); + indexLists[aMaterial.first.c_str()].push_back(localVertexToGlobalIndex[k][1]); + } } - //MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k][0] + " " + localVertexToGlobalIndex[k][1]); - indexLists[aMaterial.first.c_str()].push_back(localVertexToGlobalIndex[k][1]); } + // MGlobal::displayInfo( MString() + "localVertexToGlobalIndex.size(): " + localVertexToGlobalIndex.size()); + // if (localVertexToGlobalIndex.size() > 0) { + // MGlobal::displayInfo(MString() + "triangleList.length(): " + triangleList.length()); + // for (unsigned int i = triangleList.length() - 1; i >= 0; i--) { + // MGlobal::displayInfo(MString() + "i: " + i); + // unsigned int k = localVertexToGlobalIndex.size() - 1; + // MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); + // while (localVertexToGlobalIndex[k] != triangleList[i] && k >= 0) { + // MGlobal::displayInfo(MString() + "k: " + k); + // k--; + // } + // MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k]); + // indexList.push_back(indexOffset + k); + // } + // } } } - // MGlobal::displayInfo( MString() + "localVertexToGlobalIndex.size(): " + localVertexToGlobalIndex.size()); - // if (localVertexToGlobalIndex.size() > 0) { - // MGlobal::displayInfo(MString() + "triangleList.length(): " + triangleList.length()); - // for (unsigned int i = triangleList.length() - 1; i >= 0; i--) { - // MGlobal::displayInfo(MString() + "i: " + i); - // unsigned int k = localVertexToGlobalIndex.size() - 1; - // MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]); - // while (localVertexToGlobalIndex[k] != triangleList[i] && k >= 0) { - // MGlobal::displayInfo(MString() + "k: " + k); - // k--; - // } - // MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k]); - // indexList.push_back(indexOffset + k); - // } - // } } - - int totalIndecies = 0; + int totalIndices = 0; for (auto aList : newMesh.Indices) { - totalIndecies += aList.second.size(); + totalIndices += aList.second.size(); } - - newMesh.NumIndices = totalIndecies; + newMesh.NumIndices = totalIndices; newMesh.NumVertices = newMesh.Vertices.size(); return newMesh; diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 15c16913..0538e83c 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -69,8 +69,9 @@ public: for (auto aVertex : Vertices) { aVertex.WriteBinary(out); } - for (auto aIndex : Indices) { - out.write((char*)aIndex.second.data(), sizeof(int) * aIndex.second.size()); + //for (auto aIndex : Indices) { + for (std::map>::reverse_iterator aIndex = Indices.rbegin(); aIndex != Indices.rend(); aIndex++){ + out.write((char*)(*aIndex).second.data(), sizeof(int) * (*aIndex).second.size()); } } @@ -101,7 +102,7 @@ class MeshClass { public: MeshClass(); - Mesh GetMeshData(MObject Object); + Mesh GetMeshData(MObjectArray Object); ~MeshClass(); private: struct WeightInfo { From e64358197190bc148ec0b63cb7d3b7de4063791a Mon Sep 17 00:00:00 2001 From: antc13 Date: Tue, 19 Jan 2016 18:21:27 +0100 Subject: [PATCH 18/80] Commit in order to pull from Master. --- resources/Shaders/ForwardPlus.frag.glsl | 3 +-- src/Engine/Rendering/DrawFinalPassState.cpp | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 4 +++- src/Engine/Rendering/Renderer.cpp | 8 ++++---- tools/MayaExporter/MayaExporter/Mesh.h | 7 ++++--- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 450d8929..b6d07ba2 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -113,7 +113,7 @@ void main() totalLighting.Specular += result.Specular; } - //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; + fragmentColor += (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1); //fragmentColor = texel * Input.DiffuseColor * Color; @@ -125,7 +125,6 @@ void main() } - fragmentColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); } diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index 5bafc294..1cb9d7da 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -7,7 +7,7 @@ DrawFinalPassState::DrawFinalPassState() Enable(GL_BLEND); BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Enable(GL_DEPTH_TEST); - Disable(GL_CULL_FACE); //Should be enabled, fix it johan and andreas. + Enable(GL_CULL_FACE); ClearColor(glm::vec4(200.f / 255, 0.f / 255, 200.f / 255, 0.f)); Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index a749e1fd..b7f2a2fd 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -148,7 +148,9 @@ void RawModel::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned throw Resource::FailedLoadingException("Reading Material texture path failed"); } - newMaterial.TexturePath = (fileData + offset); + newMaterial.TexturePath = "Textures/"; + newMaterial.TexturePath += (fileData + offset); + newMaterial.TexturePath += ".png"; offset += nameLengths[0]; } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index f86fea43..983b0736 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -101,10 +101,10 @@ void Renderer::Draw(RenderFrame& frame) m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras. FillDepth(*scene); - //m_PickingPass->Draw(*scene); - //m_LightCullingPass->GenerateNewFrustum(*scene); - //m_LightCullingPass->FillLightList(*scene); - //m_LightCullingPass->CullLights(*scene); + m_PickingPass->Draw(*scene); + m_LightCullingPass->GenerateNewFrustum(*scene); + m_LightCullingPass->FillLightList(*scene); + m_LightCullingPass->CullLights(*scene); m_DrawFinalPass->Draw(*scene); //m_DrawScenePass->Draw(rq); diff --git a/tools/MayaExporter/MayaExporter/Mesh.h b/tools/MayaExporter/MayaExporter/Mesh.h index 0538e83c..11f6bcf8 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.h +++ b/tools/MayaExporter/MayaExporter/Mesh.h @@ -69,9 +69,10 @@ public: for (auto aVertex : Vertices) { aVertex.WriteBinary(out); } - //for (auto aIndex : Indices) { - for (std::map>::reverse_iterator aIndex = Indices.rbegin(); aIndex != Indices.rend(); aIndex++){ - out.write((char*)(*aIndex).second.data(), sizeof(int) * (*aIndex).second.size()); + for (auto aIndex : Indices) { + //for (std::map>::reverse_iterator aIndex = Indices.rbegin(); aIndex != Indices.rend(); aIndex++){ + //out.write((char*)(*aIndex).second.data(), sizeof(int) * (*aIndex).second.size()); + out.write((char*)aIndex.second.data(), sizeof(int) * aIndex.second.size()); } } From 386e76f6422ad206be119af06c90b590f42bcc35 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 20 Jan 2016 09:49:54 +0100 Subject: [PATCH 19/80] Puyshing --- src/Engine/Editor/EditorSystem.cpp | 14 +++++++------- src/Engine/Network/Client.cpp | 2 +- src/Engine/Network/Server.cpp | 2 +- src/Engine/Rendering/RenderSystem.cpp | 4 ++-- src/Engine/Sound/SoundSystem.cpp | 2 +- src/Tests/CollisionTest.cpp | 10 +++++----- src/Tests/HealthSystemTest.cpp | 4 ++-- src/Tests/OctTreeTestGameClass.cpp | 2 +- src/Tests/OctTreeTestHardCodedTestWorld.h | 4 ++-- src/Tests/OldOctTree.cpp | 2 +- src/Tests/ResourceManagerTest.cpp | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 2790ebbb..624c4ad6 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -292,21 +292,21 @@ void EditorSystem::createWidget() m_WidgetPlaneX = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneX, "Transform"); m_World->AttachComponent(m_WidgetPlaneX, "Model"); - m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube"; + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneX m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); m_World->AttachComponent(m_WidgetY, "Model"); m_WidgetPlaneY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneY, "Transform"); m_World->AttachComponent(m_WidgetPlaneY, "Model"); - m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube"; + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneY m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); m_World->AttachComponent(m_WidgetZ, "Model"); m_WidgetPlaneZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneZ, "Transform"); m_World->AttachComponent(m_WidgetPlaneZ, "Model"); - m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube"; + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneZ m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); m_World->AttachComponent(m_WidgetOrigin, "Model"); @@ -351,7 +351,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false; if (newMode == WidgetMode::Translate) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; // 360NoScope TranslationWidgets mesh //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj"; //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj"; // Temporarily disabled for local space until I can figure out what's wrong with the math @@ -367,17 +367,17 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) } } } else if (newMode == WidgetMode::Scale) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; // 360NoScope ScaleWidgets mesh //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj"; //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj"; m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = true; - //m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; + //m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; // 360NoScope ScaleWidgetOrigin mesh if (m_Selection != EntityID_Invalid) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); widgetTransform["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(m_World, m_Selection)); } } else if (newMode == WidgetMode::Rotate) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; + //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; // 360NoScope RotationWidget mesh //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj"; //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj"; if (m_Selection != EntityID_Invalid) { diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index b8849ed0..efd25120 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -331,7 +331,7 @@ EntityID Client::createPlayer() EntityID entityID = m_World->CreateEntity(); ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; + model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere mesh ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); return entityID; } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 07fed65b..367f444b 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -349,7 +349,7 @@ EntityID Server::createPlayer() ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; + model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f); ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); return entityID; diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index d243afff..1b016f73 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -96,10 +96,10 @@ void RenderSystem::fillModels(std::list>& jobs, World model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; - model = ResourceManager::Load<::Model>("Models/coolCube"); + model = ResourceManager::Load<::Model>("Models/coolCube"); // 360NoScope StillLoading mesh } catch (const std::exception&) { try { - model = ResourceManager::Load<::Model>("Models/coolCube"); + model = ResourceManager::Load<::Model>("Models/coolCube"); // 360NoScope Error mesh } catch (const std::exception&) { continue; } diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 1292e0b1..2494581d 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; auto model = m_World->AttachComponent(emitterID, "Model"); - (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; + (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; // 360NoScope UnitCube source->Type = SoundType::SFX; m_Sources[emitterID] = source; playSound(source); diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 9f400330..4ba7ca87 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(collisionTest2) BOOST_AUTO_TEST_CASE(rayVsModelTest) { //simple box test - RayTest("Models/Core/UnitCube.obj"); + RayTest("Models/Core/UnitCube.obj"); // 360NoScope Unitcube } BOOST_AUTO_TEST_CASE(rayVsModelTest2) @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2) someAABB = AABB(minPos, maxPos); //using a rawmodel here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); - auto unitBox = ResourceManager::Load("Models/Core/UnitCube.obj"); + auto unitBox = ResourceManager::Load("Models/Core/UnitCube.obj"); // 360NoScope unitcube BOOST_CHECK(unitBox != nullptr); for (size_t i = 0; i < 1000000; i++) @@ -187,19 +187,19 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2) BOOST_AUTO_TEST_CASE(rayVsModelTest3) { //simple test - RayTest("Models/Core/UnitSphere.obj"); + RayTest("Models/Core/UnitSphere.obj"); // 360NoScope unitSphere } BOOST_AUTO_TEST_CASE(rayVsModelTest4) { //simple test - RayTest("Models/Core/UnitCylinder.obj"); + RayTest("Models/Core/UnitCylinder.obj"); // 360NoScope unitCylinder } BOOST_AUTO_TEST_CASE(rayVsModelTest5) { //simple test - RayTest("Models/Core/UnitRaptor.obj"); + RayTest("Models/Core/UnitRaptor.obj"); // 360NoScope unitRaptor } BOOST_AUTO_TEST_CASE(octTest) { diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index 84d6199d..7c3ad641 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -55,7 +55,7 @@ GameHealthSystemTest::GameHealthSystemTest() EntityID playerID = m_World->CreateEntity(); ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform"); ComponentWrapper model = m_World->AttachComponent(playerID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; + model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere ComponentWrapper player = m_World->AttachComponent(playerID, "Player"); ComponentWrapper health = m_World->AttachComponent(playerID, "Health"); healthsID = playerID; @@ -80,7 +80,7 @@ GameHealthSystemTest::GameHealthSystemTest() EntityID playerID2 = m_World->CreateEntity(); ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform"); ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model"); - model2["Resource"] = "Models/Core/UnitSphere.obj"; + model2["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //END TEST diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index 2c45d897..d03153e7 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -149,7 +149,7 @@ void Game::Tick() ComponentWrapper transform = m_World->AttachComponent(m_BoxID, "Transform"); transform["Scale"] = boxSize; ComponentWrapper model = m_World->AttachComponent(m_BoxID, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox m_World->createTestEntitiesTest2(); } diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index db0b3b3c..89c3c3f3 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -112,7 +112,7 @@ private: ComponentWrapper transform = world.AttachComponent(entityCollisionBox, "Transform"); transform["Position"] = glm::vec3(0.f, 2.f, 0.f); ComponentWrapper model = world.AttachComponent(entityCollisionBox, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox } void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, Octree::Child* child, EntityID &outEntityId) { @@ -124,7 +124,7 @@ private: transform["Position"] = center; transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f; ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope unitBox model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); if (child->m_DynamicObjIndices.size() != 0) model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/Tests/OldOctTree.cpp b/src/Tests/OldOctTree.cpp index 0fb92e18..a94bf465 100644 --- a/src/Tests/OldOctTree.cpp +++ b/src/Tests/OldOctTree.cpp @@ -112,7 +112,7 @@ void OctTree::Update(float dt, World* world, Camera* cam) ComponentWrapper transform = world->AttachComponent(m_BoxID, "Transform"); transform["Scale"] = boxSize; ComponentWrapper model = world->AttachComponent(m_BoxID, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; + model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox m_UpdatedOnce = true; } diff --git a/src/Tests/ResourceManagerTest.cpp b/src/Tests/ResourceManagerTest.cpp index 9d62fa93..f83c6c9f 100644 --- a/src/Tests/ResourceManagerTest.cpp +++ b/src/Tests/ResourceManagerTest.cpp @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(resourceManagerTest) //configfile without register //check so output says "EE failed to load: type not registered..." - auto m_ScreenQuadNoRegister = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + auto m_ScreenQuadNoRegister = ResourceManager::Load("Models/Core/ScreenQuad.obj"); // 360NoScope ScreenQuad BOOST_CHECK(!ResourceManager::IsResourceLoaded("Model", "Models/Core/ScreenQuad.obj")); //there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either From 84b7cf165c449d9ec48d8882c519545a42112bd2 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 20 Jan 2016 11:46:32 +0100 Subject: [PATCH 20/80] Reduced the chance of crashing in Export. --- tools/MayaExporter/MayaExporter/Mesh.cpp | 154 ++++++++++++++++++----- 1 file changed, 125 insertions(+), 29 deletions(-) diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 0f99533c..2062bad5 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -10,22 +10,43 @@ MeshClass::MeshClass() std::map MeshClass::GetWeightData() { + MS status; map weightMap; MItDependencyNodes it(MFn::kSkinClusterFilter); while (!it.isDone()) { - MObject object = it.item(); - MFnSkinCluster skinCluster(object); + MObject object = it.thisNode(&status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " it.thisNode() ERROR: " + status.errorString()); + break; + } + MFnSkinCluster skinCluster(object, &status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "skinCluster() ERROR: " + status.errorString()); + break; + } MDagPathArray influences; - unsigned int nrOfInfluences = skinCluster.influenceObjects(influences); + unsigned int nrOfInfluences = skinCluster.influenceObjects(influences,&status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "skinCluster.influenceObjects() ERROR: " + status.errorString()); + break; + } unsigned int index; - index = skinCluster.indexForOutputConnection(0); + index = skinCluster.indexForOutputConnection(0,&status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "skinCluster.indexForOutputConnection() ERROR: " + status.errorString()); + break; + } MDagPath skinPath; - skinCluster.getPathAtIndex(index, skinPath); + status = skinCluster.getPathAtIndex(index, skinPath); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "skinCluster.getPathAtIndex() ERROR: " + status.errorString()); + break; + } MItGeometry geomIter(skinPath); //for (unsigned int i = 0; i < nrOfInfluences; i++) { @@ -34,10 +55,18 @@ std::map MeshClass::GetWeightData() WeightInfo weightInfo; while (!geomIter.isDone()) { - MObject comp = geomIter.component(); + MObject comp = geomIter.component(&status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "geomIter.component() ERROR: " + status.errorString()); + break; + } MFloatArray weights; unsigned int influenceCount; - skinCluster.getWeights(skinPath, comp, weights, influenceCount); + status = skinCluster.getWeights(skinPath, comp, weights, influenceCount); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "skinCluster.getWeights() ERROR: " + status.errorString()); + break; + } MFnDependencyNode test(comp); unsigned int nrOfWeights = 0; @@ -64,10 +93,7 @@ std::map MeshClass::GetWeightData() //MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]); } geomIter.next(); - - } - it.next(); } return weightMap; @@ -75,6 +101,7 @@ std::map MeshClass::GetWeightData() Mesh MeshClass::GetMeshData(MObjectArray object) { + MS status; Mesh newMesh; vector& vertexList = newMesh.Vertices; map>& indexLists = newMesh.Indices; @@ -85,11 +112,21 @@ Mesh MeshClass::GetMeshData(MObjectArray object) // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object[ObjectID]); MDagPathArray dagPaths; - MDagPath::getAllPathsTo(object[ObjectID], dagPaths); + status = MDagPath::getAllPathsTo(object[ObjectID], dagPaths); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "MDagPath::getAllPathsTo() ERROR: " + status.errorString()); + break; + } + for (int pathID = 0; pathID < dagPaths.length(); pathID++) { MGlobal::displayInfo(dagPaths[pathID].fullPathName()); MDagPath thisMeshPath(dagPaths[pathID]); - MMatrix transformMatrix = thisMeshPath.inclusiveMatrix(); + + MMatrix transformMatrix = thisMeshPath.inclusiveMatrix(&status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "thisMeshPath.inclusiveMatrix() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + break; + } map> vertexToIndex;; @@ -106,28 +143,57 @@ Mesh MeshClass::GetMeshData(MObjectArray object) MObjectArray shaderList; MIntArray shaderIndexList; - mesh.getConnectedShaders(0, shaderList, shaderIndexList); + status = mesh.getConnectedShaders(0, shaderList, shaderIndexList); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "mesh.getConnectedShaders() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + break; + } + if (shaderList.length() == 0) { + MGlobal::displayError(MString() + "Object: \"" + thisMeshPath.fullPathName() + "\" have no material and will not be exported"); + break; + } map> materialFaceIDs; MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length()); MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length()); MPlugArray plugArray; for (int i = 0; i < shaderIndexList.length(); i++) { MFnDependencyNode shader(shaderList[shaderIndexList[i]]); - MPlug p_Plug = shader.findPlug("surfaceShader"); - if (p_Plug.connectedTo(plugArray, true, false)) { + MPlug p_Plug = shader.findPlug("surfaceShader", status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "shader.findPlug(\"surfaceShader\") ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + continue; + } + if (p_Plug.connectedTo(plugArray, true, false, &status)) { + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "p_Plug.connectedTo() ERROR in if: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + continue; + } MFnDependencyNode node = plugArray[0].node(); materialFaceIDs[node.name().asChar()].push_back(i); } + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "p_Plug.connectedTo() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + continue; + } } map vertexWeights = GetWeightData(); - - mesh.getTangents(Tangents, MSpace::kTransform, NULL); - mesh.getBinormals(biNormals, MSpace::kTransform, NULL); - + status = mesh.getTangents(Tangents, MSpace::kObject); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "mesh.getTangents ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + continue; + } + status = mesh.getBinormals(biNormals, MSpace::kObject); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "mesh.getBinormals ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); + continue; + } + if(Tangents.length() == 0 || biNormals.length() == 0){ + MGlobal::displayError(MString() + "Unknown ERROR with " + thisMeshPath.fullPathName()); + continue; + } MItMeshFaceVertex faceVert(object[ObjectID]); - int intDummy = 0; MItMeshPolygon meshPolyIter(object[ObjectID]); @@ -137,17 +203,40 @@ Mesh MeshClass::GetMeshData(MObjectArray object) for (auto aMaterial : materialFaceIDs) { for (auto faceID : aMaterial.second) { - vector> localVertexToGlobalIndex; - meshPolyIter.setIndex(faceID, intDummy); - meshPolyIter.getVertices(vertices); - meshPolyIter.getTriangles(dummy, triangleList); + status = meshPolyIter.setIndex(faceID, intDummy); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " meshPolyIter.setIndex() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } + + status = meshPolyIter.getVertices(vertices); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " meshPolyIter.getVertices() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } + + status = meshPolyIter.getTriangles(dummy, triangleList); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " meshPolyIter.getTriangles() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } //MGlobal::displayInfo("Befor Second Loop"); for (unsigned int i = 0; i < vertices.length(); i++) { VertexLayout thisVertex; - vertexIndex = meshPolyIter.vertexIndex(i); - faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); + + vertexIndex = meshPolyIter.vertexIndex(i, &status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " meshPolyIter.vertexIndex() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } + + status = faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "faceVert.setIndex() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } //MGlobal::displayInfo("In Second Loop"); //pos = faceVert.position(MSpace::kTransform); //mesh.getPoint(vertexIndex, pos, MSpace::kPostTransform); @@ -160,7 +249,11 @@ Mesh MeshClass::GetMeshData(MObjectArray object) if (abs(pos.z) > 0.0001) thisVertex.Pos[2] = pos.z; - faceVert.getNormal(normal, MSpace::kTransform); + status = faceVert.getNormal(normal, MSpace::kObject); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "faceVert.getNormal() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } if (abs(normal[0]) > 0.0001) thisVertex.Normal[0] = normal[0]; if (abs(normal[1]) > 0.0001) @@ -187,7 +280,11 @@ Mesh MeshClass::GetMeshData(MObjectArray object) if (abs(biNormal[2]) > 0.0001) thisVertex.BiNormal[2] = biNormal[2]; - faceVert.getUV(UV); + status = faceVert.getUV(UV); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); + break; + } thisVertex.Uv[0] = UV[0]; thisVertex.Uv[1] = UV[1]; @@ -195,7 +292,6 @@ Mesh MeshClass::GetMeshData(MObjectArray object) thisVertex.BoneIndices[1] = vertexWeights[faceVert.vertId()].BoneIndices[1]; thisVertex.BoneIndices[2] = vertexWeights[faceVert.vertId()].BoneIndices[2]; thisVertex.BoneIndices[3] = vertexWeights[faceVert.vertId()].BoneIndices[3]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[0]) > 0.0001) thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; if (abs(vertexWeights[faceVert.vertId()].BoneWeights[1]) > 0.0001) From c984f76b2fea45d0e7b67fd3eb44a75df3fcdb55 Mon Sep 17 00:00:00 2001 From: antc13 Date: Wed, 20 Jan 2016 18:36:03 +0100 Subject: [PATCH 21/80] Importing & Reading Custom animation data. TODO: Shaders. --- include/Engine/Rendering/RawModelCustom.h | 9 +- include/Engine/Rendering/Skeleton.h | 2 +- resources/Schema/Entities/Model.xml | 2 +- src/Engine/Editor/EditorSystem.cpp | 6 +- src/Engine/Rendering/RawModelCustom.cpp | 180 ++++++++++++++++++- src/Engine/Rendering/RenderSystem.cpp | 4 +- tools/MayaExporter/MayaExporter/Export.cpp | 13 +- tools/MayaExporter/MayaExporter/Skeleton.cpp | 9 +- tools/MayaExporter/MayaExporter/Skeleton.h | 44 +++-- 9 files changed, 230 insertions(+), 39 deletions(-) diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index bc85e32c..a3c29f62 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -22,7 +22,7 @@ class RawModel : public Resource friend class ResourceManager; protected: - RawModel(std::string& fileName); + RawModel(std::string fileName); public: ~RawModel(); @@ -74,6 +74,13 @@ private: void ReadMaterialFile(std::string filePath); void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize); void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + + void ReadAnimationFile(std::string filePath); + void ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize); + void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips); + void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex); + void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation); //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 73d407dd..4a4d507b 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -38,9 +38,9 @@ public: , OffsetMatrix(offsetMatrix) { } - int ID; std::string Name; glm::mat4 OffsetMatrix; + int ID; Bone* Parent; std::vector Children; diff --git a/resources/Schema/Entities/Model.xml b/resources/Schema/Entities/Model.xml index 8962d7e1..6534815c 100644 --- a/resources/Schema/Entities/Model.xml +++ b/resources/Schema/Entities/Model.xml @@ -19,7 +19,7 @@ - models/Baljj + models/Baljj.mesh diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 624c4ad6..547a96e1 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -292,21 +292,21 @@ void EditorSystem::createWidget() m_WidgetPlaneX = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneX, "Transform"); m_World->AttachComponent(m_WidgetPlaneX, "Model"); - m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneX + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneX m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); m_World->AttachComponent(m_WidgetY, "Model"); m_WidgetPlaneY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneY, "Transform"); m_World->AttachComponent(m_WidgetPlaneY, "Model"); - m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneY + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneY m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); m_World->AttachComponent(m_WidgetZ, "Model"); m_WidgetPlaneZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneZ, "Transform"); m_World->AttachComponent(m_WidgetPlaneZ, "Model"); - m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube"; // 360NoScope widgetPlaneZ + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneZ m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); m_World->AttachComponent(m_WidgetOrigin, "Model"); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index b7f2a2fd..f7354d92 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -1,9 +1,12 @@ #include "Rendering/RawModelCustom.h" -RawModel::RawModel(std::string& fileName) +RawModel::RawModel(std::string fileName) { + fileName = fileName.erase(fileName.find_last_of("."), fileName.find_last_of(".") - fileName.size()); ReadMeshFile(fileName); ReadMaterialFile(fileName); + ReadAnimationFile(fileName); + int k = 0; } void RawModel::ReadMeshFile(std::string filePath) @@ -53,8 +56,7 @@ void RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { throw Resource::FailedLoadingException("Reading vertices failed"); } - unsigned int i = sizeof(Vertex); - unsigned int ii = sizeof(unsigned int); + memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex)); offset += m_Vertices.size() * sizeof(Vertex); #else @@ -187,6 +189,178 @@ void RawModel::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned MaterialGroups.push_back(newMaterial); } +void RawModel::ReadAnimationFile(std::string filePath) +{ + char* fileData; + filePath += ".anim"; + std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate); + + if (!in.is_open()) { + //throw Resource::FailedLoadingException("Open animation file failed"); + return; // AJABAJA!!!!!!!! + } + + unsigned int fileByteSize = in.tellg(); + in.seekg(0, std::ios_base::beg); + + fileData = new char[fileByteSize]; + in.read(fileData, fileByteSize); + in.close(); + + unsigned int offset = 0; + if (fileByteSize > 0) { + m_Skeleton = new Skeleton(); + +#ifdef BOOST_LITTLE_ENDIAN + unsigned int numBindPoses = *(unsigned int*)(fileData); + offset += sizeof(unsigned int); + unsigned int numAnimations = *(unsigned int*)(fileData); + offset += sizeof(unsigned int); +#else +#endif + + ReadAnimationBindPoses(offset, fileData, fileByteSize); + ReadAnimationClips(offset, fileData, fileByteSize, numAnimations); + } + delete fileData; +} + +void RawModel::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + unsigned int* numBones = (unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + for (unsigned int i = 0; i < *numBones; i++) { + ReadAnimationJoint(offset, fileData, fileByteSize); + } +#else +#endif +} + +void RawModel::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +{ +#ifdef BOOST_LITTLE_ENDIAN + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading Joint name length failed"); + } + unsigned int jointNameLength = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (offset + jointNameLength > fileByteSize) { + throw Resource::FailedLoadingException("Reading Joint name failed"); + } + std::string jointName = (fileData + offset); + offset += jointNameLength; + + if (offset + sizeof(float) * 4 * 4 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Joint offset matrix failed"); + } + glm::mat4 offsetMatrix; + memcpy(&offsetMatrix, fileData + offset, sizeof(float) * 4 * 4); + offset += sizeof(float) * 4 * 4; + + if (offset + sizeof(int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading Joint ID failed"); + } + int jointID = *(int*)(fileData + offset); + offset += sizeof(int); + + if (offset + sizeof(int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading Joint Parent ID failed"); + } + int jointParentID = *(int*)(fileData + offset); + offset += sizeof(int); + + // Adding joint to the Skeleton + m_Skeleton->CreateBone(jointID, jointParentID, jointName, offsetMatrix); + + +#else +#endif +} + +void RawModel::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips) +{ + for (unsigned int i = 0; i < numberOfClips; i++) { + ReadAnimationClipSingle(offset, fileData, fileByteSize, i); + } +} + +void RawModel::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex) +{ +#ifdef BOOST_LITTLE_ENDIAN + Skeleton::Animation newAnimation; + + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip name length failed"); + } + unsigned int clipNameLength = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (offset + clipNameLength > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip name failed"); + } + newAnimation.Name = (fileData + offset); + offset += clipNameLength; + + if (offset + sizeof(float) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip duration failed"); + } + + newAnimation.Duration = *(float*)(fileData + offset); + offset += sizeof(float); + + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip NrOfKeyframes failed"); + } + unsigned int nrOfKeyframes = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + if (offset + sizeof(unsigned int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationClip NrOfJoints failed"); + } + unsigned int nrOfJoints = *(unsigned int*)(fileData + offset); + offset += sizeof(unsigned int); + + newAnimation.Keyframes.reserve(nrOfKeyframes); + for (unsigned int i = 0; i < nrOfKeyframes; i++) { + ReadAnimationKeyFrame(offset, fileData, fileByteSize, nrOfJoints, newAnimation); + } + m_Skeleton->Animations[newAnimation.Name] = newAnimation; +#else +#endif +} + +void RawModel::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation) +{ + Skeleton::Animation::Keyframe newKeyFrame; + + if (offset + sizeof(int) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame index failed"); + } + newKeyFrame.Index = *(int*)(fileData + offset); + offset += sizeof(int); + + if (offset + sizeof(float) > fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame time failed"); + } + newKeyFrame.Time = *(float*)(fileData + offset); + offset += sizeof(float); + + if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) { + throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed"); + } + + Skeleton::Animation::Keyframe::BoneProperty newBone; + for (unsigned int i = 0; i < nrOfJoints; i++) { + memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); + offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty); + newKeyFrame.BoneProperties[i] = newBone; + } + animation.Keyframes.push_back(newKeyFrame); +} + RawModel::~RawModel() { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 1b016f73..2a6a49c2 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -96,10 +96,10 @@ void RenderSystem::fillModels(std::list>& jobs, World model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; - model = ResourceManager::Load<::Model>("Models/coolCube"); // 360NoScope StillLoading mesh + model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope StillLoading mesh } catch (const std::exception&) { try { - model = ResourceManager::Load<::Model>("Models/coolCube"); // 360NoScope Error mesh + model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope Error mesh } catch (const std::exception&) { continue; } diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index 1db753d7..d25faa4c 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -11,7 +11,9 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file"); return false; } - + MSelectionList selectedOnStart; + MGlobal::getActiveSelectionList(selectedOnStart); + MObjectArray Objects; if (selectedOnly) { // Retrieving the objects we currently have selected @@ -36,18 +38,14 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) MFnDependencyNode thisNode(node); MPlugArray connections; 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; + MGlobal::select(node); + MGlobal::executeCommand("gotoBindPose"); } } - if (next) - continue; - Objects.append(node); } } @@ -139,6 +137,7 @@ void Export::WriteAnimData(std::string pathName) int size = allBindPoses.size(); m_AnimFile.writeToFiles(&size); + size = allAnimations.size(); m_AnimFile.writeToFiles(&size); diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 0497aa31..9f887561 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -70,6 +70,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e Animation returnData; double oneDivSixty = 1 / 60.0; returnData.Name = animationName; + returnData.nameLength = animationName.size() + 1; returnData.Duration = (endFrame - startFrame) * oneDivSixty; MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); @@ -132,7 +133,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e } int currentFrame = startFrame; - while (currentFrame != endFrame) { + while (currentFrame != endFrame + 1) { // ANDREAS Animation::Keyframe thisKeyFrame; thisKeyFrame.Index = currentFrame - startFrame; thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty; @@ -188,7 +189,6 @@ std::vector Skeleton::GetBindPoses() MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint); BindPoseSkeletonNode SkeletonStorage; - while (!jointIt.isDone()) { MFnTransform MayaJoint(jointIt.currentItem()); BindPoseSkeletonNode::BindPoseJoint NewJoint; @@ -227,7 +227,8 @@ std::vector Skeleton::GetBindPoses() } NewJoint.Name = MayaJoint.name().asChar(); - + NewJoint.NameLength = MayaJoint.name().length() + 1; + NewJoint.ID = SkeletonStorage.Joints.size(); //double tmp[3]; //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp); //NewJoint.Rotation[0] = tmp[0]; @@ -242,9 +243,9 @@ std::vector Skeleton::GetBindPoses() //NewJoint.Translation[1] = tmp[1]; //NewJoint.Translation[2] = tmp[2]; SkeletonStorage.Joints.push_back(NewJoint); + SkeletonStorage.numBones++; jointIt.next(); } - m_AllSkeletons.push_back(SkeletonStorage); return m_AllSkeletons; diff --git a/tools/MayaExporter/MayaExporter/Skeleton.h b/tools/MayaExporter/MayaExporter/Skeleton.h index dda0cfea..6a288c8a 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.h +++ b/tools/MayaExporter/MayaExporter/Skeleton.h @@ -13,32 +13,35 @@ public: { struct JointProperty { - int ID; - float Position[3]; - float Rotation[4]; - float Scale[3]; + int ID = 0; + float Position[3]{ 0 }; + float Rotation[4]{ 0 }; + float Scale[3]{ 0 }; }; - int Index; - double Time; + int Index = 0; + float Time = 0; std::vector JointProperties; }; std::string Name; - double Duration; - int NumKeyFrames; - int NumberOfJoints; + int nameLength = 0; + float Duration = 0; + int NumKeyFrames = 0; + int NumberOfJoints = 0; std::vector Keyframes; virtual void WriteBinary(std::ostream& out) { + out.write((char*)&nameLength, sizeof(int)); out.write(Name.c_str(), Name.size() + 1); - out.write((char*)&Duration, sizeof(double)); + out.write((char*)&Duration, sizeof(float)); out.write((char*)&NumKeyFrames, sizeof(int)); out.write((char*)&NumberOfJoints, sizeof(int)); + //Här under loopas alla key frames igenom for (auto aKeyframe : Keyframes) { out.write((char*)&aKeyframe.Index, sizeof(int)); - out.write((char*)&aKeyframe.Time, sizeof(double)); + out.write((char*)&aKeyframe.Time, sizeof(float)); for (auto aJoint : aKeyframe.JointProperties) { out.write((char*)&aJoint.ID, sizeof(int)); out.write((char*)aJoint.Position, sizeof(float) * 3); @@ -72,20 +75,24 @@ class BindPoseSkeletonNode : public OutputData { public: struct BindPoseJoint { - int ParentID; + int NameLength; std::string Name; - float OffsetMatrix[4][4]; + float OffsetMatrix[4][4]{ 0 }; + int ID = 0; + int ParentID = 0; }; - + int numBones = 0; std::string Name; std::vector Joints; virtual void WriteBinary(std::ostream& out) { - out.write(Name.c_str(), Name.size() + 1); + out.write((char*)&numBones, sizeof(int)); for (auto Joint:Joints) { + out.write((char*)&Joint.NameLength, sizeof(int)); out.write(Joint.Name.c_str(), Joint.Name.size() + 1); out.write((char*)&Joint.OffsetMatrix, sizeof(float) * 4 * 4); + out.write((char*)&Joint.ID, sizeof(int)); out.write((char*)&Joint.ParentID, sizeof(int)); } @@ -93,16 +100,19 @@ public: virtual void WriteASCII(std::ostream& out) const { - out << "Bind Pose: " << Name << endl; + out << "Bind Pose: " << Name << " _ not in binary" << endl; + out << "numberOfBones: " << numBones << endl; for (auto Joint : Joints) { - out << Joint.Name << endl; + out << "Joint NameLength " << Joint.NameLength << endl; + out << "Joint name " << 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.ID << endl; out << Joint.ParentID << endl; } }; From 1e3fc1ae2d276838c19fafc1780163b83343d429 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 10:16:35 +0100 Subject: [PATCH 22/80] Created EPlayerSpawned that gets published when a player spawns --- include/Game/Events/EPlayerSpawned.h | 19 +++++++++++++++++++ include/Game/Systems/PlayerSpawnSystem.h | 9 ++++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 18 ++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 include/Game/Events/EPlayerSpawned.h diff --git a/include/Game/Events/EPlayerSpawned.h b/include/Game/Events/EPlayerSpawned.h new file mode 100644 index 00000000..a5700ed3 --- /dev/null +++ b/include/Game/Events/EPlayerSpawned.h @@ -0,0 +1,19 @@ +#ifndef EPlayerSpawned_h__ +#define EPlayerSpawned_h__ + +#include "Core/Event.h" +#include "Core/EntityWrapper.h" + +namespace Events +{ + +struct PlayerSpawned : Event +{ + int PlayerID; + EntityWrapper Player; + EntityWrapper Spawner; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 8ade03a6..69014f65 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -2,6 +2,7 @@ #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" +#include "Events/EPlayerSpawned.h" class PlayerSpawnSystem : public ImpureSystem { @@ -11,8 +12,14 @@ public: virtual void Update(double dt) override; private: + struct SpawnRequest + { + int PlayerID; + ComponentInfo::EnumType Team; + }; + EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); - std::vector m_SpawnRequests; + std::vector m_SpawnRequests; }; \ No newline at end of file diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 4224d46c..11be0486 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -13,7 +13,7 @@ void PlayerSpawnSystem::Update(double dt) return; } - for (auto& team : m_SpawnRequests) { + for (auto& req : m_SpawnRequests) { for (auto& cPlayerSpawn : *playerSpawns) { EntityWrapper spawner(m_World, cPlayerSpawn.EntityID); if (!spawner.HasComponent("Spawner")) { @@ -22,7 +22,7 @@ void PlayerSpawnSystem::Update(double dt) // If the spawner has a team affiliation, check it if (spawner.HasComponent("Team")) { - if ((int)spawner["Team"]["Team"] != team) { + if ((int)spawner["Team"]["Team"] != req.Team) { continue; } } @@ -30,7 +30,14 @@ void PlayerSpawnSystem::Update(double dt) // Spawn the player! EntityWrapper player = SpawnerSystem::Spawn(spawner); // Set the player team affiliation - player["Team"]["Team"] = team; + player["Team"]["Team"] = req.Team; + + // Publish a PlayerSpawned event + Events::PlayerSpawned e; + e.PlayerID = req.PlayerID; + e.Player = player; + e.Spawner = spawner; + m_EventBroker->Publish(e); } } m_SpawnRequests.clear(); @@ -43,7 +50,10 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) } if (e.Value != 0) { - m_SpawnRequests.push_back((int)e.Value); + SpawnRequest req; + req.PlayerID = e.PlayerID; + req.Team = (ComponentInfo::EnumType)e.Value; + m_SpawnRequests.push_back(req); } return true; From 6cd073c3c8bee442df6a4b6e273d77a2d7f7f43e Mon Sep 17 00:00:00 2001 From: Jocke Date: Fri, 22 Jan 2016 10:32:54 +0100 Subject: [PATCH 23/80] Added network metrics logging and reactored code. --- include/Engine/Network/Client.h | 6 +-- include/Engine/Network/MessageType.h | 3 +- include/Engine/Network/Network.h | 13 ++++++ include/Engine/Network/NetworkData.h | 18 ++++++++ include/Engine/Network/Packet.h | 2 + include/Engine/Network/Server.h | 4 +- src/Engine/Network/Client.cpp | 57 +++++++++++++++----------- src/Engine/Network/Network.cpp | 61 ++++++++++++++++++++++++++++ src/Engine/Network/Packet.cpp | 1 + src/Engine/Network/Server.cpp | 56 ++++++++++++++++++------- 10 files changed, 176 insertions(+), 45 deletions(-) create mode 100644 include/Engine/Network/NetworkData.h create mode 100644 src/Engine/Network/Network.cpp diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 96511baa..38db1e9b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -61,21 +61,21 @@ private: SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; + std::clock_t m_TimeSinceSentInputs; + unsigned int m_SendInputIntervalMs = 33; std::vector m_InputCommandBuffer; // Private member functions void readFromServer(); - int receive(char* data, size_t length); + int receive(char* data); void send(Packet& packet); void connect(); void disconnect(); - void ping(); void parseMessageType(Packet& packet); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); - void parseServerPing(); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index f0026190..8468f2fc 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -7,8 +7,7 @@ enum class MessageType { Connect, Disconnect, - ClientPing, - ServerPing, + Ping, Message, Snapshot, OnInputCommand, diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 1464a96f..7166eec6 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -1,9 +1,14 @@ #ifndef Network_h__ #define Network_h__ +#include + #include "Core/World.h" #include "Core/EventBroker.h" #include "Network/Packet.h" +#include "Network/NetworkData.h" +#include +#include #define MAXCONNECTIONS 8 #define INPUTSIZE 4097 @@ -15,6 +20,14 @@ public: virtual ~Network() { }; virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Update() = 0; +protected: + // For Debug + bool isReadingData = false; + NetworkData m_NetworkData; + unsigned int m_SaveDataIntervalMs = 1000; + std::clock_t m_SaveDataTimer; + void saveToFile(); + void updateNetworkData(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/NetworkData.h b/include/Engine/Network/NetworkData.h new file mode 100644 index 00000000..87f7a215 --- /dev/null +++ b/include/Engine/Network/NetworkData.h @@ -0,0 +1,18 @@ +#ifndef NetworkData_h__ +#define NetworkData_h__ +#include + +struct NetworkData { + unsigned int TotalTime = 0; + unsigned int TotalDataReceived = 0; + unsigned int TotalDataSent = 0; + unsigned int AmountOfMessagesReceived = 0; + unsigned int AmountOfMessagesSent = 0; + // Interval based + unsigned int DataReceivedThisInterval = 0; + unsigned int DataSentThisInterval = 0; + // pair: first=reveived, second=send + std::vector> BandwidthBytes; +}; + +#endif diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index 2891bf87..d38ddf58 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -55,12 +55,14 @@ public: char* Data() { return m_Data; }; unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int MaxSize() { return m_MaxPacketSize; } + unsigned int HeaderSize() { return m_HeaderSize; } private: char* m_Data; unsigned int m_ReturnDataOffset = 0; int m_Offset = 0; unsigned int m_MaxPacketSize = 512; + unsigned int m_HeaderSize = 0; void resizeData(); }; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 8aabceba..c4f1bf16 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -54,7 +54,7 @@ private: unsigned int m_PreviousPacketID = 0; // Private member functions - int receive(char* data, size_t length); + int receive(char* data); void readFromClients(); void send(Packet& packet, int playerID); void send(Packet& packet); @@ -69,7 +69,7 @@ private: void parseConnect(Packet& packet); void parseDisconnect(); void parseClientPing(); - void parseServerPing(); + void parsePing(); void identifyPacketLoss(); void createPlayer(); int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 8eee335e..644b719b 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -7,6 +7,8 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) { // Asumes root node is EntityID 0 insertIntoServerClientMaps(0, 0); + // Init timer + m_TimeSinceSentInputs = std::clock(); // Default is local host std::string address = config->Get("Networking.Address", "127.0.0.1"); int port = config->Get("Networking.Port", 13); @@ -37,19 +39,24 @@ void Client::Update() readFromServer(); if (m_IsConnected) { hasServerTimedOut(); + // Don't sent 1 input in 1 packet, bunch em up. + if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) { + sendInputCommands(); + m_TimeSinceSentInputs = std::clock(); + } } + Network::Update(); } void Client::readFromServer() { while (m_Socket.available()) { - bytesRead = receive(readBuf, INPUTSIZE); + bytesRead = receive(readBuf); if (bytesRead > 0) { Packet packet(readBuf, bytesRead); parseMessageType(packet); } } - sendInputCommands(); } void Client::parseMessageType(Packet& packet) @@ -66,12 +73,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::Connect: parseConnect(packet); break; - case MessageType::ClientPing: + case MessageType::Ping: parsePing(); break; - case MessageType::ServerPing: - parseServerPing(); - break; case MessageType::Message: break; case MessageType::Snapshot: @@ -99,11 +103,6 @@ void Client::parsePlayerConnected(Packet & packet) } void Client::parsePing() -{ - -} - -void Client::parseServerPing() { // Might miss connect message so set it here instead. m_IsConnected = true; @@ -112,7 +111,7 @@ void Client::parseServerPing() LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); m_StartPingTime = std::clock(); - Packet packet(MessageType::ServerPing, m_SendPacketID); + Packet packet(MessageType::Ping, m_SendPacketID); packet.WriteString("Ping recieved"); send(packet); } @@ -211,15 +210,20 @@ void Client::parseSnapshot(Packet& packet) } } -int Client::receive(char* data, size_t length) +int Client::receive(char* data) { boost::system::error_code error; int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, length), + ::asio::buffer((void*)data, INPUTSIZE), m_ReceiverEndpoint, 0, error); - + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; + m_NetworkData.AmountOfMessagesReceived++; + } if (error) { //LOG_ERROR("receive: %s", error.message().c_str()); } @@ -232,6 +236,12 @@ void Client::send(Packet& packet) packet.Data(), packet.Size()), m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } } void Client::connect() @@ -250,14 +260,6 @@ void Client::disconnect() send(packet); } -void Client::ping() -{ - //Packet packet(MessageType::Connect, m_SendPacketID); - //packet.WriteString("Ping"); - //m_StartPingTime = std::clock(); - //send(packet); -} - bool Client::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "ConnectToServer") { // Connect for now @@ -275,6 +277,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e) if (e.Value > 0) { becomePlayer(); } + } else if (e.Command == "LogNetworkBandwidth") { + if (e.Value > 0) { + // Save to file if we no longer want to read data. + if (isReadingData) { + saveToFile(); + } + isReadingData = !isReadingData; + m_SaveDataTimer = std::clock(); + } } else { m_InputCommandBuffer.push_back(e); //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp new file mode 100644 index 00000000..c9ed3637 --- /dev/null +++ b/src/Engine/Network/Network.cpp @@ -0,0 +1,61 @@ +#include "Network/Network.h" + +void Network::Update() +{ + updateNetworkData(); +} + +void Network::saveToFile() +{ + std::ofstream outfile; + time_t t = time(0); + // get time now + struct tm * now = localtime(&t); + // Get current time and date + std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-' + + std::to_string(now->tm_mon + 1) + '-' + + std::to_string(now->tm_mday) + '_' + + std::to_string(now->tm_hour) + "h." + + std::to_string(now->tm_min) + "m." + + std::to_string(now->tm_sec) + 's'; + + outfile.open(dateAndTime + ".csv"); + outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n"; + outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n"; + outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n"; + outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n"; + outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n"; + + float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000); + float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000); + float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000); + float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000); + outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n"; + outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n"; + outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n"; + outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n"; + + outfile << "time, avg receive B, avg send B\n"; + for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) { + outfile << std::to_string(i) + ","; + outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ","; + outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n"; + } + outfile.close(); + +} + +void Network::updateNetworkData() +{ + std::clock_t currentTime = std::clock(); + // Send snapshot + if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) { + // Set values + m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC); + m_NetworkData.BandwidthBytes.push_back(std::pair(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval)); + // Reset interval stuff + m_SaveDataTimer = std::clock(); + m_NetworkData.DataSentThisInterval = 0; + m_NetworkData.DataReceivedThisInterval = 0; + } +} \ No newline at end of file diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 6308a130..d40a1b32 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -39,6 +39,7 @@ void Packet::Init(MessageType type, unsigned int & packetID) Packet::WritePrimitive(messageType); Packet::WritePrimitive(packetID); packetID++; + m_HeaderSize = m_Offset; } void Packet::WriteString(const std::string& str) diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 8a194c0e..a3fc4fe8 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -24,14 +24,17 @@ void Server::Update() { readFromClients(); m_EventBroker->Process(); -} + if (isReadingData) { + Network::Update(); + } +} void Server::readFromClients() { while (m_Socket.available()) { try { - bytesRead = receive(readBuffer, INPUTSIZE); + bytesRead = receive(readBuffer); Packet packet(readBuffer, bytesRead); parseMessageType(packet); } catch (const std::exception& err) { @@ -70,11 +73,8 @@ void Server::parseMessageType(Packet& packet) case MessageType::Connect: parseConnect(packet); break; - case MessageType::ClientPing: - //parseClientPing(); - break; - case MessageType::ServerPing: - parseServerPing(); + case MessageType::Ping: + parsePing(); break; case MessageType::Message: break; @@ -97,12 +97,18 @@ void Server::parseMessageType(Packet& packet) } } -int Server::receive(char * data, size_t length) +int Server::receive(char * data) { - length = m_Socket.receive_from( + unsigned int length = m_Socket.receive_from( boost::asio::buffer((void*)data - , length) + , INPUTSIZE) , m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } return length; } @@ -112,6 +118,12 @@ void Server::send(Packet& packet, int userID) boost::asio::buffer(packet.Data(), packet.Size()), m_ConnectedUsers[userID].Endpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } } void Server::send(Packet & packet) @@ -122,6 +134,11 @@ void Server::send(Packet & packet) packet.Size()), m_ReceiverEndpoint, 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } } void Server::broadcast(Packet& packet) @@ -160,7 +177,9 @@ void Server::sendSnapshot() } } } - broadcast(packet); + if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) { + broadcast(packet); + } } } @@ -174,7 +193,7 @@ void Server::sendPing() } } // Create ping message - Packet packet(MessageType::ServerPing); + Packet packet(MessageType::Ping); packet.WriteString("Ping from server"); // Time message m_StartPingTime = std::clock(); @@ -298,12 +317,12 @@ void Server::parseClientPing() return; } // Return ping - Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID); + Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID); packet.WriteString("Ping received"); send(packet); } -void Server::parseServerPing() +void Server::parsePing() { for (int i = 0; i < m_ConnectedUsers.size(); i++) { if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { @@ -356,7 +375,7 @@ void Server::createPlayer() } } LOG_WARNING("Server is full!"); - + } int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) @@ -373,5 +392,12 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) bool Server::OnInputCommand(const Events::InputCommand & e) { //LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); + if (e.Command == "LogNetworkBandwidth" && e.Value > 0) { + if (isReadingData) { + saveToFile(); + } + isReadingData = !isReadingData; + m_SaveDataTimer = std::clock(); + } return true; } From fcc9d64e7a95e2aa420060fe1018327525cf9739 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 10:58:10 +0100 Subject: [PATCH 24/80] Now publishes an EPlayerDisconnected event --- include/Engine/Network/EPlayerDisconnected.h | 18 ++++++++++++++++++ include/Engine/Network/Server.h | 1 + src/Engine/Network/Server.cpp | 5 +++++ 3 files changed, 24 insertions(+) create mode 100644 include/Engine/Network/EPlayerDisconnected.h diff --git a/include/Engine/Network/EPlayerDisconnected.h b/include/Engine/Network/EPlayerDisconnected.h new file mode 100644 index 00000000..278a7b1f --- /dev/null +++ b/include/Engine/Network/EPlayerDisconnected.h @@ -0,0 +1,18 @@ +#ifndef Events_PlayerDisconnected +#define Events_PlayerDisconnected + +#include "Core/EventBroker.h" +#include "Core/Entity.h" + +namespace Events +{ + +struct PlayerDisconnected : public Event +{ + unsigned int PlayerID; + EntityID Entity; +}; + +} + +#endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index c4f1bf16..cdbcd357 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -14,6 +14,7 @@ #include "../Network/Network.h" #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" +#include "Network/EPlayerDisconnected.h" class Server : public Network { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index a8c6ced9..4ccc6a7d 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -223,6 +223,11 @@ void Server::disconnect(int i) //broadcast("A player disconnected"); LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) + Events::PlayerDisconnected e; + e.Entity = m_PlayerDefinitions[i].EntityID; + e.PlayerID = i; + m_EventBroker->Publish(e); + m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); m_PlayerDefinitions[i].EntityID = -1; m_PlayerDefinitions[i].Name = ""; From b1ea5429cefdfb2243bc8a6581b5bc80d37c0059 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 11:53:04 +0100 Subject: [PATCH 25/80] Used config for a lot of things --- include/Engine/Network/Client.h | 4 +-- include/Engine/Network/Network.h | 7 +++-- include/Engine/Network/Server.h | 6 ++-- include/Game/Systems/InterpolationSystem.h | 9 ++++-- resources/DefaultConfig.ini | 5 +++ src/Engine/Network/Client.cpp | 3 +- src/Engine/Network/Network.cpp | 9 +++++- src/Engine/Network/Server.cpp | 19 +++++++----- src/Game/Systems/InterpolationSystem.cpp | 36 ++-------------------- 9 files changed, 46 insertions(+), 52 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 38db1e9b..61fa5ff0 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -57,12 +57,12 @@ private: std::unordered_map m_ClientIDToServerID; // Network logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; std::clock_t m_TimeSinceSentInputs; - unsigned int m_SendInputIntervalMs = 33; + unsigned int m_SendInputIntervalMs; std::vector m_InputCommandBuffer; // Private member functions diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 7166eec6..73cb01d3 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -7,12 +7,12 @@ #include "Core/EventBroker.h" #include "Network/Packet.h" #include "Network/NetworkData.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include #include -#define MAXCONNECTIONS 8 #define INPUTSIZE 4097 -#define TIMEOUTMS 15000 class Network { @@ -26,8 +26,11 @@ protected: NetworkData m_NetworkData; unsigned int m_SaveDataIntervalMs = 1000; std::clock_t m_SaveDataTimer; + unsigned int m_MaxConnections; + unsigned int m_TimeoutMs; void saveToFile(); void updateNetworkData(); + void initialize(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cdbcd357..f1b5691a 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -30,7 +30,7 @@ private: boost::asio::ip::udp::socket m_Socket; // Sending messages to client logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; // std::vector m_ConnectedUsers; char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; @@ -39,8 +39,8 @@ private: std::clock_t previousSnapshotMessage = std::clock(); std::clock_t timOutTimer = std::clock(); // How often we send messages (milliseconds) - int intervalMs = 1000; - int snapshotInterval = 50; + int pingIntervalMs; + int snapshotInterval; int checkTimeOutInterval = 100; //Timers diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 4b05571b..0e137598 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -10,11 +10,11 @@ #include "Common.h" #include "Core/System.h" #include "Core/EventBroker.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include "Network/EInterpolate.h" -#define SNAPSHOTINTERVAL 0.05f - class InterpolationSystem : public PureSystem { struct Transform @@ -29,6 +29,8 @@ public: : System(world, eventBroker) , PureSystem("Transform") { + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); } ~InterpolationSystem() { } @@ -42,9 +44,10 @@ private: T vectorInterpolation(T prev, T next, double currentTime) { T difference = next - prev; - T vector = (difference / SNAPSHOTINTERVAL) * static_cast(currentTime); + T vector = (difference / m_SnapshotInterval) * static_cast(currentTime); return vector; } + float m_SnapshotInterval; EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..53e86699 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -19,6 +19,11 @@ IsServer=false Name=Bob Address=127.0.0.1 Port=13 +MaxConnections=8 +SnapshotInterval=0.05 +SendInputIntervalMs=33 +PingIntervalMs= 1000 +TimeoutMs=15000 [Multithreading] ResourceLoading=true diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4dc4c93e..1fd823cf 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -15,6 +15,7 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); + m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); } Client::~Client() @@ -316,7 +317,7 @@ bool Client::hasServerTimedOut() { // Time in ms float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - if (timeSincePing > TIMEOUTMS) { + if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); m_IsConnected = false; diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index c9ed3637..f4dcd1a2 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -58,4 +58,11 @@ void Network::updateNetworkData() m_NetworkData.DataSentThisInterval = 0; m_NetworkData.DataReceivedThisInterval = 0; } -} \ No newline at end of file +} + +void Network::initialize() +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_MaxConnections = config->Get("Networking.MaxConnections", 8); + m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 4ccc6a7d..07c43829 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,7 +1,12 @@ #include "Network/Server.h" Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) -{ } +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05); + pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); + +} Server::~Server() { @@ -14,7 +19,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { + for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } LOG_INFO("I am Server. BIP BOP\n"); @@ -49,7 +54,7 @@ void Server::readFromClients() } // Send pings each - if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { sendPing(); previousePingMessage = currentTime; } @@ -210,7 +215,7 @@ void Server::checkForTimeOuts() if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { int stopPing = 1000 * m_ConnectedUsers[i].StopTime / static_cast(CLOCKS_PER_SEC); - if (startPing > stopPing + TIMEOUTMS) { + if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); disconnect(i); } @@ -239,7 +244,7 @@ void Server::parseOnInputCommand(Packet& packet) { int playerID = -1; // Check which player it was who sent the message - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -364,7 +369,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) { + for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -384,7 +389,7 @@ void Server::createPlayer() int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { return i; diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 75f68678..be2c9a4f 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,35 +1,15 @@ #include "Systems/InterpolationSystem.h" -//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt) -//{ -// if (m_InterpolationPoints[transform.EntityID].size() > 0) { -// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime += dt; -// if (sTransform.interpolationTime > 0.05) { -// double time = std::fmod(sTransform.interpolationTime, 0.05f); -// m_InterpolationPoints[transform.EntityID].pop(); -// if (m_InterpolationPoints[transform.EntityID].size() <= 0) { -// return; -// } -// sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime = time; -// } -// glm::vec3 nextPosition = sTransform.Position; -// glm::vec3 currentPosition = static_cast(transform["Position"]); -// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); -// } -//} - void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += dt; Transform sTransform = m_NextTransform[transform.EntityID]; double time = sTransform.interpolationTime; - if (time > SNAPSHOTINTERVAL) { + if (time > m_SnapshotInterval) { if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) { m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID]; - m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL; + m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval; sTransform = m_NextTransform[transform.EntityID]; m_LastReceivedTransform.erase(transform.EntityID); } else { @@ -44,7 +24,7 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe // Orientation glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL)); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -72,15 +52,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) } else { // Did not m_NextTransform[e.Entity] = transform; } - // Check if queue already exists - //if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue - // m_InterpolationPoints[e.Entity].push(transform); - //} - - //else { // Did not exist, create queue - // std::queue transformQueue; - // transformQueue.push(transform); - // m_InterpolationPoints[e.Entity] = transformQueue; - //} return false; } From 08fcdb382b3dc2ebcf05692c7fa788acc05c6e3d Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 11:53:04 +0100 Subject: [PATCH 26/80] Used config for a lot of things --- include/Engine/Network/Client.h | 4 +-- include/Engine/Network/Network.h | 7 +++-- include/Engine/Network/Server.h | 6 ++-- include/Game/Systems/InterpolationSystem.h | 9 ++++-- resources/DefaultConfig.ini | 5 +++ src/Engine/Network/Client.cpp | 6 +++- src/Engine/Network/Network.cpp | 9 +++++- src/Engine/Network/Server.cpp | 20 +++++++----- src/Game/Systems/InterpolationSystem.cpp | 36 ++-------------------- 9 files changed, 50 insertions(+), 52 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 38db1e9b..61fa5ff0 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -57,12 +57,12 @@ private: std::unordered_map m_ClientIDToServerID; // Network logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; SnapshotDefinitions m_NextSnapshot; double m_DurationOfPingTime; std::clock_t m_StartPingTime; std::clock_t m_TimeSinceSentInputs; - unsigned int m_SendInputIntervalMs = 33; + unsigned int m_SendInputIntervalMs; std::vector m_InputCommandBuffer; // Private member functions diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 7166eec6..73cb01d3 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -7,12 +7,12 @@ #include "Core/EventBroker.h" #include "Network/Packet.h" #include "Network/NetworkData.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include #include -#define MAXCONNECTIONS 8 #define INPUTSIZE 4097 -#define TIMEOUTMS 15000 class Network { @@ -26,8 +26,11 @@ protected: NetworkData m_NetworkData; unsigned int m_SaveDataIntervalMs = 1000; std::clock_t m_SaveDataTimer; + unsigned int m_MaxConnections; + unsigned int m_TimeoutMs; void saveToFile(); void updateNetworkData(); + void initialize(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cdbcd357..f1b5691a 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -30,7 +30,7 @@ private: boost::asio::ip::udp::socket m_Socket; // Sending messages to client logic - PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; + PlayerDefinition m_PlayerDefinitions[8]; // std::vector m_ConnectedUsers; char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; @@ -39,8 +39,8 @@ private: std::clock_t previousSnapshotMessage = std::clock(); std::clock_t timOutTimer = std::clock(); // How often we send messages (milliseconds) - int intervalMs = 1000; - int snapshotInterval = 50; + int pingIntervalMs; + int snapshotInterval; int checkTimeOutInterval = 100; //Timers diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 4b05571b..0e137598 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -10,11 +10,11 @@ #include "Common.h" #include "Core/System.h" #include "Core/EventBroker.h" +#include "Core/ResourceManager.h" +#include "Core/ConfigFile.h" #include "Network/EInterpolate.h" -#define SNAPSHOTINTERVAL 0.05f - class InterpolationSystem : public PureSystem { struct Transform @@ -29,6 +29,8 @@ public: : System(world, eventBroker) , PureSystem("Transform") { + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); } ~InterpolationSystem() { } @@ -42,9 +44,10 @@ private: T vectorInterpolation(T prev, T next, double currentTime) { T difference = next - prev; - T vector = (difference / SNAPSHOTINTERVAL) * static_cast(currentTime); + T vector = (difference / m_SnapshotInterval) * static_cast(currentTime); return vector; } + float m_SnapshotInterval; EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..53e86699 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -19,6 +19,11 @@ IsServer=false Name=Bob Address=127.0.0.1 Port=13 +MaxConnections=8 +SnapshotInterval=0.05 +SendInputIntervalMs=33 +PingIntervalMs= 1000 +TimeoutMs=15000 [Multithreading] ResourceLoading=true diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4dc4c93e..fe552fa2 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -5,6 +5,8 @@ using namespace boost::asio::ip; Client::Client(ConfigFile* config) : m_Socket(m_IOService) { + Network::initialize(); + // Asumes root node is EntityID 0 insertIntoServerClientMaps(0, 0); // Init timer @@ -15,6 +17,8 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); + m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); + } Client::~Client() @@ -316,7 +320,7 @@ bool Client::hasServerTimedOut() { // Time in ms float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - if (timeSincePing > TIMEOUTMS) { + if (timeSincePing > m_TimeoutMs) { // Clear everything and go to menu. LOG_INFO("Server has timed out, returning to menu, Beep Boop."); m_IsConnected = false; diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index c9ed3637..f4dcd1a2 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -58,4 +58,11 @@ void Network::updateNetworkData() m_NetworkData.DataSentThisInterval = 0; m_NetworkData.DataReceivedThisInterval = 0; } -} \ No newline at end of file +} + +void Network::initialize() +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_MaxConnections = config->Get("Networking.MaxConnections", 8); + m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 4ccc6a7d..719ca16f 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,7 +1,13 @@ #include "Network/Server.h" Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) -{ } +{ + Network::initialize(); + ConfigFile* config = ResourceManager::Load("Config.ini"); + snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05); + pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); + +} Server::~Server() { @@ -14,7 +20,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { + for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } LOG_INFO("I am Server. BIP BOP\n"); @@ -49,7 +55,7 @@ void Server::readFromClients() } // Send pings each - if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { sendPing(); previousePingMessage = currentTime; } @@ -210,7 +216,7 @@ void Server::checkForTimeOuts() if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { int stopPing = 1000 * m_ConnectedUsers[i].StopTime / static_cast(CLOCKS_PER_SEC); - if (startPing > stopPing + TIMEOUTMS) { + if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); disconnect(i); } @@ -239,7 +245,7 @@ void Server::parseOnInputCommand(Packet& packet) { int playerID = -1; // Check which player it was who sent the message - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -364,7 +370,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) { + for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -384,7 +390,7 @@ void Server::createPlayer() int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { - for (int i = 0; i < MAXCONNECTIONS; i++) { + for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { return i; diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 75f68678..be2c9a4f 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,35 +1,15 @@ #include "Systems/InterpolationSystem.h" -//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt) -//{ -// if (m_InterpolationPoints[transform.EntityID].size() > 0) { -// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime += dt; -// if (sTransform.interpolationTime > 0.05) { -// double time = std::fmod(sTransform.interpolationTime, 0.05f); -// m_InterpolationPoints[transform.EntityID].pop(); -// if (m_InterpolationPoints[transform.EntityID].size() <= 0) { -// return; -// } -// sTransform = m_InterpolationPoints[transform.EntityID].front(); -// sTransform.interpolationTime = time; -// } -// glm::vec3 nextPosition = sTransform.Position; -// glm::vec3 currentPosition = static_cast(transform["Position"]); -// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); -// } -//} - void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += dt; Transform sTransform = m_NextTransform[transform.EntityID]; double time = sTransform.interpolationTime; - if (time > SNAPSHOTINTERVAL) { + if (time > m_SnapshotInterval) { if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) { m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID]; - m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL; + m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval; sTransform = m_NextTransform[transform.EntityID]; m_LastReceivedTransform.erase(transform.EntityID); } else { @@ -44,7 +24,7 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe // Orientation glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL)); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -72,15 +52,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) } else { // Did not m_NextTransform[e.Entity] = transform; } - // Check if queue already exists - //if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue - // m_InterpolationPoints[e.Entity].push(transform); - //} - - //else { // Did not exist, create queue - // std::queue transformQueue; - // transformQueue.push(transform); - // m_InterpolationPoints[e.Entity] = transformQueue; - //} return false; } From 08c476e9e37f2cc90465366edc2f894d3efabe56 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 15:42:36 +0100 Subject: [PATCH 27/80] Added kick logic to the server. Also typedefed. --- include/Engine/Network/Client.h | 9 ++--- include/Engine/Network/MessageType.h | 3 +- include/Engine/Network/Network.h | 3 ++ include/Engine/Network/Server.h | 11 +++--- src/Engine/Network/Client.cpp | 9 +++++ src/Engine/Network/Server.cpp | 53 +++++++++++++++++----------- 6 files changed, 57 insertions(+), 31 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 61fa5ff0..4a16034b 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -39,14 +39,14 @@ private: char readBuf[INPUTSIZE] = { 0 }; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; - unsigned int m_SendPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; + PacketID m_SendPacketID = 0; // Game logic World* m_World; std::string m_PlayerName; - int m_PlayerID = -1; + PlayerID m_PlayerID = -1; EntityID m_ServerEntityID = std::numeric_limits::max(); bool m_IsConnected = false; // Server Client Lookup map @@ -76,6 +76,7 @@ private: void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); + void parseKick(); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 8468f2fc..7d8094de 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -13,7 +13,8 @@ enum class MessageType OnInputCommand, OnPlayerDamage, PlayerConnected, - BecomePlayer + BecomePlayer, + Kick }; #endif diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 73cb01d3..480ac602 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -13,6 +13,9 @@ #include #define INPUTSIZE 4097 +typedef unsigned int PlayerID; +typedef unsigned int PacketID; +typedef unsigned int UserID; class Network { diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index f1b5691a..cbad08b0 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -51,19 +51,19 @@ private: EventBroker* m_EventBroker; // Packet loss logic - unsigned int m_PacketID = 0; - unsigned int m_PreviousPacketID = 0; + PacketID m_PacketID = 0; + PacketID m_PreviousPacketID = 0; // Private member functions int receive(char* data); void readFromClients(); - void send(Packet& packet, int playerID); + void send(Packet& packet, UserID user); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); void sendPing(); void checkForTimeOuts(); - void disconnect(int i); + void disconnect(UserID user); void parseMessageType(Packet& packet); void parseOnInputCommand(Packet& packet); void parseOnPlayerDamage(Packet& packet); @@ -73,7 +73,8 @@ private: void parsePing(); void identifyPacketLoss(); void createPlayer(); - int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); + void kick(PlayerID player); + PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index fe552fa2..129e0b42 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -89,6 +89,9 @@ void Client::parseMessageType(Packet& packet) break; case MessageType::PlayerConnected: parsePlayerConnected(packet); + case MessageType::Kick: + parseKick(); + break; default: break; } @@ -120,6 +123,12 @@ void Client::parsePing() send(packet); } +void Client::parseKick() +{ + LOG_WARNING("You have been kicked from the server."); + m_IsConnected = false; +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 719ca16f..03b9775a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -118,11 +118,11 @@ int Server::receive(char * data) return length; } -void Server::send(Packet& packet, int userID) +void Server::send(Packet& packet, UserID user) { int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), - m_ConnectedUsers[userID].Endpoint, + m_ConnectedUsers[user].Endpoint, 0); // Network Debug data if (isReadingData) { @@ -224,40 +224,40 @@ void Server::checkForTimeOuts() } } -void Server::disconnect(int i) +void Server::disconnect(UserID user) { //broadcast("A player disconnected"); - LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str()); + LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) Events::PlayerDisconnected e; - e.Entity = m_PlayerDefinitions[i].EntityID; - e.PlayerID = i; + e.Entity = m_PlayerDefinitions[user].EntityID; + e.PlayerID = user; m_EventBroker->Publish(e); - m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint(); - m_PlayerDefinitions[i].EntityID = -1; - m_PlayerDefinitions[i].Name = ""; - m_PlayerDefinitions[i].PacketID = 0; - m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i); + m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint(); + m_PlayerDefinitions[user].EntityID = -1; + m_PlayerDefinitions[user].Name = ""; + m_PlayerDefinitions[user].PacketID = 0; + m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user); } void Server::parseOnInputCommand(Packet& packet) { - int playerID = -1; + PlayerID player = -1; // Check which player it was who sent the message for (int i = 0; i < m_MaxConnections; i++) { // if the player is connected set playerID to the correct PlayerID if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { - playerID = i; + player = i; break; } } - if (playerID != -1) { + if (player != -1) { while (packet.DataReadSize() < packet.Size()) { Events::InputCommand e; e.Command = packet.ReadString(); - e.PlayerID = playerID; // Set correct player id + e.PlayerID = player; // Set correct player id e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); @@ -322,12 +322,12 @@ void Server::parseDisconnect() void Server::parseClientPing() { LOG_INFO("%i: Parsing ping", m_PacketID); - int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - if (playerID == -1) { + PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); + if (player == -1) { return; } // Return ping - Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID); + Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); packet.WriteString("Ping received"); send(packet); } @@ -358,7 +358,7 @@ void Server::createPlayer() LOG_WARNING("Already connected!"); return; } - int userIndex; + UserID userIndex; for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) { if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() && m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) { @@ -370,7 +370,7 @@ void Server::createPlayer() LOG_WARNING("Not a recognized user!"); return; } - for (int playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { + for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; EntityID entityID = m_World->CreateEntity(); @@ -388,7 +388,14 @@ void Server::createPlayer() } -int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) +void Server::kick(PlayerID player) +{ + disconnect(player); + Packet packet = Packet(MessageType::Kick); + send(packet); +} + +PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { for (int i = 0; i < m_MaxConnections; i++) { if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && @@ -409,5 +416,9 @@ bool Server::OnInputCommand(const Events::InputCommand & e) isReadingData = !isReadingData; m_SaveDataTimer = std::clock(); } + if (e.Command == "KickPlayer" && e.Value > 0) { + kick(0); + } + return true; } From ca2aab449e340af9968dd97c1f39a6706876e511 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 16:12:51 +0100 Subject: [PATCH 28/80] Basic movement and camera management between players and editor --- assets | 2 +- include/Engine/Core/EntityWrapper.h | 1 + include/Engine/Core/Transform.h | 5 + .../Editor/EditorCameraInputController.h | 98 ++++++++++++++ include/Engine/Editor/EditorSystem.h | 19 ++- include/Engine/Input/EInputCommand.h | 2 +- .../Engine/Input/FirstPersonInputController.h | 33 ++++- .../Rendering/DebugCameraInputController.h | 84 ------------ include/Engine/Rendering/RenderSystem.h | 1 - include/Game/Systems/PlayerMovementSystem.h | 18 ++- include/Game/Systems/PlayerSpawnSystem.h | 1 + resources/DefaultConfig.ini | 4 +- resources/Schema/Components/Player.xml | 6 +- resources/Schema/Components/Player.xsd | 6 +- resources/Schema/Entities/CollidableCube.xml | 15 +++ resources/Schema/Entities/MovementTest.xml | 125 +++++++++++++----- resources/Schema/Entities/Player.xml | 61 +++++++-- resources/Schema/Types.xsd | 3 + src/Engine/Core/EntityWrapper.cpp | 16 +++ src/Engine/Core/Transform.cpp | 20 +++ src/Engine/Editor/EditorSystem.cpp | 86 +++++++++--- src/Engine/Rendering/RenderSystem.cpp | 9 +- src/Game/Systems/PlayerMovementSystem.cpp | 52 +++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 8 ++ 24 files changed, 499 insertions(+), 176 deletions(-) create mode 100644 include/Engine/Editor/EditorCameraInputController.h delete mode 100644 include/Engine/Rendering/DebugCameraInputController.h create mode 100644 resources/Schema/Entities/CollidableCube.xml diff --git a/assets b/assets index 6ffb46e1..2a800ea9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6ffb46e155c8f013241cd1507098c94900ec2448 +Subproject commit 2a800ea92b323646432c65217d55aab6750d5a72 diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 3ba4e087..d0e5e31f 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -25,6 +25,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentName); EntityWrapper Parent(); + EntityWrapper FirstChildByName(const std::string& name); bool Valid(); ComponentWrapper operator[](const char* componentName); diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index 474a7bdb..3b0811c9 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -3,13 +3,18 @@ #include "../GLM.h" #include "World.h" +#include "EntityWrapper.h" namespace Transform { +glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(World* world, EntityID entity); +glm::quat AbsoluteOrientation(EntityWrapper entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); +glm::vec3 AbsoluteScale(EntityWrapper entity); glm::vec3 AbsoluteScale(World* world, EntityID entity); +glm::mat4 ModelMatrix(EntityWrapper entity); glm::mat4 ModelMatrix(EntityID entity, World* world); } diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h new file mode 100644 index 00000000..c12113c7 --- /dev/null +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -0,0 +1,98 @@ +#ifndef EditorCameraInputController_h__ +#define EditorCameraInputController_h__ + +#include +#include "../Input/FirstPersonInputController.h" +#include "../Core/EMousePress.h" +#include "../Core/EMouseRelease.h" +#include "../Core/EMouseScroll.h" +#include "../Core/ConfigFile.h" + +template +class EditorCameraInputController : public FirstPersonInputController +{ +public: + EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID) + : FirstPersonInputController(eventBroker, playerID) + { + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &EditorCameraInputController::OnMouseScroll); + + m_Config = ResourceManager::Load("Config.ini"); + m_SpeedMultiplier = m_Config->Get("Editor.CameraSpeed", 3.f); + } + + virtual const glm::vec3 Movement() const override + { + return m_Movement * m_SpeedMultiplier; + } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + ImGuiIO& io = ImGui::GetIO(); + if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) { + return false; + } + + if (e.Command == "Jump") { + if (e.Value > 0) { + m_Movement.y = glm::max(e.Value, 1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Crouch") { + if (e.Value > 0) { + m_Movement.y = glm::min(-e.Value, -1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Sprint") { + if (e.Value > 0) { + m_SpeedMultiplier *= 2.f; + } else { + m_SpeedMultiplier /= 2.f; + } + } + + return FirstPersonInputController::OnCommand(e); + } + +protected: + ConfigFile* m_Config; + float m_SpeedMultiplier = 1.f; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + ImGuiIO& io = ImGui::GetIO(); + if (!io.WantCaptureMouse) { + LockMouse(); + } + } + return true; + } + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + UnlockMouse(); + } + return true; + } + EventRelay m_EMouseScroll; + bool OnMouseScroll(const Events::MouseScroll& e) + { + m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier); + m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); + m_Config->SaveToDisk(); + return true; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index b354ddf3..2db24ba3 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -1,7 +1,6 @@ #include "../Core/System.h" #include "../Rendering/IRenderer.h" #include "../Rendering/Camera.h" -#include "../Rendering/DebugCameraInputController.h" #include "../Rendering/ESetCamera.h" #include "../Core/World.h" #include "../Core/SystemPipeline.h" @@ -10,8 +9,10 @@ #include "../Core/EntityFileParser.h" #include "../Core/EntityFileWriter.h" #include "../Core/EMousePress.h" +#include "../Input/EInputCommand.h" #include "EditorGUI.h" #include "EditorStats.h" +#include "EditorCameraInputController.h" class EditorSystem : public ImpureSystem { @@ -21,18 +22,24 @@ public: void Update(double dt); + void Enable(); + void Disable(); + private: IRenderer* m_Renderer; RenderFrame* m_RenderFrame; World* m_EditorWorld; SystemPipeline* m_EditorWorldSystemPipeline; - Camera* m_EditorCamera; - EntityWrapper m_Camera = EntityWrapper::Invalid; - DebugCameraInputController* m_DebugCameraInputController; + //Camera* m_EditorCamera; + EntityWrapper m_EditorCamera = EntityWrapper::Invalid; + EntityWrapper m_ActualCamera = EntityWrapper::Invalid; + EditorCameraInputController* m_EditorCameraInputController; EditorGUI* m_EditorGUI; EditorStats* m_EditorStats; // State + double m_LastTime = 0.f; + bool m_Enabled = true; EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate; EntityWrapper m_Widget = EntityWrapper::Invalid; EntityWrapper m_CurrentSelection = EntityWrapper::Invalid; @@ -56,4 +63,8 @@ private: bool OnMousePress(const Events::MousePress& e); EventRelay m_EWidgetDelta; bool OnWidgetDelta(const Events::WidgetDelta& e); + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_ESetCamera; + bool OnSetCamera(const Events::SetCamera& e); }; \ No newline at end of file diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 9ec897d3..1e150786 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -9,7 +9,7 @@ namespace Events struct InputCommand : Event { /** Numerical ID of the player. */ - unsigned int PlayerID; + int PlayerID; /** The command that was sent. */ std::string Command; /** The value of the command. */ diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index d8584494..91445534 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -9,7 +9,7 @@ template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) + FirstPersonInputController(EventBroker* eventBroker, int playerID) : InputController(eventBroker) , m_PlayerID(playerID) { @@ -17,7 +17,8 @@ public: EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); } - const glm::quat Orientation() const { return m_Orientation; } + virtual const glm::vec3 Movement() const { return m_Movement; } + virtual const glm::vec3 Orientation() const { return m_Orientation; } void LockMouse() { @@ -42,24 +43,44 @@ public: if (m_MouseLocked) { if (e.Command == "Pitch") { float val = glm::radians(e.Value); - m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + m_Orientation.x += -val; + m_Orientation.x = glm::clamp(m_Orientation.x, -glm::half_pi(), glm::half_pi()); + //m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); return true; } if (e.Command == "Yaw") { float val = glm::radians(e.Value); - m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + m_Orientation.y += -val; + //m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Orientation; return true; } } + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + return true; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + return true; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + return false; } protected: - const unsigned int m_PlayerID; - glm::quat m_Orientation; + const int m_PlayerID; bool m_MouseLocked = false; + glm::vec3 m_Orientation; + glm::vec3 m_Movement; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h deleted file mode 100644 index 5ce85b3f..00000000 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef DebugCameraInputController_h__ -#define DebugCameraInputController_h__ - -#include -#include "../Input/FirstPersonInputController.h" -#include "../Core/EMousePress.h" -#include "../Core/EMouseRelease.h" - -template -class DebugCameraInputController : public FirstPersonInputController -{ -public: - DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID) - : FirstPersonInputController(eventBroker, playerID) - { - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &DebugCameraInputController::OnMousePress); - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &DebugCameraInputController::OnMouseRelease); - } - - void SetPosition(const glm::vec3 position) { m_Position = position; } - void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; } - - const glm::vec3 Position() const { return m_Position; } - void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } - - virtual bool OnCommand(const Events::InputCommand& e) override - { - ImGuiIO& io = ImGui::GetIO(); - - if (!io.WantCaptureKeyboard) { - if (e.Command == "Right") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.x = value; - } - if (e.Command == "Forward") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.z = -value; - } - if (e.Command == "Sprint") { - if (e.Value > 0.f) { - m_Speed = m_BaseSpeed * 2.f * (e.Value); - } else { - m_Speed = m_BaseSpeed; - } - } - } - - return FirstPersonInputController::OnCommand(e); - } - - void Update(double dt) - { - if (glm::length2(m_Velocity) > 0) { - m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt); - } - } - -protected: - glm::vec3 m_Position = glm::vec3(0, 0, 0); - glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 2.0f; - float m_Speed = m_BaseSpeed; - EventRelay m_EMousePress; - bool OnMousePress(const Events::MousePress& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - ImGuiIO& io = ImGui::GetIO(); - if (!io.WantCaptureMouse) { - LockMouse(); - } - } - return true; - } - EventRelay m_EMouseRelease; - bool OnMouseRelease(const Events::MouseRelease& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - UnlockMouse(); - } - return true; - } -}; - -#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 003e308e..04c394a9 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,7 +15,6 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" -#include "DebugCameraInputController.h" class RenderSystem : public ImpureSystem { diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 1be61bdd..f5b6539b 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -1,14 +1,22 @@ #include "Common.h" #include "GLM.h" #include "Core/System.h" +#include "Events/EPlayerSpawned.h" +#include "Input/FirstPersonInputController.h" -class PlayerMovementSystem : public PureSystem +class PlayerMovementSystem : public ImpureSystem, PureSystem { public: - PlayerMovementSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) - , PureSystem("Player") - { } + PlayerMovementSystem(World* world, EventBroker* eventBroker); + ~PlayerMovementSystem(); + virtual void Update(double dt) override; virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt); + +private: + // State + std::unordered_map*> m_PlayerInputControllers; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 69014f65..9e9ce0be 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -3,6 +3,7 @@ #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" #include "Events/EPlayerSpawned.h" +#include "Rendering/ESetCamera.h" class PlayerSpawnSystem : public ImpureSystem { diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..7e7dc08c 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -1,11 +1,13 @@ [Debug] LogLevel=1 LoadMap= -EditorEnabled=false ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if false -> Use pool allocation. DisableMemoryPool=false +[Editor] +CameraSpeed=3 + [Video] Fullscreen=false VSYNC=false diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index caefd6e6..a9ecc6be 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,8 +1,4 @@ - - false - false - false - false + 0.2 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 1a315a35..89c4a398 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -9,11 +9,7 @@ - - - - - + diff --git a/resources/Schema/Entities/CollidableCube.xml b/resources/Schema/Entities/CollidableCube.xml new file mode 100644 index 00000000..ebba54be --- /dev/null +++ b/resources/Schema/Entities/CollidableCube.xml @@ -0,0 +1,15 @@ + + + + + + + + Models/Core/UnitCube.obj + + + + + + + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 93b4d374..9ea1ae68 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -6,14 +6,7 @@ - - - - - - - - + @@ -22,46 +15,116 @@ - - + + - + - - - - - - - - Models/Assault.obj - - - + + + Schema/Entities/Player.xml + + + + + + - + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + + + Models/DirectionalLightWidget.obj + + + + - + + + + Models/Test/ObstacleCourse.obj + + + + + + - - - Models/Core/UnitCube.obj - - - - + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 6c3b39c3..087b1f7e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -2,17 +2,60 @@ - - + + + + - - Models/Core/UnitSphere.obj - - - - + + + 3 + + + + + - + + + + + + Models/Camera.obj + false + + + + + + + + + + + + + Models/Camera.obj + + + + + + + + + + + + Models/Assault.obj + + + + + + + + diff --git a/resources/Schema/Types.xsd b/resources/Schema/Types.xsd index fb584c64..8d9bf289 100644 --- a/resources/Schema/Types.xsd +++ b/resources/Schema/Types.xsd @@ -16,6 +16,9 @@ + + + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 98b9c7d4..6177d91d 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -17,6 +17,22 @@ EntityWrapper EntityWrapper::Parent() } } +EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) +{ + auto itPair = this->World->GetChildren(this->ID); + if (itPair.first == itPair.second) { + return EntityWrapper::Invalid; + } + + for (auto it = itPair.first; it != itPair.second; ++it) { + if (this->World->GetName(it->second) == name) { + return EntityWrapper(this->World, it->second); + } + } + + return EntityWrapper::Invalid; +} + bool EntityWrapper::Valid() { if (this->World == nullptr) { diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index cbc405a3..c9869014 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -1,5 +1,10 @@ #include "Core/Transform.h" +glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) +{ + return AbsolutePosition(entity.World, entity.ID); +} + glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) { glm::vec3 position; @@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) return position; } +glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) +{ + return AbsoluteOrientation(entity.World, entity.ID); +} + glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) { glm::quat orientation; @@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) return orientation; } +glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) +{ + return AbsoluteScale(entity.World, entity.ID); +} + glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) { glm::vec3 scale(1.f); @@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) return scale; } +glm::mat4 Transform::ModelMatrix(EntityWrapper entity) +{ + return ModelMatrix(entity.ID, entity.World); +} + glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) { glm::vec3 position = Transform::AbsolutePosition(world, entity); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 35b8a361..a357a542 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorWorldSystemPipeline->AddSystem(0, m_Renderer); m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); - m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Transform"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Camera"); - m_DebugCameraInputController = new DebugCameraInputController(m_EventBroker, -1); + m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); + m_ActualCamera = m_EditorCamera; + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); + m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1)); @@ -33,38 +34,66 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera); m_EditorStats = new EditorStats(); - Events::SetCamera e; - e.CameraEntity = m_Camera; - m_EventBroker->Publish(e); + if (m_Enabled) { + Enable(); + } } EditorSystem::~EditorSystem() { delete m_EditorStats; delete m_EditorGUI; - delete m_DebugCameraInputController; + delete m_EditorCameraInputController; delete m_EditorWorldSystemPipeline; delete m_EditorWorld; } void EditorSystem::Update(double dt) { - m_EventBroker->Process(); - m_EditorGUI->Draw(); - m_EditorStats->Draw(dt); + double now = glfwGetTime(); + double actualDelta = now - m_LastTime; + m_LastTime = now; - if (m_CurrentSelection.Valid() && m_Widget.Valid()) { - (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + if (m_Enabled) { + m_EventBroker->Process(); + m_EditorGUI->Draw(); + m_EditorStats->Draw(actualDelta); + + if (m_CurrentSelection.Valid() && m_Widget.Valid()) { + (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + } + + m_EditorWorldSystemPipeline->Update(actualDelta); + + ComponentWrapper& cameraTransform = m_EditorCamera["Transform"]; + glm::vec3& ori = cameraTransform["Orientation"]; + ori.x = m_EditorCameraInputController->Orientation().x; + ori.y = m_EditorCameraInputController->Orientation().y; + glm::vec3& pos = cameraTransform["Position"]; + pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta; } +} - m_EditorWorldSystemPipeline->Update(dt); +void EditorSystem::Enable() +{ + Events::SetCamera e; + e.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e); + (glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera); + m_Enabled = true; +} - m_DebugCameraInputController->Update(dt); - m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position(); - m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation()); +void EditorSystem::Disable() +{ + Events::SetCamera e; + e.CameraEntity = m_ActualCamera; + m_EventBroker->Publish(e); + m_Enabled = false; } void EditorSystem::OnEntitySelected(EntityWrapper entity) @@ -148,6 +177,29 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) return true; } +bool EditorSystem::OnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "ToggleEditor" && e.Value > 0) { + if (m_Enabled) { + Disable(); + } else { + Enable(); + } + } + return true; +} + +bool EditorSystem::OnSetCamera(const Events::SetCamera& e) +{ + if (m_Enabled && e.CameraEntity != m_EditorCamera) { + m_ActualCamera = e.CameraEntity; + Events::SetCamera e2; + e2.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e2); + } + return true; +} + EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath) { if (parent.World == nullptr) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 80b6696c..6eedc34c 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -119,11 +119,12 @@ void RenderSystem::Update(double dt) { m_EventBroker->Process(); - if (m_CurrentCamera) { - ComponentWrapper cameraTransform = m_CurrentCamera["Transform"]; - m_Camera->SetPosition(cameraTransform["Position"]); - m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"])); + // Update the current camera used for rendering + if (m_CurrentCamera.Valid()) { + m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera)); + m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera)); } + //Only supports opaque geometry atm RenderScene scene; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index e14cd146..351acad5 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -1,5 +1,45 @@ #include "Systems/PlayerMovementSystem.h" +PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Player") +{ + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); +} + +PlayerMovementSystem::~PlayerMovementSystem() +{ + for (auto& kv : m_PlayerInputControllers) { + delete kv.second; + } +} + +void PlayerMovementSystem::Update(double dt) +{ + for (auto& kv : m_PlayerInputControllers) { + EntityWrapper player = kv.first; + auto& controller = kv.second; + + if (!player.Valid()) { + continue; + } + + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; + cameraOrientation.x = controller->Orientation().x; + } + + ComponentWrapper& cTransform = player["Transform"]; + glm::vec3& ori = cTransform["Orientation"]; + ori.y = controller->Orientation().y; + + glm::vec3& pos = cTransform["Position"]; + pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + + } +} + void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { ComponentWrapper& cTransform = entity["Transform"]; @@ -10,9 +50,17 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp glm::vec3& velocity = cPhysics["Velocity"]; if (cPhysics["Gravity"]) { - velocity.y -= 9.82 * dt; + velocity.y -= 9.82f * (float)dt; } glm::vec3& position = cTransform["Position"]; position += velocity * (float)dt; -} \ No newline at end of file +} + +bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // When a player spawns, create an input controller for them + m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); + + return true; +} diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 11be0486..0763fa9c 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -38,6 +38,14 @@ void PlayerSpawnSystem::Update(double dt) e.Player = player; e.Spawner = spawner; m_EventBroker->Publish(e); + + // Set the camera to the correct entity + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + Events::SetCamera e; + e.CameraEntity = cameraEntity; + m_EventBroker->Publish(e); + } } } m_SpawnRequests.clear(); From 74d9bae8968d2775b87c1bb49016e49c5188bbed Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 17:34:57 +0100 Subject: [PATCH 29/80] Added conditional spawning based on whether the running instance is a server or not --- include/Game/Systems/PlayerSpawnSystem.h | 8 +++++-- src/Game/Systems/PlayerSpawnSystem.cpp | 29 ++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 9e9ce0be..6c0f6ce3 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -4,6 +4,7 @@ #include "Events/ESpawnerSpawn.h" #include "Events/EPlayerSpawned.h" #include "Rendering/ESetCamera.h" +#include "Core/ConfigFile.h" class PlayerSpawnSystem : public ImpureSystem { @@ -19,8 +20,11 @@ private: ComponentInfo::EnumType Team; }; + bool m_NetworkEnabled = false; + std::vector m_SpawnRequests; + EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); - - std::vector m_SpawnRequests; + EventRelay m_OnPlayerSpawnerd; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; \ No newline at end of file diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 0763fa9c..f18808cc 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -4,6 +4,8 @@ PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker) : System(m_World, eventBroker) { EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned); + m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); } void PlayerSpawnSystem::Update(double dt) @@ -39,13 +41,6 @@ void PlayerSpawnSystem::Update(double dt) e.Spawner = spawner; m_EventBroker->Publish(e); - // Set the camera to the correct entity - EntityWrapper cameraEntity = player.FirstChildByName("Camera"); - if (cameraEntity.Valid()) { - Events::SetCamera e; - e.CameraEntity = cameraEntity; - m_EventBroker->Publish(e); - } } } m_SpawnRequests.clear(); @@ -57,6 +52,12 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) return false; } + // Team picks should be processed ONLY server-side! + // Don't make a spawn request if PlayerID is -1, i.e. we're the client. + if (e.PlayerID == -1 && m_NetworkEnabled) { + return false; + } + if (e.Value != 0) { SpawnRequest req; req.PlayerID = e.PlayerID; @@ -67,3 +68,17 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) return true; } +bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // When a player is actually spawned (since the actual spawning is handled on the server) + + // Set the camera to the correct entity + EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + Events::SetCamera e; + e.CameraEntity = cameraEntity; + m_EventBroker->Publish(e); + } + + return true; +} \ No newline at end of file From 389e057611105eb97a34dbbe6f1121e39199002d Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 17:49:21 +0100 Subject: [PATCH 30/80] EPlayerSpawned special logic added to server and client. --- include/Engine/Network/Client.h | 2 ++ include/Engine/Network/MessageType.h | 13 +++++++------ include/Engine/Network/Server.h | 5 +++++ src/Engine/Network/Client.cpp | 12 ++++++++++++ src/Engine/Network/Server.cpp | 23 +++++++++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 4a16034b..9717d22f 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -20,6 +20,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EInterpolate.h" +#include "Game/Events/EPlayerSpawned.h" class Client : public Network { @@ -77,6 +78,7 @@ private: void parsePlayerConnected(Packet& packet); void parsePing(); void parseKick(); + void parsePlayersSpawned(Packet& packet); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 7d8094de..13ac5e9d 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -5,16 +5,17 @@ // Used to determine what type of message was sent. enum class MessageType { - Connect, - Disconnect, - Ping, - Message, - Snapshot, + Connect, + Disconnect, + Ping, + Message, + Snapshot, OnInputCommand, OnPlayerDamage, PlayerConnected, BecomePlayer, - Kick + Kick, + OnPlayerSpawned }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cbad08b0..cf649dba 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -16,6 +16,8 @@ #include "Core/EPlayerDamage.h" #include "Network/EPlayerDisconnected.h" +#include "Game/Events/EPlayerSpawned.h" + class Server : public Network { public: @@ -58,6 +60,7 @@ private: int receive(char* data); void readFromClients(); void send(Packet& packet, UserID user); + void send(Packet& packet, PlayerID player); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); @@ -78,6 +81,8 @@ private: // Debug event EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned& e); }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 129e0b42..fb5c3573 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -92,6 +92,9 @@ void Client::parseMessageType(Packet& packet) case MessageType::Kick: parseKick(); break; + case MessageType::OnPlayerSpawned: + parsePlayersSpawned(); + break; default: break; } @@ -129,6 +132,15 @@ void Client::parseKick() m_IsConnected = false; } +void Client::parsePlayersSpawned(Packet& packet) +{ + Events::PlayerSpawned e; + e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); + e.PlayerID = -1; + m_EventBroker->Publish(e); +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 03b9775a..6f3c6f3a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -132,6 +132,20 @@ void Server::send(Packet& packet, UserID user) } } +void Server::send(Packet& packet, PlayerID player) +{ + int bytesSent = m_Socket.send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + m_PlayerDefinitions[player].Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} + void Server::send(Packet & packet) { m_Socket.send_to( @@ -422,3 +436,12 @@ bool Server::OnInputCommand(const Events::InputCommand & e) return true; } + +bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) +{ + Packet packet = Packet(MessageType::OnPlayerSpawned); + packet.WritePrimitive(e.Player.ID); + packet.WritePrimitive(e.Spawner.ID); + send(packet, e.PlayerID); + return false; +} From b37b20b7d8e755af4d8c2518cd4a1d1f0e27b7d4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 17:57:31 +0100 Subject: [PATCH 31/80] Didn't bulid lol. Fixed. --- include/Engine/Network/Server.h | 2 +- src/Engine/Network/Client.cpp | 2 +- src/Engine/Network/Server.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index cf649dba..91ea5d21 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -60,7 +60,7 @@ private: int receive(char* data); void readFromClients(); void send(Packet& packet, UserID user); - void send(Packet& packet, PlayerID player); + void send(PlayerID player, Packet& packet); void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index fb5c3573..98aeb9a8 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -93,7 +93,7 @@ void Client::parseMessageType(Packet& packet) parseKick(); break; case MessageType::OnPlayerSpawned: - parsePlayersSpawned(); + parsePlayersSpawned(packet); break; default: break; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 6f3c6f3a..b16a6850 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -132,7 +132,7 @@ void Server::send(Packet& packet, UserID user) } } -void Server::send(Packet& packet, PlayerID player) +void Server::send(PlayerID player, Packet& packet) { int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), @@ -442,6 +442,6 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) Packet packet = Packet(MessageType::OnPlayerSpawned); packet.WritePrimitive(e.Player.ID); packet.WritePrimitive(e.Spawner.ID); - send(packet, e.PlayerID); + send(e.PlayerID, packet); return false; } From 406b730ef33e3c74d96ecd9bf264b8c520849fe4 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 22 Jan 2016 19:07:20 +0100 Subject: [PATCH 32/80] Sends entity names. Temporarily --- src/Engine/Network/Client.cpp | 5 +++++ src/Engine/Network/Server.cpp | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 98aeb9a8..1dd2bd04 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -89,6 +89,7 @@ void Client::parseMessageType(Packet& packet) break; case MessageType::PlayerConnected: parsePlayerConnected(packet); + break; case MessageType::Kick: parseKick(); break; @@ -177,8 +178,12 @@ void Client::parseSnapshot(Packet& packet) { std::string componentType = packet.ReadString(); while (packet.DataReadSize() < packet.Size()) { + // HACK + std::string entityName = packet.ReadString(); // Components EntityID EntityID receivedEntityID = packet.ReadPrimitive(); + // HACK + m_World->SetName(receivedEntityID, entityName); // Parents EntityID EntityID receivedParentEntityID = packet.ReadPrimitive(); ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index b16a6850..9d0a83d9 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,6 +1,6 @@ #include "Network/Server.h" -Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) +Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)) { Network::initialize(); ConfigFile* config = ResourceManager::Load("Config.ini"); @@ -20,6 +20,7 @@ void Server::Start(World* world, EventBroker* eventBroker) m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } @@ -180,9 +181,12 @@ void Server::sendSnapshot() Packet packet(MessageType::Snapshot); ComponentPool* componentPool = it.second; ComponentInfo componentInfo = componentPool->ComponentInfo(); + // Component Type packet.WriteString(componentInfo.Name); for (auto& componentWrapper : *componentPool) { + // HACK: Send entity name + packet.WriteString(m_World->GetName(componentWrapper.EntityID)); // Components EntityID packet.WritePrimitive(componentWrapper.EntityID); // Parents EntityID From 55ee2bb3bf1b7ee13a50a86683c517f3a9a0204c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 21:35:31 +0100 Subject: [PATCH 33/80] Player input properly separated from editor input and server --- .../Editor/EditorCameraInputController.h | 25 ++++++++++--- .../Engine/Input/FirstPersonInputController.h | 35 ++++++++++--------- src/Engine/Editor/EditorSystem.cpp | 12 +++++-- src/Game/Systems/PlayerMovementSystem.cpp | 7 ++-- 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index c12113c7..82e8b337 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -23,13 +23,17 @@ public: m_SpeedMultiplier = m_Config->Get("Editor.CameraSpeed", 3.f); } - virtual const glm::vec3 Movement() const override - { - return m_Movement * m_SpeedMultiplier; - } + virtual const glm::vec3 Movement() const override { return m_Movement * m_SpeedMultiplier; } + + void Enable() { m_Enabled = true; } + void Disable() { m_Enabled = false; } virtual bool OnCommand(const Events::InputCommand& e) override { + if (!m_MouseLocked) { + return false; + } + ImGuiIO& io = ImGui::GetIO(); if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) { return false; @@ -64,11 +68,16 @@ public: protected: ConfigFile* m_Config; + bool m_Enabled = false; float m_SpeedMultiplier = 1.f; EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e) { + if (!m_Enabled) { + return false; + } + if (e.Button == GLFW_MOUSE_BUTTON_2) { ImGuiIO& io = ImGui::GetIO(); if (!io.WantCaptureMouse) { @@ -80,6 +89,10 @@ protected: EventRelay m_EMouseRelease; bool OnMouseRelease(const Events::MouseRelease& e) { + if (!m_Enabled) { + return false; + } + if (e.Button == GLFW_MOUSE_BUTTON_2) { UnlockMouse(); } @@ -88,6 +101,10 @@ protected: EventRelay m_EMouseScroll; bool OnMouseScroll(const Events::MouseScroll& e) { + if (!m_Enabled) { + return false; + } + m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier); m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); m_Config->SaveToDisk(); diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 91445534..cd80fb21 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -18,7 +18,7 @@ public: } virtual const glm::vec3 Movement() const { return m_Movement; } - virtual const glm::vec3 Orientation() const { return m_Orientation; } + virtual const glm::vec3 Rotation() const { return m_Rotation; } void LockMouse() { @@ -40,21 +40,19 @@ public: return false; } - if (m_MouseLocked) { - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Orientation.x += -val; - m_Orientation.x = glm::clamp(m_Orientation.x, -glm::half_pi(), glm::half_pi()); - //m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); + return true; + } - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Orientation.y += -val; - //m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Orientation; - return true; - } + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; + return true; } if (e.Command == "Forward" || e.Command == "Right") { @@ -75,11 +73,16 @@ public: return false; } + + virtual void Reset() + { + m_Rotation = glm::vec3(0.f, 0.f, 0.f); + } protected: const int m_PlayerID; bool m_MouseLocked = false; - glm::vec3 m_Orientation; + glm::vec3 m_Rotation; glm::vec3 m_Movement; EventRelay m_ELockMouse; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index a357a542..9c0e2e47 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -72,8 +72,8 @@ void EditorSystem::Update(double dt) ComponentWrapper& cameraTransform = m_EditorCamera["Transform"]; glm::vec3& ori = cameraTransform["Orientation"]; - ori.x = m_EditorCameraInputController->Orientation().x; - ori.y = m_EditorCameraInputController->Orientation().y; + ori.x = m_EditorCameraInputController->Rotation().x; + ori.y = m_EditorCameraInputController->Rotation().y; glm::vec3& pos = cameraTransform["Position"]; pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta; } @@ -81,6 +81,8 @@ void EditorSystem::Update(double dt) void EditorSystem::Enable() { + m_EditorCameraInputController->Enable(); + m_EventBroker->Publish(Events::UnlockMouse()); Events::SetCamera e; e.CameraEntity = m_EditorCamera; m_EventBroker->Publish(e); @@ -90,6 +92,8 @@ void EditorSystem::Enable() void EditorSystem::Disable() { + m_EditorCameraInputController->Disable(); + m_EventBroker->Publish(Events::LockMouse()); Events::SetCamera e; e.CameraEntity = m_ActualCamera; m_EventBroker->Publish(e); @@ -179,6 +183,10 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) bool EditorSystem::OnInputCommand(const Events::InputCommand& e) { + if (e.PlayerID != -1) { + return false; + } + if (e.Command == "ToggleEditor" && e.Value > 0) { if (m_Enabled) { Disable(); diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 351acad5..843601e8 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -27,16 +27,17 @@ void PlayerMovementSystem::Update(double dt) EntityWrapper cameraEntity = player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; - cameraOrientation.x = controller->Orientation().x; + cameraOrientation.x += controller->Rotation().x; } ComponentWrapper& cTransform = player["Transform"]; glm::vec3& ori = cTransform["Orientation"]; - ori.y = controller->Orientation().y; + ori.y += controller->Rotation().y; glm::vec3& pos = cTransform["Position"]; pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; - + + controller->Reset(); } } From 3ac3311c0c5342459d81270772eb6bbcbd008f43 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 00:37:47 +0100 Subject: [PATCH 34/80] "inline" caused missing symbol when compiling in Release for some reason --- include/Engine/Core/Octree.h | 2 +- src/Engine/Core/Octree.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index bbd27b3c..8bac5503 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -111,7 +111,7 @@ struct Child std::vector& m_StaticObjectsRef; std::vector& m_DynamicObjectsRef; - inline bool hasChildren() const; + bool hasChildren() const; int childIndexContainingPoint(const glm::vec3& point) const; std::vector childIndicesContainingBox(const AABB& box) const; }; diff --git a/src/Engine/Core/Octree.cpp b/src/Engine/Core/Octree.cpp index d7feba45..18effea5 100644 --- a/src/Engine/Core/Octree.cpp +++ b/src/Engine/Core/Octree.cpp @@ -276,7 +276,7 @@ std::vector Child::childIndicesContainingBox(const AABB& box) const } } -inline bool Child::hasChildren() const +bool Child::hasChildren() const { return m_Children[0] != nullptr; } From 31e7340daf4ebd0993a17bb229105b17f4f08a7e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 00:40:18 +0100 Subject: [PATCH 35/80] Ignoring interpolation and rendering for local player entities! --- assets | 2 +- .../Editor/EditorCameraInputController.h | 2 +- include/Engine/Rendering/RenderSystem.h | 5 ++ include/Game/Systems/InterpolationSystem.h | 13 ++--- resources/Schema/Entities/Player.xml | 47 +++++++++++++++---- src/Engine/Core/EntityWrapper.cpp | 3 ++ src/Engine/Rendering/RenderSystem.cpp | 35 +++++++++++++- src/Game/Systems/InterpolationSystem.cpp | 29 ++++++++++-- 8 files changed, 113 insertions(+), 23 deletions(-) diff --git a/assets b/assets index 2a800ea9..e8174f63 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 2a800ea92b323646432c65217d55aab6750d5a72 +Subproject commit e8174f630fc3242e15ada1346b42c72f44cbc854 diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index 82e8b337..66c7952a 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -30,7 +30,7 @@ public: virtual bool OnCommand(const Events::InputCommand& e) override { - if (!m_MouseLocked) { + if (glm::abs(e.Value) > 0 && !m_MouseLocked) { return false; } diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index ef824ea5..4c23c6c6 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,6 +15,7 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" +#include "../../Game/Events/EPlayerSpawned.h" class RenderSystem : public ImpureSystem { @@ -29,6 +30,7 @@ private: RenderFrame* m_RenderFrame; Camera* m_Camera; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; EventRelay m_ESetCamera; bool OnSetCamera(Events::SetCamera &event); @@ -40,6 +42,9 @@ private: void fillModels(std::list>& jobs); void fillLight(std::list>& jobs); + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; #endif \ No newline at end of file diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 0e137598..707c0acf 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -12,6 +12,7 @@ #include "Core/EventBroker.h" #include "Core/ResourceManager.h" #include "Core/ConfigFile.h" +#include "Events/EPlayerSpawned.h" #include "Network/EInterpolate.h" @@ -25,19 +26,13 @@ class InterpolationSystem : public PureSystem double interpolationTime; }; public: - InterpolationSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) - , PureSystem("Transform") - { - ConfigFile* config = ResourceManager::Load("Config.ini"); - m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); - EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); - } + InterpolationSystem(World* world, EventBroker* eventBroker); ~InterpolationSystem() { } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; private: std::unordered_map m_NextTransform; std::unordered_map m_LastReceivedTransform; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; //glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime); template @@ -51,6 +46,8 @@ private: EventRelay m_EInterpolate; bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; #endif diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 087b1f7e..fa8b7686 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -11,9 +11,13 @@ 3 + + + + + - - + @@ -21,22 +25,47 @@ - - Models/Camera.obj - false - - + - + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Camera.obj + + + + + + + + + Models/Camera.obj + false @@ -48,7 +77,7 @@ - Models/Assault.obj + Models/AssaultHeadless.obj diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 6177d91d..2f9c17db 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv bool EntityWrapper::HasComponent(const std::string& componentName) { + if (!Valid()) { + return false; + } return World->HasComponent(ID, componentName); } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 5aa0108e..a478bb43 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -7,6 +7,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned); m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); } @@ -46,6 +47,18 @@ void RenderSystem::fillModels(std::list>& jobs) continue; } + EntityWrapper entity(m_World, modelComponent.EntityID); + bool isLocalPlayer = entity == m_LocalPlayer; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == m_LocalPlayer) { + isLocalPlayer = true; + } + } + if (isLocalPlayer) { + continue; + } + Model* model; try { model = ResourceManager::Load<::Model, true>(resource); @@ -68,6 +81,14 @@ void RenderSystem::fillModels(std::list>& jobs) } } +bool RenderSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + if (e.PlayerID == -1) { + m_LocalPlayer = e.Player; + } + return true; +} + void RenderSystem::fillPointLights(std::list>& jobs, World* world) { auto pointLights = m_World->GetComponents("PointLight"); @@ -128,6 +149,18 @@ void RenderSystem::fillText(std::list>& jobs, World* continue; } + EntityWrapper entity(m_World, textComponent.EntityID); + bool isLocalPlayer = entity == m_LocalPlayer; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == m_LocalPlayer) { + isLocalPlayer = true; + } + } + if (isLocalPlayer) { + continue; + } + Font* font; try { font = ResourceManager::Load(resource); @@ -169,7 +202,7 @@ void RenderSystem::Update(double dt) fillModels(scene.ForwardJobs); fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); - fillText(scene.TextJobs, world); + fillText(scene.TextJobs, m_World); m_RenderFrame->Add(scene); } \ No newline at end of file diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index be2c9a4f..84f50456 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,5 +1,15 @@ #include "Systems/InterpolationSystem.h" +InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Transform") +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05); + EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned); +} + void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map @@ -17,14 +27,21 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } if (transform.Info.Name == "Transform") { + bool isLocalPlayer = entity == m_LocalPlayer || entity.Parent() == m_LocalPlayer; // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); + if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { + return; + } (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation - glm::quat nextOrientation = sTransform.Orientation; - glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); + //bool isPlayer = entity.HasComponent("Player") || entity.Parent().HasComponent("Player"); + if (!isLocalPlayer) { + glm::quat nextOrientation = sTransform.Orientation; + glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); + } // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -33,6 +50,12 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } +bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + m_LocalPlayer = e.Player; + return true; +} + bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) { Transform transform; From db0e67b9bd39093d5a2046ae1e6c28c77f18ce77 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 11:44:16 +0100 Subject: [PATCH 36/80] Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky --- .../Events => Engine/Core}/EPlayerSpawned.h | 0 include/Engine/Core/EntityWrapper.h | 1 + include/Engine/Rendering/RenderSystem.h | 2 +- include/Game/Systems/InterpolationSystem.h | 2 +- src/Engine/Core/EntityWrapper.cpp | 12 ++++++++++ src/Engine/Rendering/RenderSystem.cpp | 23 +++---------------- src/Game/Systems/InterpolationSystem.cpp | 5 ++-- 7 files changed, 21 insertions(+), 24 deletions(-) rename include/{Game/Events => Engine/Core}/EPlayerSpawned.h (100%) diff --git a/include/Game/Events/EPlayerSpawned.h b/include/Engine/Core/EPlayerSpawned.h similarity index 100% rename from include/Game/Events/EPlayerSpawned.h rename to include/Engine/Core/EPlayerSpawned.h diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index d0e5e31f..711f5045 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -26,6 +26,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentName); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); + bool IsChildOf(EntityWrapper potentialParent); bool Valid(); ComponentWrapper operator[](const char* componentName); diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 4c23c6c6..005d2eb7 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,7 +15,7 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" -#include "../../Game/Events/EPlayerSpawned.h" +#include "../Core/EPlayerSpawned.h" class RenderSystem : public ImpureSystem { diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 707c0acf..1e345c91 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -12,7 +12,7 @@ #include "Core/EventBroker.h" #include "Core/ResourceManager.h" #include "Core/ConfigFile.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Network/EInterpolate.h" diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 2f9c17db..55d341e1 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -36,6 +36,18 @@ EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) return EntityWrapper::Invalid; } +bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) +{ + EntityWrapper entity = *this; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity == potentialParent) { + return true; + } + } + return false; +} + bool EntityWrapper::Valid() { if (this->World == nullptr) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index a478bb43..a8f330f0 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -48,14 +48,9 @@ void RenderSystem::fillModels(std::list>& jobs) } EntityWrapper entity(m_World, modelComponent.EntityID); - bool isLocalPlayer = entity == m_LocalPlayer; - while (entity.Parent().Valid()) { - entity = entity.Parent(); - if (entity == m_LocalPlayer) { - isLocalPlayer = true; - } - } - if (isLocalPlayer) { + + // Don't render the local player + if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { continue; } @@ -149,18 +144,6 @@ void RenderSystem::fillText(std::list>& jobs, World* continue; } - EntityWrapper entity(m_World, textComponent.EntityID); - bool isLocalPlayer = entity == m_LocalPlayer; - while (entity.Parent().Valid()) { - entity = entity.Parent(); - if (entity == m_LocalPlayer) { - isLocalPlayer = true; - } - } - if (isLocalPlayer) { - continue; - } - Font* font; try { font = ResourceManager::Load(resource); diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 84f50456..2b6e82f2 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -27,16 +27,17 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } if (transform.Info.Name == "Transform") { - bool isLocalPlayer = entity == m_LocalPlayer || entity.Parent() == m_LocalPlayer; + bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer); // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); + // HACK: Hardcoded tolerance value for player position desync = 1 if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { return; } (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation - //bool isPlayer = entity.HasComponent("Player") || entity.Parent().HasComponent("Player"); + // Don't force orientation for players if (!isLocalPlayer) { glm::quat nextOrientation = sTransform.Orientation; glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); From 4d5cbb60574239816bb3e4d378b6aeb2077c0770 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:14:00 +0100 Subject: [PATCH 37/80] fixup! Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky --- include/Engine/Network/Client.h | 2 +- include/Engine/Network/Server.h | 3 +-- include/Game/Systems/PlayerMovementSystem.h | 2 +- include/Game/Systems/PlayerSpawnSystem.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 9717d22f..92d78f4a 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -20,7 +20,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EInterpolate.h" -#include "Game/Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" class Client : public Network { diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 91ea5d21..e7c745e7 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -15,8 +15,7 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EPlayerDisconnected.h" - -#include "Game/Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" class Server : public Network { diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index f5b6539b..72f3b879 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -1,7 +1,7 @@ #include "Common.h" #include "GLM.h" #include "Core/System.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Input/FirstPersonInputController.h" class PlayerMovementSystem : public ImpureSystem, PureSystem diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 6c0f6ce3..eb4d3c97 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -2,7 +2,7 @@ #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" -#include "Events/EPlayerSpawned.h" +#include "Core/EPlayerSpawned.h" #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" From 3aeeb3cad5e7aa3c9743e3bde3c4a27eb1eaf90d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 11:54:03 +0100 Subject: [PATCH 38/80] Moved FirstPersonInputController implementation out of header --- .../Engine/Input/FirstPersonInputController.h | 74 ++-------------- .../Input/FirstPersonInputController.cpp | 87 +++++++++++++++++++ 2 files changed, 94 insertions(+), 67 deletions(-) create mode 100644 src/Engine/Input/FirstPersonInputController.cpp diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index cd80fb21..4a55bf39 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -9,75 +9,15 @@ template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, int playerID) - : InputController(eventBroker) - , m_PlayerID(playerID) - { - EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); - EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); - } + FirstPersonInputController(EventBroker* eventBroker, int playerID); virtual const glm::vec3 Movement() const { return m_Movement; } virtual const glm::vec3 Rotation() const { return m_Rotation; } - void LockMouse() - { - Events::LockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = true; - } - - void UnlockMouse() - { - Events::UnlockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = false; - } - - virtual bool OnCommand(const Events::InputCommand& e) override - { - if (m_PlayerID != e.PlayerID) { - return false; - } - - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Rotation.x += -val; - m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); - //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } - - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Rotation.y += -val; - //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; - return true; - } - - if (e.Command == "Forward" || e.Command == "Right") { - if (e.Command == "Forward") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.z = -val; - return true; - } - if (e.Command == "Right") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.x = val; - return true; - } - if (glm::length2(m_Movement) > 0) { - m_Movement = glm::normalize(m_Movement); - } - } - - return false; - } - - virtual void Reset() - { - m_Rotation = glm::vec3(0.f, 0.f, 0.f); - } + void LockMouse(); + void UnlockMouse(); + virtual bool OnCommand(const Events::InputCommand& e) override; + virtual void Reset(); protected: const int m_PlayerID; @@ -86,9 +26,9 @@ protected: glm::vec3 m_Movement; EventRelay m_ELockMouse; - bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } + bool OnLockMouse(const Events::LockMouse& e); EventRelay m_EUnlockMouse; - bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; } + bool OnUnlockMouse(const Events::UnlockMouse& e); }; #endif \ No newline at end of file diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp new file mode 100644 index 00000000..cdacc606 --- /dev/null +++ b/src/Engine/Input/FirstPersonInputController.cpp @@ -0,0 +1,87 @@ +#include "Input/FirstPersonInputController.h" + +template +FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) +{ + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); +} + +template +void FirstPersonInputController::Reset() +{ + m_Rotation = glm::vec3(0.f, 0.f, 0.f); +} + +template +void FirstPersonInputController::LockMouse() +{ + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; +} + +template +void FirstPersonInputController::UnlockMouse() +{ + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; +} + +template +bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) +{ + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); + return true; + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; + return true; + } + + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + return true; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + return true; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + + return false; +} + +template +bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) +{ + m_MouseLocked = false; + return true; +} + +template +bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) +{ + m_MouseLocked = true; + return true; +} From 32f73201c5cc1dfca7513722889c9e332e905fdc Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:15:24 +0100 Subject: [PATCH 39/80] Basic jumping! --- .../Engine/Input/FirstPersonInputController.h | 93 +++++++++++++++++++ .../Input/FirstPersonInputController.cpp | 85 ----------------- src/Game/Systems/PlayerMovementSystem.cpp | 9 ++ 3 files changed, 102 insertions(+), 85 deletions(-) diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 4a55bf39..426670c4 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -13,6 +13,8 @@ public: virtual const glm::vec3 Movement() const { return m_Movement; } virtual const glm::vec3 Rotation() const { return m_Rotation; } + virtual bool Jumping() const { return m_Jumping; } + virtual bool Crouching() const { return m_Crouching; } void LockMouse(); void UnlockMouse(); @@ -24,6 +26,8 @@ protected: bool m_MouseLocked = false; glm::vec3 m_Rotation; glm::vec3 m_Movement; + bool m_Jumping = false; + bool m_Crouching = false; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e); @@ -31,4 +35,93 @@ protected: bool OnUnlockMouse(const Events::UnlockMouse& e); }; +template +FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) +{ + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); +} + +template +void FirstPersonInputController::Reset() +{ + m_Rotation = glm::vec3(0.f, 0.f, 0.f); + m_Jumping = false; +} + +template +void FirstPersonInputController::LockMouse() +{ + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; +} + +template +void FirstPersonInputController::UnlockMouse() +{ + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; +} + +template +bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) +{ + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Rotation.x += -val; + //m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Rotation.y += -val; + } + + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + + if (e.Command == "Jump") { + m_Jumping = e.Value > 0; + } + + if (e.Command == "Crouch") { + m_Crouching = e.Value > 0; + } + + return true; +} + +template +bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) +{ + m_MouseLocked = false; + return true; +} + +template +bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) +{ + m_MouseLocked = true; + return true; +} + #endif \ No newline at end of file diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp index cdacc606..d3757dd0 100644 --- a/src/Engine/Input/FirstPersonInputController.cpp +++ b/src/Engine/Input/FirstPersonInputController.cpp @@ -1,87 +1,2 @@ #include "Input/FirstPersonInputController.h" -template -FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) - : InputController(eventBroker) - , m_PlayerID(playerID) -{ - EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); - EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); -} - -template -void FirstPersonInputController::Reset() -{ - m_Rotation = glm::vec3(0.f, 0.f, 0.f); -} - -template -void FirstPersonInputController::LockMouse() -{ - Events::LockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = true; -} - -template -void FirstPersonInputController::UnlockMouse() -{ - Events::UnlockMouse e; - m_EventBroker->Publish(e); - m_MouseLocked = false; -} - -template -bool FirstPersonInputController::OnCommand(const Events::InputCommand& e) -{ - if (m_PlayerID != e.PlayerID) { - return false; - } - - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Rotation.x += -val; - m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi(), glm::half_pi()); - //m_Rotation = m_Rotation * glm::angleAxis(-val, glm::vec3(1.f, 0, 0)); - return true; - } - - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Rotation.y += -val; - //m_Rotation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Rotation; - return true; - } - - if (e.Command == "Forward" || e.Command == "Right") { - if (e.Command == "Forward") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.z = -val; - return true; - } - if (e.Command == "Right") { - float val = glm::clamp(e.Value, -1.f, 1.f); - m_Movement.x = val; - return true; - } - if (glm::length2(m_Movement) > 0) { - m_Movement = glm::normalize(m_Movement); - } - } - - return false; -} - -template -bool FirstPersonInputController::OnUnlockMouse(const Events::UnlockMouse& e) -{ - m_MouseLocked = false; - return true; -} - -template -bool FirstPersonInputController::OnLockMouse(const Events::LockMouse& e) -{ - m_MouseLocked = true; - return true; -} diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 843601e8..10fc29f6 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -28,6 +28,8 @@ void PlayerMovementSystem::Update(double dt) if (cameraEntity.Valid()) { glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; cameraOrientation.x += controller->Rotation().x; + // Limit camera pitch so we don't break our necks + cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi(), glm::half_pi()); } ComponentWrapper& cTransform = player["Transform"]; @@ -36,6 +38,13 @@ void PlayerMovementSystem::Update(double dt) glm::vec3& pos = cTransform["Position"]; pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + + if (player.HasComponent("Physics")) { + if (controller->Jumping()) { + glm::vec3& velocity = player["Physics"]["Velocity"]; + velocity.y += 10.f; + } + } controller->Reset(); } From 482689fd486ef4303759169e16dc3aef478ad094 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 12:16:40 +0100 Subject: [PATCH 40/80] fixup! Moved FirstPersonInputController implementation out of header --- src/Engine/Input/FirstPersonInputController.cpp | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 src/Engine/Input/FirstPersonInputController.cpp diff --git a/src/Engine/Input/FirstPersonInputController.cpp b/src/Engine/Input/FirstPersonInputController.cpp deleted file mode 100644 index d3757dd0..00000000 --- a/src/Engine/Input/FirstPersonInputController.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "Input/FirstPersonInputController.h" - From 680a12d88fc1f81dcc5f5b184f468d40716062b7 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sat, 23 Jan 2016 14:53:17 +0100 Subject: [PATCH 41/80] HealthMeter --- assets | 2 +- include/Engine/Rendering/ModelJob.h | 9 +- include/Game/Systems/PlayerHUD.h | 23 +++ resources/Schema/Components.xsd | 2 + resources/Schema/Components/Fill.xml | 5 + resources/Schema/Components/Fill.xsd | 14 ++ resources/Schema/Components/HealthHUD.xml | 2 + resources/Schema/Components/HealthHUD.xsd | 8 + resources/Schema/Entities/RenderingWorld.xml | 163 +++++++++++++------ resources/Shaders/ForwardPlus.frag.glsl | 9 + src/Engine/Editor/EditorRenderSystem.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 4 + src/Engine/Rendering/RenderSystem.cpp | 18 +- src/Game/Game.cpp | 3 + src/Game/Systems/PlayerHUD.cpp | 79 +++++++++ 15 files changed, 286 insertions(+), 57 deletions(-) create mode 100644 include/Game/Systems/PlayerHUD.h create mode 100644 resources/Schema/Components/Fill.xml create mode 100644 resources/Schema/Components/Fill.xsd create mode 100644 resources/Schema/Components/HealthHUD.xml create mode 100644 resources/Schema/Components/HealthHUD.xsd create mode 100644 src/Game/Systems/PlayerHUD.cpp diff --git a/assets b/assets index b6592dbb..e8174f63 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b6592dbb0216bbac00ccea43a0afd0e27d0b185e +Subproject commit e8174f630fc3242e15ada1346b42c72f44cbc854 diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index a88530e7..6b8bd55b 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -16,7 +16,7 @@ struct ModelJob : RenderJob { - ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world) + ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage) : RenderJob() { Model = model; @@ -33,6 +33,10 @@ struct ModelJob : RenderJob glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1)); Depth = worldpos.z; World = world; + + + FillColor = fillColor; + FillPercentage = fillPercentage; }; unsigned int TextureID; @@ -50,6 +54,9 @@ struct ModelJob : RenderJob unsigned int EndIndex = 0; World* World; + glm::vec4 FillColor = glm::vec4(0); + float FillPercentage = 0.0; + void CalculateHash() override { Hash = TextureID; diff --git a/include/Game/Systems/PlayerHUD.h b/include/Game/Systems/PlayerHUD.h new file mode 100644 index 00000000..180f5a2a --- /dev/null +++ b/include/Game/Systems/PlayerHUD.h @@ -0,0 +1,23 @@ +#ifndef PlayerHUD_h__ +#define PlayerHUD_h__ + +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" +#include "../../Engine/Rendering/ESetCamera.h" +#include + +class PlayerHUD : public ImpureSystem +{ +public: + PlayerHUD(World* world, EventBroker* eventBrokerer); + ~PlayerHUD(); + + virtual void Update(double dt) override; + +private: + World* m_World; + EventBroker* m_EventBroker; + +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 12d94611..96f93eab 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -23,4 +23,6 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/Fill.xml b/resources/Schema/Components/Fill.xml new file mode 100644 index 00000000..397f8e49 --- /dev/null +++ b/resources/Schema/Components/Fill.xml @@ -0,0 +1,5 @@ + + + 0.0 + + \ No newline at end of file diff --git a/resources/Schema/Components/Fill.xsd b/resources/Schema/Components/Fill.xsd new file mode 100644 index 00000000..2bf6548f --- /dev/null +++ b/resources/Schema/Components/Fill.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/HealthHUD.xml b/resources/Schema/Components/HealthHUD.xml new file mode 100644 index 00000000..d7e20f92 --- /dev/null +++ b/resources/Schema/Components/HealthHUD.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/HealthHUD.xsd b/resources/Schema/Components/HealthHUD.xsd new file mode 100644 index 00000000..821a65a2 --- /dev/null +++ b/resources/Schema/Components/HealthHUD.xsd @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 69b18982..7ecd25c9 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -6,34 +6,127 @@ - + - - ActionCamera - - - Models/Camera.obj - + + 69.990005493164063 + + - - + - + - - Camera #2 - Fonts/DroidSans.ttf,64 - 0 - + + Models/Assault.obj + - - + + + + + 80 + + + Models/Camera.obj + + + + + + + + + + + + + + + + + + + 0.69990003108978271 + + + + Models/Core/UnitHexagon.obj + + + + + + + + + + + + + Models/Core/UnitHexagon.obj + + + + + + + + + + + + Models/SecondaryWeapon.fbx + + + + + + + + + + + + + + + Models/Core/UnitHexagon.obj + + + + + + + + + + + + Models/SecondaryWeapon.fbx + + + + + + + + + + + + + + + + + @@ -42,7 +135,7 @@ Models/Core/UnitPlane.obj - + @@ -79,7 +172,7 @@ - + @@ -198,38 +291,6 @@ - - - - MainCamera - - - - Models/Camera.obj - false - - - - - - - - - - - Taiwan #1 - Fonts/DroidSans.ttf,64 - 0 - - - - - - - - - - diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 78a2125e..8b1ba686 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -6,6 +6,8 @@ uniform mat4 P; uniform vec4 Color; uniform vec2 ScreenDimensions; uniform sampler2D texture0; +uniform vec4 FillColor; +uniform float FillPercentage; #define TILE_SIZE 16 @@ -133,6 +135,13 @@ void main() //fragmentColor += Input.DiffuseColor; fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + + if(pos <= FillPercentage) { + fragmentColor += FillColor; + } + //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1); //fragmentColor = texel * Input.DiffuseColor * Color; diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 2e31e3f0..9e9b5206 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -48,7 +48,7 @@ void EditorRenderSystem::Update(double dt) EntityWrapper entity(m_World, cModel.EntityID); glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World); for (auto matGroup : model->MaterialGroups()) { - std::shared_ptr modelJob = std::make_shared(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World); + std::shared_ptr modelJob = std::make_shared(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f); scene.ForwardJobs.push_back(modelJob); } } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index eeaa7bb3..51bc33ba 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -51,6 +51,10 @@ void DrawFinalPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); + glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(modelJob->FillColor)); + glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), modelJob->FillPercentage); + + if(modelJob->DiffuseTexture != nullptr) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 430992f6..577fddf6 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -61,9 +61,21 @@ void RenderSystem::fillModels(std::list>& jobs) } } + + float fillPercentage = 0.f; + glm::vec4 fillColor = glm::vec4(0); + + if(m_World->HasComponent(modelComponent.EntityID, "Fill")) { + auto fillComponent = m_World->GetComponent(modelComponent.EntityID, "Fill"); + fillPercentage = (float)(double)fillComponent["Percentage"]; + fillColor = (glm::vec4)fillComponent["Color"]; + } + + + glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, m_World); for (auto matGroup : model->MaterialGroups()) { - std::shared_ptr modelJob = std::shared_ptr(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, m_World)); + std::shared_ptr modelJob = std::shared_ptr(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, m_World, fillColor, fillPercentage)); jobs.push_back(modelJob); } } @@ -141,8 +153,8 @@ void RenderSystem::fillText(std::list>& jobs, World* } glm::mat4 modelMatrix = Transform::ModelMatrix(textComponent.EntityID, world); - std::shared_ptr modelJob = std::shared_ptr(new TextJob(modelMatrix, font, textComponent)); - jobs.push_back(modelJob); + std::shared_ptr textJob = std::shared_ptr(new TextJob(modelMatrix, font, textComponent)); + jobs.push_back(textJob); } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 384c4a5b..6343cffe 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -10,6 +10,7 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" +#include "Game/Systems/PlayerHUD.h" Game::Game(int argc, char* argv[]) { @@ -86,6 +87,8 @@ Game::Game(int argc, char* argv[]) // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); + m_SystemPipeline->AddSystem(updateOrderLevel); + // Collision and TriggerSystem should update after player. ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); diff --git a/src/Game/Systems/PlayerHUD.cpp b/src/Game/Systems/PlayerHUD.cpp new file mode 100644 index 00000000..57e0e2f8 --- /dev/null +++ b/src/Game/Systems/PlayerHUD.cpp @@ -0,0 +1,79 @@ +#include "Game/Systems/PlayerHUD.h" + +PlayerHUD::PlayerHUD(World* world, EventBroker* eventBrokerer) + :System(world, eventBrokerer) + , m_World(world) + , m_EventBroker(eventBrokerer) +{ + + +} + +PlayerHUD::~PlayerHUD() +{ +// + +} + +void PlayerHUD::Update(double dt) +{ + + if(ImGui::Button("Set Camera", ImVec2(70, 20))){ + auto cameras = m_World->GetComponents("Camera"); + + if(cameras == nullptr) { + return; + } + + EntityWrapper ew = EntityWrapper(m_World, (*cameras->begin()).EntityID); + + if (ew.Valid()) { + Events::SetCamera e; + e.CameraEntity = ew; + m_EventBroker->Publish(e); + } else { + LOG_INFO("Coulnd't find a camera"); + } + } + + + auto healthHUDs = m_World->GetComponents("HealthHUD"); + if (healthHUDs == nullptr) { + return; + } + + for (auto& healthHUDComponent : *healthHUDs) { + EntityWrapper entity = EntityWrapper(m_World, healthHUDComponent.EntityID); + + EntityWrapper entityIDParent = entity; + while (entityIDParent.Parent().Valid()) { + entityIDParent = entityIDParent.Parent(); + + if (entityIDParent.HasComponent("Health")) { + break; + } + } + + if (entityIDParent.HasComponent("Health")) { + + if (entity.HasComponent("Text")) { + + std::string s = ""; + s = s + std::to_string((int)(double)entityIDParent["Health"]["Health"]); + s = s + "/"; + s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]); + + float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; + (glm::vec4&) entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, healthPercentage, 0.f, 0.f); + entity["Text"]["Content"] = s; + } + + if(entity.HasComponent("Fill")) { + float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; + (glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 0.f); + (double&)entity["Fill"]["Percentage"] = healthPercentage; + + } + } + } +} From b83d7736276ca64f31abd7e9f0f0243408f79e9d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 15:06:41 +0100 Subject: [PATCH 42/80] Infinite respawning for now --- include/Game/Systems/PlayerSpawnSystem.h | 1 + src/Game/Systems/PlayerSpawnSystem.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index eb4d3c97..b0ff1d79 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -22,6 +22,7 @@ private: bool m_NetworkEnabled = false; std::vector m_SpawnRequests; + std::map m_PlayerEntities; EventRelay m_OnInputCommand; bool OnInputCommand(const Events::InputCommand& e); diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index f18808cc..fe377866 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -72,6 +72,12 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player is actually spawned (since the actual spawning is handled on the server) + // Check if a player already exists + if (m_PlayerEntities.count(e.PlayerID) != 0) { + // TODO: Disallow infinite respawning here + m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); + } + // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { @@ -80,5 +86,8 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_EventBroker->Publish(e); } + // Store the player for future reference + m_PlayerEntities[e.PlayerID] = e.Player; + return true; } \ No newline at end of file From 666ef6589e2082751a4d7e3a5f23842d3f70f569 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 15:06:47 +0100 Subject: [PATCH 43/80] Crouching! --- resources/Schema/Components/Player.xml | 3 +- resources/Schema/Components/Player.xsd | 1 + resources/Schema/Entities/MovementTest.xml | 4 +++ resources/Schema/Entities/Player.xml | 37 +++++++++++++++++++--- src/Game/Systems/PlayerMovementSystem.cpp | 23 +++++++++++--- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index a9ecc6be..b51326aa 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,4 +1,5 @@ - 0.2 + 3 + 1.5 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 89c4a398..13948dc2 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -10,6 +10,7 @@ + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 9ea1ae68..00f94120 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -13,6 +13,7 @@ Models/Core/UnitCube.obj + false @@ -93,6 +94,7 @@ Models/Core/UnitCube.obj + false @@ -107,6 +109,7 @@ Models/Core/UnitCube.obj + false @@ -121,6 +124,7 @@ Models/Core/UnitCube.obj + false diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fa8b7686..4398dcc1 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -7,6 +7,9 @@ + + + 3 @@ -17,7 +20,7 @@ - + @@ -27,19 +30,18 @@ - - Fonts/DroidSans.ttf,100 + false - + @@ -85,6 +87,33 @@ + + + + Models/Core/UnitCube.obj + + false + + + + + + + + + + + + Models/Core/UnitCube.obj + + false + + + + + + + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 10fc29f6..c5b55cde 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -37,12 +37,27 @@ void PlayerMovementSystem::Update(double dt) ori.y += controller->Rotation().y; glm::vec3& pos = cTransform["Position"]; - pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + float speed; + if (controller->Crouching()) { + speed = player["Player"]["CrouchSpeed"]; + } else { + speed = player["Player"]["MovementSpeed"]; + } + pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; if (player.HasComponent("Physics")) { - if (controller->Jumping()) { - glm::vec3& velocity = player["Physics"]["Velocity"]; - velocity.y += 10.f; + glm::vec3& velocity = player["Physics"]["Velocity"]; + if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + velocity.y += 4.f; + } + } + + if (player.HasComponent("AABB")) { + glm::vec3& size = player["AABB"]["Size"]; + if (controller->Crouching()) { + size = glm::vec3(1.f, 1.f, 1.f); + } else { + size = glm::vec3(1.f, 1.6f, 1.f); } } From 2bf0434bcbff625d19a55bc2bc7cb1f5d2a7ff0b Mon Sep 17 00:00:00 2001 From: Jocke Date: Sat, 23 Jan 2016 16:40:38 +0100 Subject: [PATCH 44/80] Remade Snapshot logic from component based to entity based. --- include/Engine/Network/Server.h | 1 + src/Engine/Network/Client.cpp | 102 ++++++++++++++------------------ src/Engine/Network/Server.cpp | 66 +++++++++++++-------- 3 files changed, 85 insertions(+), 84 deletions(-) diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 91ea5d21..87c8d944 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -64,6 +64,7 @@ private: void send(Packet& packet); void broadcast(Packet& packet); void sendSnapshot(); + void addChildrenToPacket(Packet& packet, EntityID entityID); void sendPing(); void checkForTimeOuts(); void disconnect(UserID user); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 1dd2bd04..387961ef 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -7,13 +7,13 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) { Network::initialize(); - // Asumes root node is EntityID 0 - insertIntoServerClientMaps(0, 0); + // Asumes root node is EntityID_Invalid + insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid); // Init timer m_TimeSinceSentInputs = std::clock(); // Default is local host std::string address = config->Get("Networking.Address", "127.0.0.1"); - int port = config->Get("Networking.Port", 13); + int port = config->Get("Networking.Port", 27666); m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); // Set up network stream m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); @@ -128,13 +128,13 @@ void Client::parsePing() } void Client::parseKick() -{ +{ LOG_WARNING("You have been kicked from the server."); m_IsConnected = false; } void Client::parsePlayersSpawned(Packet& packet) -{ +{ Events::PlayerSpawned e; e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); @@ -176,66 +176,50 @@ void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, co void Client::parseSnapshot(Packet& packet) { - std::string componentType = packet.ReadString(); while (packet.DataReadSize() < packet.Size()) { - // HACK - std::string entityName = packet.ReadString(); - // Components EntityID - EntityID receivedEntityID = packet.ReadPrimitive(); - // HACK - m_World->SetName(receivedEntityID, entityName); - // Parents EntityID - EntityID receivedParentEntityID = packet.ReadPrimitive(); - ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); - // Check if the received EntityID is mapped to one of our local EntityIDs - if (serverClientMapsHasEntity(receivedEntityID)) { - // Get the local EntityID - EntityID entityID = m_ServerIDToClientID.at(receivedEntityID); - // Check if the component exists - if (m_World->HasComponent(entityID, componentType)) { - // If the entity and the component exists update it - if (componentType == "Transform") { - InterpolateFields(packet, componentInfo, entityID, componentType); + EntityID serverEntityID = packet.ReadPrimitive(); + EntityID serverParentID = packet.ReadPrimitive(); + std::string serverEntityName = packet.ReadString(); + int ammountOfComponents = packet.ReadPrimitive(); + for (int i = 0; i < ammountOfComponents; i++) { + std::string componentType = packet.ReadString(); + ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); + if (serverClientMapsHasEntity(serverEntityID)) { + EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID); + // Update entity + if (m_World->HasComponent(localEntityID, componentType)) { + // Update component + if (componentType == "Transform") { + // Interpolate only transform components + InterpolateFields(packet, componentInfo, localEntityID, componentType); + } else { + // Set component values + updateFields(packet, componentInfo, localEntityID, componentType); + } } else { - updateFields(packet, componentInfo, entityID, componentType); + // Has entity but no component + m_World->AttachComponent(localEntityID, componentType); + updateFields(packet, componentInfo, localEntityID, componentType); } - // if entity exists but not the component } else { - // Create component - m_World->AttachComponent(entityID, componentType); - // Copy data to newly created component - updateFields(packet, componentInfo, entityID, componentType); + // Create Entity and component + EntityID newLocalEntityID; + if (serverParentID == EntityID_Invalid) { + newLocalEntityID = m_World->CreateEntity(EntityID_Invalid); + } else { + newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID)); + } + m_World->SetName(newLocalEntityID, serverEntityName); + insertIntoServerClientMaps(serverEntityID, newLocalEntityID); + m_World->AttachComponent(newLocalEntityID, componentType); + updateFields(packet, componentInfo, newLocalEntityID, componentType); } - // If the entity dosent exist nor the component - } else { - // Create Entity - // If entity dosen't exist - EntityID newEntityID = m_World->CreateEntity(); - insertIntoServerClientMaps(receivedEntityID, newEntityID); - // Check if EntityIDs are out of sync - if (newEntityID != receivedEntityID) { - LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the \ - same as the one sent by server (EntityIDs are out of sync)"); - } - // Create component - m_World->AttachComponent(newEntityID, componentType); - // Copy data to newly created component - updateFields(packet, componentInfo, newEntityID, componentType); } - - // Parent Logic - // Don't need to check if receivedEntityID is mapped. (It should have been set) - if (receivedParentEntityID != std::numeric_limits::max()) { - if (serverClientMapsHasEntity(receivedParentEntityID)) { - m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), m_ServerIDToClientID.at(receivedParentEntityID)); - // If Parent dosen't exist create one and map receivedParentEntityID to it. - } else { - // Create the new parent and add it to map - EntityID newParentEntityID = m_World->CreateEntity(); - insertIntoServerClientMaps(receivedParentEntityID, newParentEntityID); - // Set the newly created Entity as parent. - m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), newParentEntityID); - } + // Parent logic + // This should be enough beacause we know that the entities arives in pre-order (there will always be a parent) + if (serverParentID != EntityID_Invalid) { + EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID); + m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID)); } } } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 9d0a83d9..98774b99 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -175,35 +175,51 @@ void Server::broadcast(Packet& packet) // Send snapshot fields void Server::sendSnapshot() { - // Should time this - std::unordered_map worldComponentPools = m_World->GetComponentPools(); - for (auto& it : worldComponentPools) { - Packet packet(MessageType::Snapshot); - ComponentPool* componentPool = it.second; - ComponentInfo componentInfo = componentPool->ComponentInfo(); + Packet packet(MessageType::Snapshot); + addChildrenToPacket(packet, EntityID_Invalid); + broadcast(packet); +} - // Component Type - packet.WriteString(componentInfo.Name); - for (auto& componentWrapper : *componentPool) { - // HACK: Send entity name - packet.WriteString(m_World->GetName(componentWrapper.EntityID)); - // Components EntityID - packet.WritePrimitive(componentWrapper.EntityID); - // Parents EntityID - packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID)); - for (auto& componentField : componentWrapper.Info.FieldsInOrder) { - ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField); - if (fieldInfo.Type == "string") { - std::string& value = componentWrapper[componentField]; - packet.WriteString(value); - } else { - packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride); +void Server::addChildrenToPacket(Packet & packet, EntityID entityID) +{ + auto itPair = m_World->GetChildren(entityID); + std::unordered_map worldComponentPools = m_World->GetComponentPools(); + // Loop through every child + for (auto it = itPair.first; it != itPair.second; it++) { + EntityID childEntityID = it->second; + // Write EntityID and parentsID and Entity name + packet.WritePrimitive(childEntityID); + packet.WritePrimitive(entityID); + packet.WriteString(m_World->GetName(childEntityID)); + // Write components to child + int numberOfComponents = 0; + for (auto& i : worldComponentPools) { + if (i.second->KnowsEntity(childEntityID)) { + numberOfComponents++; + } + } + // Write how many components should be read + packet.WritePrimitive(numberOfComponents); + for (auto& i : worldComponentPools) { + // If the entity exist in the pool + if (i.second->KnowsEntity(childEntityID)) { + ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID); + // ComponentType + packet.WriteString(componentWrapper.Info.Name); + // Loop through fields + for (auto& componentField : componentWrapper.Info.FieldsInOrder) { + ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField); + if (fieldInfo.Type == "string") { + std::string& value = componentWrapper[componentField]; + packet.WriteString(value); + } else { + packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride); + } } } } - if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) { - broadcast(packet); - } + // Go to to your children + addChildrenToPacket(packet, childEntityID); } } From f1835fd89c2abcd9e069bc3e4074cd42db1db8ef Mon Sep 17 00:00:00 2001 From: antc13 Date: Sat, 23 Jan 2016 18:02:42 +0100 Subject: [PATCH 45/80] Animations PROBABLY works fine if all joints got keyframes. --- include/Engine/Collision/Collision.h | 4 +- .../Rendering/DebugCameraInputController.h | 2 +- include/Engine/Rendering/Model.h | 3 +- include/Engine/Rendering/RawModelAssimp.h | 11 +- include/Engine/Rendering/RawModelCustom.h | 17 ++- include/Engine/Rendering/Skeleton.h | 1 + resources/Schema/Entities/Model.xml | 2 +- resources/Shaders/ForwardPlus.vert.glsl | 13 ++- src/Engine/Editor/EditorSystem.cpp | 12 ++ src/Engine/Rendering/DrawFinalPass.cpp | 20 +++- src/Engine/Rendering/Model.cpp | 3 + src/Engine/Rendering/RawModelAssimp.cpp | 11 +- src/Engine/Rendering/RawModelCustom.cpp | 46 ++++---- src/Engine/Rendering/RenderSystem.cpp | 8 ++ src/Engine/Rendering/Skeleton.cpp | 9 +- src/Tests/CollisionTest.cpp | 4 +- tools/MayaExporter/MayaExporter/Export.cpp | 59 ++++++++-- .../MayaExporter/MayaExporter/MayaIncludes.h | 3 + tools/MayaExporter/MayaExporter/Menu.cpp | 16 +-- tools/MayaExporter/MayaExporter/Mesh.cpp | 61 ++++++---- tools/MayaExporter/MayaExporter/Skeleton.cpp | 104 ++++++++++++++++-- 21 files changed, 325 insertions(+), 84 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 207d4893..194a18dc 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -10,8 +10,8 @@ #include "../Core/Ray.h" #include "../Core/AABB.h" -//#include "Engine/Rendering/RawModelAssimp.h" -#include "Engine/Rendering/RawModelCustom.h" +#include "Rendering/RawModelCustom.h" +//#include "Rendering/RawModelAssimp.h" #include "../Core/Transform.h" #include "../Core/Entity.h" #include "../Core/EntityWrapper.h" diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h index 4d74e288..d69098c2 100644 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -61,6 +61,6 @@ public: protected: glm::vec3 m_Position = glm::vec3(0, 0, 0); glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 2.0f; + float m_BaseSpeed = 50.0f;//2.0f; float m_Speed = m_BaseSpeed; }; \ No newline at end of file diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index 4b83562c..f751a8cc 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -1,7 +1,8 @@ #ifndef Model_h__ #define Model_h__ -#include "RawModelCustom.h" +#include "Rendering/RawModelCustom.h" +//#include "Rendering/RawModelAssimp.h" #include "../OpenGL.h" class Model : public ThreadUnsafeResource diff --git a/include/Engine/Rendering/RawModelAssimp.h b/include/Engine/Rendering/RawModelAssimp.h index 92258782..08df818d 100644 --- a/include/Engine/Rendering/RawModelAssimp.h +++ b/include/Engine/Rendering/RawModelAssimp.h @@ -1,6 +1,8 @@ #ifndef RawModelAssimp_h__ #define RawModelAssimp_h__ +#ifdef USING_ASSIMP_AS_IMPORTER + #include #include #include @@ -18,15 +20,17 @@ #include "Texture.h" #include "Skeleton.h" -class RawModel : public Resource +#define RawModel RawModelAssimp + +class RawModelAssimp : public Resource { friend class ResourceManager; protected: - RawModel(std::string fileName); + RawModelAssimp(std::string fileName); public: - ~RawModel(); + ~RawModelAssimp(); struct Vertex { @@ -72,3 +76,4 @@ private: }; #endif +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index a3c29f62..2dea51ff 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -1,6 +1,10 @@ #ifndef RawModelCustom_h__ #define RawModelCustom_h__ +#ifndef USING_ASSIMP_AS_IMPORTER + +#define RawModel RawModelCustom + #include #include #include @@ -17,15 +21,17 @@ #include "boost\endian\buffers.hpp" -class RawModel : public Resource + + +class RawModelCustom : public Resource { friend class ResourceManager; protected: - RawModel(std::string fileName); + RawModelCustom(std::string fileName); public: - ~RawModel(); + ~RawModelCustom(); struct Vertex { @@ -85,4 +91,9 @@ private: //void CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID); }; +#else + +#include "RawModelAssimp.h" + #endif +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 4a4d507b..3b89b89b 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -4,6 +4,7 @@ #include #include "Common.h" #include "../GLM.h" +#include //struct Bone //{ diff --git a/resources/Schema/Entities/Model.xml b/resources/Schema/Entities/Model.xml index 6534815c..57856cbd 100644 --- a/resources/Schema/Entities/Model.xml +++ b/resources/Schema/Entities/Model.xml @@ -19,7 +19,7 @@ - models/Baljj.mesh + models/animTest.mesh diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index e4b4eacc..aa8c9446 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -3,6 +3,7 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; +uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; @@ -20,9 +21,17 @@ out VertexData{ void main() { - gl_Position = P*V*M * vec4(Position, 1.0); - Output.Position = Position; + + mat4 boneTransform = mat4(1); + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + + Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; Output.TextureCoordinate = TextureCoords; Output.Normal = vec3(M * vec4(Normal, 0.0)); } \ No newline at end of file diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 547a96e1..46aad8df 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -292,21 +292,33 @@ void EditorSystem::createWidget() m_WidgetPlaneX = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneX, "Transform"); m_World->AttachComponent(m_WidgetPlaneX, "Model"); +#ifdef USING_ASSIMP_AS_IMPORTER + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneX +#else m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneX +#endif m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); m_World->AttachComponent(m_WidgetY, "Model"); m_WidgetPlaneY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneY, "Transform"); m_World->AttachComponent(m_WidgetPlaneY, "Model"); +#ifdef USING_ASSIMP_AS_IMPORTER + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneY +#else m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneY +#endif m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); m_World->AttachComponent(m_WidgetZ, "Model"); m_WidgetPlaneZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetPlaneZ, "Transform"); m_World->AttachComponent(m_WidgetPlaneZ, "Model"); +#ifdef USING_ASSIMP_AS_IMPORTER + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneZ +#else m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneZ +#endif m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); m_World->AttachComponent(m_WidgetOrigin, "Model"); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 7093b00f..1dd5f9bc 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -22,6 +22,8 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusProgram->Link(); } +static double tempFrameCounter = 6.348; + void DrawFinalPass::Draw(RenderScene& scene) { GLERROR("DrawFinalPass::Draw: Pre"); @@ -38,6 +40,7 @@ void DrawFinalPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix())); glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + //tempFrameCounter += 0.01; //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : scene.ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); @@ -54,6 +57,21 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { +#ifdef USING_ASSIMP_AS_IMPORTER + auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("combinedAnim_0"); +#else + auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); +#endif + if (animation != nullptr) { + std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( + *animation, + tempFrameCounter + ); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + // -3 - 9 glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); @@ -61,4 +79,4 @@ void DrawFinalPass::Draw(RenderScene& scene) } GLERROR("DrawFinalPass::Draw: END"); -} +} \ No newline at end of file diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index c8a2bc41..cf4923a3 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -15,6 +15,9 @@ Model::Model(std::string fileName) if (!group.SpecularMapPath.empty()) { group.SpecularMap = std::shared_ptr(ResourceManager::Load(group.SpecularMapPath)); } + if (!group.IncandescenceMapPath.empty()) { + group.IncandescenceMap = std::shared_ptr(ResourceManager::Load(group.IncandescenceMapPath)); + } } // Generate GL buffers diff --git a/src/Engine/Rendering/RawModelAssimp.cpp b/src/Engine/Rendering/RawModelAssimp.cpp index 259eafc3..6bc3f3f7 100644 --- a/src/Engine/Rendering/RawModelAssimp.cpp +++ b/src/Engine/Rendering/RawModelAssimp.cpp @@ -1,6 +1,8 @@ #include "Rendering/RawModelAssimp.h" -RawModel::RawModel(std::string fileName) +#ifdef USING_ASSIMP_AS_IMPORTER + +RawModelAssimp::RawModelAssimp(std::string fileName) { Assimp::Importer importer; const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate); @@ -271,16 +273,17 @@ RawModel::RawModel(std::string fileName) m_Skeleton->Animations[animationName] = skelAnim; } + int k = 0; } -RawModel::~RawModel() +RawModelAssimp::~RawModelAssimp() { if (m_Skeleton) { delete m_Skeleton; } } -void RawModel::CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID) +void RawModelAssimp::CreateSkeleton(std::vector> &boneInfo, std::map &boneNameMapping, aiNode* node, int parentID) { std::string nodeName = node->mName.C_Str(); @@ -300,3 +303,5 @@ void RawModel::CreateSkeleton(std::vector> &b CreateSkeleton(boneInfo, boneNameMapping, child, parentID); } } + +#endif \ No newline at end of file diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index f7354d92..7c387dd9 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -1,6 +1,8 @@ #include "Rendering/RawModelCustom.h" -RawModel::RawModel(std::string fileName) +#ifndef USING_ASSIMP_AS_IMPORTER + +RawModelCustom::RawModelCustom(std::string fileName) { fileName = fileName.erase(fileName.find_last_of("."), fileName.find_last_of(".") - fileName.size()); ReadMeshFile(fileName); @@ -9,7 +11,7 @@ RawModel::RawModel(std::string fileName) int k = 0; } -void RawModel::ReadMeshFile(std::string filePath) +void RawModelCustom::ReadMeshFile(std::string filePath) { char* fileData; filePath += ".mesh"; @@ -33,7 +35,7 @@ void RawModel::ReadMeshFile(std::string filePath) delete fileData; } -void RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN m_Vertices.resize(*(unsigned int*)(fileData + offset)); @@ -44,13 +46,13 @@ void RawModel::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned #endif } -void RawModel::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { ReadVertices(offset, fileData, fileByteSize); ReadIndices(offset, fileData, fileByteSize); } -void RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) { @@ -63,7 +65,7 @@ void RawModel::ReadVertices(unsigned int& offset, char* fileData, unsigned int& #endif } -void RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) { @@ -77,7 +79,7 @@ void RawModel::ReadIndices(unsigned int& offset, char* fileData, unsigned int& f #endif } -void RawModel::ReadMaterialFile(std::string filePath) +void RawModelCustom::ReadMaterialFile(std::string filePath) { char* fileData; filePath += ".mtrl"; @@ -100,7 +102,7 @@ void RawModel::ReadMaterialFile(std::string filePath) delete fileData; } -void RawModel::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN unsigned int* numMaterials = (unsigned int*)(fileData); @@ -114,7 +116,7 @@ void RawModel::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& #endif } -void RawModel::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize) { MaterialGroup newMaterial; @@ -189,7 +191,7 @@ void RawModel::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned MaterialGroups.push_back(newMaterial); } -void RawModel::ReadAnimationFile(std::string filePath) +void RawModelCustom::ReadAnimationFile(std::string filePath) { char* fileData; filePath += ".anim"; @@ -214,7 +216,7 @@ void RawModel::ReadAnimationFile(std::string filePath) #ifdef BOOST_LITTLE_ENDIAN unsigned int numBindPoses = *(unsigned int*)(fileData); offset += sizeof(unsigned int); - unsigned int numAnimations = *(unsigned int*)(fileData); + unsigned int numAnimations = *(unsigned int*)(fileData + offset); offset += sizeof(unsigned int); #else #endif @@ -225,7 +227,7 @@ void RawModel::ReadAnimationFile(std::string filePath) delete fileData; } -void RawModel::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN unsigned int* numBones = (unsigned int*)(fileData + offset); @@ -238,7 +240,7 @@ void RawModel::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsi #endif } -void RawModel::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize) +void RawModelCustom::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize) { #ifdef BOOST_LITTLE_ENDIAN if (offset + sizeof(unsigned int) > fileByteSize) { @@ -259,7 +261,7 @@ void RawModel::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned glm::mat4 offsetMatrix; memcpy(&offsetMatrix, fileData + offset, sizeof(float) * 4 * 4); offset += sizeof(float) * 4 * 4; - + if (offset + sizeof(int) > fileByteSize) { throw Resource::FailedLoadingException("Reading Joint ID failed"); } @@ -280,14 +282,14 @@ void RawModel::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned #endif } -void RawModel::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips) +void RawModelCustom::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips) { for (unsigned int i = 0; i < numberOfClips; i++) { ReadAnimationClipSingle(offset, fileData, fileByteSize, i); } } -void RawModel::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex) +void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex) { #ifdef BOOST_LITTLE_ENDIAN Skeleton::Animation newAnimation; @@ -332,7 +334,7 @@ void RawModel::ReadAnimationClipSingle(unsigned int &offset, char* fileData, uns #endif } -void RawModel::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation) +void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation) { Skeleton::Animation::Keyframe newKeyFrame; @@ -356,12 +358,16 @@ void RawModel::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsig for (unsigned int i = 0; i < nrOfJoints; i++) { memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty)); offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty); - newKeyFrame.BoneProperties[i] = newBone; + newKeyFrame.BoneProperties[newBone.ID] = newBone; } animation.Keyframes.push_back(newKeyFrame); } -RawModel::~RawModel() +RawModelCustom::~RawModelCustom() { + if (m_Skeleton != nullptr) { + delete m_Skeleton; + } +} -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 2a6a49c2..5d9d474d 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -96,10 +96,18 @@ void RenderSystem::fillModels(std::list>& jobs, World model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; +#ifdef USING_ASSIMP_AS_IMPORTER + model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope StillLoading mesh +#else model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope StillLoading mesh +#endif } catch (const std::exception&) { try { +#ifdef USING_ASSIMP_AS_IMPORTER + model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope Error mesh +#else model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope Error mesh +#endif } catch (const std::exception&) { continue; } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 44276308..986e634c 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -68,7 +68,7 @@ std::vector Skeleton::GetFrameBones(const Animation& animation, doubl void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) { - glm::mat4 boneMatrix; + glm::mat4 boneMatrix; if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) { Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID); @@ -84,10 +84,14 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf positionInterp.z = 0; } + boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + int k = 0; } else { - boneMatrix = parentMatrix * bone->Parent->OffsetMatrix; // * glm::inverse(bone->OffsetMatrix); + if (bone->Parent) { + boneMatrix = parentMatrix * bone->Parent->OffsetMatrix * glm::translate(glm::vec3(1.718, 0, 0)); // * glm::inverse(bone->OffsetMatrix); + } boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; } @@ -95,6 +99,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf std::string name = child->Name; AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix); } + } int Skeleton::GetBoneID(std::string name) diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 4ba7ca87..767fbe3a 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -27,7 +27,9 @@ using boost::unit_test_framework::test_case; void RayTest(std::string fileName) { //simple box test Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0)); - //using a rawmodel here, else we have to init the renderingsystem + //using a + + here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); auto unitBox = ResourceManager::Load(fileName); BOOST_REQUIRE(unitBox != nullptr); diff --git a/tools/MayaExporter/MayaExporter/Export.cpp b/tools/MayaExporter/MayaExporter/Export.cpp index d25faa4c..d8f1abd4 100644 --- a/tools/MayaExporter/MayaExporter/Export.cpp +++ b/tools/MayaExporter/MayaExporter/Export.cpp @@ -7,26 +7,56 @@ Export::Export() bool Export::Meshes(std::string pathName, bool selectedOnly) { + MStatus status; if (pathName.empty()) { MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file"); return false; } + MSelectionList selectedOnStart; MGlobal::getActiveSelectionList(selectedOnStart); - + if (selectedOnStart.length() > 0) { + for (int i = 0; i < selectedOnStart.length(); i++) { + MObject item; + selectedOnStart.getDependNode(i, item); + MGlobal::unselect(item); + } + } + MGlobal::displayInfo(MString() + "Disabel IKSolvers"); + status = MGlobal::executeCommand("doEnableNodeItems false all;"); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "EnableNodeItems false all failed: " + status.errorString()); + } + MGlobal::displayInfo(MString() + "Has disabel IKSolvers"); MObjectArray Objects; if (selectedOnly) { // Retrieving the objects we currently have selected - MSelectionList selected; - 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 < selectedOnStart.length(); i++) { MObject object; - selected.getDependNode(i, object); + selectedOnStart.getDependNode(i, object); if (object.hasFn(MFn::kMesh)) { - MFnDependencyNode thisNode(object); + MFnMesh shape(object); + + for (unsigned int k = 0; k < shape.parentCount(); k++) { + MFnDependencyNode thisNode(object); + MPlugArray connections; + thisNode.findPlug("inMesh").connectedTo(connections, true, true); + + for (unsigned int i = 0; i < connections.length(); i++) { + if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { + MGlobal::select(shape.parent(i), MGlobal::kReplaceList); + MGlobal::displayInfo(MString() + "Moving " + thisNode.name() + " to bindPose."); + status = MGlobal::executeCommand("GoToBindPose;"); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "GoToBindPose: " + status.errorString()); + } + MGlobal::displayInfo(MString() + "Has moved " + thisNode.name() + " to bindPose."); + } + } + } Objects.append(object); } } @@ -42,7 +72,9 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) for (unsigned int i = 0; i < connections.length(); i++) { if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { MGlobal::select(node); - MGlobal::executeCommand("gotoBindPose"); + MGlobal::displayInfo(MString() + "Moving " + thisNode.name() + " to bindPose."); + MGlobal::executeCommand("GoToBindPose"); + MGlobal::displayInfo(MString() + "Has moved " + thisNode.name() + " to bindPose."); } } @@ -51,6 +83,19 @@ bool Export::Meshes(std::string pathName, bool selectedOnly) } GetMeshData(Objects); WriteMeshData(pathName); + MGlobal::displayInfo(MString() + "Enabling IKSolvers"); + status = MGlobal::executeCommand("doEnableNodeItems true all;"); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "doEnableNodeItems true all: " + status.errorString()); + } + MGlobal::displayInfo(MString() + "Has enabling IKSolvers"); + if (selectedOnStart.length() > 0) { + for (int i = 0; i < selectedOnStart.length(); i++) { + MObject item; + selectedOnStart.getDependNode(i, item); + MGlobal::select(item); + } + } return true; } diff --git a/tools/MayaExporter/MayaExporter/MayaIncludes.h b/tools/MayaExporter/MayaExporter/MayaIncludes.h index 66527470..7322bdc5 100644 --- a/tools/MayaExporter/MayaExporter/MayaIncludes.h +++ b/tools/MayaExporter/MayaExporter/MayaIncludes.h @@ -42,6 +42,9 @@ #include #include #include +#include +#include +#include // Wrappers diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index a03788a6..897cc655 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -60,7 +60,7 @@ Menu::Menu(QDialog* dialog) m_ExportPath = new QLineEdit; m_FileDialog = new QFileDialog; - QString tmpPath("C:/Users/Nickelodion/Desktop/Baljj"); + QString tmpPath("C:/Users/Nickelodion/Desktop/animTest"); m_ExportPath->setText(tmpPath); QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); @@ -175,6 +175,13 @@ void Menu::ExportAll(bool) return; } + if (m_ExportMaterialButton->isChecked()) { + if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) { + MGlobal::displayError(MString() + "Could not export materials"); + return; + } + } + std::vector animations; for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { Export::AnimationInfo thisClip; @@ -191,13 +198,6 @@ void Menu::ExportAll(bool) return; } } - - if (m_ExportMaterialButton->isChecked()) { - if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())){ - MGlobal::displayError(MString() + "Could not export materials"); - return; - } - } } void Menu::CancelClicked(bool) diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 2062bad5..26d5c7b2 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -68,7 +68,6 @@ std::map MeshClass::GetWeightData() break; } MFnDependencyNode test(comp); - unsigned int nrOfWeights = 0; for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) { @@ -90,7 +89,7 @@ std::map MeshClass::GetWeightData() for (unsigned int k = 0; k!=nrOfWeights; k++) { - //MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]); + MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]); } geomIter.next(); } @@ -109,6 +108,26 @@ Mesh MeshClass::GetMeshData(MObjectArray object) if (!object[ObjectID].hasFn(MFn::kMesh)) continue; + MObject node = object[ObjectID]; + MFnDependencyNode thisNode(node); + MPlugArray connections; + thisNode.findPlug("inMesh").connectedTo(connections, true, true); + MGlobal::displayInfo(MString() + "inMesh"); + bool hasSkin = false; + MPlug weightList, weights; + MObject weightListObject; + for (unsigned int i = 0; i < connections.length(); i++) { + if (connections[i].node().apiType() == MFn::kSkinClusterFilter) { + MFnSkinCluster skinCluster(connections[i].node()); + weightList = skinCluster.findPlug("weightList", &status); + weightListObject = weightList.attribute(); + weights = skinCluster.findPlug("weights"); + hasSkin = true; + break; + } + } + + // In here, we retrieve triangulated polygons from the mesh MFnMesh mesh(object[ObjectID]); MDagPathArray dagPaths; @@ -178,7 +197,7 @@ Mesh MeshClass::GetMeshData(MObjectArray object) } } - map vertexWeights = GetWeightData(); + // map vertexWeights = GetWeightData(); status = mesh.getTangents(Tangents, MSpace::kObject); if (status != MS::kSuccess) { MGlobal::displayError(MString() + "mesh.getTangents ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName()); @@ -288,27 +307,25 @@ Mesh MeshClass::GetMeshData(MObjectArray object) thisVertex.Uv[0] = UV[0]; thisVertex.Uv[1] = UV[1]; - 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]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[0]) > 0.0001) - thisVertex.BoneWeights[0] = vertexWeights[faceVert.vertId()].BoneWeights[0]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[1]) > 0.0001) - thisVertex.BoneWeights[1] = vertexWeights[faceVert.vertId()].BoneWeights[1]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[2]) > 0.0001) - thisVertex.BoneWeights[2] = vertexWeights[faceVert.vertId()].BoneWeights[2]; - if (abs(vertexWeights[faceVert.vertId()].BoneWeights[3]) > 0.0001) - thisVertex.BoneWeights[3] = vertexWeights[faceVert.vertId()].BoneWeights[3]; - - float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; - if (totalWeight < 1.00f && totalWeight > 0.01f) { - thisVertex.BoneWeights[0] /= totalWeight; - thisVertex.BoneWeights[1] /= totalWeight; - thisVertex.BoneWeights[2] /= totalWeight; - thisVertex.BoneWeights[3] /= totalWeight; + + if (hasSkin) { + MIntArray jointIDs /* ??? */; + weights.selectAncestorLogicalIndex(vertexIndex, weightListObject); + weights.getExistingArrayAttributeIndices(jointIDs); + for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) { + thisVertex.BoneIndices[i] = jointIDs[i]; + thisVertex.BoneWeights[i] = weights[i].asFloat(); + } } + //float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; + //if (totalWeight > 0.0001f) { + // thisVertex.BoneWeights[0] /= totalWeight; + // thisVertex.BoneWeights[1] /= totalWeight; + // thisVertex.BoneWeights[2] /= totalWeight; + // thisVertex.BoneWeights[3] /= totalWeight; + //} + std::vector::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex); array tmp; if (it != vertexList.end()) { diff --git a/tools/MayaExporter/MayaExporter/Skeleton.cpp b/tools/MayaExporter/MayaExporter/Skeleton.cpp index 9f887561..c30311b8 100644 --- a/tools/MayaExporter/MayaExporter/Skeleton.cpp +++ b/tools/MayaExporter/MayaExporter/Skeleton.cpp @@ -64,6 +64,7 @@ std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY" Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame) { + MStatus status; std::vector animatedJoints; std::vector m_Hierarchy; @@ -121,7 +122,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MFnMatrixData MartixFn(DataHandle.data()); MMatrix BindPoseMatrix = MartixFn.matrix(); - if (BindPoseMatrix != MayaJoint.transformationMatrix()) + if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix())) { MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " 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"); } @@ -153,19 +154,43 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e MGlobal::displayError(MString() + "Could not find joint ID for: " + thisJoint.name()); } - MMatrix Matrix = thisJoint.transformationMatrix(); - + MTransformationMatrix Matrix = thisJoint.transformation(); + MPlug BindPose = thisJoint.findPlug("bindPose"); + MDataHandle DataHandle; + BindPose.getValue(DataHandle); + MFnMatrixData MartixFn(DataHandle.data()); + MMatrix BindPoseMatrix = MartixFn.matrix(); + Matrix = Matrix.asMatrix(); + + MObject jointOrientObj = thisJoint.attribute("jointOrient"); + MFnNumericAttribute jointOrient(jointOrientObj); + double jointOrientDouble[3]; + jointOrient.getDefault(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]); + //MGlobal::displayError(MString() + "Joint Matrix: "); + //MGlobal::displayError(MString() + Matrix.asMatrix()[0][0] + " " + Matrix.asMatrix()[0][1] + " " + Matrix.asMatrix()[0][2] + " " + Matrix.asMatrix()[0][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[1][0] + " " + Matrix.asMatrix()[1][1] + " " + Matrix.asMatrix()[1][2] + " " + Matrix.asMatrix()[1][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[2][0] + " " + Matrix.asMatrix()[2][1] + " " + Matrix.asMatrix()[2][2] + " " + Matrix.asMatrix()[2][3]); + //MGlobal::displayError(MString() + Matrix.asMatrix()[3][0] + " " + Matrix.asMatrix()[3][1] + " " + Matrix.asMatrix()[3][2] + " " + Matrix.asMatrix()[3][3]); + + MEulerRotation joEuler(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]); + MQuaternion jo = joEuler.asQuaternion(); + double tmp[4]; - thisJoint.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + Matrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]); + MQuaternion rotation(tmp); + + rotation = rotation * jo; + rotation.get(tmp); + 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); + Matrix.getTranslation(MSpace::kTransform).get(tmp); joint.Position[0] = tmp[0]; joint.Position[1] = tmp[1]; joint.Position[2] = tmp[2]; - thisJoint.getScale(tmp); + Matrix.getScale(tmp, MSpace::kTransform); joint.Scale[0] = tmp[0]; joint.Scale[1] = tmp[1]; joint.Scale[2] = tmp[2]; @@ -184,6 +209,7 @@ Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int e std::vector Skeleton::GetBindPoses() { + MStatus status; std::vector m_AllSkeletons; std::vector m_Hierarchy; @@ -214,12 +240,76 @@ std::vector Skeleton::GetBindPoses() } m_Hierarchy.push_back(MayaJoint.object()); - MPlug BindPose = MayaJoint.findPlug("bindPose"); + MPlug BindPose = MayaJoint.findPlug("bindPose", &status); + if (status != MS::kSuccess) { + MGlobal::displayError(MString() + "Could not find bindPose plug: " + status.errorString()); + } MDataHandle DataHandle; BindPose.getValue(DataHandle); MFnMatrixData MartixFn(DataHandle.data()); MMatrix Matrix = MartixFn.matrix(); + + MVector tmp = MayaJoint.transformation().getTranslation(MSpace::kObject); + MGlobal::displayError(MString() + "translation befor: " + tmp[0] + " " + tmp[1] + " " + tmp[2]); + //Matrix[3][0] *= -1; + //Matrix[3][2] *= -1; + //Matrix[3][1] *= -1; + + double test[3]; + MayaJoint.transformation().getScale(test, MSpace::kObject); + MGlobal::displayError(MString() + "scale: " + test[0] + " " + test[1] + " " + test[2]); + + MTransformationMatrix::RotationOrder order = MTransformationMatrix::RotationOrder::kXYZ; + MayaJoint.transformation().getRotation(test, order); + MGlobal::displayError(MString() + "rotation: " + test[0] + " " + test[1] + " " + test[2]); + + //----- test + + + //MDataHandle DataHandle; + //MObject jointObject(jointIt.currentItem()); + //MFnDependencyNode jointDependNode(jointObject); + //MPlug worldMatrixArray(jointObject, jointDependNode.attribute("worldMatrix")); + + //MMatrix Matrix; + //for (int i = 0; i < worldMatrixArray.numElements(); i++) { + // MPlugArray connections; + + // MPlug element = worldMatrixArray[i]; + // unsigned int logicalIndex = element.logicalIndex(); + + // MItDependencyGraph it(element, MFn::kSkinClusterFilter); + + // for (; !it.isDone(); it.next()) { + // MFnSkinCluster skinCluster(it.thisNode()); + + // MPlug bindPreMatrixArrayPlug = + // skinCluster.findPlug("bindPreMatrix", &status); + + // if (status != MS::kSuccess) { + // MGlobal::displayError(MString() + "Could not find bindPreMatrix plug: " + status.errorString()); + // break; + // } + + // MPlug bindPreMatrixPlug = + // bindPreMatrixArrayPlug.elementByLogicalIndex(logicalIndex); + // MObject dataObject; + // bindPreMatrixPlug.getValue(dataObject); + + // MFnMatrixData matDataFn(dataObject); + + // MMatrix invMat = matDataFn.matrix(); + // Matrix = invMat.inverse(); + // } + //} + + + //----- end test + + + Matrix = Matrix.inverse(); + for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j]; From 1ce9128da8c76220f19f37e0df4037a4cfc6613b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 23 Jan 2016 19:45:23 +0100 Subject: [PATCH 46/80] Source-like movement --- include/Game/Systems/PlayerMovementSystem.h | 1 + resources/Schema/Entities/Player.xml | 13 ++-- src/Game/Systems/PlayerMovementSystem.cpp | 67 +++++++++++++++------ 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 72f3b879..f39740ec 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -3,6 +3,7 @@ #include "Core/System.h" #include "Core/EPlayerSpawned.h" #include "Input/FirstPersonInputController.h" +#include class PlayerMovementSystem : public ImpureSystem, PureSystem { diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4398dcc1..58550357 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,13 +6,12 @@ - - - - - + + + false + - 3 + 7 @@ -20,7 +19,7 @@ - + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index c5b55cde..ae54d684 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -36,29 +36,51 @@ void PlayerMovementSystem::Update(double dt) glm::vec3& ori = cTransform["Orientation"]; ori.y += controller->Rotation().y; - glm::vec3& pos = cTransform["Position"]; - float speed; - if (controller->Crouching()) { - speed = player["Player"]["CrouchSpeed"]; - } else { - speed = player["Player"]["MovementSpeed"]; - } - pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; - if (player.HasComponent("Physics")) { - glm::vec3& velocity = player["Physics"]["Velocity"]; - if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { - velocity.y += 4.f; - } - } + ComponentWrapper cPhysics = player["Physics"]; - if (player.HasComponent("AABB")) { - glm::vec3& size = player["AABB"]["Size"]; + glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); + float wishSpeed; if (controller->Crouching()) { - size = glm::vec3(1.f, 1.f, 1.f); + wishSpeed = player["Player"]["CrouchSpeed"]; } else { - size = glm::vec3(1.f, 1.6f, 1.f); + wishSpeed = player["Player"]["MovementSpeed"]; } + glm::vec3& velocity = cPhysics["Velocity"]; + ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); + ImGui::Text("wishDirection: (%f, %f, %f)", wishDirection.x, wishDirection.y, wishDirection.z); + float currentSpeedProj = glm::dot(velocity, wishDirection); + float addSpeed = wishSpeed - currentSpeedProj; + ImGui::Text("currentSpeedProj: %f", currentSpeedProj); + ImGui::Text("wishSpeed: %f", wishSpeed); + ImGui::Text("addSpeed: %f", addSpeed); + + if (addSpeed > 0) { + static float accel = 15.f; + ImGui::InputFloat("accel", &accel); + float actualAccel = accel; + static float surfaceFriction = 1.f; + ImGui::InputFloat("surfaceFriction", &surfaceFriction); + float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction; + accelerationSpeed = glm::min(accelerationSpeed, addSpeed); + velocity += accelerationSpeed * wishDirection; + ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); + } + //pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; + + //glm::vec3& velocity = player["Physics"]["Velocity"]; + //if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + // velocity.y += 4.f; + //} + + //if (player.HasComponent("AABB")) { + // glm::vec3& size = player["AABB"]["Size"]; + // if (controller->Crouching()) { + // size = glm::vec3(1.f, 1.f, 1.f); + // } else { + // size = glm::vec3(1.f, 1.6f, 1.f); + // } + //} } controller->Reset(); @@ -78,6 +100,15 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp velocity.y -= 9.82f * (float)dt; } + // Ground friction + float speed = glm::length(velocity); + static float groundFriction = 7.f; + ImGui::InputFloat("groundFriction", &groundFriction); + if (speed > 0) { + float drop = speed * groundFriction * (float)dt; + velocity *= glm::max(speed - drop, 0.f) / speed; + } + glm::vec3& position = cTransform["Position"]; position += velocity * (float)dt; } From 3baa988ad46ab495e51e387b0d0a6a412697a5fc Mon Sep 17 00:00:00 2001 From: antc13 Date: Sat, 23 Jan 2016 20:35:58 +0100 Subject: [PATCH 47/80] Changed .obj files to our own format. DummyScene.mesh may be broken. --- .../Rendering/DebugCameraInputController.h | 2 +- .../Schema/Entities/CollisionTestLevel.xml | 14 ++++----- resources/Schema/Entities/EditorTestWorld.xml | 8 ++--- resources/Schema/Entities/MovementTest.xml | 6 ++-- resources/Schema/Entities/OctreeTest.xml | 6 ++-- resources/Schema/Entities/Player.xml | 2 +- resources/Schema/Entities/RaptorCopter.xml | 8 ++--- resources/Schema/Entities/RenderingWorld.xml | 6 ++-- resources/Schema/Entities/SoundTestLevel.xml | 2 +- resources/Schema/Entities/SpawnTest.xml | 4 +-- resources/Shaders/ForwardPlus.vert.glsl | 2 ++ src/Engine/Editor/EditorSystem.cpp | 26 ++++++++-------- src/Engine/Network/Client.cpp | 2 +- src/Engine/Network/Server.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 12 ++----- src/Engine/Rendering/RawModelCustom.cpp | 15 +++++---- src/Engine/Rendering/RenderSystem.cpp | 4 +-- src/Engine/Sound/SoundSystem.cpp | 2 +- src/Tests/CollisionTest.cpp | 10 +++--- src/Tests/HealthSystemTest.cpp | 4 +-- src/Tests/OctTreeTestGameClass.cpp | 2 +- src/Tests/OctTreeTestHardCodedTestWorld.h | 4 +-- src/Tests/OldOctTree.cpp | 2 +- src/Tests/ResourceManagerTest.cpp | 4 +-- tools/MayaExporter/MayaExporter/Material.cpp | 31 ++++++++++++++----- tools/MayaExporter/MayaExporter/Menu.cpp | 2 +- 26 files changed, 99 insertions(+), 83 deletions(-) diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h index d69098c2..4d74e288 100644 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -61,6 +61,6 @@ public: protected: glm::vec3 m_Position = glm::vec3(0, 0, 0); glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 50.0f;//2.0f; + float m_BaseSpeed = 2.0f; float m_Speed = m_BaseSpeed; }; \ No newline at end of file diff --git a/resources/Schema/Entities/CollisionTestLevel.xml b/resources/Schema/Entities/CollisionTestLevel.xml index d5e932c2..e58ab6ce 100644 --- a/resources/Schema/Entities/CollisionTestLevel.xml +++ b/resources/Schema/Entities/CollisionTestLevel.xml @@ -6,7 +6,7 @@ - Models/DummyScene.obj + Models/DummyScene.mesh @@ -17,7 +17,7 @@ - Models/Core/UnitSphere.obj + Models/Core/UnitSphere.mesh @@ -28,7 +28,7 @@ - Models/RotationWidgetX.obj + Models/RotationWidgetX.mesh @@ -43,7 +43,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -69,7 +69,7 @@ - Models/Core/UnitRaptor.obj + Models/Core/UnitRaptor.mesh @@ -94,7 +94,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -107,7 +107,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/EditorTestWorld.xml b/resources/Schema/Entities/EditorTestWorld.xml index 2e95d626..5649a630 100755 --- a/resources/Schema/Entities/EditorTestWorld.xml +++ b/resources/Schema/Entities/EditorTestWorld.xml @@ -9,7 +9,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -58,7 +58,7 @@ - Models/DirectionalLightWidget.obj + Models/DirectionalLightWidget.mesh @@ -70,7 +70,7 @@ - Models/Assault.obj + Models/Assault.mesh @@ -94,7 +94,7 @@ - Models/Core/UnitSphere.obj + Models/Core/UnitSphere.mesh diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 93b4d374..dc271908 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -18,7 +18,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -37,7 +37,7 @@ - Models/Assault.obj + Models/Assault.mesh @@ -55,7 +55,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/OctreeTest.xml b/resources/Schema/Entities/OctreeTest.xml index 4d7fe709..a510a98c 100644 --- a/resources/Schema/Entities/OctreeTest.xml +++ b/resources/Schema/Entities/OctreeTest.xml @@ -11,7 +11,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -27,7 +27,7 @@ false - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -42,7 +42,7 @@ false - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 6c3b39c3..485c6cff 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,7 +6,7 @@ - Models/Core/UnitSphere.obj + Models/Core/UnitSphere.mesh diff --git a/resources/Schema/Entities/RaptorCopter.xml b/resources/Schema/Entities/RaptorCopter.xml index 0ee62368..82aa0efa 100644 --- a/resources/Schema/Entities/RaptorCopter.xml +++ b/resources/Schema/Entities/RaptorCopter.xml @@ -7,7 +7,7 @@ - Models/Core/UnitRaptor.obj + Models/Core/UnitRaptor.mesh @@ -31,7 +31,7 @@ - Models/Core/UnitCylinder.obj + Models/Core/UnitCylinder.mesh @@ -44,7 +44,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh @@ -57,7 +57,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 86a3090a..67ddd046 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -13,7 +13,7 @@ - Models/Camera.obj + Models/Camera.mesh MainCamera @@ -26,7 +26,7 @@ - Models/Camera.obj + Models/Camera.mesh ActionCamera @@ -40,7 +40,7 @@ - Models/Core/UnitPlane.obj + Models/Core/UnitPlane.mesh diff --git a/resources/Schema/Entities/SoundTestLevel.xml b/resources/Schema/Entities/SoundTestLevel.xml index 366ae81b..4e9c3093 100644 --- a/resources/Schema/Entities/SoundTestLevel.xml +++ b/resources/Schema/Entities/SoundTestLevel.xml @@ -12,7 +12,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/SpawnTest.xml b/resources/Schema/Entities/SpawnTest.xml index a5574027..16608b47 100644 --- a/resources/Schema/Entities/SpawnTest.xml +++ b/resources/Schema/Entities/SpawnTest.xml @@ -24,7 +24,7 @@ - Models/Core/UnitSphere.obj + Models/Core/UnitSphere.mesh @@ -37,7 +37,7 @@ - Models/Core/UnitSphere.obj + Models/Core/UnitSphere.mesh diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index aa8c9446..cb5f41b3 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -24,10 +24,12 @@ void main() mat4 boneTransform = mat4(1); + if(BoneWeights[0] > 0.f){ boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + BoneWeights[1] * Bones[int(BoneIndices[1])] + BoneWeights[2] * Bones[int(BoneIndices[2])] + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 46aad8df..e60890b6 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -295,7 +295,7 @@ void EditorSystem::createWidget() #ifdef USING_ASSIMP_AS_IMPORTER m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneX #else - m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneX + m_World->GetComponent(m_WidgetPlaneX, "Model")["Resource"] = "Models/WidgetPlaneZ.mesh"; #endif m_WidgetY = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetY, "Transform"); @@ -306,7 +306,7 @@ void EditorSystem::createWidget() #ifdef USING_ASSIMP_AS_IMPORTER m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneY #else - m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneY + m_World->GetComponent(m_WidgetPlaneY, "Model")["Resource"] = "Models/WidgetPlaneZ.mesh"; #endif m_WidgetZ = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetZ, "Transform"); @@ -317,7 +317,7 @@ void EditorSystem::createWidget() #ifdef USING_ASSIMP_AS_IMPORTER m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/WidgetPlaneZ.obj"; // 360NoScope widgetPlaneZ #else - m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/coolCube.mesh"; // 360NoScope widgetPlaneZ + m_World->GetComponent(m_WidgetPlaneZ, "Model")["Resource"] = "Models/WidgetPlaneZ.mesh"; #endif m_WidgetOrigin = m_World->CreateEntity(m_Widget); m_World->AttachComponent(m_WidgetOrigin, "Transform"); @@ -363,9 +363,9 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false; if (newMode == WidgetMode::Translate) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; // 360NoScope TranslationWidgets mesh - //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj"; - //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj"; + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.mesh"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.mesh"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.mesh"; // Temporarily disabled for local space until I can figure out what's wrong with the math if (m_WidgetSpace != WidgetSpace::Local) { m_World->GetComponent(m_WidgetPlaneX, "Model")["Visible"] = true; @@ -379,19 +379,19 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) } } } else if (newMode == WidgetMode::Scale) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; // 360NoScope ScaleWidgets mesh - //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj"; - //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj"; + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.mesh"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.mesh"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.mesh"; m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = true; - //m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; // 360NoScope ScaleWidgetOrigin mesh + m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.mesh"; if (m_Selection != EntityID_Invalid) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); widgetTransform["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(m_World, m_Selection)); } } else if (newMode == WidgetMode::Rotate) { - //m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; // 360NoScope RotationWidget mesh - //m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj"; - //m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj"; + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.mesh"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.mesh"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.mesh"; if (m_Selection != EntityID_Invalid) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); if (m_WidgetSpace == WidgetSpace::Local) { diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index efd25120..162ccfd6 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -331,7 +331,7 @@ EntityID Client::createPlayer() EntityID entityID = m_World->CreateEntity(); ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere mesh + model["Resource"] = "Models/Core/UnitSphere.mesh"; ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); return entityID; } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 367f444b..951fbfb9 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -349,7 +349,7 @@ EntityID Server::createPlayer() ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere + model["Resource"] = "Models/Core/UnitSphere.mesh"; model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f); ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); return entityID; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 1dd5f9bc..afb27d69 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -22,8 +22,6 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusProgram->Link(); } -static double tempFrameCounter = 6.348; - void DrawFinalPass::Draw(RenderScene& scene) { GLERROR("DrawFinalPass::Draw: Pre"); @@ -40,7 +38,6 @@ void DrawFinalPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix())); glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); - //tempFrameCounter += 0.01; //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : scene.ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); @@ -57,21 +54,18 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } + //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { -#ifdef USING_ASSIMP_AS_IMPORTER - auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("combinedAnim_0"); -#else auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); -#endif if (animation != nullptr) { std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( *animation, - tempFrameCounter + 1.0f ); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } - // -3 - 9 + glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 7c387dd9..3bad2ae5 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -162,8 +162,9 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un if (offset + nameLengths[1] > fileByteSize) { throw Resource::FailedLoadingException("Reading Material NormalMap path failed"); } - - newMaterial.NormalMapPath = (fileData + offset); + newMaterial.NormalMapPath = "Textures/"; + newMaterial.NormalMapPath += (fileData + offset); + newMaterial.NormalMapPath += ".png"; offset += nameLengths[1]; } @@ -171,8 +172,9 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un if (offset + nameLengths[2] > fileByteSize) { throw Resource::FailedLoadingException("Reading Material SpecularMap path failed"); } - - newMaterial.SpecularMapPath = (fileData + offset); + newMaterial.SpecularMapPath = "Textures/"; + newMaterial.SpecularMapPath += (fileData + offset); + newMaterial.SpecularMapPath += ".png"; offset += nameLengths[2]; } @@ -180,8 +182,9 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un if (offset + nameLengths[3] > fileByteSize) { throw Resource::FailedLoadingException("Reading Material IncandescenceMap path failed"); } - - newMaterial.IncandescenceMapPath = (fileData + offset); + newMaterial.IncandescenceMapPath = "Textures/"; + newMaterial.IncandescenceMapPath += (fileData + offset); + newMaterial.IncandescenceMapPath += ".png"; offset += nameLengths[3]; } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 5d9d474d..16de4961 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -99,14 +99,14 @@ void RenderSystem::fillModels(std::list>& jobs, World #ifdef USING_ASSIMP_AS_IMPORTER model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope StillLoading mesh #else - model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope StillLoading mesh + model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.mesh"); #endif } catch (const std::exception&) { try { #ifdef USING_ASSIMP_AS_IMPORTER model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope Error mesh #else - model = ResourceManager::Load<::Model>("Models/coolCube.mesh"); // 360NoScope Error mesh + model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.mesh"); #endif } catch (const std::exception&) { continue; diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundSystem.cpp index 2494581d..a55c1fee 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundSystem.cpp @@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; auto model = m_World->AttachComponent(emitterID, "Model"); - (std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; // 360NoScope UnitCube + (std::string&)model["Resource"] = "Models/Core/UnitCube.mesh"; // 360NoScope UnitCube source->Type = SoundType::SFX; m_Sources[emitterID] = source; playSound(source); diff --git a/src/Tests/CollisionTest.cpp b/src/Tests/CollisionTest.cpp index 767fbe3a..42d7667c 100644 --- a/src/Tests/CollisionTest.cpp +++ b/src/Tests/CollisionTest.cpp @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(collisionTest2) BOOST_AUTO_TEST_CASE(rayVsModelTest) { //simple box test - RayTest("Models/Core/UnitCube.obj"); // 360NoScope Unitcube + RayTest("Models/Core/UnitCube.mesh"); // 360NoScope Unitcube } BOOST_AUTO_TEST_CASE(rayVsModelTest2) @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2) someAABB = AABB(minPos, maxPos); //using a rawmodel here, else we have to init the renderingsystem ResourceManager::RegisterType("RawModel"); - auto unitBox = ResourceManager::Load("Models/Core/UnitCube.obj"); // 360NoScope unitcube + auto unitBox = ResourceManager::Load("Models/Core/UnitCube.mesh"); // 360NoScope unitcube BOOST_CHECK(unitBox != nullptr); for (size_t i = 0; i < 1000000; i++) @@ -189,19 +189,19 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2) BOOST_AUTO_TEST_CASE(rayVsModelTest3) { //simple test - RayTest("Models/Core/UnitSphere.obj"); // 360NoScope unitSphere + RayTest("Models/Core/UnitSphere.mesh"); // 360NoScope unitSphere } BOOST_AUTO_TEST_CASE(rayVsModelTest4) { //simple test - RayTest("Models/Core/UnitCylinder.obj"); // 360NoScope unitCylinder + RayTest("Models/Core/UnitCylinder.mesh"); // 360NoScope unitCylinder } BOOST_AUTO_TEST_CASE(rayVsModelTest5) { //simple test - RayTest("Models/Core/UnitRaptor.obj"); // 360NoScope unitRaptor + RayTest("Models/Core/UnitRaptor.mesh"); // 360NoScope unitRaptor } BOOST_AUTO_TEST_CASE(octTest) { diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index 7c3ad641..6f157352 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -55,7 +55,7 @@ GameHealthSystemTest::GameHealthSystemTest() EntityID playerID = m_World->CreateEntity(); ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform"); ComponentWrapper model = m_World->AttachComponent(playerID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere + model["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere ComponentWrapper player = m_World->AttachComponent(playerID, "Player"); ComponentWrapper health = m_World->AttachComponent(playerID, "Health"); healthsID = playerID; @@ -80,7 +80,7 @@ GameHealthSystemTest::GameHealthSystemTest() EntityID playerID2 = m_World->CreateEntity(); ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform"); ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model"); - model2["Resource"] = "Models/Core/UnitSphere.obj"; // 360NoScope UnitSphere + model2["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); //END TEST diff --git a/src/Tests/OctTreeTestGameClass.cpp b/src/Tests/OctTreeTestGameClass.cpp index d03153e7..9ddee19b 100644 --- a/src/Tests/OctTreeTestGameClass.cpp +++ b/src/Tests/OctTreeTestGameClass.cpp @@ -149,7 +149,7 @@ void Game::Tick() ComponentWrapper transform = m_World->AttachComponent(m_BoxID, "Transform"); transform["Scale"] = boxSize; ComponentWrapper model = m_World->AttachComponent(m_BoxID, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox + model["Resource"] = "Models/Core/UnitBox.mesh"; // 360NoScope UnitBox m_World->createTestEntitiesTest2(); } diff --git a/src/Tests/OctTreeTestHardCodedTestWorld.h b/src/Tests/OctTreeTestHardCodedTestWorld.h index 89c3c3f3..9c8f3988 100644 --- a/src/Tests/OctTreeTestHardCodedTestWorld.h +++ b/src/Tests/OctTreeTestHardCodedTestWorld.h @@ -112,7 +112,7 @@ private: ComponentWrapper transform = world.AttachComponent(entityCollisionBox, "Transform"); transform["Position"] = glm::vec3(0.f, 2.f, 0.f); ComponentWrapper model = world.AttachComponent(entityCollisionBox, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox + model["Resource"] = "Models/Core/UnitBox.mesh"; // 360NoScope UnitBox } void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, Octree::Child* child, EntityID &outEntityId) { @@ -124,7 +124,7 @@ private: transform["Position"] = center; transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f; ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope unitBox + model["Resource"] = "Models/Core/UnitBox.mesh"; // 360NoScope unitBox model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); if (child->m_DynamicObjIndices.size() != 0) model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/src/Tests/OldOctTree.cpp b/src/Tests/OldOctTree.cpp index a94bf465..ec51b522 100644 --- a/src/Tests/OldOctTree.cpp +++ b/src/Tests/OldOctTree.cpp @@ -112,7 +112,7 @@ void OctTree::Update(float dt, World* world, Camera* cam) ComponentWrapper transform = world->AttachComponent(m_BoxID, "Transform"); transform["Scale"] = boxSize; ComponentWrapper model = world->AttachComponent(m_BoxID, "Model"); - model["Resource"] = "Models/Core/UnitBox.obj"; // 360NoScope UnitBox + model["Resource"] = "Models/Core/UnitBox.mesh"; // 360NoScope UnitBox m_UpdatedOnce = true; } diff --git a/src/Tests/ResourceManagerTest.cpp b/src/Tests/ResourceManagerTest.cpp index f83c6c9f..1f52472e 100644 --- a/src/Tests/ResourceManagerTest.cpp +++ b/src/Tests/ResourceManagerTest.cpp @@ -26,8 +26,8 @@ BOOST_AUTO_TEST_CASE(resourceManagerTest) //configfile without register //check so output says "EE failed to load: type not registered..." - auto m_ScreenQuadNoRegister = ResourceManager::Load("Models/Core/ScreenQuad.obj"); // 360NoScope ScreenQuad - BOOST_CHECK(!ResourceManager::IsResourceLoaded("Model", "Models/Core/ScreenQuad.obj")); + auto m_ScreenQuadNoRegister = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); // 360NoScope ScreenQuad + BOOST_CHECK(!ResourceManager::IsResourceLoaded("Model", "Models/Core/ScreenQuad.mesh")); //there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either } diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 8f6b0a62..0a897e6e 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -57,22 +57,27 @@ void Material::grabPhongProperties(MaterialNode& material_node, MFnDependencyNod 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(); + + std::string FullPath = TextureNode.findPlug("fileTextureName").asString().asChar(); m_TexturePaths.push_back(FullPath); - FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); material_node.ColorMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); material_node.ColorMapFileLength = material_node.ColorMapFile.length() + 1; // Test + MGlobal::displayInfo(MString() + "getAbsolutePathToResources: " + workspace); MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str()); return true; } @@ -101,7 +106,11 @@ bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); material_node.NormalMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); material_node.NormalMapFileLength = material_node.NormalMapFile.length() + 1; return true; @@ -127,7 +136,11 @@ bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNod std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); material_node.SpecularMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); material_node.SpecularMapFileLength = material_node.SpecularMapFile.length() + 1; return true; @@ -150,7 +163,11 @@ bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependen std::string FullPath = TextureNode.findPlug("ftn").asString().asChar(); m_TexturePaths.push_back(FullPath); - FullPath = FullPath.substr(FullPath.find_last_of("/") + 1); + MString workspace; + MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"), + workspace); + FullPath = FullPath.substr(workspace.length()); + FullPath = FullPath.substr(FullPath.find_first_of("/") + 1); material_node.IncandescenceMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size()); material_node.IncandescenceMapFileLength = material_node.IncandescenceMapFile.length() + 1; return true; diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 897cc655..4f32af84 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -60,7 +60,7 @@ Menu::Menu(QDialog* dialog) m_ExportPath = new QLineEdit; m_FileDialog = new QFileDialog; - QString tmpPath("C:/Users/Nickelodion/Desktop/animTest"); + QString tmpPath("C:/Users/Nickelodion/Desktop/workspace/tacticalZ/assets/models/"); m_ExportPath->setText(tmpPath); QLabel* exportLabel = new QLabel; exportLabel->setText("Export Path:"); From 97d70f8e32917396a6396a0b87aafded4fe6969e Mon Sep 17 00:00:00 2001 From: Jocke Date: Sun, 24 Jan 2016 11:36:01 +0100 Subject: [PATCH 48/80] Fixed in client for shoot event. Weapon system now damages health on any target not only players. --- resources/DefaultInput.ini | 3 ++- src/Engine/Network/Client.cpp | 4 ++-- src/Game/Systems/HealthSystem.cpp | 1 - src/Game/Systems/WeaponSystem.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index 5ed46241..d07ed6a3 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -21,4 +21,5 @@ F1=ToggleEditor X=EditorToggleTransformSpace C=ConnectToServer N=SwitchToServer -M=SwitchToClient \ No newline at end of file +M=SwitchToClient +P=SwitchToPlayer \ No newline at end of file diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 387961ef..2a4f531e 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -310,9 +310,9 @@ bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnPlayerDamage(const Events::PlayerDamage & e) { - Packet packet(MessageType::OnInputCommand, m_SendPacketID); + Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); packet.WritePrimitive(e.DamageAmount); - packet.WritePrimitive(e.PlayerDamagedID); + packet.WritePrimitive(m_ClientIDToServerID.at(e.PlayerDamagedID)); send(packet); return false; } diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 5e5be33e..4190e04f 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -12,7 +12,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker) void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { //if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity) - ComponentWrapper player = m_World->GetComponent(component.EntityID, "Player"); double maxHealth = (double)component["MaxHealth"]; //process the DeltaHealthVector and change the entitys health accordingly diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 11f76490..da5b057b 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -22,8 +22,8 @@ void WeaponSystem::Update(double dt) continue; } //if its a player, do PlayerDamage event - const bool hasPlayerComponent = m_World->HasComponent(pickDataFromShot.Entity, "Player"); - if (hasPlayerComponent) { + const bool hasHealthComponent = m_World->HasComponent(pickDataFromShot.Entity, "Health"); + if (hasHealthComponent) { Events::PlayerDamage ePlayerDamage; //TODO: damage based on weapontype/class? //TODO: multiple shots at the same time? (shotgunner) From 7567f47a68afdfff10e0bafabe3ef2fa36289db8 Mon Sep 17 00:00:00 2001 From: Jocke Date: Sun, 24 Jan 2016 11:56:46 +0100 Subject: [PATCH 49/80] Weapon system now searches parents for health component (stops at first health component). --- src/Game/Systems/WeaponSystem.cpp | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index da5b057b..8ee55c76 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -11,25 +11,23 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re void WeaponSystem::Update(double dt) { - for (int i = m_EShootVector.size(); i > 0; i--) - { - //TODO: check if player has enough ammo and if weapon has a cooldown or not - + for (int i = m_EShootVector.size(); i > 0; i--) { //pick the object PickData pickDataFromShot = m_Renderer->Pick(std::get<1>(m_EShootVector[i - 1])); - if (pickDataFromShot.Entity == EntityID_Invalid) { - m_EShootVector.erase(m_EShootVector.begin() + i - 1); - continue; - } - //if its a player, do PlayerDamage event - const bool hasHealthComponent = m_World->HasComponent(pickDataFromShot.Entity, "Health"); - if (hasHealthComponent) { - Events::PlayerDamage ePlayerDamage; - //TODO: damage based on weapontype/class? - //TODO: multiple shots at the same time? (shotgunner) - ePlayerDamage.DamageAmount = 25; - ePlayerDamage.PlayerDamagedID = pickDataFromShot.Entity; - m_EventBroker->Publish(ePlayerDamage); + EntityID entityID = pickDataFromShot.Entity; + while (entityID != EntityID_Invalid) { + // If has health + if (m_World->HasComponent(entityID, "Health")) { + Events::PlayerDamage ePlayerDamage; + //TODO: damage based on weapontype/class? + //TODO: multiple shots at the same time? (shotgunner) + ePlayerDamage.DamageAmount = 25; + ePlayerDamage.PlayerDamagedID = entityID; + m_EventBroker->Publish(ePlayerDamage); + break; + } else { + entityID = m_World->GetParent(entityID); + } } m_EShootVector.erase(m_EShootVector.begin() + i - 1); } @@ -44,8 +42,10 @@ bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) } return true; } -bool WeaponSystem::OnShoot(const Events::Shoot& e) { +bool WeaponSystem::OnShoot(const Events::Shoot& e) +{ //screen center, based on current resolution! + //TODO: check if player has enough ammo and if weapon has a cooldown or not Rectangle screenResolution = m_Renderer->Resolution(); glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); m_EShootVector.push_back(std::make_pair(e.shooter, centerScreen)); From b5b1140f5c3a29b3fc91969df603507c7195c86d Mon Sep 17 00:00:00 2001 From: antc13 Date: Sun, 24 Jan 2016 13:28:40 +0100 Subject: [PATCH 50/80] Custom Animations should now work. We also save color values if there's no texture. --- include/Engine/Rendering/RawModelCustom.h | 3 + resources/Schema/Entities/AnimatedArmy | 273 ++++++++++++++++++ resources/Shaders/ForwardPlus.vert.glsl | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 6 +- src/Engine/Rendering/RawModelCustom.cpp | 15 +- tools/MayaExporter/MayaExporter/Material.cpp | 30 +- tools/MayaExporter/MayaExporter/Material.h | 9 + tools/MayaExporter/MayaExporter/Menu.cpp | 7 +- tools/MayaExporter/MayaExporter/Mesh.cpp | 14 +- .../MayaExporter/MayaExporter/WriteToFile.cpp | 9 +- tools/MayaExporter/MayaExporter/WriteToFile.h | 1 + 11 files changed, 341 insertions(+), 28 deletions(-) create mode 100644 resources/Schema/Entities/AnimatedArmy diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index 2dea51ff..a1a2f1f6 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -48,6 +48,9 @@ public: { float SpecularExponent; float ReflectionFactor; + float DiffuseColor[3]; + float SpecularColor[3]; + float IncandescenceColor[3]; unsigned int StartIndex; unsigned int EndIndex; //float Transparency; diff --git a/resources/Schema/Entities/AnimatedArmy b/resources/Schema/Entities/AnimatedArmy new file mode 100644 index 00000000..b711a0fe --- /dev/null +++ b/resources/Schema/Entities/AnimatedArmy @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + models/dummyscene.mesh + + + + + + + + + + + models/animtest. + + + + + + + + + + + models/animTest.mesh + + + + + + + + + + + models/animTest.mesh + + + + + + + + + + + models/animTest.mesh + + + + + + + + + + + 0.13000047206878662 + + + + + + + + + + + + 0.30000001192092896 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + 0.80000001192092896 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + + 0.50999981164932251 + + + + + + + + + + + + + 5 + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + 5 + + + + + + + + + + + + 5 + + + + + + + + + + + + diff --git a/resources/Shaders/ForwardPlus.vert.glsl b/resources/Shaders/ForwardPlus.vert.glsl index cb5f41b3..c51216cb 100644 --- a/resources/Shaders/ForwardPlus.vert.glsl +++ b/resources/Shaders/ForwardPlus.vert.glsl @@ -24,7 +24,7 @@ void main() mat4 boneTransform = mat4(1); - if(BoneWeights[0] > 0.f){ + if(BoneWeights[0] > 0.0f){ boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + BoneWeights[1] * Bones[int(BoneIndices[1])] + BoneWeights[2] * Bones[int(BoneIndices[2])] diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index afb27d69..7be1223a 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -21,7 +21,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusProgram->Compile(); m_ForwardPlusProgram->Link(); } - +static double tempTime = 0.0; void DrawFinalPass::Draw(RenderScene& scene) { GLERROR("DrawFinalPass::Draw: Pre"); @@ -53,14 +53,14 @@ void DrawFinalPass::Draw(RenderScene& scene) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } - + tempTime += 0.01f; //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); if (animation != nullptr) { std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( *animation, - 1.0f + tempTime ); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 3bad2ae5..de87d5fc 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -129,8 +129,8 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un unsigned int* nameLengths = (unsigned int*)(fileData + offset); offset += sizeof(unsigned int) * 4; - if (offset + sizeof(float) * 2 > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material specular and reflection values failed"); + if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) { + throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed"); } newMaterial.SpecularExponent = *(float*)(fileData + offset); @@ -138,9 +138,12 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un newMaterial.ReflectionFactor = *(float*)(fileData + offset); offset += sizeof(float); - if (offset + sizeof(unsigned int) * 2 > fileByteSize) { - throw Resource::FailedLoadingException("Reading Material start and end index values failed"); - } + memcpy(newMaterial.DiffuseColor, fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + memcpy(newMaterial.SpecularColor, fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; + memcpy(newMaterial.IncandescenceColor, fileData + offset, sizeof(float) * 3); + offset += sizeof(float) * 3; newMaterial.StartIndex = *(unsigned int*)(fileData + offset); offset += sizeof(unsigned int); @@ -202,7 +205,7 @@ void RawModelCustom::ReadAnimationFile(std::string filePath) if (!in.is_open()) { //throw Resource::FailedLoadingException("Open animation file failed"); - return; // AJABAJA!!!!!!!! + return; } unsigned int fileByteSize = in.tellg(); diff --git a/tools/MayaExporter/MayaExporter/Material.cpp b/tools/MayaExporter/MayaExporter/Material.cpp index 0a897e6e..03521231 100644 --- a/tools/MayaExporter/MayaExporter/Material.cpp +++ b/tools/MayaExporter/MayaExporter/Material.cpp @@ -5,23 +5,30 @@ void Material::grabLambertProperties(MaterialNode& material_node, MFnDependencyN material_node.Name = node.name().asChar(); if (!findColorTexture(material_node, node)) { - MGlobal::displayWarning(MString() + "Material " + node.name() + " has no color texture. Please apply a texture insted of using a value"); + node.findPlug("colorR").getValue(material_node.DiffuseColor[0]); + node.findPlug("colorG").getValue(material_node.DiffuseColor[1]); + node.findPlug("colorB").getValue(material_node.DiffuseColor[2]); + } - if (findIncandescenceTexture(material_node, node)) { - MGlobal::displayWarning(MString() + "Material " + node.name() + " has no Incandescence texture. Please apply a texture insted of using value"); + if (!findIncandescenceTexture(material_node, node)) { + node.findPlug("incandescenceR").getValue(material_node.IncandescenceColor[0]); + node.findPlug("incandescenceG").getValue(material_node.IncandescenceColor[1]); + node.findPlug("incandescenceB").getValue(material_node.IncandescenceColor[2]); } if (findNormalTexture(material_node, node)) { - MGlobal::displayWarning(MString() + "Material " + node.name() + " has no normal texture. Please apply a texture to it"); + MGlobal::displayWarning(MString() + "Material " + node.name() + " has no normal texture."); } } void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node) { - if (findSpecularTexture(material_node, node)) { - MGlobal::displayWarning(MString() + "Material " + node.name() + " has no specular texture. Please apply a specular to it"); + if (!findSpecularTexture(material_node, node)) { + node.findPlug("specularColorR").getValue(material_node.SpecularColor[0]); + node.findPlug("specularColorG").getValue(material_node.SpecularColor[1]); + node.findPlug("specularColorB").getValue(material_node.SpecularColor[2]); } m_Plug = node.findPlug("reflectivity"); @@ -43,8 +50,10 @@ void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNod void Material::grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node) { - if (findSpecularTexture(material_node, node)) { - MGlobal::displayWarning(MString() + "Material " + node.name() + " has no specular texture. Please apply a specular to it"); + if (!findSpecularTexture(material_node, node)) { + node.findPlug("specularColorR").getValue(material_node.SpecularColor[0]); + node.findPlug("specularColorG").getValue(material_node.SpecularColor[1]); + node.findPlug("specularColorB").getValue(material_node.SpecularColor[2]); } m_Plug = node.findPlug("reflectivity"); @@ -188,20 +197,21 @@ std::vector* Material::DoIt(Mesh mesh) // All materials we care about inherit from Lambert MItDependencyNodes matIt(MFn::kLambert); m_AllMaterials.clear(); - int totalIndices = 0; while (!matIt.isDone()) { MFnDependencyNode MaterialFnDN(matIt.thisNode()); MaterialNode MaterialStorage; bool meshHasMaterial = false; //Mesh Indices is a map with : indices> + int totalIndices = 0; for (auto aMeshMaterial : mesh.Indices) { + MGlobal::displayInfo(MString() + "Material: " + aMeshMaterial.first.c_str() + " " + MaterialFnDN.name().asChar()); if (aMeshMaterial.first.compare(MaterialFnDN.name().asChar()) == 0) { meshHasMaterial = true; MaterialStorage.IndexStart = totalIndices; MaterialStorage.IndexEnd = totalIndices + aMeshMaterial.second.size() - 1; - totalIndices += aMeshMaterial.second.size(); break; } + totalIndices += aMeshMaterial.second.size(); } if (meshHasMaterial) { grabLambertProperties(MaterialStorage, MaterialFnDN); diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index 4b567d8b..341843e8 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -19,15 +19,18 @@ public: float ReflectionFactor; float SpecularExponent; + float DiffuseColor[3]{ 1.0f }; unsigned int ColorMapFileLength = 0; std::string ColorMapFile; + float SpecularColor[3]{ 1.0f }; unsigned int SpecularMapFileLength = 0; std::string SpecularMapFile; unsigned int NormalMapFileLength = 0; std::string NormalMapFile; + float IncandescenceColor[3]{ 1.0f }; unsigned int IncandescenceMapFileLength = 0; std::string IncandescenceMapFile; @@ -43,6 +46,9 @@ public: out.write((char*)&SpecularExponent, sizeof(float)); out.write((char*)&ReflectionFactor, sizeof(float)); + out.write((char*)&DiffuseColor, sizeof(float) * 3); + out.write((char*)&SpecularColor, sizeof(float) * 3); + out.write((char*)&IncandescenceColor, sizeof(float) * 3); out.write((char*)&IndexStart, sizeof(unsigned int)); out.write((char*)&IndexEnd, sizeof(unsigned int)); @@ -64,6 +70,9 @@ public: out << "SpecularExponent: " << SpecularExponent << endl; out << "ReflectionFactor: " << ReflectionFactor << endl; + out << "DiffuseColor: " << DiffuseColor[0] << " " << DiffuseColor[1] << " " << DiffuseColor[2] << endl; + out << "SpecularColor: " << SpecularColor[0] << " " << SpecularColor[1] << " " << SpecularColor[2] << endl; + out << "IncandescenceColor: " << IncandescenceColor[0] << " " << IncandescenceColor[1] << " " << IncandescenceColor[2] << endl; out << "IndexStart: " << IndexStart << endl; out << "IndexEnd: " << IndexEnd << endl; diff --git a/tools/MayaExporter/MayaExporter/Menu.cpp b/tools/MayaExporter/MayaExporter/Menu.cpp index 4f32af84..9cc6de91 100644 --- a/tools/MayaExporter/MayaExporter/Menu.cpp +++ b/tools/MayaExporter/MayaExporter/Menu.cpp @@ -104,9 +104,10 @@ Menu::Menu(QDialog* dialog) // Set the layout for our window dialog->setLayout(baseLayout); - for (unsigned int i = 0; i < 3; i++) { - this->AddClipClicked(true); - } + this->AddClipClicked(true); + //for (unsigned int i = 0; i < 3; i++) { + // this->AddClipClicked(true); + //} } diff --git a/tools/MayaExporter/MayaExporter/Mesh.cpp b/tools/MayaExporter/MayaExporter/Mesh.cpp index 26d5c7b2..6af8a557 100644 --- a/tools/MayaExporter/MayaExporter/Mesh.cpp +++ b/tools/MayaExporter/MayaExporter/Mesh.cpp @@ -309,12 +309,22 @@ Mesh MeshClass::GetMeshData(MObjectArray object) if (hasSkin) { + float totalWeight = 0.0f; + unsigned int totalBones = 0; MIntArray jointIDs /* ??? */; weights.selectAncestorLogicalIndex(vertexIndex, weightListObject); weights.getExistingArrayAttributeIndices(jointIDs); for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) { - thisVertex.BoneIndices[i] = jointIDs[i]; - thisVertex.BoneWeights[i] = weights[i].asFloat(); + if (weights[i].asFloat() > 0.001f) { + thisVertex.BoneIndices[totalBones] = jointIDs[i]; + thisVertex.BoneWeights[totalBones] = weights[i].asFloat(); + totalWeight = totalWeight + weights[i].asFloat(); + totalBones++; + } + } + + for (unsigned int i = 0; i < 4; i++) { + thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; } } diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.cpp b/tools/MayaExporter/MayaExporter/WriteToFile.cpp index 10883416..a0368c4f 100644 --- a/tools/MayaExporter/MayaExporter/WriteToFile.cpp +++ b/tools/MayaExporter/MayaExporter/WriteToFile.cpp @@ -25,10 +25,13 @@ bool WriteToFile::ASCIIFilePath(string filePathAndFileName) void WriteToFile::OpenFiles() { - if (binFile) - binFile.open(binFileName, ofstream::binary); - if (ASCIIFile) + if (binFile) { + binFile.open(binFileName, ofstream::binary); + } + if (ASCIIFile){ ASCIIFile.open(ASCIIFileName); + ASCIIFile << std::fixed << std::setprecision(3); + } } void WriteToFile::CloseFiles() diff --git a/tools/MayaExporter/MayaExporter/WriteToFile.h b/tools/MayaExporter/MayaExporter/WriteToFile.h index 91ca7103..216fcfc9 100644 --- a/tools/MayaExporter/MayaExporter/WriteToFile.h +++ b/tools/MayaExporter/MayaExporter/WriteToFile.h @@ -5,6 +5,7 @@ #include "OutputData.h" #include #include +#include using namespace std; From aa3b8cd652808a6193cf7953031327de42195c96 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 13:37:07 +0100 Subject: [PATCH 51/80] Fixed text color and removed debugging code --- resources/Schema/Entities/RenderingWorld.xml | 141 ++++++++++++++++--- src/Game/Systems/PlayerHUD.cpp | 26 +--- 2 files changed, 123 insertions(+), 44 deletions(-) diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 7ecd25c9..73cafdb9 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -9,7 +9,7 @@ - 69.990005493164063 + 65.990005493164063 @@ -21,6 +21,7 @@ Models/Assault.obj + @@ -53,8 +54,8 @@ - 0.69990003108978271 - + 0.65990006923675537 + Models/Core/UnitHexagon.obj @@ -83,7 +84,7 @@ Models/SecondaryWeapon.fbx - + @@ -110,7 +111,7 @@ Models/SecondaryWeapon.fbx - + @@ -121,8 +122,68 @@ + + + + 24 + Fonts/DroidSans.ttf,60 + + + + + + + + + + + 262 + Fonts/DroidSans.ttf,60 + + + + + + + + + + + + + + + 65/100 + Fonts/DroidSans.ttf,60 + + + + + + + + + + + + + 0.65990006923675537 + + + + Models/Core/UnitRaptor.obj + + + + + + + + + + @@ -145,6 +206,7 @@ Models/Assault.obj + @@ -157,6 +219,7 @@ Welcome! Fonts/DroidSans.ttf,1280 + @@ -167,32 +230,40 @@ - 2 - + 3 + - - + + + Models/Core/UnitSphere.obj + + - 6 + 70 0.5 + + + Models/Core/UnitSphere.obj + + - 8 + 70 @@ -204,21 +275,30 @@ + + Models/Core/UnitSphere.obj + + - 6 + 70 0.5 + + + Models/Core/UnitSphere.obj + + - 8 + 70 @@ -230,21 +310,30 @@ + + Models/Core/UnitSphere.obj + + - 6 + 70 0.5 + + + Models/Core/UnitSphere.obj + + - - 8 + + 70 @@ -256,19 +345,28 @@ + + Models/Core/UnitSphere.obj + + - 6 + 70 0.5 + + + Models/Core/UnitSphere.obj + + - 8 + 70 @@ -284,6 +382,7 @@ Models/Assault.obj + @@ -291,14 +390,15 @@ - + - 0.80000001192092896 + 0.10000000149011612 Models/DirectionalLightWidget.obj + @@ -311,6 +411,7 @@ Models/Core/UnitCube.obj + diff --git a/src/Game/Systems/PlayerHUD.cpp b/src/Game/Systems/PlayerHUD.cpp index 57e0e2f8..55d0c3f1 100644 --- a/src/Game/Systems/PlayerHUD.cpp +++ b/src/Game/Systems/PlayerHUD.cpp @@ -11,32 +11,12 @@ PlayerHUD::PlayerHUD(World* world, EventBroker* eventBrokerer) PlayerHUD::~PlayerHUD() { -// + } void PlayerHUD::Update(double dt) { - - if(ImGui::Button("Set Camera", ImVec2(70, 20))){ - auto cameras = m_World->GetComponents("Camera"); - - if(cameras == nullptr) { - return; - } - - EntityWrapper ew = EntityWrapper(m_World, (*cameras->begin()).EntityID); - - if (ew.Valid()) { - Events::SetCamera e; - e.CameraEntity = ew; - m_EventBroker->Publish(e); - } else { - LOG_INFO("Coulnd't find a camera"); - } - } - - auto healthHUDs = m_World->GetComponents("HealthHUD"); if (healthHUDs == nullptr) { return; @@ -57,14 +37,12 @@ void PlayerHUD::Update(double dt) if (entityIDParent.HasComponent("Health")) { if (entity.HasComponent("Text")) { - std::string s = ""; s = s + std::to_string((int)(double)entityIDParent["Health"]["Health"]); s = s + "/"; s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]); - float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"]; - (glm::vec4&) entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, healthPercentage, 0.f, 0.f); + (glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 1.f); entity["Text"]["Content"] = s; } From 67477ff3ae02fd5907d049418b6a380812aed91c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 13:49:45 +0100 Subject: [PATCH 52/80] EEntityDeleted and EComponentDeleted events published by World --- include/Engine/Core/EComponentDeleted.h | 21 ++++++ include/Engine/Core/EEntityDeleted.h | 19 +++++ include/Engine/Core/World.h | 6 ++ src/Engine/Core/World.cpp | 93 ++++++++++++++++--------- src/Game/Game.cpp | 2 +- 5 files changed, 108 insertions(+), 33 deletions(-) create mode 100644 include/Engine/Core/EComponentDeleted.h create mode 100644 include/Engine/Core/EEntityDeleted.h diff --git a/include/Engine/Core/EComponentDeleted.h b/include/Engine/Core/EComponentDeleted.h new file mode 100644 index 00000000..6d9c468d --- /dev/null +++ b/include/Engine/Core/EComponentDeleted.h @@ -0,0 +1,21 @@ +#ifndef EComponentDeleted_h__ +#define EComponentDeleted_h__ + +#include "../Common.h" +#include "Event.h" +#include "Entity.h" + +namespace Events +{ + +struct ComponentDeleted : Event +{ + EntityID Entity; + std::string ComponentType; + // True if the component was deleted as a result of the entity it was attached to being deleted + bool Cascaded; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Core/EEntityDeleted.h b/include/Engine/Core/EEntityDeleted.h new file mode 100644 index 00000000..80e20e17 --- /dev/null +++ b/include/Engine/Core/EEntityDeleted.h @@ -0,0 +1,19 @@ +#ifndef EEntityDeleted_h__ +#define EEntityDeleted_h__ + +#include "Event.h" +#include "Entity.h" + +namespace Events +{ + +struct EntityDeleted : Event +{ + EntityID DeletedEntity; + // True if the entity deletion was triggered because the entity's parent was deleted before it + bool Cascaded; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index b201d4ac..35394b9f 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -5,11 +5,15 @@ #include "Entity.h" #include "ObjectPool.h" #include "ComponentPool.h" +#include "EventBroker.h" class World { public: World() = default; + World(EventBroker* eventBroker) + : m_EventBroker(eventBroker) + { } ~World(); // Create empty entity @@ -46,6 +50,7 @@ public: std::string GetName(EntityID entity) const; private: + EventBroker* m_EventBroker = nullptr; EntityID m_CurrentEntityID = 0; std::unordered_map m_EntityParents; @@ -55,6 +60,7 @@ private: std::unordered_map m_EntityNames; EntityID generateEntityID(); + void deleteEntityRecursive(EntityID entity, bool cascaded = false); }; #endif \ No newline at end of file diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index 477e2ab2..97e3ba9f 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -1,4 +1,6 @@ #include "Core/World.h" +#include "Core/EEntityDeleted.h" +#include "Core/EComponentDeleted.h" World::~World() { @@ -21,37 +23,7 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/) void World::DeleteEntity(EntityID entity) { - // Delete components - for (auto& pair : m_ComponentPools) { - auto& pool = pair.second; - if (pool->KnowsEntity(entity)) { - auto& c = pool->GetByEntity(entity); - pool->Delete(c); - } - } - - // Loop through children - std::vector childrenToDelete; - auto children = m_EntityChildren.equal_range(entity); - for (auto it = children.first; it != children.second; ++it) { - childrenToDelete.push_back(it->second); - } - for (auto& child : childrenToDelete) { - DeleteEntity(child); - } - - EntityID parent = m_EntityParents.at(entity); - m_EntityParents.erase(entity); - auto parentChildren = m_EntityChildren.equal_range(parent); - for (auto it = parentChildren.first; it != parentChildren.second; ++it) { - if (it->second == entity) { - m_EntityChildren.erase(it); - break; - } - } - - // Erase potential name - m_EntityNames.erase(entity); + deleteEntityRecursive(entity, false); } bool World::ValidEntity(EntityID entity) const @@ -96,7 +68,15 @@ void World::DeleteComponent(EntityID entity, const std::string& componentType) { ComponentPool* pool = m_ComponentPools.at(componentType); ComponentWrapper c = pool->GetByEntity(entity); - return pool->Delete(c); + pool->Delete(c); + + if (m_EventBroker != nullptr) { + Events::ComponentDeleted e; + e.Entity = entity; + e.ComponentType = componentType; + e.Cascaded = false; + m_EventBroker->Publish(e); + } } const ComponentPool* World::GetComponents(const std::string& componentType) @@ -155,3 +135,52 @@ EntityID World::generateEntityID() return m_CurrentEntityID++; } +void World::deleteEntityRecursive(EntityID entity, bool cascaded /*= false*/) +{ + if (m_EventBroker != nullptr) { + Events::EntityDeleted e; + e.DeletedEntity = entity; + e.Cascaded = cascaded; + m_EventBroker->Publish(e); + } + + // Delete components + for (auto& pair : m_ComponentPools) { + auto& pool = pair.second; + if (pool->KnowsEntity(entity)) { + auto& c = pool->GetByEntity(entity); + pool->Delete(c); + if (m_EventBroker != nullptr) { + Events::ComponentDeleted e; + e.Entity = entity; + e.ComponentType = pair.first; + e.Cascaded = true; + m_EventBroker->Publish(e); + } + } + } + + // Loop through children + std::vector childrenToDelete; + auto children = m_EntityChildren.equal_range(entity); + for (auto it = children.first; it != children.second; ++it) { + childrenToDelete.push_back(it->second); + } + for (auto& child : childrenToDelete) { + deleteEntityRecursive(child, true); + } + + EntityID parent = m_EntityParents.at(entity); + m_EntityParents.erase(entity); + auto parentChildren = m_EntityChildren.equal_range(parent); + for (auto it = parentChildren.first; it != parentChildren.second; ++it) { + if (it->second == entity) { + m_EntityChildren.erase(it); + break; + } + } + + // Erase potential name + m_EntityNames.erase(entity); +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 384c4a5b..5de61b8c 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -57,7 +57,7 @@ Game::Game(int argc, char* argv[]) m_FrameStack->Height = m_Renderer->Resolution().Height; // Create a world - m_World = new World(); + m_World = new World(m_EventBroker); std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); if (!mapToLoad.empty()) { auto file = ResourceManager::Load(mapToLoad); From 8286d052b34801763295e6ab487100c1f9606a2d Mon Sep 17 00:00:00 2001 From: antc13 Date: Sun, 24 Jan 2016 14:18:04 +0100 Subject: [PATCH 53/80] Changed color values from floats to glm::vec4 --- include/Engine/Rendering/ModelJob.h | 8 ++++++++ include/Engine/Rendering/RawModelCustom.h | 6 +++--- resources/Shaders/ForwardPlus.frag.glsl | 3 ++- src/Engine/Rendering/DrawFinalPass.cpp | 1 + src/Engine/Rendering/RawModelCustom.cpp | 6 +++--- src/Engine/Rendering/Skeleton.cpp | 2 +- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index a88530e7..01f4cca4 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -24,6 +24,10 @@ struct ModelJob : RenderJob DiffuseTexture = matGroup.Texture.get(); NormalTexture = matGroup.NormalMap.get(); SpecularTexture = matGroup.SpecularMap.get(); + IncandescenceTexture = matGroup.IncandescenceMap.get(); + DiffuseColor = matGroup.DiffuseColor; + SpecularColor = matGroup.SpecularColor; + IncandescenceColor = matGroup.IncandescenceColor; StartIndex = matGroup.StartIndex; EndIndex = matGroup.EndIndex; Matrix = matrix; @@ -43,9 +47,13 @@ struct ModelJob : RenderJob const Texture* DiffuseTexture; const Texture* NormalTexture; const Texture* SpecularTexture; + const Texture* IncandescenceTexture; float Shininess = 0.f; glm::vec4 Color; const ::Model* Model = nullptr; + glm::vec4 DiffuseColor; + glm::vec4 SpecularColor; + glm::vec4 IncandescenceColor; unsigned int StartIndex = 0; unsigned int EndIndex = 0; World* World; diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index a1a2f1f6..f1bc0e24 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -48,9 +48,9 @@ public: { float SpecularExponent; float ReflectionFactor; - float DiffuseColor[3]; - float SpecularColor[3]; - float IncandescenceColor[3]; + glm::vec4 DiffuseColor{ 1.0f, 1.0f, 1.0f, 1.0f }; + glm::vec4 SpecularColor{ 1.0f, 1.0f, 1.0f, 1.0f }; + glm::vec4 IncandescenceColor{ 1.0f, 1.0f, 1.0f, 1.0f }; unsigned int StartIndex; unsigned int EndIndex; //float Transparency; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index b9db56d3..2a524096 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -4,6 +4,7 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; uniform vec4 Color; +uniform vec4 DiffuseColor; uniform vec2 ScreenDimensions; uniform sampler2D texture0; @@ -129,7 +130,7 @@ void main() totalLighting.Specular += result.Specular; } - fragmentColor += (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; + fragmentColor += DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color; //fragmentColor += Input.DiffuseColor; //fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color; //fragmentColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 7be1223a..2b126951 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -45,6 +45,7 @@ void DrawFinalPass::Draw(RenderScene& scene) //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); + glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor)); if(modelJob->DiffuseTexture != nullptr) { glActiveTexture(GL_TEXTURE0); diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index de87d5fc..fca796ac 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -138,11 +138,11 @@ void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, un newMaterial.ReflectionFactor = *(float*)(fileData + offset); offset += sizeof(float); - memcpy(newMaterial.DiffuseColor, fileData + offset, sizeof(float) * 3); + memcpy(&newMaterial.DiffuseColor[0], fileData + offset, sizeof(float) * 3); offset += sizeof(float) * 3; - memcpy(newMaterial.SpecularColor, fileData + offset, sizeof(float) * 3); + memcpy(&newMaterial.SpecularColor[0], fileData + offset, sizeof(float) * 3); offset += sizeof(float) * 3; - memcpy(newMaterial.IncandescenceColor, fileData + offset, sizeof(float) * 3); + memcpy(&newMaterial.IncandescenceColor[0], fileData + offset, sizeof(float) * 3); offset += sizeof(float) * 3; newMaterial.StartIndex = *(unsigned int*)(fileData + offset); diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 986e634c..1f150b00 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -90,7 +90,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf int k = 0; } else { if (bone->Parent) { - boneMatrix = parentMatrix * bone->Parent->OffsetMatrix * glm::translate(glm::vec3(1.718, 0, 0)); // * glm::inverse(bone->OffsetMatrix); + boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix); } boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; } From 373bb33cf0f58934d55db75f950b2addcf5ce907 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 15:20:34 +0100 Subject: [PATCH 54/80] Player jumping taking air acceleration into account --- resources/Schema/Entities/Player.xml | 9 +++-- src/Engine/Collision/CollisionSystem.cpp | 2 +- src/Game/Systems/PlayerMovementSystem.cpp | 42 ++++++++++++++--------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 58550357..00d2e295 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,12 +6,13 @@ + - false + - 7 + 5 @@ -19,7 +20,8 @@ - + + @@ -29,6 +31,7 @@ + diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 0c77c306..ba841e36 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c } if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { (glm::vec3&)cTransform["Position"] += resolutionVector; - cPhysics["Velocity"] = glm::vec3(0, 0, 0); + ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index ae54d684..5c75a673 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -48,8 +48,12 @@ void PlayerMovementSystem::Update(double dt) } glm::vec3& velocity = cPhysics["Velocity"]; ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); - ImGui::Text("wishDirection: (%f, %f, %f)", wishDirection.x, wishDirection.y, wishDirection.z); - float currentSpeedProj = glm::dot(velocity, wishDirection); + glm::vec3 groundVelocity(0.f, 0.f, 0.f); + groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f)); + groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f)); + ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection)); + ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection)); + float currentSpeedProj = glm::dot(groundVelocity, wishDirection); float addSpeed = wishSpeed - currentSpeedProj; ImGui::Text("currentSpeedProj: %f", currentSpeedProj); ImGui::Text("wishSpeed: %f", wishSpeed); @@ -58,20 +62,20 @@ void PlayerMovementSystem::Update(double dt) if (addSpeed > 0) { static float accel = 15.f; ImGui::InputFloat("accel", &accel); - float actualAccel = accel; - static float surfaceFriction = 1.f; + static float airAccel = 0.5f; + ImGui::InputFloat("airAccel", &airAccel); + float actualAccel = (velocity.y != 0) ? airAccel : accel; + static float surfaceFriction = 5.f; ImGui::InputFloat("surfaceFriction", &surfaceFriction); float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction; accelerationSpeed = glm::min(accelerationSpeed, addSpeed); velocity += accelerationSpeed * wishDirection; ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); } - //pos += controller->Movement() * glm::inverse(glm::quat(ori)) * speed * (float)dt; - //glm::vec3& velocity = player["Physics"]["Velocity"]; - //if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { - // velocity.y += 4.f; - //} + if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) { + velocity.y += 4.f; + } //if (player.HasComponent("AABB")) { // glm::vec3& size = player["AABB"]["Size"]; @@ -93,20 +97,26 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp if (!entity.HasComponent("Physics")) { return; } - ComponentWrapper& cPhysics = entity["Physics"]; + ComponentWrapper& cPhysics = entity["Physics"]; glm::vec3& velocity = cPhysics["Velocity"]; - if (cPhysics["Gravity"]) { - velocity.y -= 9.82f * (float)dt; - } // Ground friction float speed = glm::length(velocity); - static float groundFriction = 7.f; + static float groundFriction = 7.f; ImGui::InputFloat("groundFriction", &groundFriction); + static float airFriction = 0.f; + ImGui::InputFloat("airFriction", &airFriction); + float friction = (velocity.y != 0) ? airFriction : groundFriction; if (speed > 0) { - float drop = speed * groundFriction * (float)dt; - velocity *= glm::max(speed - drop, 0.f) / speed; + float drop = speed * friction * (float)dt; + float multiplier = glm::max(speed - drop, 0.f) / speed; + velocity.x *= multiplier; + velocity.z *= multiplier; + } + + if (cPhysics["Gravity"]) { + velocity.y -= 9.82f * (float)dt; } glm::vec3& position = cTransform["Position"]; From 666f1fd8784a9aed5439ae5f1df0d0335996bd31 Mon Sep 17 00:00:00 2001 From: antc13 Date: Sun, 24 Jan 2016 15:30:20 +0100 Subject: [PATCH 55/80] Removed temp variables & the "forced" animation in DrawFinalPass --- resources/Shaders/ForwardPlus.frag.glsl | 4 +-- .../Rendering/DrawColorCorrectionPass.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 30 +++++++------------ src/Engine/Rendering/RawModelAssimp.cpp | 1 - src/Engine/Rendering/RawModelCustom.cpp | 1 - src/Engine/Rendering/RenderSystem.cpp | 12 ++------ src/Engine/Rendering/Skeleton.cpp | 1 - tools/MayaExporter/MayaExporter/Material.h | 6 ++-- 8 files changed, 19 insertions(+), 38 deletions(-) diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index e158640e..57b1d627 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -4,6 +4,7 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; uniform vec4 Color; +uniform vec4 DiffuseColor; uniform vec2 ScreenDimensions; layout (binding = 0) uniform sampler2D DiffuseTexture; layout (binding = 1) uniform sampler2D GlowMap; @@ -46,7 +47,6 @@ in VertexData{ vec3 Position; vec3 Normal; vec2 TextureCoordinate; - vec4 DiffuseColor; }Input; out vec4 sceneColor; @@ -135,7 +135,7 @@ void main() } //sceneColor += Input.DiffuseColor; - vec4 color_result = Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color; + vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color; //bloomColor = vec4(0.3, 0.8, 0.6, 1.0); sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); //These if statements should be removed if they are slow. diff --git a/src/Engine/Rendering/DrawColorCorrectionPass.cpp b/src/Engine/Rendering/DrawColorCorrectionPass.cpp index c9789602..5989584e 100644 --- a/src/Engine/Rendering/DrawColorCorrectionPass.cpp +++ b/src/Engine/Rendering/DrawColorCorrectionPass.cpp @@ -5,7 +5,7 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer) m_Renderer = renderer; m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); - m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting. + m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting. InitializeShaderPrograms(); } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index fddc0338..9977f194 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -43,7 +43,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusProgram->BindFragDataLocation(1, "bloomColor"); m_ForwardPlusProgram->Link(); } -static double tempTime = 0.0; + void DrawFinalPass::Draw(RenderScene& scene) { GLERROR("DrawFinalPass::Draw: Pre"); @@ -65,6 +65,7 @@ void DrawFinalPass::Draw(RenderScene& scene) glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : scene.ForwardJobs) { auto modelJob = std::dynamic_pointer_cast(job); @@ -80,33 +81,24 @@ void DrawFinalPass::Draw(RenderScene& scene) } else { glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } - tempTime += 0.01f; - //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) - if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); - if (animation != nullptr) { - std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( - *animation, - tempTime glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - - /*if(modelJob->GlowMap != nullptr) { - glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture); + if (modelJob->IncandescenceTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture); } else { glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); - }*/ - ); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } } - + + /*if(modelJob->GlowMap != nullptr) { + glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture); + } else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + }*/ + glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); } } - m_FinalPassFrameBuffer.Unbind(); GLERROR("DrawFinalPass::Draw: END"); delete state; } diff --git a/src/Engine/Rendering/RawModelAssimp.cpp b/src/Engine/Rendering/RawModelAssimp.cpp index 6bc3f3f7..7bf72a22 100644 --- a/src/Engine/Rendering/RawModelAssimp.cpp +++ b/src/Engine/Rendering/RawModelAssimp.cpp @@ -273,7 +273,6 @@ RawModelAssimp::RawModelAssimp(std::string fileName) m_Skeleton->Animations[animationName] = skelAnim; } - int k = 0; } RawModelAssimp::~RawModelAssimp() diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index fca796ac..74c524c9 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -8,7 +8,6 @@ RawModelCustom::RawModelCustom(std::string fileName) ReadMeshFile(fileName); ReadMaterialFile(fileName); ReadAnimationFile(fileName); - int k = 0; } void RawModelCustom::ReadMeshFile(std::string filePath) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 455e25e9..334b3b1b 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -51,18 +51,10 @@ void RenderSystem::fillModels(std::list>& jobs) model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; -#ifdef USING_ASSIMP_AS_IMPORTER - model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope StillLoading mesh -#else - model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.mesh"); -#endif + model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); } catch (const std::exception&) { try { -#ifdef USING_ASSIMP_AS_IMPORTER - model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.obj"); // 360NoScope Error mesh -#else - model = ResourceManager::Load<::Model>("Models/WidgetPlaneZ.mesh"); -#endif + model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); } catch (const std::exception&) { continue; } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 1f150b00..cebabb67 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -87,7 +87,6 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - int k = 0; } else { if (bone->Parent) { boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix); diff --git a/tools/MayaExporter/MayaExporter/Material.h b/tools/MayaExporter/MayaExporter/Material.h index 341843e8..e405dd07 100644 --- a/tools/MayaExporter/MayaExporter/Material.h +++ b/tools/MayaExporter/MayaExporter/Material.h @@ -19,18 +19,18 @@ public: float ReflectionFactor; float SpecularExponent; - float DiffuseColor[3]{ 1.0f }; + float DiffuseColor[3]{ 1.0f, 1.0f, 1.0f }; unsigned int ColorMapFileLength = 0; std::string ColorMapFile; - float SpecularColor[3]{ 1.0f }; + float SpecularColor[3]{ 1.0f, 1.0f, 1.0f }; unsigned int SpecularMapFileLength = 0; std::string SpecularMapFile; unsigned int NormalMapFileLength = 0; std::string NormalMapFile; - float IncandescenceColor[3]{ 1.0f }; + float IncandescenceColor[3]{ 1.0f, 1.0f, 1.0f }; unsigned int IncandescenceMapFileLength = 0; std::string IncandescenceMapFile; From 3261e21d9663e31a56025a2d00185dac99bec15a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 15:46:01 +0100 Subject: [PATCH 56/80] Coloring players depending on team and created a blue spawn in MovementTest --- resources/Schema/Entities/MovementTest.xml | 47 +++++++++++++++++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 22 +++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 00f94120..26d25edb 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -22,7 +22,7 @@ - + @@ -133,6 +133,51 @@ + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index fe377866..84dce05c 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -78,6 +78,9 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID); } + // Store the player for future reference + m_PlayerEntities[e.PlayerID] = e.Player; + // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { @@ -86,8 +89,23 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) m_EventBroker->Publish(e); } - // Store the player for future reference - m_PlayerEntities[e.PlayerID] = e.Player; + // HACK: Set the player model color to team color + EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel"); + if (playerModel.Valid() && e.Player.HasComponent("Team")) { + ComponentWrapper cTeam = e.Player["Team"]; + ComponentWrapper cModel = playerModel["Model"]; + if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) { + cModel["Color"] = glm::vec3(1.f, 0.f, 0.f); + } else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) { + cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f); + } + } + + // TODO: Set the player name to whatever + //EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); + //if (playerName.Valid()) { + // playerName["Text"]["Content"] = ???; + //} return true; } \ No newline at end of file From 96a735c54289ca80108f6a0c2d48101418801347 Mon Sep 17 00:00:00 2001 From: antc13 Date: Sun, 24 Jan 2016 16:12:31 +0100 Subject: [PATCH 57/80] Changed .obj to .mesh for all meshes. --- assets | 2 +- .../{AnimatedArmy => AnimatedArmy.xml} | 0 resources/Schema/Entities/CaptureTest.xml | 14 ++++++------- .../Schema/Entities/CaptureTestState1.xml | 14 ++++++------- .../Schema/Entities/CaptureTestState2.xml | 14 ++++++------- .../Schema/Entities/CaptureTestState3.xml | 20 +++++++++---------- .../Schema/Entities/CaptureTestState4.xml | 20 +++++++++---------- resources/Schema/Entities/CollisionTest1.xml | 2 +- .../Schema/Entities/EditorWidgetRotate.xml | 6 +++--- .../Schema/Entities/EditorWidgetScale.xml | 8 ++++---- .../Schema/Entities/EditorWidgetTranslate.xml | 14 ++++++------- resources/Schema/Entities/Empty.xml | 12 ++++++++++- resources/Schema/Entities/RenderingWorld.xml | 14 ++++++------- resources/Schema/Entities/ShootEventTest.xml | 20 +++++++++---------- resources/Schema/Entities/Test.xml | 4 ++-- src/Engine/Editor/EditorRenderSystem.cpp | 2 +- src/Engine/Rendering/DrawBloomPass.cpp | 2 +- .../Rendering/DrawColorCorrectionPass.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 12 +++++++++++ src/Engine/Rendering/DrawScreenQuadPass.cpp | 2 +- src/Engine/Rendering/RawModelCustom.cpp | 3 +++ src/Tests/ResourceManagerTest.cpp | 2 +- 22 files changed, 107 insertions(+), 82 deletions(-) rename resources/Schema/Entities/{AnimatedArmy => AnimatedArmy.xml} (100%) diff --git a/assets b/assets index e8174f63..068fbb2d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e8174f630fc3242e15ada1346b42c72f44cbc854 +Subproject commit 068fbb2d20682dd60f186c82172d7731e60ed7e9 diff --git a/resources/Schema/Entities/AnimatedArmy b/resources/Schema/Entities/AnimatedArmy.xml similarity index 100% rename from resources/Schema/Entities/AnimatedArmy rename to resources/Schema/Entities/AnimatedArmy.xml diff --git a/resources/Schema/Entities/CaptureTest.xml b/resources/Schema/Entities/CaptureTest.xml index 70a8ae14..5f657e51 100644 --- a/resources/Schema/Entities/CaptureTest.xml +++ b/resources/Schema/Entities/CaptureTest.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -81,7 +81,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -102,7 +102,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -120,7 +120,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -138,7 +138,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState1.xml b/resources/Schema/Entities/CaptureTestState1.xml index 75b14858..ffabd5c2 100644 --- a/resources/Schema/Entities/CaptureTestState1.xml +++ b/resources/Schema/Entities/CaptureTestState1.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -42,7 +42,7 @@ 6.9158446328696002 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -63,7 +63,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -83,7 +83,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -104,7 +104,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -122,7 +122,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -140,7 +140,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState2.xml b/resources/Schema/Entities/CaptureTestState2.xml index 77673324..29abdfbd 100644 --- a/resources/Schema/Entities/CaptureTestState2.xml +++ b/resources/Schema/Entities/CaptureTestState2.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -98,7 +98,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -116,7 +116,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -134,7 +134,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState3.xml b/resources/Schema/Entities/CaptureTestState3.xml index 99da90a6..ff875dc4 100644 --- a/resources/Schema/Entities/CaptureTestState3.xml +++ b/resources/Schema/Entities/CaptureTestState3.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -81,7 +81,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -101,7 +101,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -122,7 +122,7 @@ 4 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -140,7 +140,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -158,7 +158,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -176,7 +176,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -194,7 +194,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CaptureTestState4.xml b/resources/Schema/Entities/CaptureTestState4.xml index 695df52e..740d7e7b 100644 --- a/resources/Schema/Entities/CaptureTestState4.xml +++ b/resources/Schema/Entities/CaptureTestState4.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -96,7 +96,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -115,7 +115,7 @@ 4 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -133,7 +133,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -151,7 +151,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -169,7 +169,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -187,7 +187,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/CollisionTest1.xml b/resources/Schema/Entities/CollisionTest1.xml index f0b310e1..e731a17a 100644 --- a/resources/Schema/Entities/CollisionTest1.xml +++ b/resources/Schema/Entities/CollisionTest1.xml @@ -24,7 +24,7 @@ false - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/EditorWidgetRotate.xml b/resources/Schema/Entities/EditorWidgetRotate.xml index b918794e..88452aac 100644 --- a/resources/Schema/Entities/EditorWidgetRotate.xml +++ b/resources/Schema/Entities/EditorWidgetRotate.xml @@ -18,7 +18,7 @@ - Models/RotationWidgetX.obj + Models/RotationWidgetX.mesh @@ -33,7 +33,7 @@ - Models/RotationWidgetY.obj + Models/RotationWidgetY.mesh @@ -48,7 +48,7 @@ - Models/RotationWidgetZ.obj + Models/RotationWidgetZ.mesh diff --git a/resources/Schema/Entities/EditorWidgetScale.xml b/resources/Schema/Entities/EditorWidgetScale.xml index 15bcb38b..786b079e 100644 --- a/resources/Schema/Entities/EditorWidgetScale.xml +++ b/resources/Schema/Entities/EditorWidgetScale.xml @@ -3,7 +3,7 @@ - Models/ScaleWidgetOrigin.obj + Models/ScaleWidgetOrigin.mesh @@ -20,7 +20,7 @@ - Models/ScaleWidgetX.obj + Models/ScaleWidgetX.mesh @@ -34,7 +34,7 @@ - Models/ScaleWidgetY.obj + Models/ScaleWidgetY.mesh @@ -48,7 +48,7 @@ - Models/ScaleWidgetZ.obj + Models/ScaleWidgetZ.mesh diff --git a/resources/Schema/Entities/EditorWidgetTranslate.xml b/resources/Schema/Entities/EditorWidgetTranslate.xml index a9b7eaff..d4ed5e76 100644 --- a/resources/Schema/Entities/EditorWidgetTranslate.xml +++ b/resources/Schema/Entities/EditorWidgetTranslate.xml @@ -3,7 +3,7 @@ - Models/TranslationWidgetOrigin.obj + Models/TranslationWidgetOrigin.mesh @@ -18,7 +18,7 @@ - Models/TranslationWidgetX.obj + Models/TranslationWidgetX.mesh @@ -30,7 +30,7 @@ - Models/TranslationWidgetY.obj + Models/TranslationWidgetY.mesh @@ -42,7 +42,7 @@ - Models/TranslationWidgetZ.obj + Models/TranslationWidgetZ.mesh @@ -54,7 +54,7 @@ - Models/WidgetPlaneX.obj + Models/WidgetPlaneX.mesh @@ -66,7 +66,7 @@ - Models/WidgetPlaneY.obj + Models/WidgetPlaneY.mesh @@ -78,7 +78,7 @@ - Models/WidgetPlaneZ.obj + Models/WidgetPlaneZ.mesh diff --git a/resources/Schema/Entities/Empty.xml b/resources/Schema/Entities/Empty.xml index 6efd8318..c9b8924f 100644 --- a/resources/Schema/Entities/Empty.xml +++ b/resources/Schema/Entities/Empty.xml @@ -5,6 +5,16 @@ - + + + + + + + + + + + diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 69b18982..796a66f0 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -12,7 +12,7 @@ ActionCamera - Models/Camera.obj + Models/Camera.mesh @@ -39,7 +39,7 @@ - Models/Core/UnitPlane.obj + Models/Core/UnitPlane.mesh @@ -51,7 +51,7 @@ - Models/Assault.obj + Models/Assault.mesh @@ -190,7 +190,7 @@ - Models/Assault.obj + Models/Assault.mesh @@ -205,7 +205,7 @@ - Models/Camera.obj + Models/Camera.mesh false @@ -237,7 +237,7 @@ 0.80000001192092896 - Models/DirectionalLightWidget.obj + Models/DirectionalLightWidget.mesh @@ -249,7 +249,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/ShootEventTest.xml b/resources/Schema/Entities/ShootEventTest.xml index eae333b6..9e9adf50 100644 --- a/resources/Schema/Entities/ShootEventTest.xml +++ b/resources/Schema/Entities/ShootEventTest.xml @@ -9,7 +9,7 @@ - ../assets/Models/DummyScene.obj + ../assets/Models/DummyScene.mesh @@ -41,7 +41,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -61,7 +61,7 @@ 1 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -79,7 +79,7 @@ 2 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -96,7 +96,7 @@ 3 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -115,7 +115,7 @@ 4 - ../assets/Models/Core/UnitSphere.obj + ../assets/Models/Core/UnitSphere.mesh @@ -133,7 +133,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -151,7 +151,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -171,7 +171,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh @@ -191,7 +191,7 @@ - ../assets/Models/Core/UnitCube.obj + ../assets/Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 42e2660e..1f8da1a3 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -6,7 +6,7 @@ - Models/DummyScene.obj + Models/DummyScene.mesh @@ -19,7 +19,7 @@ - Models/Camera.obj + Models/Camera.mesh diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 2e31e3f0..ed054052 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -39,7 +39,7 @@ void EditorRenderSystem::Update(double dt) continue; } catch (const std::exception&) { try { - model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); + model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); } catch (const std::exception&) { continue; } diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index 1ad97eb5..8fe1d807 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -4,7 +4,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer) { m_Renderer = renderer; - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); InitializeTextures(); InitializeBuffers(); diff --git a/src/Engine/Rendering/DrawColorCorrectionPass.cpp b/src/Engine/Rendering/DrawColorCorrectionPass.cpp index 5989584e..ba9efe3e 100644 --- a/src/Engine/Rendering/DrawColorCorrectionPass.cpp +++ b/src/Engine/Rendering/DrawColorCorrectionPass.cpp @@ -4,7 +4,7 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer) { m_Renderer = renderer; - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting. InitializeShaderPrograms(); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 9977f194..ca2a9d77 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -94,6 +94,18 @@ void DrawFinalPass::Draw(RenderScene& scene) glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); }*/ + //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); + if (animation != nullptr) { + std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( + *animation, + 0.0f + ); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); diff --git a/src/Engine/Rendering/DrawScreenQuadPass.cpp b/src/Engine/Rendering/DrawScreenQuadPass.cpp index 4b155fc9..b17f5e29 100644 --- a/src/Engine/Rendering/DrawScreenQuadPass.cpp +++ b/src/Engine/Rendering/DrawScreenQuadPass.cpp @@ -4,7 +4,7 @@ DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer) { m_Renderer = renderer; - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); InitializeShaderPrograms(); } diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 74c524c9..83f6e703 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -4,6 +4,9 @@ RawModelCustom::RawModelCustom(std::string fileName) { + if(fileName.substr(fileName.find_last_of(".")).compare(".mesh") != 0) { + throw Resource::FailedLoadingException("Unknown model file format. Please use \".mesh\" files."); + } fileName = fileName.erase(fileName.find_last_of("."), fileName.find_last_of(".") - fileName.size()); ReadMeshFile(fileName); ReadMaterialFile(fileName); diff --git a/src/Tests/ResourceManagerTest.cpp b/src/Tests/ResourceManagerTest.cpp index df1fd76d..1f9f4991 100644 --- a/src/Tests/ResourceManagerTest.cpp +++ b/src/Tests/ResourceManagerTest.cpp @@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(resourceManagerTest) BOOST_CHECK(!ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini")); //configfile without register - BOOST_CHECK_THROW(ResourceManager::Load("Models/Core/ScreenQuad.obj"),Resource::FailedLoadingException); + BOOST_CHECK_THROW(ResourceManager::Load("Models/Core/ScreenQuad.mesh"),Resource::FailedLoadingException); //there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either } From aa115befa936512a9d7a33c36db1e6cac040023a Mon Sep 17 00:00:00 2001 From: antc13 Date: Sun, 24 Jan 2016 17:04:12 +0100 Subject: [PATCH 58/80] UnitRaptor is now displayed while models are being loaded in. --- src/Engine/Rendering/RenderSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 9496fe7a..58bbd1ee 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -59,7 +59,7 @@ void RenderSystem::fillModels(std::list>& jobs) model = ResourceManager::Load<::Model, true>(resource); } catch (const Resource::StillLoadingException&) { //continue; - model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); + model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.mesh"); } catch (const std::exception&) { try { model = ResourceManager::Load<::Model>("Models/Core/Error.mesh"); From af2f017cb4664321d381e1008ce32e279af85fc2 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 17:05:34 +0100 Subject: [PATCH 59/80] AnimationSystem base WIP --- include/Engine/Rendering/AnimationSystem.h | 28 +++++++++++ include/Engine/Rendering/EAnimationComplete.h | 18 ++++++++ resources/Schema/Components.xsd | 1 + resources/Schema/Components/Animation.xml | 6 +++ resources/Schema/Components/Animation.xsd | 16 +++++++ resources/Schema/Entities/RenderingWorld.xml | 46 +++++++++++++++---- src/Engine/Rendering/AnimationSystem.cpp | 32 +++++++++++++ 7 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 include/Engine/Rendering/AnimationSystem.h create mode 100644 include/Engine/Rendering/EAnimationComplete.h create mode 100644 resources/Schema/Components/Animation.xml create mode 100644 resources/Schema/Components/Animation.xsd create mode 100644 src/Engine/Rendering/AnimationSystem.cpp diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h new file mode 100644 index 00000000..0876bfd7 --- /dev/null +++ b/include/Engine/Rendering/AnimationSystem.h @@ -0,0 +1,28 @@ +#ifndef AnimationSystem_h__ +#define AnimationSystem_h__ + +#include "GLM.h" + +#include "Common.h" +#include "Core/System.h" +#include "Core/ResourceManager.h" +#include "Rendering/Model.h" +#include "Rendering/EAnimationComplete.h" + +class AnimationSystem : public PureSystem +{ +public: + AnimationSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Animation") + { + + } + ~AnimationSystem() { } + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) override; +private: + + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/EAnimationComplete.h b/include/Engine/Rendering/EAnimationComplete.h new file mode 100644 index 00000000..00519a38 --- /dev/null +++ b/include/Engine/Rendering/EAnimationComplete.h @@ -0,0 +1,18 @@ +#ifndef Events_AnimationComplete_h__ +#define Events_AnimationComplete_h__ + +#include "../Core/EventBroker.h" +#include "../Core/EntityWrapper.h" + +namespace Events +{ + +struct AnimationComplete : Event +{ + EntityWrapper Entity; + std::string Name; +}; + +} + +#endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 12d94611..d663f695 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -23,4 +23,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xml b/resources/Schema/Components/Animation.xml new file mode 100644 index 00000000..01af2747 --- /dev/null +++ b/resources/Schema/Components/Animation.xml @@ -0,0 +1,6 @@ + + + + 0 + true + \ No newline at end of file diff --git a/resources/Schema/Components/Animation.xsd b/resources/Schema/Components/Animation.xsd new file mode 100644 index 00000000..0dd21f29 --- /dev/null +++ b/resources/Schema/Components/Animation.xsd @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 69b18982..f8aa2491 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -8,9 +8,7 @@ - - ActionCamera - + Models/Camera.obj @@ -25,7 +23,9 @@ Camera #2 Fonts/DroidSans.ttf,64 - 0 + + + @@ -79,7 +79,7 @@ - + @@ -200,9 +200,7 @@ - - MainCamera - + Models/Camera.obj @@ -219,7 +217,9 @@ Taiwan #1 Fonts/DroidSans.ttf,64 - 0 + + + @@ -257,6 +257,34 @@ + + + + + Models/Arm.dae + + + + + + + + + + + + + + Models/Sid_Flying.dae + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp new file mode 100644 index 00000000..b65c5a33 --- /dev/null +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -0,0 +1,32 @@ +#include "Rendering/AnimationSystem.h" + +void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) +{ + if(!entity.HasComponent("Model")) { + return; + } + + Model* model = ResourceManager::Load(entity["Model"]["Resource"]); + //Skeleton* skeleton = model->m_Skeleton; + //auto animation == skeleton->GetAnimation(animation["Name"]); + + double animationSpeed = (double)animationComponent["Speed"]; + + if( animationSpeed != 0.0) { + double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; + + if (!animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; + (double&)animationComponent["Speed"] = 0.0; + Events::AnimationComplete e; + e.Entity = entity; + // e.Name = animationComponent->Name; + m_EventBroker->Publish(e); + } else { + (double&)animationComponent["Time"] = nextTime; + } + + } + +} + From 235b26ad616ada2ce3e4292b81499d19fa532acc Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 17:16:18 +0100 Subject: [PATCH 60/80] WIP shoot --- include/Engine/Core/EPlayerDamage.h | 6 +-- include/Engine/Core/EShoot.h | 6 +-- include/Engine/Core/EntityWrapper.h | 3 +- include/Game/Systems/WeaponSystem.h | 19 ++++--- resources/Schema/Entities/Player.xml | 5 +- src/Engine/Core/EntityWrapper.cpp | 12 +++++ src/Engine/Network/Client.cpp | 4 +- src/Engine/Network/Server.cpp | 4 +- src/Game/Systems/HealthSystem.cpp | 2 +- src/Game/Systems/WeaponSystem.cpp | 80 +++++++++++++++++++--------- 10 files changed, 93 insertions(+), 48 deletions(-) diff --git a/include/Engine/Core/EPlayerDamage.h b/include/Engine/Core/EPlayerDamage.h index e0f2acd7..a7e135ce 100644 --- a/include/Engine/Core/EPlayerDamage.h +++ b/include/Engine/Core/EPlayerDamage.h @@ -2,15 +2,15 @@ #define EPlayerDamage_h__ #include "EventBroker.h" -#include "../Core/Entity.h" +#include "../Core/EntityWrapper.h" namespace Events { struct PlayerDamage : Event { - double DamageAmount; - EntityID PlayerDamagedID; + EntityWrapper Player; + double Damage; }; } diff --git a/include/Engine/Core/EShoot.h b/include/Engine/Core/EShoot.h index fd54122f..76821a24 100644 --- a/include/Engine/Core/EShoot.h +++ b/include/Engine/Core/EShoot.h @@ -2,16 +2,14 @@ #define EShoot_h__ #include "EventBroker.h" -#include "../Core/Entity.h" -#include "Engine/GLM.h" +#include "../Core/EntityWrapper.h" namespace Events { struct Shoot : Event { - //ID for who made the shot - EntityID shooter; + EntityWrapper Player; }; } diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 711f5045..79bae9ed 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -23,9 +23,10 @@ struct EntityWrapper static const EntityWrapper Invalid; - bool HasComponent(const std::string& componentName); + bool HasComponent(const std::string& componentType); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); + EntityWrapper FirstParentWithComponent(const std::string& componentType); bool IsChildOf(EntityWrapper potentialParent); bool Valid(); diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index 5acf72b3..0397b1a3 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -9,6 +9,7 @@ #include "Core/System.h" #include "Core/EPlayerDamage.h" #include "Core/EShoot.h" +#include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" #include @@ -23,16 +24,18 @@ public: virtual void Update(double dt) override; private: - //methods which will take care of specific events - EventRelay m_EShoot; - bool WeaponSystem::OnShoot(const Events::Shoot& e); - - EventRelay m_EInputCommand; - bool WeaponSystem::OnInputCommand(const Events::InputCommand& e); - IRenderer* m_Renderer; - std::vector> m_EShootVector; + // State + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; + + // Events + EventRelay m_EPlayerSpawned; + bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e); + EventRelay m_EShoot; + bool WeaponSystem::OnShoot(const Events::Shoot& e); + EventRelay m_EInputCommand; + bool WeaponSystem::OnInputCommand(const Events::InputCommand& e); }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 00d2e295..4ac1d205 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -9,7 +9,7 @@ - + false 5 @@ -20,7 +20,7 @@ - + @@ -82,6 +82,7 @@ Models/AssaultHeadless.obj + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 55d341e1..02d9246a 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -36,6 +36,18 @@ EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) return EntityWrapper::Invalid; } +EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType) +{ + EntityWrapper entity = *this; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity.HasComponent(componentType)) { + return entity; + } + } + return EntityWrapper::Invalid; +} + bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) { EntityWrapper entity = *this; diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 1dd2bd04..5ddba631 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -327,8 +327,8 @@ bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnPlayerDamage(const Events::PlayerDamage & e) { Packet packet(MessageType::OnInputCommand, m_SendPacketID); - packet.WritePrimitive(e.DamageAmount); - packet.WritePrimitive(e.PlayerDamagedID); + packet.WritePrimitive(e.Damage); + packet.WritePrimitive(e.Player.ID); send(packet); return false; } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 9d0a83d9..77702960 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -286,8 +286,8 @@ void Server::parseOnInputCommand(Packet& packet) void Server::parseOnPlayerDamage(Packet & packet) { Events::PlayerDamage e; - e.DamageAmount = packet.ReadPrimitive(); - e.PlayerDamagedID = packet.ReadPrimitive(); + e.Damage = packet.ReadPrimitive(); + e.Player = EntityWrapper(m_World, packet.ReadPrimitive()); m_EventBroker->Publish(e); //LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str()); } diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 5e5be33e..64b8e51b 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -49,7 +49,7 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e) { //save the changed HP to a vector. it will be taken care of in UpdateComponent - m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount)); + //m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount)); return true; } diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 11f76490..8a88eb13 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -5,49 +5,79 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re , ImpureSystem() , m_Renderer(renderer) { + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); } void WeaponSystem::Update(double dt) { - for (int i = m_EShootVector.size(); i > 0; i--) - { - //TODO: check if player has enough ammo and if weapon has a cooldown or not - //pick the object - PickData pickDataFromShot = m_Renderer->Pick(std::get<1>(m_EShootVector[i - 1])); - if (pickDataFromShot.Entity == EntityID_Invalid) { - m_EShootVector.erase(m_EShootVector.begin() + i - 1); - continue; - } - //if its a player, do PlayerDamage event - const bool hasPlayerComponent = m_World->HasComponent(pickDataFromShot.Entity, "Player"); - if (hasPlayerComponent) { - Events::PlayerDamage ePlayerDamage; - //TODO: damage based on weapontype/class? - //TODO: multiple shots at the same time? (shotgunner) - ePlayerDamage.DamageAmount = 25; - ePlayerDamage.PlayerDamagedID = pickDataFromShot.Entity; - m_EventBroker->Publish(ePlayerDamage); - } - m_EShootVector.erase(m_EShootVector.begin() + i - 1); +} + +bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e) +{ + if (e.PlayerID == -1) { + m_LocalPlayer = e.Player; } + return true; } bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) { + // Only shoot client-side! + if (e.PlayerID != -1) { + return false; + } + + // Only shoot if the player is alive + if (!m_LocalPlayer.Valid()) { + return false; + } + if (e.Command == "PrimaryFire" && e.Value > 0) { Events::Shoot eShoot; - eShoot.shooter = e.PlayerID; + eShoot.Player = m_LocalPlayer; m_EventBroker->Publish(eShoot); } + return true; } -bool WeaponSystem::OnShoot(const Events::Shoot& e) { - //screen center, based on current resolution! + +bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) { + // Screen center, based on current resolution! Rectangle screenResolution = m_Renderer->Resolution(); glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); - m_EShootVector.push_back(std::make_pair(e.shooter, centerScreen)); + + // TODO: check if player has enough ammo and if weapon has a cooldown or not + + // Pick middle of screen + PickData pickData = m_Renderer->Pick(centerScreen); + if (pickData.Entity == EntityID_Invalid) { + return false; + } + + EntityWrapper player(m_World, pickData.Entity); + + // Only care about players being hit + if (!player.HasComponent("Player")) { + player = player.FirstParentWithComponent("Player"); + } + if (!player.Valid()) { + return false; + } + + // Check for friendly fire + EntityWrapper shooter = eShoot.Player; + if ((ComponentInfo::EnumType)player["Team"]["Team"] == (ComponentInfo::EnumType)shooter["Team"]["Team"]) { + return false; + } + + // TODO: Weapon damage calculations etc + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Player = player; + ePlayerDamage.Damage = 100; + m_EventBroker->Publish(ePlayerDamage); + return true; -} \ No newline at end of file +} From 2eaad2aa00c62607e8a963e995a72451d2c62dd0 Mon Sep 17 00:00:00 2001 From: stiffly Date: Sun, 24 Jan 2016 17:15:26 +0100 Subject: [PATCH 61/80] Client now responds to deleted entity and component in server --- include/Engine/Network/Client.h | 3 ++ include/Engine/Network/MessageType.h | 4 ++- include/Engine/Network/Server.h | 6 ++++ src/Engine/Network/Client.cpp | 49 ++++++++++++++++++++++++++-- src/Engine/Network/Server.cpp | 23 +++++++++++++ src/Game/Game.cpp | 2 +- 6 files changed, 83 insertions(+), 4 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 92d78f4a..e2ba8bc2 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -79,6 +79,8 @@ private: void parsePing(); void parseKick(); void parsePlayersSpawned(Packet& packet); + void parseEntityDeletion(Packet& packet); + void parseComponentDeletion(Packet& packet); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); @@ -92,6 +94,7 @@ private: // Returns if server EntityID exist in map bool serverClientMapsHasEntity(EntityID serverEntityID); void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID); + void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID); // Events EventBroker* m_EventBroker; diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 13ac5e9d..894feea0 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -15,7 +15,9 @@ enum class MessageType PlayerConnected, BecomePlayer, Kick, - OnPlayerSpawned + OnPlayerSpawned, + EntityDeleted, + ComponentDeleted }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 35e6d855..00de3444 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -16,6 +16,8 @@ #include "Core/EPlayerDamage.h" #include "Network/EPlayerDisconnected.h" #include "Core/EPlayerSpawned.h" +#include "Core/EEntityDeleted.h" +#include "Core/EComponentDeleted.h" class Server : public Network { @@ -83,6 +85,10 @@ private: bool OnInputCommand(const Events::InputCommand& e); EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned& e); + EventRelay m_EEntityDeleted; + bool OnEntityDeleted(const Events::EntityDeleted& e); + EventRelay m_EComponentDeleted; + bool OnComponentDeleted(const Events::ComponentDeleted& e); }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 2a4f531e..699a82aa 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -96,6 +96,12 @@ void Client::parseMessageType(Packet& packet) case MessageType::OnPlayerSpawned: parsePlayersSpawned(packet); break; + case MessageType::EntityDeleted: + parseEntityDeletion(packet); + break; + case MessageType::ComponentDeleted: + parseComponentDeletion(packet); + break; default: break; } @@ -142,6 +148,25 @@ void Client::parsePlayersSpawned(Packet& packet) m_EventBroker->Publish(e); } +void Client::parseEntityDeletion(Packet & packet) +{ + EntityID entityToDelete = packet.ReadPrimitive(); + EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); + if (m_World->ValidEntity(localEntity)) { + m_World->DeleteEntity(localEntity); + deleteFromServerClientMaps(entityToDelete, localEntity); + } +} + +void Client::parseComponentDeletion(Packet & packet) +{ + EntityID entity = packet.ReadPrimitive(); + std::string componentType = packet.ReadString(); + if (m_World->HasComponent(entity, componentType)) { + m_World->DeleteComponent(m_ServerIDToClientID.at(entity), componentType); + } +} + // Fields with strings will not work right now void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) { @@ -370,12 +395,26 @@ void Client::becomePlayer() bool Client::clientServerMapsHasEntity(EntityID clientEntityID) { - return m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end(); + if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) { + if (m_World->ValidEntity(clientEntityID)) { + return true; + } + EntityID serverEntityID = m_ClientIDToServerID.at(clientEntityID); + deleteFromServerClientMaps(serverEntityID, clientEntityID); + } + return false; } bool Client::serverClientMapsHasEntity(EntityID serverEntityID) { - return m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end(); + if (m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end()) { + EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID); + if (m_World->ValidEntity(localEntityID)) { + return true; + } + deleteFromServerClientMaps(serverEntityID, localEntityID); + } + return false; } void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID) @@ -384,3 +423,9 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID)); } + +void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID) +{ + m_ServerIDToClientID.erase(serverEntityID); + m_ClientIDToServerID.erase(clientEntityID); +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 98774b99..d8064c3a 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -21,6 +21,8 @@ void Server::Start(World* world, EventBroker* eventBroker) // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); + EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); for (size_t i = 0; i < m_MaxConnections; i++) { m_PlayerDefinitions[i].StopTime = std::clock(); } @@ -465,3 +467,24 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) send(e.PlayerID, packet); return false; } + +bool Server::OnEntityDeleted(const Events::EntityDeleted & e) +{ + if (!e.Cascaded) { + Packet packet = Packet(MessageType::EntityDeleted); + packet.WritePrimitive(e.DeletedEntity); + broadcast(packet); + } + return false; +} + +bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) +{ + if (!e.Cascaded) { + Packet packet = Packet(MessageType::ComponentDeleted); + packet.WritePrimitive(e.Entity); + packet.WriteString(e.ComponentType); + broadcast(packet); + } + return false; +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5de61b8c..ef51aca6 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -77,7 +77,7 @@ Game::Game(int argc, char* argv[]) // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); + //m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From 8d61632c26d3f3df578bea005cd019e3f3824ea7 Mon Sep 17 00:00:00 2001 From: stiffly Date: Sun, 24 Jan 2016 17:40:43 +0100 Subject: [PATCH 62/80] No longer spawns a f**king sphere. --- src/Engine/Network/Server.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index d8064c3a..325ff845 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -409,14 +409,6 @@ void Server::createPlayer() for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; - EntityID entityID = m_World->CreateEntity(); - ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); - transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); - ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); - model["Resource"] = "Models/Core/UnitSphere.obj"; - model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f); - ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); - m_PlayerDefinitions[playerIndex].EntityID = entityID; return; } } From 8cf9caf7aaf191cb0b13124a7228d7e74e88593c Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 18:31:23 +0100 Subject: [PATCH 63/80] AnimationSystem working --- include/Engine/Rendering/AnimationSystem.h | 1 + include/Engine/Rendering/ModelJob.h | 14 +++++ resources/Schema/Entities/FastWorld.xml | 66 ++++++++++++++++++++ resources/Schema/Entities/RenderingWorld.xml | 12 ++-- src/Engine/Rendering/AnimationSystem.cpp | 16 +++-- src/Engine/Rendering/DrawFinalPass.cpp | 9 +-- src/Game/Game.cpp | 2 + 7 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 resources/Schema/Entities/FastWorld.xml diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h index 0876bfd7..fcdcbc92 100644 --- a/include/Engine/Rendering/AnimationSystem.h +++ b/include/Engine/Rendering/AnimationSystem.h @@ -8,6 +8,7 @@ #include "Core/ResourceManager.h" #include "Rendering/Model.h" #include "Rendering/EAnimationComplete.h" +#include "Rendering/Skeleton.h" class AnimationSystem : public PureSystem { diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 01f4cca4..ccfd209c 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -13,6 +13,7 @@ #include "Camera.h" #include "../Core/World.h" #include "../Core/Transform.h" +#include "Skeleton.h" struct ModelJob : RenderJob { @@ -37,6 +38,14 @@ struct ModelJob : RenderJob glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1)); Depth = worldpos.z; World = world; + + Skeleton = Model->m_RawModel->m_Skeleton; + + if (world->HasComponent(Entity, "Animation")) { + auto animationComponent = world->GetComponent(Entity, "Animation"); + Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["Name"]); + AnimationTime = (double)animationComponent["Time"]; + } }; unsigned int TextureID; @@ -51,6 +60,11 @@ struct ModelJob : RenderJob float Shininess = 0.f; glm::vec4 Color; const ::Model* Model = nullptr; + ::Skeleton* Skeleton = nullptr; + const ::Skeleton::Animation* Animation = nullptr; + + float AnimationTime = 0.f; + glm::vec4 DiffuseColor; glm::vec4 SpecularColor; glm::vec4 IncandescenceColor; diff --git a/resources/Schema/Entities/FastWorld.xml b/resources/Schema/Entities/FastWorld.xml new file mode 100644 index 00000000..655a9766 --- /dev/null +++ b/resources/Schema/Entities/FastWorld.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + + running + + 1 + + + Models/Animtest.mesh + + + + + + + + + + + + + + + + + + + + + Got to Go FAST!!!! + Fonts/DroidSans.ttf,60 + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 6b2dc510..2c101dc6 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -64,6 +64,7 @@ Welcome! Fonts/DroidSans.ttf,1280 + @@ -79,7 +80,7 @@ - + @@ -261,7 +262,7 @@ - Models/Arm.dae + asd @@ -273,14 +274,15 @@ - + + + - Models/Sid_Flying.dae + Models/Animtest.mesh - diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index b65c5a33..e699866b 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -7,25 +7,29 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } Model* model = ResourceManager::Load(entity["Model"]["Resource"]); - //Skeleton* skeleton = model->m_Skeleton; - //auto animation == skeleton->GetAnimation(animation["Name"]); + Skeleton* skeleton = model->m_RawModel->m_Skeleton; + const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["Name"]); double animationSpeed = (double)animationComponent["Speed"]; if( animationSpeed != 0.0) { double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; - if (!animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { + + if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; (double&)animationComponent["Speed"] = 0.0; Events::AnimationComplete e; e.Entity = entity; - // e.Name = animationComponent->Name; + e.Name = (std::string)animationComponent["Name"]; m_EventBroker->Publish(e); } else { - (double&)animationComponent["Time"] = nextTime; + if (glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; + } else { + (double&)animationComponent["Time"] = nextTime; + } } - } } diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index ca2a9d77..9abf69d3 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -96,12 +96,9 @@ void DrawFinalPass::Draw(RenderScene& scene) //TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { - auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running"); - if (animation != nullptr) { - std::vector frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( - *animation, - 0.0f - ); + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones( *modelJob->Animation, modelJob->AnimationTime); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 384c4a5b..a8e1a947 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -10,6 +10,7 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" +#include "../Engine/Rendering/AnimationSystem.h" Game::Game(int argc, char* argv[]) { @@ -86,6 +87,7 @@ Game::Game(int argc, char* argv[]) // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); + m_SystemPipeline->AddSystem(updateOrderLevel); // Collision and TriggerSystem should update after player. ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); From 9f3d887ac4e83e79ac19811bd8fbddd14a3feaf3 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 18:37:36 +0100 Subject: [PATCH 64/80] Networking bugfixes --- resources/Schema/Entities/Player.xml | 7 ++----- src/Engine/Core/World.cpp | 5 +++++ src/Game/Systems/InterpolationSystem.cpp | 12 ++++++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4ac1d205..8d6b16a4 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -8,9 +8,7 @@ - - false - + 5 @@ -20,7 +18,7 @@ - + @@ -31,7 +29,6 @@ - diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index 97e3ba9f..0c4c9ce4 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -137,6 +137,11 @@ EntityID World::generateEntityID() void World::deleteEntityRecursive(EntityID entity, bool cascaded /*= false*/) { + // Don't attempt to delete entities that don't exist anyway + if (!ValidEntity(entity)) { + return; + } + if (m_EventBroker != nullptr) { Events::EntityDeleted e; e.DeletedEntity = entity; diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 2b6e82f2..bfb6952a 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -12,6 +12,11 @@ InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker) void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) { + // Don't interpolate entities that might already have been removed + if (!entity.Valid()) { + return; + } + if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += dt; Transform sTransform = m_NextTransform[transform.EntityID]; @@ -31,11 +36,10 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); - // HACK: Hardcoded tolerance value for player position desync = 1 - if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { - return; + // HACK: Don't force position for players + if (!isLocalPlayer) { + (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); } - (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation // Don't force orientation for players if (!isLocalPlayer) { From 0fb1dbcae1a7ca75b34e445432e82238cf8d3c7d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 19:00:50 +0100 Subject: [PATCH 65/80] Client now has authority over its own absolute position and orientation until we have reliable input messaging --- include/Engine/Network/Client.h | 6 +++++- include/Engine/Network/MessageType.h | 3 ++- include/Engine/Network/Server.h | 1 + src/Engine/Network/Client.cpp | 31 +++++++++++++++++++++++++++- src/Engine/Network/Server.cpp | 23 +++++++++++++++++++++ 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index e2ba8bc2..4f1baa67 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -50,6 +50,7 @@ private: PlayerID m_PlayerID = -1; EntityID m_ServerEntityID = std::numeric_limits::max(); bool m_IsConnected = false; + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; // Server Client Lookup map // Assumes that root node for client and server is EntityID 0. @@ -87,6 +88,7 @@ private: bool hasServerTimedOut(); EntityID createPlayer(); void sendInputCommands(); + void sendLocalPlayerTransform(); void becomePlayer(); // Mapping Logic // Returns if local EntityID exist in map @@ -100,8 +102,10 @@ private: EventBroker* m_EventBroker; EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); - EventRelay m_EPlayeDamage; + EventRelay m_EPlayerDamage; bool OnPlayerDamage(const Events::PlayerDamage& e); + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned& e); }; #endif diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 894feea0..85f22649 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -17,7 +17,8 @@ enum class MessageType Kick, OnPlayerSpawned, EntityDeleted, - ComponentDeleted + ComponentDeleted, + PlayerTransform }; #endif diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 00de3444..3ef0a0aa 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -89,6 +89,7 @@ private: bool OnEntityDeleted(const Events::EntityDeleted& e); EventRelay m_EComponentDeleted; bool OnComponentDeleted(const Events::ComponentDeleted& e); + void parsePlayerTransform(Packet& packet); }; #endif diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 9b20ef00..3fd9217b 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -31,7 +31,8 @@ void Client::Start(World* world, EventBroker* eventBroker) // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); - EVENT_SUBSCRIBE_MEMBER(m_EPlayeDamage, &Client::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); m_Socket.connect(m_ReceiverEndpoint); LOG_INFO("I am client. BIP BOP"); @@ -48,6 +49,7 @@ void Client::Update() sendInputCommands(); m_TimeSinceSentInputs = std::clock(); } + sendLocalPlayerTransform(); } Network::Update(); } @@ -342,6 +344,33 @@ bool Client::OnPlayerDamage(const Events::PlayerDamage & e) return false; } +bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e) +{ + if (e.PlayerID == -1) { + m_LocalPlayer = e.Player; + } + return true; +} + +void Client::sendLocalPlayerTransform() +{ + if (!m_LocalPlayer.Valid()) { + return; + } + + ComponentWrapper cTransform = m_LocalPlayer["Transform"]; + glm::vec3& position = cTransform["Position"]; + glm::vec3& orientation = cTransform["Orientation"]; + Packet packet(MessageType::PlayerTransform, m_SendPacketID); + packet.WritePrimitive(position.x); + packet.WritePrimitive(position.y); + packet.WritePrimitive(position.z); + packet.WritePrimitive(orientation.x); + packet.WritePrimitive(orientation.y); + packet.WritePrimitive(orientation.z); + send(packet); +} + void Client::identifyPacketLoss() { // if no packets lost, difference should be equal to 1 diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index ff3ca6d0..ff57efed 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -101,6 +101,9 @@ void Server::parseMessageType(Packet& packet) case MessageType::BecomePlayer: createPlayer(); break; + case MessageType::PlayerTransform: + parsePlayerTransform(packet); + break; default: break; } @@ -488,3 +491,23 @@ bool Server::OnComponentDeleted(const Events::ComponentDeleted & e) } return false; } + +void Server::parsePlayerTransform(Packet& packet) +{ + glm::vec3 position; + glm::vec3 orientation; + position.x = packet.ReadPrimitive(); + position.y = packet.ReadPrimitive(); + position.z = packet.ReadPrimitive(); + orientation.x = packet.ReadPrimitive(); + orientation.y = packet.ReadPrimitive(); + orientation.z = packet.ReadPrimitive(); + + PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); + EntityWrapper player(m_World, m_PlayerDefinitions[playerID].EntityID); + + if (player.Valid()) { + player["Transform"]["Position"] = position; + player["Transform"]["Orientation"] = orientation; + } +} From d4797b0808cfc6ae98353d3f4451d9fc7c5b755a Mon Sep 17 00:00:00 2001 From: Tleety Date: Sun, 24 Jan 2016 21:08:01 +0100 Subject: [PATCH 66/80] Some entity files --- resources/Schema/Entities/CollidableCube.xml | 2 +- resources/Schema/Entities/GameMap.xml | 128 +++++++++++++++++++ resources/Schema/Entities/PointLight.xml | 16 +++ 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 resources/Schema/Entities/GameMap.xml create mode 100644 resources/Schema/Entities/PointLight.xml diff --git a/resources/Schema/Entities/CollidableCube.xml b/resources/Schema/Entities/CollidableCube.xml index ebba54be..fd800a8b 100644 --- a/resources/Schema/Entities/CollidableCube.xml +++ b/resources/Schema/Entities/CollidableCube.xml @@ -5,7 +5,7 @@ - Models/Core/UnitCube.obj + Models/Core/UnitCube.mesh diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml new file mode 100644 index 00000000..8841e3c9 --- /dev/null +++ b/resources/Schema/Entities/GameMap.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + Models\MapVersion1.mesh + + + + + + + + + 2 + + + Models/DirectionalLightWidget.mesh + false + + + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + diff --git a/resources/Schema/Entities/PointLight.xml b/resources/Schema/Entities/PointLight.xml new file mode 100644 index 00000000..64c02753 --- /dev/null +++ b/resources/Schema/Entities/PointLight.xml @@ -0,0 +1,16 @@ + + + + + + 8 + 2.7999999523162842 + + + + + + + + + From a304b00038997f6a153d55af94c92bfa8a746c6f Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 21:12:41 +0100 Subject: [PATCH 67/80] fixed crashes --- assets | 2 +- include/Engine/Rendering/ModelJob.h | 2 +- resources/Schema/Entities/FastWorld.xml | 48 +++++++++++--------- resources/Schema/Entities/RenderingWorld.xml | 6 ++- src/Engine/Rendering/AnimationSystem.cpp | 41 +++++++++++------ 5 files changed, 59 insertions(+), 40 deletions(-) diff --git a/assets b/assets index 068fbb2d..5f3ab8b3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 068fbb2d20682dd60f186c82172d7731e60ed7e9 +Subproject commit 5f3ab8b35ddce150e972445fb2894fb9e9637258 diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index ccfd209c..32d89293 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -41,7 +41,7 @@ struct ModelJob : RenderJob Skeleton = Model->m_RawModel->m_Skeleton; - if (world->HasComponent(Entity, "Animation")) { + if (world->HasComponent(Entity, "Animation") && Skeleton != nullptr) { auto animationComponent = world->GetComponent(Entity, "Animation"); Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["Name"]); AnimationTime = (double)animationComponent["Time"]; diff --git a/resources/Schema/Entities/FastWorld.xml b/resources/Schema/Entities/FastWorld.xml index 655a9766..68d1dccb 100644 --- a/resources/Schema/Entities/FastWorld.xml +++ b/resources/Schema/Entities/FastWorld.xml @@ -17,25 +17,46 @@ - + + + - running - - 1 + Crouch Walk + + 32 - Models/Animtest.mesh + Models/AssaultAnimated.mesh - + + + + + pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew + Fonts/DroidSans.ttf,60 + + + + + + + + + + + + + + @@ -46,21 +67,6 @@ - - - - Got to Go FAST!!!! - Fonts/DroidSans.ttf,60 - - - - - - - - - - diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 2c101dc6..e860fd04 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -80,7 +80,7 @@ - + @@ -275,7 +275,9 @@ - + running + + 1 Models/Animtest.mesh diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index e699866b..2126362f 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -6,31 +6,42 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a return; } - Model* model = ResourceManager::Load(entity["Model"]["Resource"]); + Model* model; + try { + model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]); + } catch (const std::exception&) { + return; + } + + Skeleton* skeleton = model->m_RawModel->m_Skeleton; const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["Name"]); - double animationSpeed = (double)animationComponent["Speed"]; + if(animation != nullptr) { + double animationSpeed = (double)animationComponent["Speed"]; - if( animationSpeed != 0.0) { - double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; + if (animationSpeed != 0.0) { + double nextTime = (double)animationComponent["Time"] + animationSpeed * dt; - if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; - (double&)animationComponent["Speed"] = 0.0; - Events::AnimationComplete e; - e.Entity = entity; - e.Name = (std::string)animationComponent["Name"]; - m_EventBroker->Publish(e); - } else { - if (glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; + if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration; + (double&)animationComponent["Speed"] = 0.0; + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["Name"]; + m_EventBroker->Publish(e); } else { - (double&)animationComponent["Time"] = nextTime; + if (glm::abs(nextTime) > animation->Duration) { + (double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration; + } else { + (double&)animationComponent["Time"] = nextTime; + } } } } + + } From 382eff169fd20e2b562a7d1431f55bf65e008abd Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 21:20:43 +0100 Subject: [PATCH 68/80] Server refactoring to remove player dependency and lots of fixes. --- include/Engine/Network/Network.h | 1 - include/Engine/Network/PlayerDefinition.h | 3 +- include/Engine/Network/Server.h | 8 +- src/Engine/Network/Client.cpp | 14 +- src/Engine/Network/Server.cpp | 158 +++++++--------------- 5 files changed, 67 insertions(+), 117 deletions(-) diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 480ac602..03fcc0f3 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -15,7 +15,6 @@ #define INPUTSIZE 4097 typedef unsigned int PlayerID; typedef unsigned int PacketID; -typedef unsigned int UserID; class Network { diff --git a/include/Engine/Network/PlayerDefinition.h b/include/Engine/Network/PlayerDefinition.h index 4b8b8e6e..863948b3 100644 --- a/include/Engine/Network/PlayerDefinition.h +++ b/include/Engine/Network/PlayerDefinition.h @@ -1,9 +1,10 @@ #ifndef PlayerDefinition_h__ #define PlayerDefinition_h__ #include +#include "../Core/Entity.h" struct PlayerDefinition { - int EntityID = -1; + ::EntityID EntityID = EntityID_Invalid; std::string Name = ""; boost::asio::ip::udp::endpoint Endpoint; unsigned int PacketID; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 3ef0a0aa..17029809 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -33,8 +33,7 @@ private: boost::asio::ip::udp::socket m_Socket; // Sending messages to client logic - PlayerDefinition m_PlayerDefinitions[8]; // - std::vector m_ConnectedUsers; + std::map m_ConnectedPlayers; char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; // time for previouse message @@ -45,6 +44,7 @@ private: int pingIntervalMs; int snapshotInterval; int checkTimeOutInterval = 100; + int m_NextPlayerID = 0; //Timers std::clock_t m_StartPingTime; @@ -60,7 +60,6 @@ private: // Private member functions int receive(char* data); void readFromClients(); - void send(Packet& packet, UserID user); void send(PlayerID player, Packet& packet); void send(Packet& packet); void broadcast(Packet& packet); @@ -68,7 +67,7 @@ private: void addChildrenToPacket(Packet& packet, EntityID entityID); void sendPing(); void checkForTimeOuts(); - void disconnect(UserID user); + void disconnect(PlayerID playerID); void parseMessageType(Packet& packet); void parseOnInputCommand(Packet& packet); void parseOnPlayerDamage(Packet& packet); @@ -77,7 +76,6 @@ private: void parseClientPing(); void parsePing(); void identifyPacketLoss(); - void createPlayer(); void kick(PlayerID player); PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); // Debug event diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 3fd9217b..e32afd57 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -153,10 +153,13 @@ void Client::parsePlayersSpawned(Packet& packet) void Client::parseEntityDeletion(Packet & packet) { EntityID entityToDelete = packet.ReadPrimitive(); - EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); - if (m_World->ValidEntity(localEntity)) { - m_World->DeleteEntity(localEntity); - deleteFromServerClientMaps(entityToDelete, localEntity); + // TODO: What if an entity that didn't previously exist comes as a delete request and later comes in a delayed snapshot? + if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) { + EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); + if (m_World->ValidEntity(localEntity)) { + m_World->DeleteEntity(localEntity); + deleteFromServerClientMaps(entityToDelete, localEntity); + } } } @@ -219,6 +222,9 @@ void Client::parseSnapshot(Packet& packet) if (componentType == "Transform") { // Interpolate only transform components InterpolateFields(packet, componentInfo, localEntityID, componentType); + } else if (componentType == "Physics" && m_World->HasComponent(localEntityID, "Player")) { + // HACK: Ignore velocity of physics + packet.ReadData(componentInfo.Stride); } else { // Set component values updateFields(packet, componentInfo, localEntityID, componentType); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 74e4a15c..a29f4f02 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -23,9 +23,6 @@ void Server::Start(World* world, EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); - for (size_t i = 0; i < m_MaxConnections; i++) { - m_PlayerDefinitions[i].StopTime = std::clock(); - } LOG_INFO("I am Server. BIP BOP\n"); } @@ -98,9 +95,6 @@ void Server::parseMessageType(Packet& packet) case MessageType::OnPlayerDamage: parseOnPlayerDamage(packet); break; - case MessageType::BecomePlayer: - createPlayer(); - break; case MessageType::PlayerTransform: parsePlayerTransform(packet); break; @@ -124,31 +118,22 @@ int Server::receive(char * data) return length; } -void Server::send(Packet& packet, UserID user) -{ - int bytesSent = m_Socket.send_to( - boost::asio::buffer(packet.Data(), packet.Size()), - m_ConnectedUsers[user].Endpoint, - 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } -} - void Server::send(PlayerID player, Packet& packet) { - int bytesSent = m_Socket.send_to( - boost::asio::buffer(packet.Data(), packet.Size()), - m_PlayerDefinitions[player].Endpoint, - 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; + try { + int bytesSent = m_Socket.send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + m_ConnectedPlayers[player].Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } + } catch (const boost::system::system_error& e) { + // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later + m_ConnectedPlayers[player].Endpoint = boost::asio::ip::udp::endpoint(); } } @@ -169,11 +154,9 @@ void Server::send(Packet & packet) void Server::broadcast(Packet& packet) { - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { - packet.ChangePacketID(m_ConnectedUsers[i].PacketID); - send(packet, i); - } + for (auto& kv : m_ConnectedPlayers) { + packet.ChangePacketID(kv.second.PacketID); + send(kv.first, packet); } } @@ -231,12 +214,12 @@ void Server::addChildrenToPacket(Packet & packet, EntityID entityID) void Server::sendPing() { // Prints connected players ping - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { - int ping = 1000 * (m_ConnectedUsers[i].StopTime - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedUsers[i].PacketID, i, std::abs(ping)); - } - } + //for (int i = 0; i < m_ConnectedPlayers.size(); i++) { + // if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) { + // int ping = 1000 * (m_ConnectedPlayers[i].StopTime - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); + // LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedPlayers[i].PacketID, i, std::abs(ping)); + // } + //} // Create ping message Packet packet(MessageType::Ping); packet.WriteString("Ping from server"); @@ -251,9 +234,9 @@ void Server::checkForTimeOuts() int startPing = 1000 * m_StartPingTime / static_cast(CLOCKS_PER_SEC); - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { - int stopPing = 1000 * m_ConnectedUsers[i].StopTime / + for (int i = 0; i < m_ConnectedPlayers.size(); i++) { + if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) { + int stopPing = 1000 * m_ConnectedPlayers[i].StopTime / static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); @@ -263,35 +246,24 @@ void Server::checkForTimeOuts() } } -void Server::disconnect(UserID user) +void Server::disconnect(PlayerID playerID) { //broadcast("A player disconnected"); - LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str()); + LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str()); // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) Events::PlayerDisconnected e; - e.Entity = m_PlayerDefinitions[user].EntityID; - e.PlayerID = user; + e.Entity = m_ConnectedPlayers[playerID].EntityID; + e.PlayerID = playerID; m_EventBroker->Publish(e); - m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint(); - m_PlayerDefinitions[user].EntityID = -1; - m_PlayerDefinitions[user].Name = ""; - m_PlayerDefinitions[user].PacketID = 0; - m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user); + m_ConnectedPlayers.erase(playerID); } void Server::parseOnInputCommand(Packet& packet) { PlayerID player = -1; // Check which player it was who sent the message - for (int i = 0; i < m_MaxConnections; i++) { - // if the player is connected set playerID to the correct PlayerID - if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address() - && m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) { - player = i; - break; - } - } + player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); if (player != -1) { while (packet.DataReadSize() < packet.Size()) { Events::InputCommand e; @@ -320,9 +292,9 @@ void Server::parseConnect(Packet& packet) if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { return; } - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address() && - m_ConnectedUsers[i].Endpoint.port() == m_ReceiverEndpoint.port()) { + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() && + kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) { // Already connected return; } @@ -334,11 +306,11 @@ void Server::parseConnect(Packet& packet) pd.Name = packet.ReadString(); pd.PacketID = 0; pd.StopTime = std::clock(); - m_ConnectedUsers.push_back(pd); + m_ConnectedPlayers[m_NextPlayerID++] = pd; LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID); + Packet connnectPacket(MessageType::Connect, pd.PacketID); send(connnectPacket); // Send notification that a player has connected @@ -350,9 +322,10 @@ void Server::parseDisconnect() { LOG_INFO("%i: Parsing disconnect", m_PacketID); - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { - disconnect(i); + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() && + kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) { + disconnect(kv.first); break; } } @@ -366,16 +339,16 @@ void Server::parseClientPing() return; } // Return ping - Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); + Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID); packet.WriteString("Ping received"); send(packet); } void Server::parsePing() { - for (int i = 0; i < m_ConnectedUsers.size(); i++) { - if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { - m_ConnectedUsers[i].StopTime = std::clock(); + for (int i = 0; i < m_ConnectedPlayers.size(); i++) { + if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { + m_ConnectedPlayers[i].StopTime = std::clock(); break; } } @@ -390,35 +363,6 @@ void Server::identifyPacketLoss() } } -void Server::createPlayer() -{ - if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { - // Already connected as player - LOG_WARNING("Already connected!"); - return; - } - UserID userIndex; - for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) { - if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() && - m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) { - // Found user - break; - } - } - if (userIndex == m_ConnectedUsers.size()) { - LOG_WARNING("Not a recognized user!"); - return; - } - for (PlayerID playerIndex = 0; playerIndex < m_MaxConnections; playerIndex++) { - if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) { - m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex]; - return; - } - } - LOG_WARNING("Server is full!"); - -} - void Server::kick(PlayerID player) { disconnect(player); @@ -428,10 +372,10 @@ void Server::kick(PlayerID player) PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) { - for (int i = 0; i < m_MaxConnections; i++) { - if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && - m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { - return i; + for (auto& kv : m_ConnectedPlayers) { + if (kv.second.Endpoint.address() == endpoint.address() && + kv.second.Endpoint.port() == endpoint.port()) { + return kv.first; } } return -1; @@ -456,6 +400,8 @@ bool Server::OnInputCommand(const Events::InputCommand & e) bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) { + m_ConnectedPlayers[e.PlayerID].EntityID = e.Player.ID; + Packet packet = Packet(MessageType::OnPlayerSpawned); packet.WritePrimitive(e.Player.ID); packet.WritePrimitive(e.Spawner.ID); @@ -496,7 +442,7 @@ void Server::parsePlayerTransform(Packet& packet) orientation.z = packet.ReadPrimitive(); PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint); - EntityWrapper player(m_World, m_PlayerDefinitions[playerID].EntityID); + EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID); if (player.Valid()) { player["Transform"]["Position"] = position; From 06f64f8fbfa791dfbf0b2ce361ff3dcc4fc5cc50 Mon Sep 17 00:00:00 2001 From: stiffly Date: Sun, 24 Jan 2016 22:00:38 +0100 Subject: [PATCH 69/80] Added a player name to the PlayerSpawned event. When a player has spawned the server sends the name to the client which publishes the event. --- include/Engine/Core/EPlayerSpawned.h | 1 + src/Engine/Network/Client.cpp | 1 + src/Engine/Network/Server.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/include/Engine/Core/EPlayerSpawned.h b/include/Engine/Core/EPlayerSpawned.h index a5700ed3..fcfaef61 100644 --- a/include/Engine/Core/EPlayerSpawned.h +++ b/include/Engine/Core/EPlayerSpawned.h @@ -12,6 +12,7 @@ struct PlayerSpawned : Event int PlayerID; EntityWrapper Player; EntityWrapper Spawner; + std::string PlayerName; }; } diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4ebf551d..05e9da61 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -147,6 +147,7 @@ void Client::parsePlayersSpawned(Packet& packet) e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive()]); e.PlayerID = -1; + e.PlayerName = packet.ReadString(); m_EventBroker->Publish(e); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index a29f4f02..30676d80 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -405,6 +405,8 @@ bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) Packet packet = Packet(MessageType::OnPlayerSpawned); packet.WritePrimitive(e.Player.ID); packet.WritePrimitive(e.Spawner.ID); + // We don't send PlayerID here because it will always be set to -1 + packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name); send(e.PlayerID, packet); return false; } From 47d2fb6a9bbb84a3dff41f29b662603b5c072e6e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 22:20:42 +0100 Subject: [PATCH 70/80] Fixed wrong drawing function used in PickingPass --- src/Engine/Rendering/PickingPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index f063b344..350d471f 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -90,7 +90,7 @@ void PickingPass::Draw(RenderScene& scene) glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int))); } } From 7e92d6f53f1d83fe03ab7115a04d799f4f59afe6 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 22:21:10 +0100 Subject: [PATCH 71/80] Healthbar on player --- resources/Schema/Entities/Player.xml | 40 +++++++++++++++++++++------ src/Engine/Editor/EditorGUI.cpp | 9 ++++++ src/Engine/Editor/EditorSystem.cpp | 2 +- src/Engine/Rendering/RenderSystem.cpp | 4 ++- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4316091b..dce6154e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -2,15 +2,14 @@ + - - - + 5 @@ -19,10 +18,7 @@ - - - - + @@ -31,7 +27,6 @@ - @@ -62,6 +57,34 @@ + + + + + + + + + + + + 1 + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + @@ -82,6 +105,7 @@ Models/AssaultHeadless.mesh + diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index 390e69a5..1200ce34 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -1,4 +1,5 @@ #include "Editor/EditorGUI.h" +#include "Rendering/ESetCamera.h" EditorGUI::EditorGUI(World* world, EventBroker* eventBroker) : m_World(world) @@ -305,6 +306,14 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci) } } + if (ci.Name == "Camera") { + if (ImGui::Button("Activate")) { + Events::SetCamera e; + e.CameraEntity = entity; + m_EventBroker->Publish(e); + } + } + return true; } diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 9c0e2e47..6ffd0e24 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -203,7 +203,7 @@ bool EditorSystem::OnSetCamera(const Events::SetCamera& e) m_ActualCamera = e.CameraEntity; Events::SetCamera e2; e2.CameraEntity = m_EditorCamera; - m_EventBroker->Publish(e2); + //m_EventBroker->Publish(e2); } return true; } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 27f19452..60a90960 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -52,7 +52,9 @@ void RenderSystem::fillModels(std::list>& jobs) // Don't render the local player if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { - continue; + if (!entity.HasComponent("HealthHUD")) { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera + continue; + } } Model* model; From f8b9606cdfdaf93f3ddb8ea363f2b2211c5111bb Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 22:59:53 +0100 Subject: [PATCH 72/80] Picking animation fix --- include/Engine/Rendering/PickingPass.h | 5 +---- resources/Shaders/Picking.vert.glsl | 20 ++++++++++++-------- src/Engine/Rendering/PickingPass.cpp | 22 +++++++++++++++------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index 5fc88982..da3ed31b 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -1,8 +1,6 @@ #ifndef PickingPass_h__ #define PickingPass_h__ - - #include "IRenderer.h" #include "PickingPassState.h" #include "FrameBuffer.h" @@ -10,8 +8,7 @@ #include "Util/UnorderedMapiVec2.h" #include "../Core/EventBroker.h" #include "../Core/World.h" - - +#include "Rendering/Skeleton.h" class PickingPass { diff --git a/resources/Shaders/Picking.vert.glsl b/resources/Shaders/Picking.vert.glsl index b2857cea..205a8fdd 100644 --- a/resources/Shaders/Picking.vert.glsl +++ b/resources/Shaders/Picking.vert.glsl @@ -3,18 +3,15 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; +uniform mat4 Bones[100]; layout(location = 0) in vec3 Position; layout(location = 1) in vec3 Normal; layout(location = 2) in vec3 Tangent; layout(location = 3) in vec3 BiTangent; layout(location = 4) in vec2 TextureCoords; -layout(location = 5) in vec4 DiffuseVertexColor; -layout(location = 6) in vec4 SpecularVertexColor; -layout(location = 7) in vec4 BoneIndices1; -layout(location = 8) in vec4 BoneIndices2; -layout(location = 9) in vec4 BoneWeights1; -layout(location = 10) in vec4 BoneWeights2; +layout(location = 5) in vec4 BoneIndices; +layout(location = 6) in vec4 BoneWeights; out VertexData{ vec3 Position; @@ -22,7 +19,14 @@ out VertexData{ void main() { - gl_Position = P * V* M * vec4(Position, 1.0); + mat4 boneTransform = mat4(1); + if(BoneWeights[0] > 0.0f){ + boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])] + + BoneWeights[1] * Bones[int(BoneIndices[1])] + + BoneWeights[2] * Bones[int(BoneIndices[2])] + + BoneWeights[3] * Bones[int(BoneIndices[3])]; + } - Output.Position = Position; + gl_Position = P*V*M*boneTransform * vec4(Position, 1.0); + Output.Position = (boneTransform * vec4(Position, 1.0)).xyz; } \ No newline at end of file diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 350d471f..c7e23479 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -48,7 +48,7 @@ void PickingPass::Draw(RenderScene& scene) PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); //TODO: Render: Add code for more jobs than modeljobs. - GLuint ShaderHandle = m_PickingProgram->GetHandle(); + GLuint shaderHandle = m_PickingProgram->GetHandle(); m_PickingProgram->Bind(); if (scene.ClearDepth) { @@ -75,18 +75,26 @@ void PickingPass::Draw(RenderScene& scene) m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); if (m_ColorCounter[0] > 255) { m_ColorCounter[0] = 0; - m_ColorCounter[1]++; + m_ColorCounter[1] += 5; } else { - m_ColorCounter[0]++; + m_ColorCounter[0] += 50; } } m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); From b6ba8a5bd790dfa667a9874a787fe155edac25fa Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 23:05:26 +0100 Subject: [PATCH 73/80] Network snapshot buffer size increased, needs to be looked over later --- include/Engine/Network/Network.h | 2 +- include/Engine/Network/Server.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 03fcc0f3..e1e64fc1 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -12,7 +12,7 @@ #include #include -#define INPUTSIZE 4097 +#define INPUTSIZE 32000 typedef unsigned int PlayerID; typedef unsigned int PacketID; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 17029809..11f983a9 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -34,6 +34,7 @@ private: // Sending messages to client logic std::map m_ConnectedPlayers; + // HACK: Fix INPUTSIZE char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; // time for previouse message From 79fe7693a659fee3dea2c9825aad0124b9c73a65 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Sun, 24 Jan 2016 23:05:45 +0100 Subject: [PATCH 74/80] picking values fixed --- src/Engine/Rendering/PickingPass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index c7e23479..0d89f355 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -75,9 +75,9 @@ void PickingPass::Draw(RenderScene& scene) m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); if (m_ColorCounter[0] > 255) { m_ColorCounter[0] = 0; - m_ColorCounter[1] += 5; + m_ColorCounter[1]++; } else { - m_ColorCounter[0] += 50; + m_ColorCounter[0]++; } } From d0de169613643c959ab6bfb2f9b1228c7f957e72 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 23:05:52 +0100 Subject: [PATCH 75/80] Instagib! --- include/Game/Systems/HealthSystem.h | 2 +- resources/Schema/Entities/Empty.xml | 12 +-- resources/Schema/Entities/MovementTest.xml | 117 +++++++++++++++++++++ src/Engine/Network/Client.cpp | 2 +- src/Engine/Rendering/PickingPass.cpp | 4 +- src/Game/Game.cpp | 2 +- src/Game/Systems/HealthSystem.cpp | 12 ++- src/Game/Systems/WeaponSystem.cpp | 17 +-- 8 files changed, 142 insertions(+), 26 deletions(-) diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index f9843f11..3b069349 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -24,7 +24,7 @@ public: private: //methods which will take care of specific events EventRelay m_EPlayerDamage; - bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e); + bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e); EventRelay m_EPlayerHealthPickup; bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e); diff --git a/resources/Schema/Entities/Empty.xml b/resources/Schema/Entities/Empty.xml index c9b8924f..6efd8318 100644 --- a/resources/Schema/Entities/Empty.xml +++ b/resources/Schema/Entities/Empty.xml @@ -5,16 +5,6 @@ - - - - - - - - - - - + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 40de747a..6551bd75 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -178,6 +178,123 @@ + + + + + + + + + + false + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + false + + + + + + + + + + + + + Models/Camera.mesh + + + + + + + + + + + + + + + Models/Camera.mesh + false + + + + + + + + + + + + Models/AssaultHeadless.mesh + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 4ebf551d..dd590a6a 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -345,7 +345,7 @@ bool Client::OnPlayerDamage(const Events::PlayerDamage & e) { Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); packet.WritePrimitive(e.Damage); - packet.WritePrimitive(e.Player.ID); + packet.WritePrimitive(m_ClientIDToServerID.at(e.Player.ID)); send(packet); return false; } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 350d471f..3f8dd9b0 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -75,9 +75,9 @@ void PickingPass::Draw(RenderScene& scene) m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); if (m_ColorCounter[0] > 255) { m_ColorCounter[0] = 0; - m_ColorCounter[1]++; + m_ColorCounter[1] += 5; } else { - m_ColorCounter[0]++; + m_ColorCounter[0] += 50; } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index ef51aca6..5de61b8c 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -77,7 +77,7 @@ Game::Game(int argc, char* argv[]) // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; m_SystemPipeline->AddSystem(updateOrderLevel); - //m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 7f0bbb09..9e118070 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -45,10 +45,16 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp } } -bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e) +bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) { - //save the changed HP to a vector. it will be taken care of in UpdateComponent - //m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount)); + ComponentWrapper cHealth = e.Player["Health"]; + double& health = cHealth["Health"]; + health -= e.Damage; + + if (health <= 0.0) { + m_World->DeleteEntity(e.Player.ID); + } + return true; } diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index f72fd7dd..b210b564 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -25,11 +25,6 @@ bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e) bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) { - // Only shoot client-side! - if (e.PlayerID != -1) { - return false; - } - // Only shoot if the player is alive if (!m_LocalPlayer.Valid()) { return false; @@ -44,9 +39,17 @@ bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) return true; } -bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) { +bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) +{ + // TODO: Weapon firing effects here + + // Only run further picking code client-side! + if (eShoot.Player != m_LocalPlayer) { + return false; + } + // Screen center, based on current resolution! - //TODO: check if player has enough ammo and if weapon has a cooldown or not + // TODO: check if player has enough ammo and if weapon has a cooldown or not Rectangle screenResolution = m_Renderer->Resolution(); glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); From 04f6233d99374aa5b20a1641a119ac1b32c36539 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 24 Jan 2016 23:44:29 +0100 Subject: [PATCH 76/80] Crude animations --- assets | 2 +- resources/Schema/Entities/MovementTest.xml | 2 +- resources/Schema/Entities/Player.xml | 15 +++++----- src/Game/Systems/PlayerMovementSystem.cpp | 34 ++++++++++++++++++++-- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/assets b/assets index 5f3ab8b3..75778193 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 5f3ab8b35ddce150e972445fb2894fb9e9637258 +Subproject commit 757781933738bc4158c5c26750594b70acd537cd diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 6551bd75..199174ae 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -198,7 +198,7 @@ - + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 1ec7927b..1ee21a33 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -7,7 +7,6 @@ - 5 @@ -18,8 +17,7 @@ - - + @@ -51,6 +49,7 @@ Models/Camera.mesh + false @@ -77,13 +76,15 @@ + + Hold Pos + 1 + - Models/AssaultHeadless.mesh + Models/AssaultAnimated.mesh - - - + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 5c75a673..0f6588be 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -36,15 +36,18 @@ void PlayerMovementSystem::Update(double dt) glm::vec3& ori = cTransform["Orientation"]; ori.y += controller->Rotation().y; + float playerMovementSpeed = player["Player"]["MovementSpeed"]; + float playerCrouchSpeed = player["Player"]["CrouchSpeed"]; + if (player.HasComponent("Physics")) { ComponentWrapper cPhysics = player["Physics"]; glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); float wishSpeed; if (controller->Crouching()) { - wishSpeed = player["Player"]["CrouchSpeed"]; + wishSpeed = playerCrouchSpeed; } else { - wishSpeed = player["Player"]["MovementSpeed"]; + wishSpeed = playerMovementSpeed; } glm::vec3& velocity = cPhysics["Velocity"]; ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); @@ -85,8 +88,33 @@ void PlayerMovementSystem::Update(double dt) // size = glm::vec3(1.f, 1.6f, 1.f); // } //} + + // Animations + EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + ComponentWrapper cAnimation = playerModel["Animation"]; + + float movementLength = glm::length(groundVelocity); + if (glm::length(controller->Movement()) > 0.f) { + if (controller->Crouching()) { + cAnimation["Name"] = "Crouch Walk"; + (double&)cAnimation["Speed"] = 1.f * -glm::sign(controller->Movement().z); + } else { + cAnimation["Name"] = "Run"; + (double&)cAnimation["Speed"] = 2.f * -glm::sign(controller->Movement().z); + } + } else { + if (controller->Crouching()) { + cAnimation["Name"] = "Crouch"; + (double&)cAnimation["Speed"] = 1.f; + } else { + cAnimation["Name"] = "Hold Pos"; + (double&)cAnimation["Speed"] = 1.f; + } + } + } } - + controller->Reset(); } } From 7b348379ac079ed0e58543ba7fe857203787d4c2 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 25 Jan 2016 00:22:55 +0100 Subject: [PATCH 77/80] Quaternions are never the solution. --- resources/Schema/Entities/MovementTest.xml | 1 - src/Game/Systems/SpawnerSystem.cpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 199174ae..1378f623 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -146,7 +146,6 @@ - diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index 8cb5b99d..f9357113 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -50,7 +50,8 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent / // Set its position and orientation to that of the SpawnPoint spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID); - spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID)); + // TODO: Quaternions, bitch + //spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID)); return spawnedEntity; } From 424526402910d97c5c184ef2791616a41c6aec39 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 25 Jan 2016 10:25:44 +0100 Subject: [PATCH 78/80] Weapon RayZ Weapon RayZ --- assets | 2 +- include/Engine/Core/EntityWrapper.h | 3 ++ include/Engine/Core/Transform.h | 2 + include/Game/Systems/LifetimeSystem.h | 21 ++++++++ include/Game/Systems/WeaponSystem.h | 4 +- resources/Schema/Components.xsd | 1 + resources/Schema/Components/Lifetime.xml | 4 ++ resources/Schema/Components/Lifetime.xsd | 13 +++++ resources/Schema/Entities/Player.xml | 61 ++++++++++++++++++++++-- resources/Schema/Entities/RayBlue | 17 +++++++ resources/Schema/Entities/RayBlue.xml | 19 ++++++++ resources/Schema/Entities/RayRed | 17 +++++++ resources/Schema/Entities/RayRed.xml | 19 ++++++++ resources/Schema/Types/Entity.xsd | 1 + src/Engine/Core/EntityWrapper.cpp | 35 +++++++++----- src/Engine/Core/Transform.cpp | 27 +++++++++++ src/Engine/Rendering/RenderSystem.cpp | 2 +- src/Game/Game.cpp | 2 + src/Game/Systems/LifetimeSystem.cpp | 27 +++++++++++ src/Game/Systems/WeaponSystem.cpp | 43 ++++++++++++++++- 20 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 include/Game/Systems/LifetimeSystem.h create mode 100644 resources/Schema/Components/Lifetime.xml create mode 100644 resources/Schema/Components/Lifetime.xsd create mode 100644 resources/Schema/Entities/RayBlue create mode 100644 resources/Schema/Entities/RayBlue.xml create mode 100644 resources/Schema/Entities/RayRed create mode 100644 resources/Schema/Entities/RayRed.xml create mode 100644 src/Game/Systems/LifetimeSystem.cpp diff --git a/assets b/assets index 75778193..e4dc9529 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 757781933738bc4158c5c26750594b70acd537cd +Subproject commit e4dc9529f2178d373808ddf487165fa50a641a78 diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 79bae9ed..3d47b74c 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -35,6 +35,9 @@ struct EntityWrapper bool operator!=(const EntityWrapper& e) const; explicit operator EntityID() const; operator bool(); + +private: + EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent); }; namespace std diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index 3b0811c9..2f549140 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -8,8 +8,10 @@ namespace Transform { +glm::mat4 AbsoluteTransformation(EntityWrapper entity); glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(World* world, EntityID entity); +glm::vec3 AbsoluteOrientationEuler(EntityWrapper entity); glm::quat AbsoluteOrientation(EntityWrapper entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); glm::vec3 AbsoluteScale(EntityWrapper entity); diff --git a/include/Game/Systems/LifetimeSystem.h b/include/Game/Systems/LifetimeSystem.h new file mode 100644 index 00000000..da88cfa2 --- /dev/null +++ b/include/Game/Systems/LifetimeSystem.h @@ -0,0 +1,21 @@ +#ifndef LifetimeSystem_h__ +#define LifetimeSystem_h__ + +#include "Core/System.h" + +class LifetimeSystem : public ImpureSystem, PureSystem +{ +public: + LifetimeSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Lifetime") + { } + + virtual void Update(double dt) override; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cLifetime, double dt) override; + +private: + std::vector m_Deletions; +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index 0397b1a3..0dd5cc54 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -11,6 +11,8 @@ #include "Core/EShoot.h" #include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" +#include "Core/EntityFile.h" +#include "Core/EntityFileParser.h" #include #include @@ -33,7 +35,7 @@ private: EventRelay m_EPlayerSpawned; bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e); EventRelay m_EShoot; - bool WeaponSystem::OnShoot(const Events::Shoot& e); + bool WeaponSystem::OnShoot(Events::Shoot& e); EventRelay m_EInputCommand; bool WeaponSystem::OnInputCommand(const Events::InputCommand& e); }; diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 720cfd97..5ce7fa5f 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -26,4 +26,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Lifetime.xml b/resources/Schema/Components/Lifetime.xml new file mode 100644 index 00000000..d7e230d7 --- /dev/null +++ b/resources/Schema/Components/Lifetime.xml @@ -0,0 +1,4 @@ + + + 0 + \ No newline at end of file diff --git a/resources/Schema/Components/Lifetime.xsd b/resources/Schema/Components/Lifetime.xsd new file mode 100644 index 00000000..137c1d4a --- /dev/null +++ b/resources/Schema/Components/Lifetime.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 5c07a159..71490508 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -8,7 +8,9 @@ - + + + 5 @@ -17,8 +19,10 @@ - - + + + + @@ -27,6 +31,7 @@ + @@ -67,11 +72,11 @@ - 1 + Models/Core/UnitHexagon.mesh @@ -84,6 +89,52 @@ + + + + Models/CrosshairQuad.mesh + + + + + + + + + + + + + Models/AssaultWeapon.mesh + + + + + + + + + + + + + + + + + + + Models/CylinderBullet.mesh + + + + + + + + + + @@ -106,11 +157,13 @@ Hold Pos + 1 Models/AssaultAnimated.mesh + false diff --git a/resources/Schema/Entities/RayBlue b/resources/Schema/Entities/RayBlue new file mode 100644 index 00000000..d34e185e --- /dev/null +++ b/resources/Schema/Entities/RayBlue @@ -0,0 +1,17 @@ + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + diff --git a/resources/Schema/Entities/RayBlue.xml b/resources/Schema/Entities/RayBlue.xml new file mode 100644 index 00000000..3b985a7e --- /dev/null +++ b/resources/Schema/Entities/RayBlue.xml @@ -0,0 +1,19 @@ + + + + + + 0.25 + + + Models/CylinderBullet.mesh + + + + + + + + + + diff --git a/resources/Schema/Entities/RayRed b/resources/Schema/Entities/RayRed new file mode 100644 index 00000000..d34e185e --- /dev/null +++ b/resources/Schema/Entities/RayRed @@ -0,0 +1,17 @@ + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + diff --git a/resources/Schema/Entities/RayRed.xml b/resources/Schema/Entities/RayRed.xml new file mode 100644 index 00000000..df563476 --- /dev/null +++ b/resources/Schema/Entities/RayRed.xml @@ -0,0 +1,19 @@ + + + + + + 0.25 + + + Models/CylinderBullet.mesh + + + + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 5583b8b8..5d135847 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -32,6 +32,7 @@ + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 02d9246a..70d98aec 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -22,18 +22,7 @@ EntityWrapper EntityWrapper::Parent() EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) { - auto itPair = this->World->GetChildren(this->ID); - if (itPair.first == itPair.second) { - return EntityWrapper::Invalid; - } - - for (auto it = itPair.first; it != itPair.second; ++it) { - if (this->World->GetName(it->second) == name) { - return EntityWrapper(this->World, it->second); - } - } - - return EntityWrapper::Invalid; + return firstChildByNameRecursive(name, this->ID); } EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType) @@ -108,3 +97,25 @@ EntityWrapper::operator bool() return this->Valid(); } +EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent) +{ + auto itPair = this->World->GetChildren(parent); + if (itPair.first == itPair.second) { + return EntityWrapper::Invalid; + } + + for (auto it = itPair.first; it != itPair.second; ++it) { + std::string itName = this->World->GetName(it->second); + if (itName == name) { + return EntityWrapper(this->World, it->second); + } else if (it->second != EntityID_Invalid) { + EntityWrapper result = firstChildByNameRecursive(name, it->second); + if (result != EntityWrapper::Invalid) { + return result; + } + } + } + + return EntityWrapper::Invalid; +} + diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index c9869014..31b4493f 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -1,5 +1,17 @@ #include "Core/Transform.h" +glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity) +{ + glm::mat4 t = glm::mat4(1.f); + + while (entity.Valid()) { + t = glm::translate((glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((glm::vec3&)entity["Transform"]["Scale"]) * t; + entity = entity.Parent(); + } + + return t; +} + glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) { return AbsolutePosition(entity.World, entity.ID); @@ -19,6 +31,19 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) return position; } +glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity) +{ + glm::vec3 orientation; + + while (entity.Valid()) { + ComponentWrapper transform = entity["Transform"]; + orientation += (glm::vec3)transform["Orientation"]; + entity = entity.Parent(); + } + + return orientation; +} + glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) { return AbsoluteOrientation(entity.World, entity.ID); @@ -62,6 +87,8 @@ glm::mat4 Transform::ModelMatrix(EntityWrapper entity) glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) { + return AbsoluteTransformation(EntityWrapper(world, entity)); + glm::vec3 position = Transform::AbsolutePosition(world, entity); glm::quat orientation = Transform::AbsoluteOrientation(world, entity); glm::vec3 scale = Transform::AbsoluteScale(world, entity); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 60a90960..6db6e4bb 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -53,7 +53,7 @@ void RenderSystem::fillModels(std::list>& jobs) // Don't render the local player if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { if (!entity.HasComponent("HealthHUD")) { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera - continue; + //continue; } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 04e1bc28..903b270f 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -11,6 +11,7 @@ #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Game/Systems/PlayerHUD.h" +#include "Game/Systems/LifetimeSystem.h" #include "../Engine/Rendering/AnimationSystem.h" Game::Game(int argc, char* argv[]) @@ -85,6 +86,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); diff --git a/src/Game/Systems/LifetimeSystem.cpp b/src/Game/Systems/LifetimeSystem.cpp new file mode 100644 index 00000000..db19e88a --- /dev/null +++ b/src/Game/Systems/LifetimeSystem.cpp @@ -0,0 +1,27 @@ +#include "Systems/LifetimeSystem.h" + +void LifetimeSystem::Update(double dt) +{ + for (auto& e : m_Deletions) { + m_World->DeleteEntity(e.ID); + } + m_Deletions.clear(); +} + +void LifetimeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cLifetime, double dt) +{ + if (dt == 0.0) { + return; + } + + if (!entity.Valid()) { + return; + } + + double& lifetime = cLifetime["Lifetime"]; + lifetime -= dt; + + if (lifetime <= 0.0) { + m_Deletions.push_back(entity); + } +} \ No newline at end of file diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index b210b564..9e813867 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -39,10 +39,51 @@ bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) return true; } -bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) +bool WeaponSystem::OnShoot(Events::Shoot& eShoot) { // TODO: Weapon firing effects here + auto rayRed = ResourceManager::Load("Schema/Entities/RayRed.xml"); + auto rayBlue = ResourceManager::Load("Schema/Entities/RayBlue.xml"); + + EntityWrapper weapon = eShoot.Player.FirstChildByName("WeaponMuzzle"); + if (weapon.Valid()) { + EntityWrapper ray; + if ((ComponentInfo::EnumType)eShoot.Player["Team"]["Team"] == eShoot.Player["Team"]["Team"].Enum("Red")) { + EntityFileParser parser(rayRed); + EntityID rayID = parser.MergeEntities(m_World); + ray = EntityWrapper(m_World, rayID); + } else { + EntityFileParser parser(rayBlue); + EntityID rayID = parser.MergeEntities(m_World); + ray = EntityWrapper(m_World, rayID); + } + + glm::mat4 transformation = Transform::AbsoluteTransformation(weapon); + glm::vec3 scale; + glm::vec3 translation; + glm::quat orientation; + glm::vec3 skew; + glm::vec4 perspective; + glm::decompose(transformation, scale, orientation, translation, skew, perspective); + + // Matrix to euler angles + glm::vec3 euler; + euler.y = glm::asin(-transformation[0][2]); + if (cos(euler.y) != 0) { + euler.x = atan2(transformation[1][2], transformation[2][2]); + euler.z = atan2(transformation[0][1], transformation[0][0]); + } else { + euler.x = atan2(-transformation[2][0], transformation[1][1]); + euler.z = 0; + } + + //LOG_DEBUG("rotation: %f %f %f", euler.x, euler.y, euler.z); + (glm::vec3&)ray["Transform"]["Position"] = translation; + (glm::vec3&)ray["Transform"]["Orientation"] = euler; + //(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon); + } + // Only run further picking code client-side! if (eShoot.Player != m_LocalPlayer) { return false; From b6fd18baed34dc3f098448d9fba4ea95ceaddf16 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 25 Jan 2016 11:56:40 +0100 Subject: [PATCH 79/80] Hacked in serverside effects --- include/Engine/Input/EInputCommand.h | 2 ++ resources/Schema/Entities/Player.xml | 19 +++---------------- src/Engine/Core/EntityWrapper.cpp | 4 ++++ src/Engine/Network/Server.cpp | 1 + src/Game/Systems/WeaponSystem.cpp | 15 +++++++++------ 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 1e150786..d4608b55 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -2,6 +2,7 @@ #define Events_InputCommand_h__ #include "Core/EventBroker.h" +#include "Core/EntityWrapper.h" namespace Events { @@ -10,6 +11,7 @@ struct InputCommand : Event { /** Numerical ID of the player. */ int PlayerID; + EntityWrapper Player; /** The command that was sent. */ std::string Command; /** The value of the command. */ diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 71490508..0e13dc94 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -20,7 +20,7 @@ - + @@ -120,20 +120,7 @@ - - - - - Models/CylinderBullet.mesh - - - - - - - - - + @@ -157,7 +144,7 @@ Hold Pos - + 1 diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 70d98aec..ad423573 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -99,6 +99,10 @@ EntityWrapper::operator bool() EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent) { + if (!this->World->ValidEntity(parent)) { + return EntityWrapper::Invalid; + } + auto itPair = this->World->GetChildren(parent); if (itPair.first == itPair.second) { return EntityWrapper::Invalid; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index a29f4f02..629984a8 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -269,6 +269,7 @@ void Server::parseOnInputCommand(Packet& packet) Events::InputCommand e; e.Command = packet.ReadString(); e.PlayerID = player; // Set correct player id + e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID); e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 9e813867..f78e092f 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -25,14 +25,13 @@ bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e) bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) { - // Only shoot if the player is alive - if (!m_LocalPlayer.Valid()) { - return false; - } - if (e.Command == "PrimaryFire" && e.Value > 0) { Events::Shoot eShoot; - eShoot.Player = m_LocalPlayer; + if (e.PlayerID == -1) { + eShoot.Player = m_LocalPlayer; + } else { + eShoot.Player = e.Player; + } m_EventBroker->Publish(eShoot); } @@ -41,6 +40,10 @@ bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) bool WeaponSystem::OnShoot(Events::Shoot& eShoot) { + if (!eShoot.Player.Valid()) { + return false; + } + // TODO: Weapon firing effects here auto rayRed = ResourceManager::Load("Schema/Entities/RayRed.xml"); From 505a6c7396fb3b0b2310d90275c143f4fe2bacc0 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 25 Jan 2016 14:32:48 +0100 Subject: [PATCH 80/80] Hiding first person models properly --- include/Engine/Core/EntityWrapper.h | 1 + resources/Schema/Entities/GameMap.xml | 115 +++++++++++++++++++++++++ resources/Schema/Entities/Player.xml | 8 +- resources/Schema/Entities/Spawnpoint | 32 +++++++ src/Engine/Core/EntityWrapper.cpp | 5 ++ src/Engine/Rendering/RenderSystem.cpp | 8 +- src/Game/Systems/PlayerSpawnSystem.cpp | 8 +- 7 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 resources/Schema/Entities/Spawnpoint diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 3d47b74c..b2e0ce4c 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -23,6 +23,7 @@ struct EntityWrapper static const EntityWrapper Invalid; + const std::string Name(); bool HasComponent(const std::string& componentType); EntityWrapper Parent(); EntityWrapper FirstChildByName(const std::string& name); diff --git a/resources/Schema/Entities/GameMap.xml b/resources/Schema/Entities/GameMap.xml index 8841e3c9..97fd3f4d 100644 --- a/resources/Schema/Entities/GameMap.xml +++ b/resources/Schema/Entities/GameMap.xml @@ -123,6 +123,121 @@ + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 0e13dc94..7914f82b 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -20,7 +20,6 @@ - @@ -31,7 +30,6 @@ - @@ -40,10 +38,9 @@ Fonts/DroidSans.ttf,100 - false - + @@ -144,13 +141,12 @@ Hold Pos - + 1 Models/AssaultAnimated.mesh - false diff --git a/resources/Schema/Entities/Spawnpoint b/resources/Schema/Entities/Spawnpoint new file mode 100644 index 00000000..a53aaa08 --- /dev/null +++ b/resources/Schema/Entities/Spawnpoint @@ -0,0 +1,32 @@ + + + + + + + Models/Core/UnitCube.mesh + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index ad423573..1f3fc1ab 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -3,6 +3,11 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid); +const std::string EntityWrapper::Name() +{ + return World->GetName(ID); +} + bool EntityWrapper::HasComponent(const std::string& componentName) { if (!Valid()) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 6db6e4bb..a67f2c75 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -52,11 +52,15 @@ void RenderSystem::fillModels(std::list>& jobs) // Don't render the local player if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { - if (!entity.HasComponent("HealthHUD")) { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera - //continue; + if (!entity.HasComponent("HealthHUD") && entity.Name() != "Crosshair" && entity.Name() != "Weapon") { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera + continue; } } + if ((entity.Name() == "Weapon" || entity.HasComponent("HealthHUD")) && !entity.IsChildOf(m_LocalPlayer)) { + continue; + } + Model* model; try { model = ResourceManager::Load<::Model, true>(resource); diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 84dce05c..7db6e8ff 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -102,10 +102,10 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) } // TODO: Set the player name to whatever - //EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); - //if (playerName.Valid()) { - // playerName["Text"]["Content"] = ???; - //} + EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); + if (playerName.Valid()) { + playerName["Text"]["Content"] = e.PlayerName; + } return true; } \ No newline at end of file