Added tools/skeleton-dump tool

Debug tool that prints out the skeleton hierarchy of fbx files including joint indices, bindPose and defaultPoses.
The verbose option also prints the full FBX transformation set, pre/post rotations etc.
This commit is contained in:
Anthony J. Thibault 2016-11-04 13:52:16 -07:00
parent 836aad7d0b
commit 1732448d3c
7 changed files with 143 additions and 25 deletions

View file

@ -228,9 +228,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
}
}
#ifndef NDEBUG
#define DUMP_FBX_JOINTS
void AnimSkeleton::dump() const {
void AnimSkeleton::dump(bool verbose) const {
qCDebug(animation) << "[";
for (int i = 0; i < getNumJoints(); i++) {
qCDebug(animation) << " {";
@ -240,24 +238,24 @@ void AnimSkeleton::dump() const {
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
#ifdef DUMP_FBX_JOINTS
qCDebug(animation) << " fbxJoint =";
qCDebug(animation) << " isFree =" << _joints[i].isFree;
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
qCDebug(animation) << " translation =" << _joints[i].translation;
qCDebug(animation) << " preTransform =" << _joints[i].preTransform;
qCDebug(animation) << " preRotation =" << _joints[i].preRotation;
qCDebug(animation) << " rotation =" << _joints[i].rotation;
qCDebug(animation) << " postRotation =" << _joints[i].postRotation;
qCDebug(animation) << " postTransform =" << _joints[i].postTransform;
qCDebug(animation) << " transform =" << _joints[i].transform;
qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax;
qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation;
qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation;
qCDebug(animation) << " bindTransform" << _joints[i].bindTransform;
qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint;
#endif
if (verbose) {
qCDebug(animation) << " fbxJoint =";
qCDebug(animation) << " isFree =" << _joints[i].isFree;
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
qCDebug(animation) << " translation =" << _joints[i].translation;
qCDebug(animation) << " preTransform =" << _joints[i].preTransform;
qCDebug(animation) << " preRotation =" << _joints[i].preRotation;
qCDebug(animation) << " rotation =" << _joints[i].rotation;
qCDebug(animation) << " postRotation =" << _joints[i].postRotation;
qCDebug(animation) << " postTransform =" << _joints[i].postTransform;
qCDebug(animation) << " transform =" << _joints[i].transform;
qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax;
qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation;
qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation;
qCDebug(animation) << " bindTransform" << _joints[i].bindTransform;
qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint;
}
if (getParentIndex(i) >= 0) {
qCDebug(animation) << " parent =" << getJointName(getParentIndex(i));
}
@ -284,4 +282,4 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const {
}
qCDebug(animation) << "]";
}
#endif

View file

@ -63,10 +63,8 @@ public:
void mirrorRelativePoses(AnimPoseVec& poses) const;
void mirrorAbsolutePoses(AnimPoseVec& poses) const;
#ifndef NDEBUG
void dump() const;
void dump(bool verbose) const;
void dump(const AnimPoseVec& poses) const;
#endif
protected:
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints);

View file

@ -13,3 +13,7 @@ set_target_properties(ice-client PROPERTIES FOLDER "Tools")
add_subdirectory(ac-client)
set_target_properties(ac-client PROPERTIES FOLDER "Tools")
add_subdirectory(skeleton-dump)
set_target_properties(skeleton-dump PROPERTIES FOLDER "Tools")

View file

@ -0,0 +1,4 @@
set(TARGET_NAME skeleton-dump)
setup_hifi_project(Core Widgets)
link_hifi_libraries(shared fbx model gpu gl animation)

View file

@ -0,0 +1,63 @@
//
// SkeletonDumpApp.h
// tools/skeleton-dump/src
//
// Created by Anthony Thibault on 11/4/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "SkeletonDumpApp.h"
#include <QCommandLineParser>
#include <QFile>
#include <FBXReader.h>
#include <AnimSkeleton.h>
SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc, argv) {
// parse command-line
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity FBX Skeleton Analyzer");
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption verboseOutput("v", "verbose output");
parser.addOption(verboseOutput);
const QCommandLineOption inputFilenameOption("i", "input file", "filename.fbx");
parser.addOption(inputFilenameOption);
if (!parser.parse(QCoreApplication::arguments())) {
qCritical() << parser.errorText() << endl;
parser.showHelp();
_returnCode = 1;
return;
}
if (parser.isSet(helpOption)) {
parser.showHelp();
return;
}
bool verbose = parser.isSet(verboseOutput);
QString inputFilename;
if (parser.isSet(inputFilenameOption)) {
inputFilename = parser.value(inputFilenameOption);
}
QFile file(inputFilename);
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Failed to open file " << inputFilename;
_returnCode = 2;
return;
}
QByteArray blob = file.readAll();
std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash()));
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry));
skeleton->dump(verbose);
}
SkeletonDumpApp::~SkeletonDumpApp() {
}

View file

@ -0,0 +1,29 @@
//
// VHACDUtil.h
// tools/skeleton-dump/src
//
// Created by Anthony Thibault on 11/4/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_SkeletonDumpApp_h
#define hifi_SkeletonDumpApp_h
#include <QApplication>
class SkeletonDumpApp : public QCoreApplication {
Q_OBJECT
public:
SkeletonDumpApp(int argc, char* argv[]);
~SkeletonDumpApp();
int getReturnCode() const { return _returnCode; }
private:
int _returnCode { 0 };
};
#endif //hifi_SkeletonDumpApp_h

View file

@ -0,0 +1,22 @@
//
// main.cpp
// tools/skeleton-dump/src
//
// Created by Anthony Thibault on 11/4/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <QDebug>
#include "SkeletonDumpApp.h"
int main(int argc, char * argv[]) {
SkeletonDumpApp app(argc, argv);
return app.getReturnCode();
}