mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 13:33:27 +02:00
Add list compression to FBXWriter
This commit is contained in:
parent
fd1d4b9bd1
commit
c5852dfbe8
6 changed files with 40 additions and 21 deletions
|
@ -405,9 +405,9 @@ void FBXBaker::rewriteAndBakeSceneModels() {
|
||||||
|
|
||||||
if (needsOriginalIndices) {
|
if (needsOriginalIndices) {
|
||||||
meshBuilder.SetAttributeValuesForFace(originalIndexAttributeID, face,
|
meshBuilder.SetAttributeValuesForFace(originalIndexAttributeID, face,
|
||||||
&mesh.originalIndex[idx0],
|
&mesh.originalIndices[idx0],
|
||||||
&mesh.originalIndex[idx1],
|
&mesh.originalIndices[idx1],
|
||||||
&mesh.originalIndex[idx2]);
|
&mesh.originalIndices[idx2]);
|
||||||
}
|
}
|
||||||
if (hasNormals) {
|
if (hasNormals) {
|
||||||
meshBuilder.SetAttributeValuesForFace(normalsAttributeID, face,
|
meshBuilder.SetAttributeValuesForFace(normalsAttributeID, face,
|
||||||
|
|
|
@ -33,13 +33,13 @@ static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23;
|
||||||
static const quint32 FBX_VERSION_2015 = 7400;
|
static const quint32 FBX_VERSION_2015 = 7400;
|
||||||
static const quint32 FBX_VERSION_2016 = 7500;
|
static const quint32 FBX_VERSION_2016 = 7500;
|
||||||
|
|
||||||
|
|
||||||
// TODO Convert to GeometryAttribute type
|
|
||||||
static const int DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES = 1000;
|
static const int DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES = 1000;
|
||||||
static const int DRACO_ATTRIBUTE_MATERIAL_ID = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES;
|
static const int DRACO_ATTRIBUTE_MATERIAL_ID = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES;
|
||||||
static const int DRACO_ATTRIBUTE_TEX_COORD_1 = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 1;
|
static const int DRACO_ATTRIBUTE_TEX_COORD_1 = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 1;
|
||||||
static const int DRACO_ATTRIBUTE_ORIGINAL_INDEX = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 2;
|
static const int DRACO_ATTRIBUTE_ORIGINAL_INDEX = DRACO_BEGIN_CUSTOM_HIFI_ATTRIBUTES + 2;
|
||||||
|
|
||||||
|
static const int32_t FBX_PROPERTY_UNCOMPRESSED_FLAG = 0;
|
||||||
|
static const int32_t FBX_PROPERTY_COMPRESSED_FLAG = 1;
|
||||||
|
|
||||||
class FBXNode;
|
class FBXNode;
|
||||||
using FBXNodeList = QList<FBXNode>;
|
using FBXNodeList = QList<FBXNode>;
|
||||||
|
@ -218,7 +218,6 @@ public:
|
||||||
QVector<FBXMeshPart> parts;
|
QVector<FBXMeshPart> parts;
|
||||||
|
|
||||||
QVector<glm::vec3> vertices;
|
QVector<glm::vec3> vertices;
|
||||||
QVector<int32_t> originalIndex;
|
|
||||||
QVector<glm::vec3> normals;
|
QVector<glm::vec3> normals;
|
||||||
QVector<glm::vec3> tangents;
|
QVector<glm::vec3> tangents;
|
||||||
QVector<glm::vec3> colors;
|
QVector<glm::vec3> colors;
|
||||||
|
@ -226,6 +225,7 @@ public:
|
||||||
QVector<glm::vec2> texCoords1;
|
QVector<glm::vec2> texCoords1;
|
||||||
QVector<uint16_t> clusterIndices;
|
QVector<uint16_t> clusterIndices;
|
||||||
QVector<uint8_t> clusterWeights;
|
QVector<uint8_t> clusterWeights;
|
||||||
|
QVector<int32_t> originalIndices;
|
||||||
|
|
||||||
QVector<FBXCluster> clusters;
|
QVector<FBXCluster> clusters;
|
||||||
|
|
||||||
|
|
|
@ -355,7 +355,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
auto texCoordAttribute = dracoMesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);
|
auto texCoordAttribute = dracoMesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);
|
||||||
auto extraTexCoordAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_TEX_COORD_1);
|
auto extraTexCoordAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_TEX_COORD_1);
|
||||||
auto colorAttribute = dracoMesh->GetNamedAttribute(draco::GeometryAttribute::COLOR);
|
auto colorAttribute = dracoMesh->GetNamedAttribute(draco::GeometryAttribute::COLOR);
|
||||||
auto matTexAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_MATERIAL_ID);
|
auto materialIDAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_MATERIAL_ID);
|
||||||
auto originalIndexAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_ORIGINAL_INDEX);
|
auto originalIndexAttribute = dracoMesh->GetAttributeByUniqueId(DRACO_ATTRIBUTE_ORIGINAL_INDEX);
|
||||||
|
|
||||||
// setup extracted mesh data structures given number of points
|
// setup extracted mesh data structures given number of points
|
||||||
|
@ -445,11 +445,11 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
||||||
|
|
||||||
uint16_t materialID { 0 };
|
uint16_t materialID { 0 };
|
||||||
|
|
||||||
if (matTexAttribute) {
|
if (materialIDAttribute) {
|
||||||
// read material ID and texture ID mappings into materials and texture vectors
|
// read material ID and texture ID mappings into materials and texture vectors
|
||||||
auto mappedIndex = matTexAttribute->mapped_index(firstCorner);
|
auto mappedIndex = materialIDAttribute->mapped_index(firstCorner);
|
||||||
|
|
||||||
matTexAttribute->ConvertValue<uint16_t, 1>(mappedIndex, &materialID);
|
materialIDAttribute->ConvertValue<uint16_t, 1>(mappedIndex, &materialID);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<int, int> materialTexture(materialID, 0);
|
QPair<int, int> materialTexture(materialID, 0);
|
||||||
|
|
|
@ -48,9 +48,8 @@ QVariant readBinaryArray(QDataStream& in, int& position) {
|
||||||
QVector<T> values;
|
QVector<T> values;
|
||||||
if ((int)QSysInfo::ByteOrder == (int)in.byteOrder()) {
|
if ((int)QSysInfo::ByteOrder == (int)in.byteOrder()) {
|
||||||
values.resize(arrayLength);
|
values.resize(arrayLength);
|
||||||
const unsigned int DEFLATE_ENCODING = 1;
|
|
||||||
QByteArray arrayData;
|
QByteArray arrayData;
|
||||||
if (encoding == DEFLATE_ENCODING) {
|
if (encoding == FBX_PROPERTY_COMPRESSED_FLAG) {
|
||||||
// preface encoded data with uncompressed length
|
// preface encoded data with uncompressed length
|
||||||
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||||
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
||||||
|
@ -72,8 +71,7 @@ QVariant readBinaryArray(QDataStream& in, int& position) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
values.reserve(arrayLength);
|
values.reserve(arrayLength);
|
||||||
const unsigned int DEFLATE_ENCODING = 1;
|
if (encoding == FBX_PROPERTY_COMPRESSED_FLAG) {
|
||||||
if (encoding == DEFLATE_ENCODING) {
|
|
||||||
// preface encoded data with uncompressed length
|
// preface encoded data with uncompressed length
|
||||||
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
QByteArray compressed(sizeof(quint32) + compressedLength, 0);
|
||||||
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
*((quint32*)compressed.data()) = qToBigEndian<quint32>(arrayLength * sizeof(T));
|
||||||
|
|
|
@ -24,13 +24,34 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void writeVector(QDataStream& out, char ch, QVector<T> list) {
|
void writeVector(QDataStream& out, char ch, QVector<T> vec) {
|
||||||
out.device()->write(&ch, 1);
|
// Minimum number of bytes to consider compressing
|
||||||
out << (int32_t)list.length();
|
const int ATTEMPT_COMPRESSION_THRESHOLD_BYTES = 2000;
|
||||||
out << (int32_t)0;
|
|
||||||
out << (int32_t)0;
|
|
||||||
|
|
||||||
out.writeBytes(reinterpret_cast<const char*>(list.constData()), list.length() * sizeof(T));
|
out.device()->write(&ch, 1);
|
||||||
|
out << (int32_t)vec.length();
|
||||||
|
|
||||||
|
auto data { QByteArray::fromRawData((const char*)vec.constData(), vec.length() * sizeof(T)) };
|
||||||
|
|
||||||
|
if (data.size() >= ATTEMPT_COMPRESSION_THRESHOLD_BYTES) {
|
||||||
|
auto compressedDataWithLength { qCompress(data) };
|
||||||
|
|
||||||
|
// qCompress packs a length uint32 at the beginning of the buffer, but the FBX format
|
||||||
|
// does not expect it. This removes it.
|
||||||
|
auto compressedData = QByteArray::fromRawData(
|
||||||
|
compressedDataWithLength.constData() + sizeof(uint32_t), compressedDataWithLength.size() - sizeof(uint32_t));
|
||||||
|
|
||||||
|
if (compressedData.size() < data.size()) {
|
||||||
|
out << (int32_t)1;
|
||||||
|
out << (int32_t)compressedData.size();
|
||||||
|
out.writeRawData(compressedData.constData(), compressedData.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out << FBX_PROPERTY_UNCOMPRESSED_FLAG;
|
||||||
|
out << (int32_t)0;
|
||||||
|
out.writeRawData(data.constData(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
|
||||||
#define USE_FBX_2016_FORMAT
|
//#define USE_FBX_2016_FORMAT
|
||||||
|
|
||||||
class FBXWriter {
|
class FBXWriter {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue