This commit is contained in:
Brad Davis 2019-09-23 10:22:13 -07:00
parent 468d9f093d
commit 5edb312346
5 changed files with 1199 additions and 922 deletions

File diff suppressed because it is too large Load diff

View file

@ -38,14 +38,14 @@ struct GLTFAsset {
struct GLTFNode {
QString name;
int camera;
int mesh;
int camera{ -1 };
int mesh{ -1 };
QVector<int> children;
QVector<double> translation;
QVector<double> rotation;
QVector<double> scale;
QVector<double> matrix;
QVector<glm::mat4> transforms;
glm::mat4 transform;
int skin;
QVector<int> skeletons;
QString jointName;
@ -85,6 +85,8 @@ struct GLTFNode {
qCDebug(modelformat) << "skeletons: " << skeletons;
}
}
void normalizeTransform();
};
// Meshes
@ -460,15 +462,56 @@ struct GLTFMaterial {
// Accesors
namespace GLTFAccessorType {
enum Values {
SCALAR = 0,
VEC2,
VEC3,
VEC4,
MAT2,
MAT3,
MAT4
enum Value {
SCALAR = 1,
VEC2 = 2,
VEC3 = 3,
VEC4 = 4,
MAT2 = 5,
MAT3 = 9,
MAT4 = 16
};
inline int count(Value value) {
if (value == MAT2) {
return 4;
}
return (int)value;
}
}
namespace GLTFVertexAttribute {
enum Value {
UNKNOWN = -1,
POSITION = 0,
NORMAL,
TANGENT,
TEXCOORD_0,
TEXCOORD_1,
COLOR_0,
JOINTS_0,
WEIGHTS_0,
};
inline Value fromString(const QString& key) {
if (key == "POSITION") {
return POSITION;
} else if (key == "NORMAL") {
return NORMAL;
} else if (key == "TANGENT") {
return TANGENT;
} else if (key == "TEXCOORD_0") {
return TEXCOORD_0;
} else if (key == "TEXCOORD_1") {
return TEXCOORD_1;
} else if (key == "COLOR_0") {
return COLOR_0;
} else if (key == "JOINTS_0") {
return JOINTS_0;
} else if (key == "WEIGHTS_0") {
return WEIGHTS_0;
}
return UNKNOWN;
}
}
namespace GLTFAccessorComponentType {
enum Values {
@ -760,6 +803,13 @@ struct GLTFFile {
foreach(auto tex, textures) tex.dump();
}
}
void populateMaterialNames();
void sortNodes();
void normalizeNodeTransforms();
private:
void reorderNodes(const std::unordered_map<int, int>& reorderMap);
};
class GLTFSerializer : public QObject, public HFMSerializer {
@ -774,7 +824,7 @@ private:
hifi::URL _url;
hifi::ByteArray _glbBinary;
glm::mat4 getModelTransform(const GLTFNode& node);
const glm::mat4& getModelTransform(const GLTFNode& node);
void getSkinInverseBindMatrices(std::vector<std::vector<float>>& inverseBindMatrixValues);
void generateTargetData(int index, float weight, QVector<glm::vec3>& returnVector);
@ -843,6 +893,9 @@ private:
template <typename T>
bool addArrayFromAccessor(GLTFAccessor& accessor, QVector<T>& outarray);
template <typename T>
bool addArrayFromAttribute(GLTFVertexAttribute::Value vertexAttribute, GLTFAccessor& accessor, QVector<T>& outarray);
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices,
const QVector<glm::vec3>& in_normals, QVector<int>& out_indices,
QVector<glm::vec3>& out_vertices, QVector<glm::vec3>& out_normals);

View file

@ -122,8 +122,7 @@ public:
/// A single binding to a joint.
class Cluster {
public:
int jointIndex;
uint32_t jointIndex;
glm::mat4 inverseBindMatrix;
Transform inverseBindTransform;
};
@ -289,7 +288,8 @@ public:
class TransformNode {
public:
uint32_t parent { 0 };
static const uint32_t INVALID_PARENT_INDEX{ (uint32_t)-1 };
uint32_t parent { INVALID_PARENT_INDEX };
Transform transform;
};

View file

@ -0,0 +1,11 @@
set(TARGET_NAME fbx-test)
# This is not a testcase -- just set it up as a regular hifi project
setup_hifi_project(Quick Gui)
setup_memory_debugger()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
file(GLOB_RECURSE GLB_TEST_FILES "c:/Users/bdavi/git/glTF-Sample-Models/2.0/*.glb")
list(JOIN GLB_TEST_FILES "|" GLB_TEST_FILES)
target_compile_definitions(${TARGET_NAME} PRIVATE -DGLB_TEST_FILES="${GLB_TEST_FILES}")
link_hifi_libraries(shared graphics networking image gpu hfm fbx)
package_libraries_for_deployment()

View file

@ -0,0 +1,77 @@
//
// Created by Bradley Austin Davis on 2018/01/11
// Copyright 2014 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 <QtCore/qglobal.h>
#include <QtCore/QFile>
#include <QtGui/QGuiApplication>
#include <GLTFSerializer.h>
#include <shared/FileUtils.h>
#include <ResourceManager.h>
#include <DependencyManager.h>
#include <Windows.h>
// Currently only used by testing code
inline std::list<std::string> splitString(const std::string& source, const char delimiter = ' ') {
std::list<std::string> result;
size_t start = 0, next;
while (std::string::npos != (next = source.find(delimiter, start))) {
std::string sub = source.substr(start, next - start);
if (!sub.empty()) {
result.push_back(sub);
}
start = next + 1;
}
if (source.size() > start) {
result.push_back(source.substr(start));
}
return result;
}
std::list<std::string> getGlbTestFiles() {
return splitString(GLB_TEST_FILES, '|');
}
QtMessageHandler originalHandler;
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
#if defined(Q_OS_WIN)
OutputDebugStringA(message.toStdString().c_str());
OutputDebugStringA("\n");
#endif
originalHandler(type, context, message);
}
QByteArray readFileBytes(const std::string& filename) {
QFile file(filename.c_str());
file.open(QFile::ReadOnly);
QByteArray result = file.readAll();
file.close();
return result;
}
void processFile(const std::string& filename) {
qDebug() << filename.c_str();
GLTFSerializer().read(readFileBytes(filename), {}, QUrl::fromLocalFile(filename.c_str()));
}
int main(int argc, char** argv) {
QCoreApplication app{ argc, argv };
originalHandler = qInstallMessageHandler(messageHandler);
DependencyManager::set<ResourceManager>(false);
//processFile("c:/Users/bdavi/git/glTF-Sample-Models/2.0/Box/glTF-Binary/Box.glb");
for (const auto& testFile : getGlbTestFiles()) {
processFile(testFile);
}
}