Merge branch 'master' of github.com:syoyo/tinygltf

This commit is contained in:
Syoyo Fujita 2019-11-24 20:50:50 +09:00
commit 1322c7bf09

View File

@ -887,8 +887,13 @@ struct Accessor {
// unreachable return 0; // unreachable return 0;
} }
Accessor() { Accessor() :
bufferView = -1; bufferView(-1),
byteOffset(0),
normalized(false),
componentType(-1),
count(0),
type(-1){
sparse.isSparse = false; sparse.isSparse = false;
} }
DEFAULT_METHODS(Accessor) DEFAULT_METHODS(Accessor)
@ -5247,7 +5252,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \ #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || \
defined(_CPPUNWIND)) && \ defined(_CPPUNWIND)) && \
not defined(TINYGLTF_NOEXCEPTION) !defined(TINYGLTF_NOEXCEPTION)
try { try {
JsonParse(v, json_str, json_str_length, true); JsonParse(v, json_str, json_str_length, true);
@ -6369,6 +6374,7 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
SerializeNumberProperty<size_t>("count", accessor.count, o); SerializeNumberProperty<size_t>("count", accessor.count, o);
SerializeNumberArrayProperty<double>("min", accessor.minValues, o); SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o); SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
if (accessor.normalized)
SerializeValue("normalized", Value(accessor.normalized), o); SerializeValue("normalized", Value(accessor.normalized), o);
std::string type; std::string type;
switch (accessor.type) { switch (accessor.type) {
@ -6485,6 +6491,18 @@ static void SerializeGltfAsset(Asset &asset, json &o) {
SerializeExtensionMap(asset.extensions, o); SerializeExtensionMap(asset.extensions, o);
} }
static void SerializeGltfBufferBin(Buffer &buffer, json &o,
std::vector<unsigned char> &binBuffer) {
SerializeNumberProperty("byteLength", buffer.data.size(), o);
binBuffer=buffer.data;
if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o);
if (buffer.extras.Type() != NULL_TYPE) {
SerializeValue("extras", buffer.extras, o);
}
}
static void SerializeGltfBuffer(Buffer &buffer, json &o) { static void SerializeGltfBuffer(Buffer &buffer, json &o) {
SerializeNumberProperty("byteLength", buffer.data.size(), o); SerializeNumberProperty("byteLength", buffer.data.size(), o);
SerializeGltfBufferData(buffer.data, o); SerializeGltfBufferData(buffer.data, o);
@ -7173,14 +7191,30 @@ static bool WriteGltfFile(const std::string &output,
} }
static void WriteBinaryGltfStream(std::ostream &stream, static void WriteBinaryGltfStream(std::ostream &stream,
const std::string &content) { const std::string &content,
const std::vector<unsigned char> &binBuffer) {
const std::string header = "glTF"; const std::string header = "glTF";
const int version = 2; const int version = 2;
const int padding_size = content.size() % 4;
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info, // https://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number
// padding auto roundUp = [](uint32_t numToRound, uint32_t multiple)
const int length = 12 + 8 + int(content.size()) + padding_size; {
if (multiple == 0)
return numToRound;
uint32_t remainder = numToRound % multiple;
if (remainder == 0)
return numToRound;
return numToRound + multiple - remainder;
};
const uint32_t padding_size = roundUp(content.size(), 4) - content.size();
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
// Chunk data must be located at 4-byte boundary.
const int length = 12 + 8 + roundUp(content.size(), 4)+
(binBuffer.size()?(8+roundUp(binBuffer.size(),4)) : 0);
stream.write(header.c_str(), std::streamsize(header.size())); stream.write(header.c_str(), std::streamsize(header.size()));
stream.write(reinterpret_cast<const char *>(&version), sizeof(version)); stream.write(reinterpret_cast<const char *>(&version), sizeof(version));
@ -7200,10 +7234,27 @@ static void WriteBinaryGltfStream(std::ostream &stream,
const std::string padding = std::string(size_t(padding_size), ' '); const std::string padding = std::string(size_t(padding_size), ' ');
stream.write(padding.c_str(), std::streamsize(padding.size())); stream.write(padding.c_str(), std::streamsize(padding.size()));
} }
if (binBuffer.size() > 0){
const uint32_t bin_padding_size = roundUp(binBuffer.size(), 4) - binBuffer.size();
// BIN chunk info, then BIN data
const int bin_length = int(binBuffer.size()) + bin_padding_size;
const int bin_format = 0x004e4942;
stream.write(reinterpret_cast<const char *>(&bin_length),
sizeof(bin_length));
stream.write(reinterpret_cast<const char *>(&bin_format),
sizeof(bin_format));
stream.write((const char *)binBuffer.data(), std::streamsize(binBuffer.size()));
// Chunksize must be multiplies of 4, so pad with zeroes
if (bin_padding_size > 0) {
const std::vector<unsigned char> padding = std::vector<unsigned char>(size_t(bin_padding_size), 0);
stream.write((const char *)padding.data(), std::streamsize(padding.size()));
}
}
} }
static void WriteBinaryGltfFile(const std::string &output, static void WriteBinaryGltfFile(const std::string &output,
const std::string &content) { const std::string &content,
const std::vector<unsigned char> &binBuffer) {
#ifdef _WIN32 #ifdef _WIN32
#if defined(_MSC_VER) #if defined(_MSC_VER)
std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary); std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary);
@ -7217,7 +7268,7 @@ static void WriteBinaryGltfFile(const std::string &output,
#else #else
std::ofstream gltfFile(output.c_str(), std::ios::binary); std::ofstream gltfFile(output.c_str(), std::ios::binary);
#endif #endif
WriteBinaryGltfStream(gltfFile, content); WriteBinaryGltfStream(gltfFile, content,binBuffer);
} }
bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream, bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
@ -7230,11 +7281,16 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
// BUFFERS // BUFFERS
std::vector<std::string> usedUris; std::vector<std::string> usedUris;
std::vector<unsigned char> binBuffer;
json buffers; json buffers;
JsonReserveArray(buffers, model->buffers.size()); JsonReserveArray(buffers, model->buffers.size());
for (unsigned int i = 0; i < model->buffers.size(); ++i) { for (unsigned int i = 0; i < model->buffers.size(); ++i) {
json buffer; json buffer;
if (writeBinary && i==0 && model->buffers[i].uri.empty()){
SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer);
} else {
SerializeGltfBuffer(model->buffers[i], buffer); SerializeGltfBuffer(model->buffers[i], buffer);
}
JsonPushBack(buffers, std::move(buffer)); JsonPushBack(buffers, std::move(buffer));
} }
JsonAddMember(output, "buffers", std::move(buffers)); JsonAddMember(output, "buffers", std::move(buffers));
@ -7259,7 +7315,7 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
} }
if (writeBinary) { if (writeBinary) {
WriteBinaryGltfStream(stream, JsonToString(output)); WriteBinaryGltfStream(stream, JsonToString(output),binBuffer);
} else { } else {
WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1)); WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
} }
@ -7290,11 +7346,14 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
// BUFFERS // BUFFERS
std::vector<std::string> usedUris; std::vector<std::string> usedUris;
std::vector<unsigned char> binBuffer;
json buffers; json buffers;
JsonReserveArray(buffers, model->buffers.size()); JsonReserveArray(buffers, model->buffers.size());
for (unsigned int i = 0; i < model->buffers.size(); ++i) { for (unsigned int i = 0; i < model->buffers.size(); ++i) {
json buffer; json buffer;
if (embedBuffers) { if (writeBinary && i==0 && model->buffers[i].uri.empty()){
SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer);
} else if (embedBuffers) {
SerializeGltfBuffer(model->buffers[i], buffer); SerializeGltfBuffer(model->buffers[i], buffer);
} else { } else {
std::string binSavePath; std::string binSavePath;
@ -7343,7 +7402,7 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
} }
if (writeBinary) { if (writeBinary) {
WriteBinaryGltfFile(filename, JsonToString(output)); WriteBinaryGltfFile(filename, JsonToString(output),binBuffer);
} else { } else {
WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1))); WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
} }