Ran clang-format on tiny_gltf.h

This commit is contained in:
Arthur Brainville (Ybalrid) 2019-03-06 14:00:56 +00:00
parent 9b321a8515
commit 9223d3133a

View File

@ -380,9 +380,9 @@ struct Parameter {
return -1; return -1;
} }
/// Return the index of a texture coordinate set if this Parameter is a texture map. /// Return the index of a texture coordinate set if this Parameter is a
/// Returned value is only valid if the parameter represent a texture from a /// texture map. Returned value is only valid if the parameter represent a
/// material /// texture from a material
int TextureTexCoord() const { int TextureTexCoord() const {
const auto it = json_double_value.find("texCoord"); const auto it = json_double_value.find("texCoord");
if (it != std::end(json_double_value)) { if (it != std::end(json_double_value)) {
@ -493,7 +493,8 @@ struct Image {
int height; int height;
int component; int component;
int bits; // bit depth per channel. 8(byte), 16 or 32. int bits; // bit depth per channel. 8(byte), 16 or 32.
int pixel_type; // pixel type(TINYGLTF_COMPONENT_TYPE_***). usually UBYTE(bits = 8) or USHORT(bits = 16) int pixel_type; // pixel type(TINYGLTF_COMPONENT_TYPE_***). usually
// UBYTE(bits = 8) or USHORT(bits = 16)
std::vector<unsigned char> image; std::vector<unsigned char> image;
int bufferView; // (required if no uri) int bufferView; // (required if no uri)
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png", std::string mimeType; // (required if no uri) ["image/jpeg", "image/png",
@ -626,7 +627,10 @@ struct Accessor {
return 0; return 0;
} }
Accessor() { bufferView = -1; sparse.isSparse = false; } Accessor() {
bufferView = -1;
sparse.isSparse = false;
}
bool operator==(const tinygltf::Accessor &) const; bool operator==(const tinygltf::Accessor &) const;
}; };
@ -832,9 +836,9 @@ enum SectionCheck {
/// ///
/// LoadImageDataFunction type. Signature for custom image loading callbacks. /// LoadImageDataFunction type. Signature for custom image loading callbacks.
/// ///
typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *, std::string *, typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
int, int, const unsigned char *, int, std::string *, int, int,
void *); const unsigned char *, int, void *);
/// ///
/// WriteImageDataFunction type. Signature for custom image writing callbacks. /// WriteImageDataFunction type. Signature for custom image writing callbacks.
@ -844,9 +848,9 @@ typedef bool (*WriteImageDataFunction)(const std::string *, const std::string *,
#ifndef TINYGLTF_NO_STB_IMAGE #ifndef TINYGLTF_NO_STB_IMAGE
// Declaration of default image loader callback // Declaration of default image loader callback
bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn, bool LoadImageData(Image *image, const int image_idx, std::string *err,
int req_width, int req_height, const unsigned char *bytes, std::string *warn, int req_width, int req_height,
int size, void *); const unsigned char *bytes, int size, void *);
#endif #endif
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
@ -966,10 +970,8 @@ class TinyGLTF {
/// Write glTF to file. /// Write glTF to file.
/// ///
bool WriteGltfSceneToFile(Model *model, const std::string &filename, bool WriteGltfSceneToFile(Model *model, const std::string &filename,
bool embedImages, bool embedImages, bool embedBuffers,
bool embedBuffers, bool prettyPrint, bool writeBinary);
bool prettyPrint,
bool writeBinary);
/// ///
/// Set callback to use for loading image data /// Set callback to use for loading image data
@ -1096,8 +1098,8 @@ class TinyGLTF {
#endif #endif
#ifdef TINYGLTF_ENABLE_DRACO #ifdef TINYGLTF_ENABLE_DRACO
#include "draco/core/decoder_buffer.h"
#include "draco/compression/decode.h" #include "draco/compression/decode.h"
#include "draco/core/decoder_buffer.h"
#endif #endif
#ifndef TINYGLTF_NO_STB_IMAGE #ifndef TINYGLTF_NO_STB_IMAGE
@ -1837,7 +1839,8 @@ bool FileExists(const std::string &abs_filename, void *) {
bool ret; bool ret;
#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
if (asset_manager) { if (asset_manager) {
AAsset* asset = AAssetManager_open(asset_manager, abs_filename.c_str(), AASSET_MODE_STREAMING); AAsset *asset = AAssetManager_open(asset_manager, abs_filename.c_str(),
AASSET_MODE_STREAMING);
if (!asset) { if (!asset) {
return false; return false;
} }
@ -1918,7 +1921,8 @@ bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
const std::string &filepath, void *) { const std::string &filepath, void *) {
#ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS #ifdef TINYGLTF_ANDROID_LOAD_FROM_ASSETS
if (asset_manager) { if (asset_manager) {
AAsset* asset = AAssetManager_open(asset_manager, filepath.c_str(), AASSET_MODE_STREAMING); AAsset *asset = AAssetManager_open(asset_manager, filepath.c_str(),
AASSET_MODE_STREAMING);
if (!asset) { if (!asset) {
if (err) { if (err) {
(*err) += "File open error : " + filepath + "\n"; (*err) += "File open error : " + filepath + "\n";
@ -2497,7 +2501,8 @@ static bool ParseExtensionsProperty(ExtensionMap *ret, std::string *err,
if (!extIt.value().is_object()) continue; if (!extIt.value().is_object()) continue;
if (!ParseJsonAsValue(&extensions[extIt.key()], extIt.value())) { if (!ParseJsonAsValue(&extensions[extIt.key()], extIt.value())) {
if (!extIt.key().empty()) { if (!extIt.key().empty()) {
// create empty object so that an extension object is still of type object // create empty object so that an extension object is still of type
// object
extensions[extIt.key()] = Value{Value::Object{}}; extensions[extIt.key()] = Value{Value::Object{}};
} }
} }
@ -2521,9 +2526,9 @@ static bool ParseAsset(Asset *asset, std::string *err, const json &o) {
return true; return true;
} }
static bool ParseImage(Image *image, const int image_idx, std::string *err, std::string *warn, static bool ParseImage(Image *image, const int image_idx, std::string *err,
const json &o, const std::string &basedir, std::string *warn, const json &o,
FsCallbacks *fs, const std::string &basedir, FsCallbacks *fs,
LoadImageDataFunction *LoadImageData = nullptr, LoadImageDataFunction *LoadImageData = nullptr,
void *load_image_user_data = nullptr) { void *load_image_user_data = nullptr) {
// A glTF image must either reference a bufferView or an image uri // A glTF image must either reference a bufferView or an image uri
@ -2540,14 +2545,17 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
if (err) { if (err) {
(*err) += (*err) +=
"Only one of `bufferView` or `uri` should be defined, but both are " "Only one of `bufferView` or `uri` should be defined, but both are "
"defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; "defined for image[" +
std::to_string(image_idx) + "] name = \"" + image->name + "\"\n";
} }
return false; return false;
} }
if (!hasBufferView && !hasURI) { if (!hasBufferView && !hasURI) {
if (err) { if (err) {
(*err) += "Neither required `bufferView` nor `uri` defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; (*err) += "Neither required `bufferView` nor `uri` defined for image[" +
std::to_string(image_idx) + "] name = \"" + image->name +
"\"\n";
} }
return false; return false;
} }
@ -2559,7 +2567,9 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
double bufferView = -1; double bufferView = -1;
if (!ParseNumberProperty(&bufferView, err, o, "bufferView", true)) { if (!ParseNumberProperty(&bufferView, err, o, "bufferView", true)) {
if (err) { if (err) {
(*err) += "Failed to parse `bufferView` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; (*err) += "Failed to parse `bufferView` for image[" +
std::to_string(image_idx) + "] name = \"" + image->name +
"\"\n";
} }
return false; return false;
} }
@ -2589,7 +2599,8 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
std::string tmp_err; std::string tmp_err;
if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true)) { if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true)) {
if (err) { if (err) {
(*err) += "Failed to parse `uri` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\".\n"; (*err) += "Failed to parse `uri` for image[" + std::to_string(image_idx) +
"] name = \"" + image->name + "\".\n";
} }
return false; return false;
} }
@ -2599,7 +2610,9 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
if (IsDataURI(uri)) { if (IsDataURI(uri)) {
if (!DecodeDataURI(&img, image->mimeType, uri, 0, false)) { if (!DecodeDataURI(&img, image->mimeType, uri, 0, false)) {
if (err) { if (err) {
(*err) += "Failed to decode 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; (*err) += "Failed to decode 'uri' for image[" +
std::to_string(image_idx) + "] name = [" + image->name +
"]\n";
} }
return false; return false;
} }
@ -2612,7 +2625,9 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
#endif #endif
if (!LoadExternalFile(&img, err, warn, uri, basedir, false, 0, false, fs)) { if (!LoadExternalFile(&img, err, warn, uri, basedir, false, 0, false, fs)) {
if (warn) { if (warn) {
(*warn) += "Failed to load external 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; (*warn) += "Failed to load external 'uri' for image[" +
std::to_string(image_idx) + "] name = [" + image->name +
"]\n";
} }
// If the image cannot be loaded, keep uri as image->uri. // If the image cannot be loaded, keep uri as image->uri.
return true; return true;
@ -2620,7 +2635,9 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err, std:
if (img.empty()) { if (img.empty()) {
if (warn) { if (warn) {
(*warn) += "Image data is empty for image[" + std::to_string(image_idx) + "] name = [" + image->name + "] \n"; (*warn) += "Image data is empty for image[" +
std::to_string(image_idx) + "] name = [" + image->name +
"] \n";
} }
return false; return false;
} }
@ -2819,8 +2836,8 @@ static bool ParseBufferView(BufferView *bufferView, std::string *err,
return true; return true;
} }
static bool ParseSparseAccessor(Accessor* accessor, std::string* err, const json &o) static bool ParseSparseAccessor(Accessor *accessor, std::string *err,
{ const json &o) {
accessor->sparse.isSparse = true; accessor->sparse.isSparse = true;
double count = 0.0; double count = 0.0;
@ -2828,25 +2845,25 @@ static bool ParseSparseAccessor(Accessor* accessor, std::string* err, const json
const auto indices_iterator = o.find("indices"); const auto indices_iterator = o.find("indices");
const auto values_iterator = o.find("values"); const auto values_iterator = o.find("values");
if(indices_iterator == o.end()) if (indices_iterator == o.end()) {
{
(*err) = "the sparse object of this accessor doesn't have indices"; (*err) = "the sparse object of this accessor doesn't have indices";
return false; return false;
} }
if(values_iterator == o.end()) if (values_iterator == o.end()) {
{
(*err) = "the sparse object ob ths accessor doesn't have values"; (*err) = "the sparse object ob ths accessor doesn't have values";
return false; return false;
} }
const json &indices_obj = *indices_iterator; const json &indices_obj = *indices_iterator;
const json &values_obj = *values_iterator; const json &values_obj = *values_iterator;
double indices_buffer_view = 0.0, indices_byte_offset = 0.0, component_type = 0.0; double indices_buffer_view = 0.0, indices_byte_offset = 0.0,
ParseNumberProperty(&indices_buffer_view, err, indices_obj, "bufferView", true); component_type = 0.0;
ParseNumberProperty(&indices_byte_offset, err, indices_obj, "byteOffset", true); ParseNumberProperty(&indices_buffer_view, err, indices_obj, "bufferView",
true);
ParseNumberProperty(&indices_byte_offset, err, indices_obj, "byteOffset",
true);
ParseNumberProperty(&component_type, err, indices_obj, "componentType", true); ParseNumberProperty(&component_type, err, indices_obj, "componentType", true);
double values_buffer_view = 0.0, values_byte_offset = 0.0; double values_buffer_view = 0.0, values_byte_offset = 0.0;
@ -2948,8 +2965,7 @@ static bool ParseAccessor(Accessor *accessor, std::string *err, const json &o) {
// check if accessor has a "sparse" object: // check if accessor has a "sparse" object:
const auto iterator = o.find("sparse"); const auto iterator = o.find("sparse");
if(iterator != o.end()) if (iterator != o.end()) {
{
// here this accessor has a "sparse" subobject // here this accessor has a "sparse" subobject
return ParseSparseAccessor(accessor, err, *iterator); return ParseSparseAccessor(accessor, err, *iterator);
} }
@ -2959,79 +2975,89 @@ static bool ParseAccessor(Accessor *accessor, std::string *err, const json &o) {
#ifdef TINYGLTF_ENABLE_DRACO #ifdef TINYGLTF_ENABLE_DRACO
static void DecodeIndexBuffer(draco::Mesh* mesh, size_t componentSize, std::vector<uint8_t>& outBuffer) static void DecodeIndexBuffer(draco::Mesh *mesh, size_t componentSize,
{ std::vector<uint8_t> &outBuffer) {
if (componentSize == 4) if (componentSize == 4) {
{
assert(sizeof(mesh->face(draco::FaceIndex(0))[0]) == componentSize); assert(sizeof(mesh->face(draco::FaceIndex(0))[0]) == componentSize);
memcpy(outBuffer.data(), &mesh->face(draco::FaceIndex(0))[0], outBuffer.size()); memcpy(outBuffer.data(), &mesh->face(draco::FaceIndex(0))[0],
} outBuffer.size());
else } else {
{
size_t faceStride = componentSize * 3; size_t faceStride = componentSize * 3;
for (draco::FaceIndex f(0); f < mesh->num_faces(); ++f) for (draco::FaceIndex f(0); f < mesh->num_faces(); ++f) {
{
const draco::Mesh::Face &face = mesh->face(f); const draco::Mesh::Face &face = mesh->face(f);
if (componentSize == 2) if (componentSize == 2) {
{ uint16_t indices[3] = {(uint16_t)face[0].value(),
uint16_t indices[3] = { (uint16_t)face[0].value(), (uint16_t)face[1].value(), (uint16_t)face[2].value() }; (uint16_t)face[1].value(),
memcpy(outBuffer.data() + f.value() * faceStride, &indices[0], faceStride); (uint16_t)face[2].value()};
} memcpy(outBuffer.data() + f.value() * faceStride, &indices[0],
else faceStride);
{ } else {
uint8_t indices[3] = { (uint8_t)face[0].value(), (uint8_t)face[1].value(), (uint8_t)face[2].value() }; uint8_t indices[3] = {(uint8_t)face[0].value(),
memcpy(outBuffer.data() + f.value() * faceStride, &indices[0], faceStride); (uint8_t)face[1].value(),
(uint8_t)face[2].value()};
memcpy(outBuffer.data() + f.value() * faceStride, &indices[0],
faceStride);
} }
} }
} }
} }
template <typename T> template <typename T>
static bool GetAttributeForAllPoints(draco::Mesh* mesh, const draco::PointAttribute* pAttribute, std::vector<uint8_t>& outBuffer) static bool GetAttributeForAllPoints(draco::Mesh *mesh,
{ const draco::PointAttribute *pAttribute,
std::vector<uint8_t> &outBuffer) {
size_t byteOffset = 0; size_t byteOffset = 0;
T values[4] = {0, 0, 0, 0}; T values[4] = {0, 0, 0, 0};
for (draco::PointIndex i(0); i < mesh->num_points(); ++i) for (draco::PointIndex i(0); i < mesh->num_points(); ++i) {
{
const draco::AttributeValueIndex val_index = pAttribute->mapped_index(i); const draco::AttributeValueIndex val_index = pAttribute->mapped_index(i);
if (!pAttribute->ConvertValue<T>(val_index, pAttribute->num_components(), values)) if (!pAttribute->ConvertValue<T>(val_index, pAttribute->num_components(),
values))
return false; return false;
memcpy(outBuffer.data() + byteOffset, &values[0], sizeof(T) * pAttribute->num_components()); memcpy(outBuffer.data() + byteOffset, &values[0],
sizeof(T) * pAttribute->num_components());
byteOffset += sizeof(T) * pAttribute->num_components(); byteOffset += sizeof(T) * pAttribute->num_components();
} }
return true; return true;
} }
static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh* mesh, const draco::PointAttribute* pAttribute, std::vector<uint8_t>& outBuffer) static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh *mesh,
{ const draco::PointAttribute *pAttribute,
std::vector<uint8_t> &outBuffer) {
bool decodeResult = false; bool decodeResult = false;
switch (componentType) switch (componentType) {
{
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
decodeResult = GetAttributeForAllPoints<uint8_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<uint8_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_BYTE: case TINYGLTF_COMPONENT_TYPE_BYTE:
decodeResult = GetAttributeForAllPoints<int8_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<int8_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
decodeResult = GetAttributeForAllPoints<uint16_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<uint16_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_SHORT: case TINYGLTF_COMPONENT_TYPE_SHORT:
decodeResult = GetAttributeForAllPoints<int16_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<int16_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_INT: case TINYGLTF_COMPONENT_TYPE_INT:
decodeResult = GetAttributeForAllPoints<int32_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<int32_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
decodeResult = GetAttributeForAllPoints<uint32_t>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<uint32_t>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_FLOAT: case TINYGLTF_COMPONENT_TYPE_FLOAT:
decodeResult = GetAttributeForAllPoints<float>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<float>(mesh, pAttribute, outBuffer);
break; break;
case TINYGLTF_COMPONENT_TYPE_DOUBLE: case TINYGLTF_COMPONENT_TYPE_DOUBLE:
decodeResult = GetAttributeForAllPoints<double>(mesh, pAttribute, outBuffer); decodeResult =
GetAttributeForAllPoints<double>(mesh, pAttribute, outBuffer);
break; break;
default: default:
return false; return false;
@ -3040,14 +3066,13 @@ static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh* mesh,
return decodeResult; return decodeResult;
} }
static bool ParseDracoExtension(Primitive *primitive, Model *model, std::string *err, const Value &dracoExtensionValue) static bool ParseDracoExtension(Primitive *primitive, Model *model,
{ std::string *err,
const Value &dracoExtensionValue) {
auto bufferViewValue = dracoExtensionValue.Get("bufferView"); auto bufferViewValue = dracoExtensionValue.Get("bufferView");
if (!bufferViewValue.IsInt()) if (!bufferViewValue.IsInt()) return false;
return false;
auto attributesValue = dracoExtensionValue.Get("attributes"); auto attributesValue = dracoExtensionValue.Get("attributes");
if (!attributesValue.IsObject()) if (!attributesValue.IsObject()) return false;
return false;
auto attributesObject = attributesValue.Get<Value::Object>(); auto attributesObject = attributesValue.Get<Value::Object>();
int bufferView = bufferViewValue.Get<int>(); int bufferView = bufferViewValue.Get<int>();
@ -3055,11 +3080,11 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model, std::string
BufferView &view = model->bufferViews[bufferView]; BufferView &view = model->bufferViews[bufferView];
Buffer &buffer = model->buffers[view.buffer]; Buffer &buffer = model->buffers[view.buffer];
// BufferView has already been decoded // BufferView has already been decoded
if (view.dracoDecoded) if (view.dracoDecoded) return true;
return true;
view.dracoDecoded = true; view.dracoDecoded = true;
const char* bufferViewData = reinterpret_cast<const char*>(buffer.data.data() + view.byteOffset); const char *bufferViewData =
reinterpret_cast<const char *>(buffer.data.data() + view.byteOffset);
size_t bufferViewSize = view.byteLength; size_t bufferViewSize = view.byteLength;
// decode draco // decode draco
@ -3073,9 +3098,9 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model, std::string
const std::unique_ptr<draco::Mesh> &mesh = decodeResult.value(); const std::unique_ptr<draco::Mesh> &mesh = decodeResult.value();
// create new bufferView for indices // create new bufferView for indices
if (primitive->indices >= 0) if (primitive->indices >= 0) {
{ int32_t componentSize = GetComponentSizeInBytes(
int32_t componentSize = GetComponentSizeInBytes(model->accessors[primitive->indices].componentType); model->accessors[primitive->indices].componentType);
Buffer decodedIndexBuffer; Buffer decodedIndexBuffer;
decodedIndexBuffer.data.resize(mesh->num_faces() * 3 * componentSize); decodedIndexBuffer.data.resize(mesh->num_faces() * 3 * componentSize);
@ -3085,35 +3110,37 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model, std::string
BufferView decodedIndexBufferView; BufferView decodedIndexBufferView;
decodedIndexBufferView.buffer = int(model->buffers.size() - 1); decodedIndexBufferView.buffer = int(model->buffers.size() - 1);
decodedIndexBufferView.byteLength = int(mesh->num_faces() * 3 * componentSize); decodedIndexBufferView.byteLength =
int(mesh->num_faces() * 3 * componentSize);
decodedIndexBufferView.byteOffset = 0; decodedIndexBufferView.byteOffset = 0;
decodedIndexBufferView.byteStride = 0; decodedIndexBufferView.byteStride = 0;
decodedIndexBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; decodedIndexBufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER;
model->bufferViews.emplace_back(std::move(decodedIndexBufferView)); model->bufferViews.emplace_back(std::move(decodedIndexBufferView));
model->accessors[primitive->indices].bufferView = int(model->bufferViews.size() - 1); model->accessors[primitive->indices].bufferView =
int(model->bufferViews.size() - 1);
model->accessors[primitive->indices].count = int(mesh->num_faces() * 3); model->accessors[primitive->indices].count = int(mesh->num_faces() * 3);
} }
for (const auto& attribute : attributesObject) for (const auto &attribute : attributesObject) {
{ if (!attribute.second.IsInt()) return false;
if (!attribute.second.IsInt())
return false;
auto primitiveAttribute = primitive->attributes.find(attribute.first); auto primitiveAttribute = primitive->attributes.find(attribute.first);
if (primitiveAttribute == primitive->attributes.end()) if (primitiveAttribute == primitive->attributes.end()) return false;
return false;
int dracoAttributeIndex = attribute.second.Get<int>(); int dracoAttributeIndex = attribute.second.Get<int>();
const auto pAttribute = mesh->GetAttributeByUniqueId(dracoAttributeIndex); const auto pAttribute = mesh->GetAttributeByUniqueId(dracoAttributeIndex);
const auto pBuffer = pAttribute->buffer(); const auto pBuffer = pAttribute->buffer();
const auto componentType = model->accessors[primitiveAttribute->second].componentType; const auto componentType =
model->accessors[primitiveAttribute->second].componentType;
// Create a new buffer for this decoded buffer // Create a new buffer for this decoded buffer
Buffer decodedBuffer; Buffer decodedBuffer;
size_t bufferSize = mesh->num_points() * pAttribute->num_components() * GetComponentSizeInBytes(componentType); size_t bufferSize = mesh->num_points() * pAttribute->num_components() *
GetComponentSizeInBytes(componentType);
decodedBuffer.data.resize(bufferSize); decodedBuffer.data.resize(bufferSize);
if (!GetAttributeForAllPoints(componentType, mesh.get(), pAttribute, decodedBuffer.data)) if (!GetAttributeForAllPoints(componentType, mesh.get(), pAttribute,
decodedBuffer.data))
return false; return false;
model->buffers.emplace_back(std::move(decodedBuffer)); model->buffers.emplace_back(std::move(decodedBuffer));
@ -3123,11 +3150,15 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model, std::string
decodedBufferView.byteLength = bufferSize; decodedBufferView.byteLength = bufferSize;
decodedBufferView.byteOffset = pAttribute->byte_offset(); decodedBufferView.byteOffset = pAttribute->byte_offset();
decodedBufferView.byteStride = pAttribute->byte_stride(); decodedBufferView.byteStride = pAttribute->byte_stride();
decodedBufferView.target = primitive->indices >= 0 ? TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER : TINYGLTF_TARGET_ARRAY_BUFFER; decodedBufferView.target = primitive->indices >= 0
? TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER
: TINYGLTF_TARGET_ARRAY_BUFFER;
model->bufferViews.emplace_back(std::move(decodedBufferView)); model->bufferViews.emplace_back(std::move(decodedBufferView));
model->accessors[primitiveAttribute->second].bufferView = int(model->bufferViews.size() - 1); model->accessors[primitiveAttribute->second].bufferView =
model->accessors[primitiveAttribute->second].count = int(mesh->num_points()); int(model->bufferViews.size() - 1);
model->accessors[primitiveAttribute->second].count =
int(mesh->num_points());
} }
return true; return true;
@ -3177,9 +3208,9 @@ static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
ParseExtensionsProperty(&primitive->extensions, err, o); ParseExtensionsProperty(&primitive->extensions, err, o);
#ifdef TINYGLTF_ENABLE_DRACO #ifdef TINYGLTF_ENABLE_DRACO
auto dracoExtension = primitive->extensions.find("KHR_draco_mesh_compression"); auto dracoExtension =
if (dracoExtension != primitive->extensions.end()) primitive->extensions.find("KHR_draco_mesh_compression");
{ if (dracoExtension != primitive->extensions.end()) {
ParseDracoExtension(primitive, model, err, dracoExtension->second); ParseDracoExtension(primitive, model, err, dracoExtension->second);
} }
#endif #endif
@ -3187,7 +3218,8 @@ static bool ParsePrimitive(Primitive *primitive, Model *model, std::string *err,
return true; return true;
} }
static bool ParseMesh(Mesh *mesh, Model *model, std::string *err, const json &o) { static bool ParseMesh(Mesh *mesh, Model *model, std::string *err,
const json &o) {
ParseStringProperty(&mesh->name, err, o, "name", false); ParseStringProperty(&mesh->name, err, o, "name", false);
mesh->primitives.clear(); mesh->primitives.clear();
@ -3862,21 +3894,21 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
// Assign missing bufferView target types // Assign missing bufferView target types
// - Look for missing Mesh indices // - Look for missing Mesh indices
// - Look for missing bufferView targets // - Look for missing bufferView targets
for (auto &mesh : model->meshes) for (auto &mesh : model->meshes) {
{ for (auto &primitive : mesh.primitives) {
for (auto &primitive : mesh.primitives) if (primitive.indices >
{ -1) // has indices from parsing step, must be Element Array Buffer
if (primitive.indices > -1) // has indices from parsing step, must be Element Array Buffer
{ {
model->bufferViews[model->accessors[primitive.indices].bufferView] model->bufferViews[model->accessors[primitive.indices].bufferView]
.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; .target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
// we could optionally check if acessors' bufferView type is Scalar, as it should be // we could optionally check if acessors' bufferView type is Scalar, as
// it should be
} }
} }
} }
// find any missing targets, must be an array buffer type if not fulfilled from previous check // find any missing targets, must be an array buffer type if not fulfilled
for (auto &bufferView : model->bufferViews) // from previous check
{ for (auto &bufferView : model->bufferViews) {
if (bufferView.target == 0) // missing target type if (bufferView.target == 0) // missing target type
{ {
bufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER; bufferView.target = TINYGLTF_TARGET_ARRAY_BUFFER;
@ -3996,7 +4028,8 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
for (; it != itEnd; it++, idx++) { for (; it != itEnd; it++, idx++) {
if (!it.value().is_object()) { if (!it.value().is_object()) {
if (err) { if (err) {
(*err) += "image[" + std::to_string(idx) + "] is not a JSON object."; (*err) +=
"image[" + std::to_string(idx) + "] is not a JSON object.";
} }
return false; return false;
} }
@ -4028,10 +4061,10 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
} }
return false; return false;
} }
bool ret = LoadImageData(&image, idx, err, warn, image.width, image.height, bool ret = LoadImageData(
&image, idx, err, warn, image.width, image.height,
&buffer.data[bufferView.byteOffset], &buffer.data[bufferView.byteOffset],
static_cast<int>(bufferView.byteLength), static_cast<int>(bufferView.byteLength), load_image_user_data_);
load_image_user_data_);
if (!ret) { if (!ret) {
return false; return false;
} }
@ -4536,7 +4569,8 @@ static void SerializeExtensionMap(ExtensionMap &extensions, json &o) {
} }
if (ret.is_null()) { if (ret.is_null()) {
if (!(extIt->first.empty())) { // name should not be empty, but for sure if (!(extIt->first.empty())) { // name should not be empty, but for sure
// create empty object so that an extension name is still included in json. // create empty object so that an extension name is still included in
// json.
extMap[extIt->first] = json({}); extMap[extIt->first] = json({});
} }
} }
@ -4955,7 +4989,8 @@ static void WriteBinaryGltfFile(const std::string &output,
const int version = 2; const int version = 2;
const int padding_size = content.size() % 4; const int padding_size = content.size() % 4;
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info, padding // 12 bytes for header, JSON content length, 8 bytes for JSON chunk info,
// padding
const int length = 12 + 8 + int(content.size()) + padding_size; const int length = 12 + 8 + int(content.size()) + padding_size;
gltfFile.write(header.c_str(), header.size()); gltfFile.write(header.c_str(), header.size());
@ -4965,8 +5000,10 @@ static void WriteBinaryGltfFile(const std::string &output,
// JSON chunk info, then JSON data // JSON chunk info, then JSON data
const int model_length = int(content.size()) + padding_size; const int model_length = int(content.size()) + padding_size;
const int model_format = 0x4E4F534A; const int model_format = 0x4E4F534A;
gltfFile.write(reinterpret_cast<const char *>(&model_length), sizeof(model_length)); gltfFile.write(reinterpret_cast<const char *>(&model_length),
gltfFile.write(reinterpret_cast<const char *>(&model_format), sizeof(model_format)); sizeof(model_length));
gltfFile.write(reinterpret_cast<const char *>(&model_format),
sizeof(model_format));
gltfFile.write(content.c_str(), content.size()); gltfFile.write(content.c_str(), content.size());
// Chunk must be multiplies of 4, so pad with spaces // Chunk must be multiplies of 4, so pad with spaces
@ -5012,7 +5049,8 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
std::string defaultBinFilename = GetBaseFilename(filename); std::string defaultBinFilename = GetBaseFilename(filename);
std::string defaultBinFileExt = ".bin"; std::string defaultBinFileExt = ".bin";
std::string::size_type pos = defaultBinFilename.rfind('.', defaultBinFilename.length()); std::string::size_type pos =
defaultBinFilename.rfind('.', defaultBinFilename.length());
if (pos != std::string::npos) { if (pos != std::string::npos) {
defaultBinFilename = defaultBinFilename.substr(0, pos); defaultBinFilename = defaultBinFilename.substr(0, pos);
@ -5032,11 +5070,9 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
} else { } else {
std::string binSavePath; std::string binSavePath;
std::string binUri; std::string binUri;
if (!model->buffers[i].uri.empty() if (!model->buffers[i].uri.empty() && !IsDataURI(model->buffers[i].uri)) {
&& !IsDataURI(model->buffers[i].uri)) {
binUri = model->buffers[i].uri; binUri = model->buffers[i].uri;
} } else {
else {
binUri = defaultBinFilename + defaultBinFileExt; binUri = defaultBinFilename + defaultBinFileExt;
bool inUse = true; bool inUse = true;
int numUsed = 0; int numUsed = 0;
@ -5045,7 +5081,8 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
for (const std::string &usedName : usedUris) { for (const std::string &usedName : usedUris) {
if (binUri.compare(usedName) != 0) continue; if (binUri.compare(usedName) != 0) continue;
inUse = true; inUse = true;
binUri = defaultBinFilename + std::to_string(numUsed++) + defaultBinFileExt; binUri = defaultBinFilename + std::to_string(numUsed++) +
defaultBinFileExt;
break; break;
} }
} }