mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #13127 from SimonWalton-HiFi/half-baked-model
Incorrectly baked model crashes Interface
This commit is contained in:
commit
a1c948c0f0
9 changed files with 219 additions and 38 deletions
|
@ -33,6 +33,10 @@
|
|||
#include "ModelBakingLoggingCategory.h"
|
||||
#include "TextureBaker.h"
|
||||
|
||||
#ifdef HIFI_DUMP_FBX
|
||||
#include "FBXToJSON.h"
|
||||
#endif
|
||||
|
||||
void FBXBaker::bake() {
|
||||
qDebug() << "FBXBaker" << _modelURL << "bake starting";
|
||||
|
||||
|
@ -187,6 +191,21 @@ void FBXBaker::importScene() {
|
|||
|
||||
qCDebug(model_baking) << "Parsing" << _modelURL;
|
||||
_rootNode = reader._rootNode = reader.parseFBX(&fbxFile);
|
||||
|
||||
#ifdef HIFI_DUMP_FBX
|
||||
{
|
||||
FBXToJSON fbxToJSON;
|
||||
fbxToJSON << _rootNode;
|
||||
QFileInfo modelFile(_originalModelFilePath);
|
||||
QString outFilename(_bakedOutputDir + "/" + modelFile.completeBaseName() + "_FBX.json");
|
||||
QFile jsonFile(outFilename);
|
||||
if (jsonFile.open(QIODevice::WriteOnly)) {
|
||||
jsonFile.write(fbxToJSON.str().c_str(), fbxToJSON.str().length());
|
||||
jsonFile.close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
_geometry = reader.extractFBXGeometry({}, _modelURL.toString());
|
||||
_textureContentMap = reader._textureContent;
|
||||
}
|
||||
|
@ -231,39 +250,40 @@ void FBXBaker::rewriteAndBakeSceneModels() {
|
|||
} else if (hasWarnings()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
objectChild.children.push_back(dracoMeshNode);
|
||||
} else {
|
||||
objectChild.children.push_back(dracoMeshNode);
|
||||
|
||||
static const std::vector<QString> nodeNamesToDelete {
|
||||
// Node data that is packed into the draco mesh
|
||||
"Vertices",
|
||||
"PolygonVertexIndex",
|
||||
"LayerElementNormal",
|
||||
"LayerElementColor",
|
||||
"LayerElementUV",
|
||||
"LayerElementMaterial",
|
||||
"LayerElementTexture",
|
||||
static const std::vector<QString> nodeNamesToDelete {
|
||||
// Node data that is packed into the draco mesh
|
||||
"Vertices",
|
||||
"PolygonVertexIndex",
|
||||
"LayerElementNormal",
|
||||
"LayerElementColor",
|
||||
"LayerElementUV",
|
||||
"LayerElementMaterial",
|
||||
"LayerElementTexture",
|
||||
|
||||
// Node data that we don't support
|
||||
"Edges",
|
||||
"LayerElementTangent",
|
||||
"LayerElementBinormal",
|
||||
"LayerElementSmoothing"
|
||||
};
|
||||
auto& children = objectChild.children;
|
||||
auto it = children.begin();
|
||||
while (it != children.end()) {
|
||||
auto begin = nodeNamesToDelete.begin();
|
||||
auto end = nodeNamesToDelete.end();
|
||||
if (find(begin, end, it->name) != end) {
|
||||
it = children.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
// Node data that we don't support
|
||||
"Edges",
|
||||
"LayerElementTangent",
|
||||
"LayerElementBinormal",
|
||||
"LayerElementSmoothing"
|
||||
};
|
||||
auto& children = objectChild.children;
|
||||
auto it = children.begin();
|
||||
while (it != children.end()) {
|
||||
auto begin = nodeNamesToDelete.begin();
|
||||
auto end = nodeNamesToDelete.end();
|
||||
if (find(begin, end, it->name) != end) {
|
||||
it = children.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Geometry Object
|
||||
|
||||
} // foreach root child
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ private:
|
|||
void embedTextureMetaData();
|
||||
void rewriteAndBakeSceneModels();
|
||||
void rewriteAndBakeSceneTextures();
|
||||
void exportScene();
|
||||
|
||||
FBXGeometry* _geometry;
|
||||
QHash<QString, int> _textureNameMatchCount;
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include <draco/mesh/triangle_soup_mesh_builder.h>
|
||||
#include <draco/compression/encode.h>
|
||||
|
||||
#ifdef HIFI_DUMP_FBX
|
||||
#include "FBXToJSON.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
@ -605,5 +609,19 @@ void ModelBaker::exportScene() {
|
|||
|
||||
_outputFiles.push_back(_bakedModelFilePath);
|
||||
|
||||
#ifdef HIFI_DUMP_FBX
|
||||
{
|
||||
FBXToJSON fbxToJSON;
|
||||
fbxToJSON << _rootNode;
|
||||
QFileInfo modelFile(_bakedModelFilePath);
|
||||
QString outFilename(modelFile.dir().absolutePath() + "/" + modelFile.completeBaseName() + "_FBX.json");
|
||||
QFile jsonFile(outFilename);
|
||||
if (jsonFile.open(QIODevice::WriteOnly)) {
|
||||
jsonFile.write(fbxToJSON.str().c_str(), fbxToJSON.str().length());
|
||||
jsonFile.close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
qCDebug(model_baking) << "Exported" << _modelURL << "with re-written paths to" << _bakedModelFilePath;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,10 @@
|
|||
#include <graphics/Geometry.h>
|
||||
#include <graphics/Material.h>
|
||||
|
||||
static const QByteArray FBX_BINARY_PROLOG = "Kaydara FBX Binary ";
|
||||
// See comment in FBXReader::parseFBX().
|
||||
static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23;
|
||||
static const QByteArray FBX_BINARY_PROLOG("Kaydara FBX Binary ");
|
||||
static const QByteArray FBX_BINARY_PROLOG2("\0\x1a\0", 3);
|
||||
static const quint32 FBX_VERSION_2015 = 7400;
|
||||
static const quint32 FBX_VERSION_2016 = 7500;
|
||||
|
||||
|
|
|
@ -1603,7 +1603,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
|
||||
// NOTE: shapeVertices are in joint-frame
|
||||
std::vector<ShapeVertices> shapeVertices;
|
||||
shapeVertices.resize(geometry.joints.size());
|
||||
shapeVertices.resize(std::max(1, geometry.joints.size()) );
|
||||
|
||||
// find our special joints
|
||||
geometry.leftEyeJointIndex = modelIDs.indexOf(jointEyeLeftID);
|
||||
|
|
|
@ -214,10 +214,7 @@ FBXNode parseBinaryFBXNode(QDataStream& in, int& position, bool has64BitPosition
|
|||
|
||||
while (endOffset > position) {
|
||||
FBXNode child = parseBinaryFBXNode(in, position, has64BitPositions);
|
||||
if (child.name.isNull()) {
|
||||
return node;
|
||||
|
||||
} else {
|
||||
if (!child.name.isNull()) {
|
||||
node.children.append(child);
|
||||
}
|
||||
}
|
||||
|
|
114
libraries/fbx/src/FBXToJSON.cpp
Normal file
114
libraries/fbx/src/FBXToJSON.cpp
Normal file
|
@ -0,0 +1,114 @@
|
|||
//
|
||||
// FBXToJSON.cpp
|
||||
// libraries/fbx/src
|
||||
//
|
||||
// Created by Simon Walton on 5/4/2018.
|
||||
// Copyright 2018 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 "FBXToJSON.h"
|
||||
#include "FBX.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
template<typename T>
|
||||
inline FBXToJSON& FBXToJSON::operator<<(const QVector<T>& arrayProp) {
|
||||
*this << "[";
|
||||
char comma = ' ';
|
||||
for (auto& prop : arrayProp) {
|
||||
*(std::ostringstream*)this << comma << prop;
|
||||
comma = ',';
|
||||
}
|
||||
*this << "] ";
|
||||
|
||||
if (arrayProp.size() > 4) {
|
||||
*this << "// " << arrayProp.size() << " items";
|
||||
}
|
||||
*this << '\n';
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
FBXToJSON& FBXToJSON::operator<<(const FBXNode& fbxNode) {
|
||||
string nodeName(fbxNode.name);
|
||||
if (nodeName.empty()) {
|
||||
nodeName = "node";
|
||||
} else {
|
||||
nodeName = stringEscape(nodeName);
|
||||
}
|
||||
|
||||
*this << string(_indentLevel * 4, ' ') << '"' << nodeName << "\": {\n";
|
||||
|
||||
++_indentLevel;
|
||||
int p = 0;
|
||||
const char* eol = "";
|
||||
for (auto& prop : fbxNode.properties) {
|
||||
*this << eol << string(_indentLevel * 4, ' ') << "\"p" << p++ << "\": ";
|
||||
switch (prop.userType()) {
|
||||
case QMetaType::Short:
|
||||
case QMetaType::Bool:
|
||||
case QMetaType::Int:
|
||||
case QMetaType::LongLong:
|
||||
case QMetaType::Double:
|
||||
case QMetaType::Float:
|
||||
*this << prop.toString().toStdString();
|
||||
break;
|
||||
|
||||
case QMetaType::QString:
|
||||
case QMetaType::QByteArray:
|
||||
*this << '"' << stringEscape(prop.toByteArray().toStdString()) << '"';
|
||||
break;
|
||||
|
||||
default:
|
||||
if (prop.canConvert<QVector<float>>()) {
|
||||
*this << prop.value<QVector<float>>();
|
||||
} else if (prop.canConvert<QVector<double>>()) {
|
||||
*this << prop.value<QVector<double>>();
|
||||
} else if (prop.canConvert<QVector<bool>>()) {
|
||||
*this << prop.value<QVector<bool>>();
|
||||
} else if (prop.canConvert<QVector<qint32>>()) {
|
||||
*this << prop.value<QVector<qint32>>();
|
||||
} else if (prop.canConvert<QVector<qint64>>()) {
|
||||
*this << prop.value<QVector<qint64>>();
|
||||
} else {
|
||||
*this << "<unimplemented value>";
|
||||
}
|
||||
break;
|
||||
}
|
||||
eol = ",\n";
|
||||
}
|
||||
|
||||
for (auto& child : fbxNode.children) {
|
||||
*this << eol;
|
||||
*this << child;
|
||||
eol = ",\n";
|
||||
}
|
||||
|
||||
*this << "\n" << string(_indentLevel * 4, ' ') << "}";
|
||||
--_indentLevel;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string FBXToJSON::stringEscape(const string& in) {
|
||||
string out;
|
||||
out.reserve(in.length());
|
||||
|
||||
for (unsigned char inChar: in) {
|
||||
if (inChar == '"') {
|
||||
out.append(R"(\")");
|
||||
}
|
||||
else if (inChar == '\\') {
|
||||
out.append(R"(\\)");
|
||||
}
|
||||
else if (inChar < 0x20 || inChar == 0x7f) {
|
||||
char h[5];
|
||||
sprintf(h, "\\x%02x", inChar);
|
||||
out.append(h);
|
||||
}
|
||||
else out.append(1, inChar);
|
||||
}
|
||||
return out;
|
||||
}
|
32
libraries/fbx/src/FBXToJSON.h
Normal file
32
libraries/fbx/src/FBXToJSON.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// FBXToJSON.h
|
||||
// libraries/fbx/src
|
||||
//
|
||||
// Created by Simon Walton on 5/4/2018.
|
||||
// Copyright 2018 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_FBXToJSON_h
|
||||
#define hifi_FBXToJSON_h
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// Forward declarations.
|
||||
class FBXNode;
|
||||
template<typename T> class QVector;
|
||||
|
||||
class FBXToJSON : public std::ostringstream {
|
||||
public:
|
||||
FBXToJSON& operator<<(const FBXNode& fbxNode);
|
||||
|
||||
private:
|
||||
template<typename T> FBXToJSON& operator<<(const QVector<T>& arrayProp);
|
||||
static std::string stringEscape(const std::string& in);
|
||||
int _indentLevel { 0 };
|
||||
};
|
||||
|
||||
#endif // hifi_FBXToJSON_h
|
|
@ -62,8 +62,7 @@ QByteArray FBXWriter::encodeFBX(const FBXNode& root) {
|
|||
out.setVersion(QDataStream::Qt_4_5);
|
||||
|
||||
out.writeRawData(FBX_BINARY_PROLOG, FBX_BINARY_PROLOG.size());
|
||||
auto bytes = QByteArray(FBX_HEADER_BYTES_BEFORE_VERSION - FBX_BINARY_PROLOG.size(), '\0');
|
||||
out.writeRawData(bytes, bytes.size());
|
||||
out.writeRawData(FBX_BINARY_PROLOG2, FBX_BINARY_PROLOG2.size());
|
||||
|
||||
#ifdef USE_FBX_2016_FORMAT
|
||||
out << FBX_VERSION_2016;
|
||||
|
|
Loading…
Reference in a new issue