Animations PROBABLY works fine if all joints got keyframes.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
#include <maya/MItGeometry.h>
|
||||
#include <maya/MItMeshVertex.h>
|
||||
#include <maya/MFnWeightGeometryFilter.h>
|
||||
#include <maya/MItDependencyGraph.h>
|
||||
#include <maya/MQuaternion.h>
|
||||
#include <maya/MFnNumericAttribute.h>
|
||||
|
||||
|
||||
// Wrappers
|
||||
|
||||
@@ -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<Export::AnimationInfo> 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)
|
||||
|
||||
@@ -68,7 +68,6 @@ std::map<int, MeshClass::WeightInfo> 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<int, MeshClass::WeightInfo> 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<int, WeightInfo> vertexWeights = GetWeightData();
|
||||
// map<int, WeightInfo> 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<VertexLayout>::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex);
|
||||
array<unsigned int, 2> tmp;
|
||||
if (it != vertexList.end()) {
|
||||
|
||||
@@ -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<MObject> animatedJoints;
|
||||
std::vector<MObject> 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<BindPoseSkeletonNode> Skeleton::GetBindPoses()
|
||||
{
|
||||
MStatus status;
|
||||
std::vector<BindPoseSkeletonNode> m_AllSkeletons;
|
||||
std::vector<MObject> m_Hierarchy;
|
||||
|
||||
@@ -214,12 +240,76 @@ std::vector<BindPoseSkeletonNode> 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];
|
||||
|
||||
Reference in New Issue
Block a user