diff --git a/README.md b/README.md index bf25870..f37303a 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,9 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch. ## Note on extension property -In extension(`ExtensionMap`), JSON number value is parsed as int or float(number) and stored as `tinygltf::Value` object. If you want a floating point value from `tinygltf::Value`, use `GetAsFloat()` method. +In extension(`ExtensionMap`), JSON number value is parsed as int or float(number) and stored as `tinygltf::Value` object. If you want a floating point value from `tinygltf::Value`, use `GetNumberAsDouble()` method. -`IsNumber()` only returns true if the underlying value is a floating point value. If you wan to check if the value is `number`(int or real, in the context of JSON), Plese use `IsNumberOrInt()` method. +`IsNumber()` returns true if the underlying value is an int value or a floating point value. ## Examples diff --git a/tests/tester.cc b/tests/tester.cc index b2ba048..144e26f 100644 --- a/tests/tester.cc +++ b/tests/tester.cc @@ -302,14 +302,14 @@ TEST_CASE("pbr-khr-texture-transform", "[material]") { REQUIRE(texform["scale"].IsArray()); - // It looks json.hpp parse integer JSON number as integer, not floating point. - // so we'll check if Value is number(floating point) or integer value. - REQUIRE(texform["scale"].Get(0).IsNumberOrInt()); - REQUIRE(texform["scale"].Get(1).IsNumberOrInt()); + // Note: It looks json.hpp parse integer JSON number as integer, not floating point. + // IsNumber return true either value is int or floating point. + REQUIRE(texform["scale"].Get(0).IsNumber()); + REQUIRE(texform["scale"].Get(1).IsNumber()); double scale[2]; - scale[0] = texform["scale"].Get(0).GetAsFloat(); - scale[1] = texform["scale"].Get(1).GetAsFloat(); + scale[0] = texform["scale"].Get(0).GetNumberAsDouble(); + scale[1] = texform["scale"].Get(1).GetNumberAsDouble(); REQUIRE(scale[0] == Approx(1.0)); REQUIRE(scale[1] == Approx(-1.0)); diff --git a/tiny_gltf.h b/tiny_gltf.h index 64941cb..5fdeaf5 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -28,6 +28,8 @@ // Version: // - v2.3.0 Modified Material representation according to glTF 2.0 schema // (and introduced TextureInfo class) +// Change the behavior of `Value::IsNumber`. It return true either the +// value is int or real. // - v2.2.0 Add loading 16bit PNG support. Add Sparse accessor support(Thanks // to @Ybalrid) // - v2.1.0 Add draco compression. @@ -160,7 +162,7 @@ AAssetManager *asset_manager = nullptr; typedef enum { NULL_TYPE = 0, - NUMBER_TYPE = 1, + REAL_TYPE = 1, INT_TYPE = 2, BOOL_TYPE = 3, STRING_TYPE = 4, @@ -213,6 +215,7 @@ static inline int32_t GetTypeSizeInBytes(uint32_t ty) { } } +// TODO(syoyo): Move these functions to TinyGLTF class bool IsDataURI(const std::string &in); bool DecodeDataURI(std::vector *out, std::string &mime_type, const std::string &in, size_t reqBytes, bool checkSize); @@ -234,12 +237,12 @@ class Value { Value() : type_(NULL_TYPE), int_value_(0), - number_value_(0.0), + real_value_(0.0), boolean_value_(false) {} explicit Value(bool b) : type_(BOOL_TYPE) { boolean_value_ = b; } explicit Value(int i) : type_(INT_TYPE) { int_value_ = i; } - explicit Value(double n) : type_(NUMBER_TYPE) { number_value_ = n; } + explicit Value(double n) : type_(REAL_TYPE) { real_value_ = n; } explicit Value(const std::string &s) : type_(STRING_TYPE) { string_value_ = s; } @@ -260,13 +263,9 @@ class Value { bool IsInt() const { return (type_ == INT_TYPE); } - // for backward compatibility, we use `IsNumber` for floating point value - // only. - bool IsNumber() const { return (type_ == NUMBER_TYPE); } + bool IsNumber() const { return (type_ == REAL_TYPE) || (type_ == INT_TYPE); } - bool IsNumberOrInt() const { - return (type_ == INT_TYPE) || (type_ == NUMBER_TYPE); - } + bool IsReal() const { return (type_ == REAL_TYPE); } bool IsString() const { return (type_ == STRING_TYPE); } @@ -276,15 +275,22 @@ class Value { bool IsObject() const { return (type_ == OBJECT_TYPE); } - double GetAsFloat() const { + // Use this function if you want to have number value as double. + double GetNumberAsDouble() const { if (type_ == INT_TYPE) { return double(int_value_); - } else if (type_ == NUMBER_TYPE) { - return number_value_; + } else { + return real_value_; } + } - // TODO(syoyo): Raise error? - return std::numeric_limits::quiet_NaN(); + // Use this function if you want to have number value as int. + double GetNumberAsInt() const { + if (type_ == REAL_TYPE) { + return int(real_value_); + } else { + return int_value_; + } } // Accessor @@ -344,7 +350,7 @@ class Value { int type_ = NULL_TYPE; int int_value_ = 0; - double number_value_ = 0.0; + double real_value_ = 0.0; std::string string_value_; std::vector binary_value_; Array array_value_; @@ -366,7 +372,7 @@ class Value { return var; \ } TINYGLTF_VALUE_GET(bool, boolean_value_) -TINYGLTF_VALUE_GET(double, number_value_) +TINYGLTF_VALUE_GET(double, real_value_) TINYGLTF_VALUE_GET(int, int_value_) TINYGLTF_VALUE_GET(std::string, string_value_) TINYGLTF_VALUE_GET(std::vector, binary_value_) @@ -1351,7 +1357,7 @@ static bool Equals(const tinygltf::Value &one, const tinygltf::Value &other) { return true; case BOOL_TYPE: return one.Get() == other.Get(); - case NUMBER_TYPE: + case REAL_TYPE: return TINYGLTF_DOUBLE_EQUAL(one.Get(), other.Get()); case INT_TYPE: return one.Get() == other.Get(); @@ -5001,7 +5007,7 @@ static void SerializeStringArrayProperty(const std::string &key, static bool ValueToJson(const Value &value, json *ret) { json obj; switch (value.Type()) { - case NUMBER_TYPE: + case REAL_TYPE: obj = json(value.Get()); break; case INT_TYPE: