From 94c47b15c35e06fc8ccd2f068af146785836b1cb Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Sat, 29 Dec 2018 18:28:35 +0900 Subject: [PATCH] Introduce tiny_gltf_util.h header file which contains some useful helper/util functions. --- examples/anim-dump/anim-dump.cc | 351 +------------------------------- tiny_gltf.h | 30 +-- tiny_gltf_util.h | 294 ++++++++++++++++++++++++++ 3 files changed, 309 insertions(+), 366 deletions(-) create mode 100644 tiny_gltf_util.h diff --git a/examples/anim-dump/anim-dump.cc b/examples/anim-dump/anim-dump.cc index 40537dc..022f077 100644 --- a/examples/anim-dump/anim-dump.cc +++ b/examples/anim-dump/anim-dump.cc @@ -1,11 +1,14 @@ // // TODO(syoyo): Print extensions and extras for each glTF object. // +#include "tiny_gltf_util.h" + #define TINYGLTF_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include "tiny_gltf.h" + #include #include #include @@ -16,187 +19,6 @@ static std::string GetFilePathExtension(const std::string &FileName) { return ""; } -static std::string PrintMode(int mode) { - if (mode == TINYGLTF_MODE_POINTS) { - return "POINTS"; - } else if (mode == TINYGLTF_MODE_LINE) { - return "LINE"; - } else if (mode == TINYGLTF_MODE_LINE_LOOP) { - return "LINE_LOOP"; - } else if (mode == TINYGLTF_MODE_TRIANGLES) { - return "TRIANGLES"; - } else if (mode == TINYGLTF_MODE_TRIANGLE_FAN) { - return "TRIANGLE_FAN"; - } else if (mode == TINYGLTF_MODE_TRIANGLE_STRIP) { - return "TRIANGLE_STRIP"; - } - return "**UNKNOWN**"; -} - -static std::string PrintTarget(int target) { - if (target == 34962) { - return "GL_ARRAY_BUFFER"; - } else if (target == 34963) { - return "GL_ELEMENT_ARRAY_BUFFER"; - } else { - return "**UNKNOWN**"; - } -} - -static std::string PrintType(int ty) { - if (ty == TINYGLTF_TYPE_SCALAR) { - return "SCALAR"; - } else if (ty == TINYGLTF_TYPE_VECTOR) { - return "VECTOR"; - } else if (ty == TINYGLTF_TYPE_VEC2) { - return "VEC2"; - } else if (ty == TINYGLTF_TYPE_VEC3) { - return "VEC3"; - } else if (ty == TINYGLTF_TYPE_VEC4) { - return "VEC4"; - } else if (ty == TINYGLTF_TYPE_MATRIX) { - return "MATRIX"; - } else if (ty == TINYGLTF_TYPE_MAT2) { - return "MAT2"; - } else if (ty == TINYGLTF_TYPE_MAT3) { - return "MAT3"; - } else if (ty == TINYGLTF_TYPE_MAT4) { - return "MAT4"; - } - return "**UNKNOWN**"; -} - -static std::string PrintComponentType(int ty) { - if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) { - return "BYTE"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { - return "UNSIGNED_BYTE"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_SHORT) { - return "SHORT"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { - return "UNSIGNED_SHORT"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_INT) { - return "INT"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) { - return "UNSIGNED_INT"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_FLOAT) { - return "FLOAT"; - } else if (ty == TINYGLTF_COMPONENT_TYPE_DOUBLE) { - return "DOUBLE"; - } - - return "**UNKNOWN**"; -} - -#if 0 -static std::string PrintParameterType(int ty) { - if (ty == TINYGLTF_PARAMETER_TYPE_BYTE) { - return "BYTE"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE) { - return "UNSIGNED_BYTE"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_SHORT) { - return "SHORT"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT) { - return "UNSIGNED_SHORT"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_INT) { - return "INT"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT) { - return "UNSIGNED_INT"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT) { - return "FLOAT"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_VEC2) { - return "FLOAT_VEC2"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_VEC3) { - return "FLOAT_VEC3"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_VEC4) { - return "FLOAT_VEC4"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_INT_VEC2) { - return "INT_VEC2"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_INT_VEC3) { - return "INT_VEC3"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_INT_VEC4) { - return "INT_VEC4"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_BOOL) { - return "BOOL"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_BOOL_VEC2) { - return "BOOL_VEC2"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_BOOL_VEC3) { - return "BOOL_VEC3"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_BOOL_VEC4) { - return "BOOL_VEC4"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_MAT2) { - return "FLOAT_MAT2"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_MAT3) { - return "FLOAT_MAT3"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_FLOAT_MAT4) { - return "FLOAT_MAT4"; - } else if (ty == TINYGLTF_PARAMETER_TYPE_SAMPLER_2D) { - return "SAMPLER_2D"; - } - - return "**UNKNOWN**"; -} -#endif - -static std::string PrintWrapMode(int mode) { - if (mode == TINYGLTF_TEXTURE_WRAP_REPEAT) { - return "REPEAT"; - } else if (mode == TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE) { - return "CLAMP_TO_EDGE"; - } else if (mode == TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT) { - return "MIRRORED_REPEAT"; - } - - return "**UNKNOWN**"; -} - -static std::string PrintFilterMode(int mode) { - if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST) { - return "NEAREST"; - } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR) { - return "LINEAR"; - } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST) { - return "NEAREST_MIPMAP_NEAREST"; - } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR) { - return "NEAREST_MIPMAP_LINEAR"; - } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST) { - return "LINEAR_MIPMAP_NEAREST"; - } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR) { - return "LINEAR_MIPMAP_LINEAR"; - } - return "**UNKNOWN**"; -} - -static std::string PrintIntArray(const std::vector &arr) { - if (arr.size() == 0) { - return ""; - } - - std::stringstream ss; - ss << "[ "; - for (size_t i = 0; i < arr.size(); i++) { - ss << arr[i] << ((i != arr.size() - 1) ? ", " : ""); - } - ss << " ]"; - - return ss.str(); -} - -static std::string PrintFloatArray(const std::vector &arr) { - if (arr.size() == 0) { - return ""; - } - - std::stringstream ss; - ss << "[ "; - for (size_t i = 0; i < arr.size(); i++) { - ss << arr[i] << ((i != arr.size() - 1) ? ", " : ""); - } - ss << " ]"; - - return ss.str(); -} - static std::string Indent(const int indent) { std::string s; for (int i = 0; i < indent; i++) { @@ -206,168 +28,7 @@ static std::string Indent(const int indent) { return s; } -static std::string PrintParameterValue(const tinygltf::Parameter ¶m) { - if (!param.number_array.empty()) { - return PrintFloatArray(param.number_array); - } else { - return param.string_value; - } -} -#if 0 -static std::string PrintParameterMap(const tinygltf::ParameterMap &pmap) { - std::stringstream ss; - - ss << pmap.size() << std::endl; - for (auto &kv : pmap) { - ss << kv.first << " : " << PrintParameterValue(kv.second) << std::endl; - } - - return ss.str(); -} -#endif - -static std::string PrintValue(const std::string &name, - const tinygltf::Value &value, const int indent, const bool tag = true) { - std::stringstream ss; - - if (value.IsObject()) { - const tinygltf::Value::Object &o = value.Get(); - tinygltf::Value::Object::const_iterator it(o.begin()); - tinygltf::Value::Object::const_iterator itEnd(o.end()); - for (; it != itEnd; it++) { - ss << PrintValue(it->first, it->second, indent + 1) << std::endl; - } - } else if (value.IsString()) { - if (tag) { - ss << Indent(indent) << name << " : " << value.Get(); - } else { - ss << " " << value.Get() << " "; - } - } else if (value.IsBool()) { - if (tag) { - ss << Indent(indent) << name << " : " << value.Get(); - } else { - ss << " " << value.Get() << " "; - } - } else if (value.IsNumber()) { - if (tag) { - ss << Indent(indent) << name << " : " << value.Get(); - } else { - ss << " " << value.Get() << " "; - } - } else if (value.IsInt()) { - if (tag) { - ss << Indent(indent) << name << " : " << value.Get(); - } else { - ss << " " << value.Get() << " "; - } - } else if (value.IsArray()) { - ss << Indent(indent) << name << " [ "; - for (size_t i = 0; i < value.Size(); i++) { - ss << PrintValue("", value.Get(int(i)), indent + 1, /* tag */false); - if (i != (value.ArrayLen()-1)) { - ss << ", "; - } - - } - ss << Indent(indent) << "] "; - } - - // @todo { binary } - - return ss.str(); -} - -static void DumpNode(const tinygltf::Node &node, int indent) { - std::cout << Indent(indent) << "name : " << node.name << std::endl; - std::cout << Indent(indent) << "camera : " << node.camera << std::endl; - std::cout << Indent(indent) << "mesh : " << node.mesh << std::endl; - if (!node.rotation.empty()) { - std::cout << Indent(indent) - << "rotation : " << PrintFloatArray(node.rotation) - << std::endl; - } - if (!node.scale.empty()) { - std::cout << Indent(indent) - << "scale : " << PrintFloatArray(node.scale) << std::endl; - } - if (!node.translation.empty()) { - std::cout << Indent(indent) - << "translation : " << PrintFloatArray(node.translation) - << std::endl; - } - - if (!node.matrix.empty()) { - std::cout << Indent(indent) - << "matrix : " << PrintFloatArray(node.matrix) << std::endl; - } - - std::cout << Indent(indent) - << "children : " << PrintIntArray(node.children) << std::endl; -} - -static void DumpStringIntMap(const std::map &m, int indent) { - std::map::const_iterator it(m.begin()); - std::map::const_iterator itEnd(m.end()); - for (; it != itEnd; it++) { - std::cout << Indent(indent) << it->first << ": " << it->second << std::endl; - } -} - -static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) { - std::cout << Indent(indent) << "material : " << primitive.material - << std::endl; - std::cout << Indent(indent) << "indices : " << primitive.indices << std::endl; - std::cout << Indent(indent) << "mode : " << PrintMode(primitive.mode) - << "(" << primitive.mode << ")" << std::endl; - std::cout << Indent(indent) - << "attributes(items=" << primitive.attributes.size() << ")" - << std::endl; - DumpStringIntMap(primitive.attributes, indent + 1); - - std::cout << Indent(indent) << "extras :" << std::endl - << PrintValue("extras", primitive.extras, indent + 1) << std::endl; -} - -static void DumpExtensions(const tinygltf::ExtensionMap &extension, const int indent) -{ - // TODO(syoyo): pritty print Value - for (auto &e : extension) { - std::cout << Indent(indent) << e.first << std::endl; - std::cout << PrintValue("extensions", e.second, indent+1) << std::endl; - } -} - -static float DecodeScalarAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model) -{ - const tinygltf::BufferView &bufferView = model.bufferViews[accessor.bufferView]; - const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer]; - - const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer); - if (addr == nullptr) { - std::cerr << "Invalid glTF data?" << std::endl; - return 0.0f; - } - - float value = 0.0f; - - if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE) { - value = tinygltf::DecodeAnimationChannelValue(*(reinterpret_cast(addr))); - } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { - value = tinygltf::DecodeAnimationChannelValue(*(reinterpret_cast(addr))); - } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT) { - value = tinygltf::DecodeAnimationChannelValue(*(reinterpret_cast(addr))); - } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { - value = tinygltf::DecodeAnimationChannelValue(*(reinterpret_cast(addr))); - } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) { - value = *(reinterpret_cast(addr)); - } else { - std::cerr << "??? Unknown componentType : " << PrintComponentType(accessor.componentType) << std::endl; - } - - return value; -} static void ProcessAnimation(const tinygltf::Animation &animation, const tinygltf::Model &model) { @@ -401,8 +62,10 @@ static void ProcessAnimation(const tinygltf::Animation &animation, const tinyglt for (size_t i = 0; i < accessor.count; i++) { if (accessor.type == TINYGLTF_TYPE_SCALAR) { - float v = DecodeScalarAnimationValue(i, accessor, model); - std::cout << Indent(2) << "input value[" << i << "] = " << v << std::endl; + float v; + if (tinygltf::util::DecodeScalarAnimationValue(i, accessor, model, &v)) { + std::cout << Indent(2) << "input value[" << i << "] = " << v << std::endl; + } } } diff --git a/tiny_gltf.h b/tiny_gltf.h index 8608501..21bf527 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -196,20 +196,6 @@ static inline int32_t GetTypeSizeInBytes(uint32_t ty) { } } -// Utility function for decoding animation value -static inline float DecodeAnimationChannelValue(int8_t c) { - return std::max(float(c) / 127.0f, -1.0f); -} -static inline float DecodeAnimationChannelValue(uint8_t c) { - return float(c) / 255.0f; -} -static inline float DecodeAnimationChannelValue(int16_t c) { - return std::max(float(c) / 32767.0f, -1.0f); -} -static inline float DecodeAnimationChannelValue(uint16_t c) { - return float(c) / 65525.0f; -} - bool IsDataURI(const std::string &in); bool DecodeDataURI(std::vector *out, std::string &mime_type, const std::string &in, size_t reqBytes, bool checkSize); @@ -2036,7 +2022,7 @@ bool DecodeDataURI(std::vector *out, std::string &mime_type, const uint8_t *GetBufferAddress(const int i, const Accessor &accessor, const BufferView &bufferViewObject, const Buffer &buffer) { - if (i >= accessor.count) return nullptr; + if (i >= int(accessor.count)) return nullptr; int byte_stride = accessor.ByteStride(bufferViewObject); if (byte_stride == -1) { @@ -3529,7 +3515,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, { if (primitive.indices > -1) // has indices from parsing step, must be Element Array Buffer { - model->bufferViews[model->accessors[primitive.indices].bufferView] + model->bufferViews[size_t(model->accessors[size_t(primitive.indices)].bufferView)] .target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; // we could optionally check if acessors' bufferView type is Scalar, as it should be } @@ -4616,23 +4602,23 @@ static void WriteBinaryGltfFile(const std::string &output, const int padding_size = content.size() % 4; // 12 bytes for header, JSON content length, 8 bytes for JSON chunk info, padding - const int length = 12 + 8 + 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(), std::streamsize(header.size())); gltfFile.write(reinterpret_cast(&version), sizeof(version)); gltfFile.write(reinterpret_cast(&length), sizeof(length)); // JSON chunk info, then JSON data - const int model_length = content.size() + padding_size; + const int model_length = int(content.size()) + padding_size; const int model_format = 0x4E4F534A; gltfFile.write(reinterpret_cast(&model_length), sizeof(model_length)); gltfFile.write(reinterpret_cast(&model_format), sizeof(model_format)); - gltfFile.write(content.c_str(), content.size()); + gltfFile.write(content.c_str(), std::streamsize(content.size())); // Chunk must be multiplies of 4, so pad with spaces if (padding_size > 0) { - const std::string padding = std::string(padding_size, ' '); - gltfFile.write(padding.c_str(), padding.size()); + const std::string padding = std::string(size_t(padding_size), ' '); + gltfFile.write(padding.c_str(), std::streamsize(padding.size())); } } diff --git a/tiny_gltf_util.h b/tiny_gltf_util.h new file mode 100644 index 0000000..64fc6ca --- /dev/null +++ b/tiny_gltf_util.h @@ -0,0 +1,294 @@ +// +// TinyGLTF utility functions +// +// +// The MIT License (MIT) +// +// Copyright (c) 2015 - 2018 Syoyo Fujita, AurĂ©lien Chatelain and many +// contributors. +// + +#include + +#include "tiny_gltf.h" + +namespace tinygltf { + +namespace util { + +static std::string PrintMode(int mode) { + if (mode == TINYGLTF_MODE_POINTS) { + return "POINTS"; + } else if (mode == TINYGLTF_MODE_LINE) { + return "LINE"; + } else if (mode == TINYGLTF_MODE_LINE_LOOP) { + return "LINE_LOOP"; + } else if (mode == TINYGLTF_MODE_TRIANGLES) { + return "TRIANGLES"; + } else if (mode == TINYGLTF_MODE_TRIANGLE_FAN) { + return "TRIANGLE_FAN"; + } else if (mode == TINYGLTF_MODE_TRIANGLE_STRIP) { + return "TRIANGLE_STRIP"; + } + return "**UNKNOWN**"; +} + +static std::string PrintTarget(int target) { + if (target == 34962) { + return "GL_ARRAY_BUFFER"; + } else if (target == 34963) { + return "GL_ELEMENT_ARRAY_BUFFER"; + } else { + return "**UNKNOWN**"; + } +} + +static std::string PrintType(int ty) { + if (ty == TINYGLTF_TYPE_SCALAR) { + return "SCALAR"; + } else if (ty == TINYGLTF_TYPE_VECTOR) { + return "VECTOR"; + } else if (ty == TINYGLTF_TYPE_VEC2) { + return "VEC2"; + } else if (ty == TINYGLTF_TYPE_VEC3) { + return "VEC3"; + } else if (ty == TINYGLTF_TYPE_VEC4) { + return "VEC4"; + } else if (ty == TINYGLTF_TYPE_MATRIX) { + return "MATRIX"; + } else if (ty == TINYGLTF_TYPE_MAT2) { + return "MAT2"; + } else if (ty == TINYGLTF_TYPE_MAT3) { + return "MAT3"; + } else if (ty == TINYGLTF_TYPE_MAT4) { + return "MAT4"; + } + return "**UNKNOWN**"; +} + +static std::string PrintComponentType(int ty) { + if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) { + return "BYTE"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { + return "UNSIGNED_BYTE"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_SHORT) { + return "SHORT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { + return "UNSIGNED_SHORT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_INT) { + return "INT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) { + return "UNSIGNED_INT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_FLOAT) { + return "FLOAT"; + } else if (ty == TINYGLTF_COMPONENT_TYPE_DOUBLE) { + return "DOUBLE"; + } + + return "**UNKNOWN**"; +} + +static std::string PrintWrapMode(int mode) { + if (mode == TINYGLTF_TEXTURE_WRAP_REPEAT) { + return "REPEAT"; + } else if (mode == TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE) { + return "CLAMP_TO_EDGE"; + } else if (mode == TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT) { + return "MIRRORED_REPEAT"; + } + + return "**UNKNOWN**"; +} + +static std::string PrintFilterMode(int mode) { + if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST) { + return "NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR) { + return "LINEAR"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST) { + return "NEAREST_MIPMAP_NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR) { + return "NEAREST_MIPMAP_LINEAR"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST) { + return "LINEAR_MIPMAP_NEAREST"; + } else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR) { + return "LINEAR_MIPMAP_LINEAR"; + } + return "**UNKNOWN**"; +} + +static int GetAnimationSamplerInputCount(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model) +{ + const tinygltf::Accessor &accessor = model.accessors[sampler.input]; + return accessor.count; +} + +static int GetAnimationSamplerOutputCount(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model) +{ + const tinygltf::Accessor &accessor = model.accessors[sampler.output]; + return accessor.count; +} + +static bool GetAnimationSamplerInputMinMax(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model, float *min_value, float *max_value) +{ + const tinygltf::Accessor &accessor = model.accessors[sampler.input]; + + // Assume scalar value. + if ((accessor.minValues.size() > 0) && + (accessor.maxValues.size() > 0)) { + (*min_value) = accessor.minValues[0]; + (*max_value) = accessor.maxValues[0]; + return true; + } else { + (*min_value) = 0.0f; + (*max_value) = 0.0f; + return false; + } +} + +// Utility function for decoding animation value +static inline float DecodeAnimationChannelValue(int8_t c) { + return std::max(float(c) / 127.0f, -1.0f); +} +static inline float DecodeAnimationChannelValue(uint8_t c) { + return float(c) / 255.0f; +} +static inline float DecodeAnimationChannelValue(int16_t c) { + return std::max(float(c) / 32767.0f, -1.0f); +} +static inline float DecodeAnimationChannelValue(uint16_t c) { + return float(c) / 65525.0f; +} + +static bool DecodeScalarAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *scalar) +{ + const BufferView &bufferView = model.bufferViews[accessor.bufferView]; + const Buffer &buffer = model.buffers[bufferView.buffer]; + + const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer); + if (addr == nullptr) { + std::cerr << "Invalid glTF data?" << std::endl; + return false; + } + + float value = 0.0f; + + if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE) { + value = DecodeAnimationChannelValue(*(reinterpret_cast(addr))); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { + value = DecodeAnimationChannelValue(*(reinterpret_cast(addr))); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT) { + value = DecodeAnimationChannelValue(*(reinterpret_cast(addr))); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { + value = DecodeAnimationChannelValue(*(reinterpret_cast(addr))); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) { + value = *(reinterpret_cast(addr)); + } else { + std::cerr << "??? Unknown componentType : " << PrintComponentType(accessor.componentType) << std::endl; + return false; + } + + (*scalar) = value; + + return true; +} + +static bool DecodeTranslationAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyz) +{ + if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + std::cerr << "`translation` must be float type." << std::endl; + return false; + } + + const BufferView &bufferView = model.bufferViews[accessor.bufferView]; + const Buffer &buffer = model.buffers[bufferView.buffer]; + + const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer); + if (addr == nullptr) { + std::cerr << "Invalid glTF data?" << std::endl; + return 0.0f; + } + + const float *ptr = reinterpret_cast(addr); + + xyz[0] = *(ptr + 0); + xyz[1] = *(ptr + 1); + xyz[2] = *(ptr + 2); + + return true; +} + +static bool DecodeScaleAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyz) +{ + if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + std::cerr << "`scale` must be float type." << std::endl; + return false; + } + + const BufferView &bufferView = model.bufferViews[accessor.bufferView]; + const Buffer &buffer = model.buffers[bufferView.buffer]; + + const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer); + if (addr == nullptr) { + std::cerr << "Invalid glTF data?" << std::endl; + return 0.0f; + } + + const float *ptr = reinterpret_cast(addr); + + xyz[0] = *(ptr + 0); + xyz[1] = *(ptr + 1); + xyz[2] = *(ptr + 2); + + return true; +} + +static bool DecodeRotationAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyzw) +{ + const BufferView &bufferView = model.bufferViews[accessor.bufferView]; + const Buffer &buffer = model.buffers[bufferView.buffer]; + + const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer); + if (addr == nullptr) { + std::cerr << "Invalid glTF data?" << std::endl; + return false; + } + + float value = 0.0f; + + if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE) { + xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 0)); + xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 1)); + xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 2)); + xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 3)); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) { + xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 0)); + xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 1)); + xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 2)); + xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 3)); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT) { + xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 0)); + xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 1)); + xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 2)); + xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 3)); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) { + xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 0)); + xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 1)); + xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 2)); + xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast(addr) + 3)); + } else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) { + xyzw[0] = *(reinterpret_cast(addr) + 0); + xyzw[1] = *(reinterpret_cast(addr) + 1); + xyzw[2] = *(reinterpret_cast(addr) + 2); + xyzw[3] = *(reinterpret_cast(addr) + 3); + } else { + std::cerr << "??? Unknown componentType : " << PrintComponentType(accessor.componentType) << std::endl; + return false; + } + + return true; +} + +} // namespace util + +} // namespace tinygltf