Merge branch 'master' of https://github.com/jrkoonce/tinygltf into jrkoonce-master

This commit is contained in:
Syoyo Fujita 2019-09-05 14:22:51 +09:00
commit 59b2966f81
3 changed files with 72 additions and 29 deletions

View File

@ -4,7 +4,6 @@
#define TINYGLTF_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
//#define TINYGLTF_USE_RAPIDJSON
#include "tiny_gltf.h" #include "tiny_gltf.h"
#include <cstdio> #include <cstdio>

View File

@ -20,7 +20,7 @@ TEST_CASE("parse-error", "[parse]") {
std::string err; std::string err;
std::string warn; std::string warn;
bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", strlen("bora"), /* basedir*/ ""); bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, "bora", static_cast<int>(strlen("bora")), /* basedir*/ "");
REQUIRE(false == ret); REQUIRE(false == ret);

View File

@ -882,7 +882,7 @@ struct Accessor {
return static_cast<int>(bufferViewObject.byteStride); return static_cast<int>(bufferViewObject.byteStride);
} }
return 0; //unreachable return 0;
} }
Accessor() { Accessor() {
@ -1015,6 +1015,7 @@ struct Mesh {
Value extras; Value extras;
Mesh() = default; Mesh() = default;
~Mesh() = default;
Mesh(const Mesh&) = default; Mesh(const Mesh&) = default;
Mesh(Mesh&& rhs) noexcept Mesh(Mesh&& rhs) noexcept
: name(std::move(rhs.name)) : name(std::move(rhs.name))
@ -1022,6 +1023,14 @@ struct Mesh {
, weights(std::move(rhs.weights)) , weights(std::move(rhs.weights))
, extensions(std::move(rhs.extensions)) , extensions(std::move(rhs.extensions))
, extras(std::move(rhs.extras)) {} , extras(std::move(rhs.extras)) {}
Mesh &operator=(const Mesh &) = default;
Mesh &operator=(Mesh &&rhs) {
if (&rhs != this) {
this->~Mesh();
new (reinterpret_cast<void *>(this)) Mesh(std::move(rhs));
}
return *this;
}
bool operator==(const Mesh &) const; bool operator==(const Mesh &) const;
}; };
@ -1062,6 +1071,13 @@ class Node {
~Node() {} ~Node() {}
Node &operator=(const Node &rhs) = default; Node &operator=(const Node &rhs) = default;
Node &operator=(Node &&rhs) {
if (&rhs != this) {
this->~Node();
new (reinterpret_cast<void *>(this)) Node(std::move(rhs));
}
return *this;
}
bool operator==(const Node &) const; bool operator==(const Node &) const;
@ -1107,6 +1123,7 @@ struct Asset {
Value extras; Value extras;
Asset() = default; Asset() = default;
~Asset() = default;
Asset(const Asset&) = default; Asset(const Asset&) = default;
Asset(Asset&& rhs) noexcept Asset(Asset&& rhs) noexcept
: version(std::move(rhs.version)) : version(std::move(rhs.version))
@ -1115,6 +1132,14 @@ struct Asset {
, copyright(std::move(rhs.copyright)) , copyright(std::move(rhs.copyright))
, extensions(std::move(rhs.extensions)) , extensions(std::move(rhs.extensions))
, extras(std::move(rhs.extras)) {} , extras(std::move(rhs.extras)) {}
Asset &operator=(const Asset &) = default;
Asset &operator=(Asset &&rhs) {
if (&rhs != this) {
this->~Asset();
new (reinterpret_cast<void *>(this)) Asset(std::move(rhs));
}
return *this;
}
bool operator==(const Asset &) const; bool operator==(const Asset &) const;
}; };
@ -1625,33 +1650,52 @@ class TinyGLTF {
namespace namespace
{ {
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
#ifdef TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
// This uses the RapidJSON CRTAllocator. It is thread safe and multiple
// documents may be active at once.
using json = rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
using json_const_iterator = json::ConstMemberIterator;
using json_const_array_iterator = json const *;
using JsonDocument =
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator>;
rapidjson::CrtAllocator s_CrtAllocator; //stateless and thread safe
rapidjson::CrtAllocator &GetAllocator() { return s_CrtAllocator; }
#else
// This uses the default RapidJSON MemoryPoolAllocator. It is very fast, but
// not thread safe. Only a single JsonDocument may be active at any one time,
// meaning only a single gltf load/save can be active any one time.
using json = rapidjson::Value; using json = rapidjson::Value;
using json_const_iterator = json::ConstMemberIterator; using json_const_iterator = json::ConstMemberIterator;
using json_const_array_iterator = json const*; using json_const_array_iterator = json const *;
rapidjson::Document *s_pActiveDocument = nullptr;
rapidjson::Document* s_pActiveDocument = nullptr; rapidjson::Document::AllocatorType &GetAllocator() {
assert(s_pActiveDocument); //Root json node must be JsonDocument type
struct JsonDocument : public rapidjson::Document return s_pActiveDocument->GetAllocator();
{ }
struct JsonDocument : public rapidjson::Document {
JsonDocument() { JsonDocument() {
assert(s_pActiveDocument == nullptr); //Code assumes only one document is active at a time assert(s_pActiveDocument ==
nullptr); // When using default allocator, only one document can be active at a time, if you need
// multiple active at once, define TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
s_pActiveDocument = this; s_pActiveDocument = this;
} }
JsonDocument(const JsonDocument&) = delete; JsonDocument(const JsonDocument &) = delete;
JsonDocument(JsonDocument&& rhs) noexcept : rapidjson::Document(std::move(rhs)) JsonDocument(JsonDocument &&rhs) noexcept
{ : rapidjson::Document(std::move(rhs)) {
s_pActiveDocument = this; s_pActiveDocument = this;
rhs.isNil = true; rhs.isNil = true;
} }
~JsonDocument() { ~JsonDocument() {
if (!isNil) if (!isNil) {
{
s_pActiveDocument = nullptr; s_pActiveDocument = nullptr;
} }
} }
private: private:
bool isNil = false; bool isNil = false;
}; };
#endif // TINYGLTF_USE_RAPIDJSON_CRTALLOCATOR
#else #else
using nlohmann::json; using nlohmann::json;
using json_const_iterator = json::const_iterator; using json_const_iterator = json::const_iterator;
@ -3046,7 +3090,7 @@ static bool ParseBooleanProperty(bool *ret, std::string *err, const json &o,
auto& value = GetValue(it); auto& value = GetValue(it);
bool isBoolean; bool isBoolean;
bool boolValue; bool boolValue = false;
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
isBoolean = value.IsBool(); isBoolean = value.IsBool();
if (isBoolean) if (isBoolean)
@ -3132,7 +3176,7 @@ static bool ParseUnsignedProperty(size_t *ret, std::string *err, const json &o,
auto& value = GetValue(it); auto& value = GetValue(it);
size_t uValue; size_t uValue = 0;
bool isUValue; bool isUValue;
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
isUValue = false; isUValue = false;
@ -4987,9 +5031,9 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
auto ForEachInArray = [](const json& v, const char* member, const std::function<bool(const json&)>& cb)->bool auto ForEachInArray = [](const json& v, const char* member, const std::function<bool(const json&)>& cb)->bool
#endif #endif
{ {
json_const_iterator it; json_const_iterator itm;
if (FindMember(v, member, it) && IsArray(GetValue(it))) { if (FindMember(v, member, itm) && IsArray(GetValue(itm))) {
const json &root = GetValue(it); const json &root = GetValue(itm);
auto it = ArrayBegin(root); auto it = ArrayBegin(root);
auto end = ArrayEnd(root); auto end = ArrayEnd(root);
for (; it != end; ++it) { for (; it != end; ++it) {
@ -5649,7 +5693,7 @@ namespace
json JsonFromString(const char* s) json JsonFromString(const char* s)
{ {
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
return json(s, s_pActiveDocument->GetAllocator()); return json(s, GetAllocator());
#else #else
return json(s); return json(s);
#endif #endif
@ -5680,7 +5724,7 @@ namespace
void JsonAssign(json& dest, const json& src) void JsonAssign(json& dest, const json& src)
{ {
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
dest.CopyFrom(src, s_pActiveDocument->GetAllocator()); dest.CopyFrom(src, GetAllocator());
#else #else
dest = src; dest = src;
#endif #endif
@ -5693,7 +5737,7 @@ namespace
{ {
o.SetObject(); o.SetObject();
} }
o.AddMember(json(key, s_pActiveDocument->GetAllocator()), std::move(value), s_pActiveDocument->GetAllocator()); o.AddMember(json(key, GetAllocator()), std::move(value), GetAllocator());
#else #else
o[key] = std::move(value); o[key] = std::move(value);
#endif #endif
@ -5702,7 +5746,7 @@ namespace
void JsonPushBack(json& o, json&& value) void JsonPushBack(json& o, json&& value)
{ {
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
o.PushBack(std::move(value), s_pActiveDocument->GetAllocator()); o.PushBack(std::move(value), GetAllocator());
#else #else
o.push_back(std::move(value)); o.push_back(std::move(value));
#endif #endif
@ -5730,7 +5774,7 @@ namespace
{ {
#ifdef TINYGLTF_USE_RAPIDJSON #ifdef TINYGLTF_USE_RAPIDJSON
o.SetArray(); o.SetArray();
o.Reserve(static_cast<rapidjson::SizeType>(s), s_pActiveDocument->GetAllocator()); o.Reserve(static_cast<rapidjson::SizeType>(s), GetAllocator());
#endif #endif
(void)(o); (void)(o);
(void)(s); (void)(s);
@ -5795,16 +5839,16 @@ static bool ValueToJson(const Value &value, json *ret) {
obj.SetBool(value.Get<bool>()); obj.SetBool(value.Get<bool>());
break; break;
case STRING_TYPE: case STRING_TYPE:
obj.SetString(value.Get<std::string>().c_str(), s_pActiveDocument->GetAllocator()); obj.SetString(value.Get<std::string>().c_str(), GetAllocator());
break; break;
case ARRAY_TYPE: { case ARRAY_TYPE: {
obj.SetArray(); obj.SetArray();
obj.Reserve(static_cast<rapidjson::SizeType>(value.ArrayLen()), s_pActiveDocument->GetAllocator()); obj.Reserve(static_cast<rapidjson::SizeType>(value.ArrayLen()), GetAllocator());
for (unsigned int i = 0; i < value.ArrayLen(); ++i) { for (unsigned int i = 0; i < value.ArrayLen(); ++i) {
Value elementValue = value.Get(int(i)); Value elementValue = value.Get(int(i));
json elementJson; json elementJson;
if (ValueToJson(value.Get(int(i)), &elementJson)) if (ValueToJson(value.Get(int(i)), &elementJson))
obj.PushBack(std::move(elementJson), s_pActiveDocument->GetAllocator()); obj.PushBack(std::move(elementJson), GetAllocator());
} }
break; break;
} }
@ -5819,7 +5863,7 @@ static bool ValueToJson(const Value &value, json *ret) {
for (auto &it : objMap) { for (auto &it : objMap) {
json elementJson; json elementJson;
if (ValueToJson(it.second, &elementJson)) { if (ValueToJson(it.second, &elementJson)) {
obj.AddMember(json(it.first.c_str(), s_pActiveDocument->GetAllocator()), std::move(elementJson), s_pActiveDocument->GetAllocator()); obj.AddMember(json(it.first.c_str(), GetAllocator()), std::move(elementJson), GetAllocator());
} }
} }
break; break;