Export Collision mesh

This commit is contained in:
Teejoon
2016-02-25 13:19:35 +01:00
parent 9a41bda4cf
commit 9229b77893
6 changed files with 156 additions and 118 deletions
+22 -5
View File
@@ -5,7 +5,7 @@ Export::Export()
} }
bool Export::Meshes(std::string pathName, bool selectedOnly) bool Export::Meshes(std::string pathName, bool selectedOnly, bool isCollision)
{ {
MStatus status; MStatus status;
if (pathName.empty()) { if (pathName.empty()) {
@@ -92,8 +92,14 @@ bool Export::Meshes(std::string pathName, bool selectedOnly)
Objects.append(node); Objects.append(node);
} }
} }
GetMeshData(Objects); GetMeshData(Objects, isCollision);
WriteMeshData(pathName);
if (!isCollision) {
WriteMeshData(pathName);
} else {
WriteCollisionData(pathName);
}
MGlobal::displayInfo(MString() + "Enabling IKSolvers"); MGlobal::displayInfo(MString() + "Enabling IKSolvers");
status = MGlobal::executeCommand("doEnableNodeItems true all;"); status = MGlobal::executeCommand("doEnableNodeItems true all;");
if (status != MS::kSuccess) { if (status != MS::kSuccess) {
@@ -144,9 +150,9 @@ bool Export::Animations(std::string pathName, std::vector<AnimationInfo> animInf
return true; return true;
} }
bool Export::GetMeshData(MObjectArray object) bool Export::GetMeshData(MObjectArray object, bool collision)
{ {
meshes = m_MeshHandler.GetMeshData(object); meshes = m_MeshHandler.GetMeshData(object, collision);
return true; return true;
} }
@@ -185,6 +191,17 @@ void Export::WriteMeshData(std::string pathName)
m_MeshFile.CloseFiles(); m_MeshFile.CloseFiles();
} }
void Export::WriteCollisionData(std::string pathName) {
m_ColliFile.ASCIIFilePath(pathName + "_colli.txt");
m_ColliFile.binaryFilePath(pathName + ".colli");
m_ColliFile.OpenFiles();
m_ColliFile.writeToFiles((OutputData*)&meshes);
m_ColliFile.CloseFiles();
}
void Export::WriteAnimData(std::string pathName) void Export::WriteAnimData(std::string pathName)
{ {
if (allBindPoses.size() > 0) { if (allBindPoses.size() > 0) {
+4 -2
View File
@@ -22,18 +22,19 @@ public:
int End; int End;
}; };
bool Meshes(std::string pathName, bool selectedOnly = false); bool Meshes(std::string pathName, bool selectedOnly = false, bool isCollision = false);
bool Materials(std::string pathName); bool Materials(std::string pathName);
bool Animations(std::string pathName, std::vector<AnimationInfo> animInfo); bool Animations(std::string pathName, std::vector<AnimationInfo> animInfo);
private: private:
bool GetMeshData(MObjectArray object); bool GetMeshData(MObjectArray object, bool collision);
bool GetMaterialData(); bool GetMaterialData();
bool GetAnimationData(AnimationInfo info); bool GetAnimationData(AnimationInfo info);
void WriteMeshData(std::string pathName); void WriteMeshData(std::string pathName);
void WriteAnimData(std::string pathName); void WriteAnimData(std::string pathName);
void WriteMaterialData(std::string pathName); void WriteMaterialData(std::string pathName);
void WriteCollisionData(std::string pathName);
Material m_MaterialHandler; Material m_MaterialHandler;
Skeleton m_SkeletonHandler; Skeleton m_SkeletonHandler;
@@ -44,6 +45,7 @@ private:
WriteToFile m_MeshFile; WriteToFile m_MeshFile;
WriteToFile m_AnimFile; WriteToFile m_AnimFile;
WriteToFile m_MtrlFile; WriteToFile m_MtrlFile;
WriteToFile m_ColliFile;
//Mesh Data //Mesh Data
Mesh meshes; Mesh meshes;
+35 -30
View File
@@ -25,6 +25,7 @@ Menu::Menu(QDialog* dialog)
m_ExportSelectedButton = new QCheckBox(tr("&Export Selected")); m_ExportSelectedButton = new QCheckBox(tr("&Export Selected"));
m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations")); m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations"));
m_ExportMaterialButton = new QCheckBox(tr("&Export Material"));; m_ExportMaterialButton = new QCheckBox(tr("&Export Material"));;
m_IsCollision = new QCheckBox(tr("&Export as collision mesh"));
m_ExportAnimationsButton->setChecked(true); m_ExportAnimationsButton->setChecked(true);
m_ExportMaterialButton->setChecked(true); m_ExportMaterialButton->setChecked(true);
@@ -32,6 +33,7 @@ Menu::Menu(QDialog* dialog)
vbox->addWidget(m_ExportSelectedButton); vbox->addWidget(m_ExportSelectedButton);
vbox->addWidget(m_ExportAnimationsButton); vbox->addWidget(m_ExportAnimationsButton);
vbox->addWidget(m_ExportMaterialButton); vbox->addWidget(m_ExportMaterialButton);
vbox->addWidget(m_IsCollision);
vbox->addStretch(1); vbox->addStretch(1);
optionsBox->setLayout(vbox); optionsBox->setLayout(vbox);
@@ -46,6 +48,7 @@ Menu::Menu(QDialog* dialog)
connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_ExportMaterialButton, SIGNAL(clicked(bool)), this, SLOT(NULL)); connect(m_ExportMaterialButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(m_IsCollision, SIGNAL(clicked(bool)), this, SLOT(NULL));
// Creating several layouts, adding widgets & adding them to one layout in the end // Creating several layouts, adding widgets & adding them to one layout in the end
QHBoxLayout* topLayout = new QHBoxLayout; QHBoxLayout* topLayout = new QHBoxLayout;
@@ -163,40 +166,42 @@ void Menu::RemoveClipClicked(bool)
void Menu::ExportAll(bool) void Menu::ExportAll(bool)
{ {
if (m_ExportPath->text().isEmpty()) { if (m_ExportPath->text().isEmpty()) {
MGlobal::displayError(MString() + "Please select a folder."); MGlobal::displayError(MString() + "Please select a folder.");
return; return;
} }
//Export meshes //Export meshes
if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked())) { if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked(), m_IsCollision->isChecked())) {
MGlobal::displayError(MString() + "Could not export mesh"); MGlobal::displayError(MString() + "Could not export mesh");
return; return;
} }
if (m_ExportMaterialButton->isChecked()) { if (!m_IsCollision->isChecked()){
if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) { if (m_ExportMaterialButton->isChecked()) {
MGlobal::displayError(MString() + "Could not export materials"); if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) {
return; MGlobal::displayError(MString() + "Could not export materials");
} return;
} }
}
std::vector<Export::AnimationInfo> animations; std::vector<Export::AnimationInfo> animations;
for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) { for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) {
Export::AnimationInfo thisClip; Export::AnimationInfo thisClip;
thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData()); thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData());
thisClip.Start = m_StartFrameLines[i]->text().toInt(); thisClip.Start = m_StartFrameLines[i]->text().toInt();
thisClip.End = m_EndFrameLines[i]->text().toInt(); thisClip.End = m_EndFrameLines[i]->text().toInt();
animations.push_back(thisClip); animations.push_back(thisClip);
} }
if (m_ExportAnimationsButton->isChecked()) { if (m_ExportAnimationsButton->isChecked()) {
//Export Animations //Export Animations
if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) { if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) {
MGlobal::displayError(MString() + "Could not export animations"); MGlobal::displayError(MString() + "Could not export animations");
return; return;
} }
} }
}
} }
void Menu::CancelClicked(bool) void Menu::CancelClicked(bool)
+1
View File
@@ -66,6 +66,7 @@ private:
QCheckBox* m_ExportSelectedButton = nullptr; QCheckBox* m_ExportSelectedButton = nullptr;
QCheckBox* m_ExportAnimationsButton = nullptr; QCheckBox* m_ExportAnimationsButton = nullptr;
QCheckBox* m_ExportMaterialButton = nullptr; QCheckBox* m_ExportMaterialButton = nullptr;
QCheckBox* m_IsCollision = nullptr;
QLineEdit* m_ExportPath = nullptr; QLineEdit* m_ExportPath = nullptr;
QFileDialog* m_FileDialog = nullptr; QFileDialog* m_FileDialog = nullptr;
+62 -58
View File
@@ -94,33 +94,37 @@ MeshClass::MeshClass()
// return weightMap; // return weightMap;
//} //}
Mesh MeshClass::GetMeshData(MObjectArray object) Mesh MeshClass::GetMeshData(MObjectArray object, bool collision)
{ {
MS status; MS status;
Mesh newMesh; Mesh newMesh;
newMesh.isCollison = collision;
vector<VertexLayout>& vertexList = newMesh.Vertices; vector<VertexLayout>& vertexList = newMesh.Vertices;
map<string, vector<int>>& indexLists = newMesh.Indices; map<string, vector<int>>& indexLists = newMesh.Indices;
for (int ObjectID = 0; ObjectID < object.length(); ObjectID++) { for (int ObjectID = 0; ObjectID < object.length(); ObjectID++) {
if (!object[ObjectID].hasFn(MFn::kMesh)) if (!object[ObjectID].hasFn(MFn::kMesh))
continue; continue;
MObject node = object[ObjectID]; MObject node = object[ObjectID];
MFnDependencyNode thisNode(node); MFnDependencyNode thisNode(node);
MPlugArray connections; MPlugArray connections;
thisNode.findPlug("inMesh").connectedTo(connections, true, true); thisNode.findPlug("inMesh").connectedTo(connections, true, true);
MPlug weightList, weights; MPlug weightList, weights;
MObject weightListObject; 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");
newMesh.hasSkin = true;
break;
}
}
if (!collision) {
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");
newMesh.hasSkin = true;
break;
}
}
}
// In here, we retrieve triangulated polygons from the mesh // In here, we retrieve triangulated polygons from the mesh
MFnMesh mesh(object[ObjectID]); MFnMesh mesh(object[ObjectID]);
@@ -257,62 +261,62 @@ Mesh MeshClass::GetMeshData(MObjectArray object)
thisVertex.Pos[0] = pos.x; thisVertex.Pos[0] = pos.x;
thisVertex.Pos[1] = pos.y; thisVertex.Pos[1] = pos.y;
thisVertex.Pos[2] = pos.z; thisVertex.Pos[2] = pos.z;
thisVertex.isCollision = collision;
status = faceVert.getNormal(normal, MSpace::kObject); if (!collision) {
if (status != MS::kSuccess) { status = faceVert.getNormal(normal, MSpace::kObject);
MGlobal::displayError(MString() + "faceVert.getNormal() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); if (status != MS::kSuccess) {
break; MGlobal::displayError(MString() + "faceVert.getNormal() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
} break;
}
thisVertex.Normal[0] = normal[0]; thisVertex.Normal[0] = normal[0];
thisVertex.Normal[1] = normal[1]; thisVertex.Normal[1] = normal[1];
thisVertex.Normal[2] = normal[2]; thisVertex.Normal[2] = normal[2];
MFloatVector Tangent = Tangents[faceVert.tangentId()]; MFloatVector Tangent = Tangents[faceVert.tangentId()];
//MVector tmp = faceVert.getTangent(MSpace::kObject, NULL); //MVector tmp = faceVert.getTangent(MSpace::kObject, NULL);
//tmp.get(biTangent); //tmp.get(biTangent);
thisVertex.Tangent[0] = Tangent[0]; thisVertex.Tangent[0] = Tangent[0];
thisVertex.Tangent[1] = Tangent[1]; thisVertex.Tangent[1] = Tangent[1];
thisVertex.Tangent[2] = Tangent[2]; thisVertex.Tangent[2] = Tangent[2];
MFloatVector biNormal = biNormals[faceVert.tangentId()]; MFloatVector biNormal = biNormals[faceVert.tangentId()];
//faceVert.getBinormal().get(biNormal); //faceVert.getBinormal().get(biNormal);
thisVertex.BiNormal[0] = biNormal[0]; thisVertex.BiNormal[0] = biNormal[0];
thisVertex.BiNormal[1] = biNormal[1]; thisVertex.BiNormal[1] = biNormal[1];
thisVertex.BiNormal[2] = biNormal[2]; thisVertex.BiNormal[2] = biNormal[2];
status = faceVert.getUV(UV); status = faceVert.getUV(UV);
if (status != MS::kSuccess) { if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName()); MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
break; break;
} }
thisVertex.Uv[0] = UV[0]; thisVertex.Uv[0] = UV[0];
thisVertex.Uv[1] = UV[1]; thisVertex.Uv[1] = UV[1];
if (newMesh.hasSkin) { if (newMesh.hasSkin) {
thisVertex.useWeights = true; thisVertex.useWeights = true;
float totalWeight = 0.0f; float totalWeight = 0.0f;
unsigned int totalBones = 0; unsigned int totalBones = 0;
MIntArray jointIDs /* ??? */; MIntArray jointIDs /* ??? */;
weights.selectAncestorLogicalIndex(vertexIndex, weightListObject); weights.selectAncestorLogicalIndex(vertexIndex, weightListObject);
weights.getExistingArrayAttributeIndices(jointIDs); weights.getExistingArrayAttributeIndices(jointIDs);
for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) { for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) {
if (weights[i].asFloat() > 0.001f) { if (weights[i].asFloat() > 0.001f) {
thisVertex.BoneIndices[totalBones] = jointIDs[i]; thisVertex.BoneIndices[totalBones] = jointIDs[i];
thisVertex.BoneWeights[totalBones] = weights[i].asFloat(); thisVertex.BoneWeights[totalBones] = weights[i].asFloat();
totalWeight = totalWeight + weights[i].asFloat(); totalWeight = totalWeight + weights[i].asFloat();
totalBones++; totalBones++;
} }
} }
for (unsigned int i = 0; i < 4; i++) { for (unsigned int i = 0; i < 4; i++) {
//thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight; //thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight;
} }
} else { }
thisVertex.useWeights = false;
} }
//float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3]; //float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3];
//if (totalWeight > 0.0001f) { //if (totalWeight > 0.0001f) {
// thisVertex.BoneWeights[0] /= totalWeight; // thisVertex.BoneWeights[0] /= totalWeight;
+32 -23
View File
@@ -11,7 +11,8 @@
class VertexLayout : public OutputData class VertexLayout : public OutputData
{ {
public: public:
bool useWeights = true; bool isCollision = false;
bool useWeights = false;
float Pos[3]{ 0 }; float Pos[3]{ 0 };
float Normal[3]{ 0 }; float Normal[3]{ 0 };
float Tangent[3]{ 0 }; float Tangent[3]{ 0 };
@@ -23,28 +24,31 @@ public:
virtual void WriteBinary(std::ostream& out) virtual void WriteBinary(std::ostream& out)
{ {
out.write((char*)&Pos, sizeof(float) * 3); out.write((char*)&Pos, sizeof(float) * 3);
out.write((char*)&Normal, sizeof(float) * 3); if (!isCollision) {
out.write((char*)&Tangent, 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*)&Uv, sizeof(float) * 2); out.write((char*)&BiNormal, sizeof(float) * 3);
if (useWeights) { out.write((char*)&Uv, sizeof(float) * 2);
out.write((char*)&BoneIndices, sizeof(float) * 4); if (useWeights) {
out.write((char*)&BoneWeights, sizeof(float) * 4); 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 << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl; out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl;
out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl; if (!isCollision) {
out << Tangent[0] << " " << Tangent[1] << " " << Tangent[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 << Uv[0] << " " << Uv[1] << endl; out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl;
if (useWeights) { out << Uv[0] << " " << Uv[1] << endl;
out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl; if (useWeights) {
out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << 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) bool operator==(const VertexLayout& right)
{ {
@@ -62,6 +66,7 @@ public:
class Mesh : public OutputData { class Mesh : public OutputData {
public: public:
bool isCollison = false;
bool hasSkin = false; bool hasSkin = false;
unsigned int NumVertices; unsigned int NumVertices;
unsigned int NumIndices; unsigned int NumIndices;
@@ -70,7 +75,9 @@ public:
virtual void WriteBinary(std::ostream& out) virtual void WriteBinary(std::ostream& out)
{ {
out.write((char*)&hasSkin, sizeof(bool)); if (!isCollison) {
out.write((char*)&hasSkin, sizeof(bool));
}
out.write((char*)&NumVertices, sizeof(int)); out.write((char*)&NumVertices, sizeof(int));
out.write((char*)&NumIndices, sizeof(int)); out.write((char*)&NumIndices, sizeof(int));
for (auto aVertex : Vertices) { for (auto aVertex : Vertices) {
@@ -86,11 +93,13 @@ public:
virtual void WriteASCII(std::ostream& out) const virtual void WriteASCII(std::ostream& out) const
{ {
out << "New Mesh _ not in binary" << endl; out << "New Mesh _ not in binary" << endl;
out << "hasSkin: "; if (!isCollison) {
if(hasSkin) out << "hasSkin: ";
out << "true" << endl; if (hasSkin)
else out << "true" << endl;
out << "false" << endl; else
out << "false" << endl;
}
out << "Number of vertices: " << NumVertices << endl; out << "Number of vertices: " << NumVertices << endl;
out << "number of indices: " << NumIndices << endl; out << "number of indices: " << NumIndices << endl;
int vertexNumber = 0; int vertexNumber = 0;
@@ -115,7 +124,7 @@ class MeshClass
{ {
public: public:
MeshClass(); MeshClass();
Mesh GetMeshData(MObjectArray Object); Mesh GetMeshData(MObjectArray Object, bool collision = false);
~MeshClass(); ~MeshClass();
private: private:
struct WeightInfo { struct WeightInfo {