915 lines
28 KiB
C++

// AMD AMDUtils code
//
// Copyright(c) 2017 Advanced Micro Devices, Inc.All rights reserved.
//
// Major Code based on Header-only tiny glTF 2.0 loader and serializer.
// The MIT License (MIT)
//
// Copyright (c) 2015 - 2018 Syoyo Fujita, Aurélien Chatelain and many
// contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#ifndef TINY_GLTF_H_
#define TINY_GLTF_H_
#define TINYGLTF_NO_STB_IMAGE_WRITE
#define TINYGLTF_NO_STB_IMAGE
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
#define STB_IMAGE_WRITE_IMPLEMENTATION
#endif
#ifndef TINYGLTF_NO_STB_IMAGE
#define STB_IMAGE_IMPLEMENTATION
#endif
#include <array>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include "compressonator.h"
#include "common.h"
namespace tinygltf2 {
#define TINYGLTF_MODE_POINTS (0)
#define TINYGLTF_MODE_LINE (1)
#define TINYGLTF_MODE_LINE_LOOP (2)
#define TINYGLTF_MODE_TRIANGLES (4)
#define TINYGLTF_MODE_TRIANGLE_STRIP (5)
#define TINYGLTF_MODE_TRIANGLE_FAN (6)
#define TINYGLTF_COMPONENT_TYPE_BYTE (5120)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_COMPONENT_TYPE_SHORT (5122)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT (5123)
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5130)
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST (9984)
#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST (9985)
#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR (9986)
#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR (9987)
#define TINYGLTF_TEXTURE_WRAP_REPEAT (10497)
#define TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE (33071)
#define TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT (33648)
// Redeclarations of the above for technique.parameters.
#define TINYGLTF_PARAMETER_TYPE_BYTE (5120)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_PARAMETER_TYPE_SHORT (5122)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT (5123)
#define TINYGLTF_PARAMETER_TYPE_INT (5124)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT (5125)
#define TINYGLTF_PARAMETER_TYPE_FLOAT (5126)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC2 (35664)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC3 (35665)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC4 (35666)
#define TINYGLTF_PARAMETER_TYPE_INT_VEC2 (35667)
#define TINYGLTF_PARAMETER_TYPE_INT_VEC3 (35668)
#define TINYGLTF_PARAMETER_TYPE_INT_VEC4 (35669)
#define TINYGLTF_PARAMETER_TYPE_BOOL (35670)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC2 (35671)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC3 (35672)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC4 (35673)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT2 (35674)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT3 (35675)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT4 (35676)
#define TINYGLTF_PARAMETER_TYPE_SAMPLER_2D (35678)
// End parameter types
#define TINYGLTF_TYPE_VEC2 (2)
#define TINYGLTF_TYPE_VEC3 (3)
#define TINYGLTF_TYPE_VEC4 (4)
#define TINYGLTF_TYPE_MAT2 (32 + 2)
#define TINYGLTF_TYPE_MAT3 (32 + 3)
#define TINYGLTF_TYPE_MAT4 (32 + 4)
#define TINYGLTF_TYPE_SCALAR (64 + 1)
#define TINYGLTF_TYPE_VECTOR (64 + 4)
#define TINYGLTF_TYPE_MATRIX (64 + 16)
#define TINYGLTF_IMAGE_FORMAT_JPEG (0)
#define TINYGLTF_IMAGE_FORMAT_PNG (1)
#define TINYGLTF_IMAGE_FORMAT_BMP (2)
#define TINYGLTF_IMAGE_FORMAT_GIF (3)
#define TINYGLTF_TEXTURE_FORMAT_ALPHA (6406)
#define TINYGLTF_TEXTURE_FORMAT_RGB (6407)
#define TINYGLTF_TEXTURE_FORMAT_RGBA (6408)
#define TINYGLTF_TEXTURE_FORMAT_LUMINANCE (6409)
#define TINYGLTF_TEXTURE_FORMAT_LUMINANCE_ALPHA (6410)
#define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553)
#define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_TARGET_ARRAY_BUFFER (34962)
#define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963)
#define TINYGLTF_SHADER_TYPE_VERTEX_SHADER (35633)
#define TINYGLTF_SHADER_TYPE_FRAGMENT_SHADER (35632)
typedef enum {
NULL_TYPE = 0,
NUMBER_TYPE = 1,
INT_TYPE = 2,
BOOL_TYPE = 3,
STRING_TYPE = 4,
ARRAY_TYPE = 5,
BINARY_TYPE = 6,
OBJECT_TYPE = 7
} Type;
static inline int32_t GetComponentSizeInBytes(uint32_t componentType) {
if (componentType == TINYGLTF_COMPONENT_TYPE_BYTE) {
return 1;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
return 1;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_SHORT) {
return 2;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
return 2;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_INT) {
return 4;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) {
return 4;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) {
return 4;
} else if (componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE) {
return 8;
} else {
// Unknown componenty type
return -1;
}
}
static inline int32_t GetTypeSizeInBytes(uint32_t ty) {
if (ty == TINYGLTF_TYPE_SCALAR) {
return 1;
} else if (ty == TINYGLTF_TYPE_VEC2) {
return 2;
} else if (ty == TINYGLTF_TYPE_VEC3) {
return 3;
} else if (ty == TINYGLTF_TYPE_VEC4) {
return 4;
} else if (ty == TINYGLTF_TYPE_MAT2) {
return 4;
} else if (ty == TINYGLTF_TYPE_MAT3) {
return 9;
} else if (ty == TINYGLTF_TYPE_MAT4) {
return 16;
} else {
// Unknown componenty type
return -1;
}
}
#ifdef __clang__
#pragma clang diagnostic push
// Suppress warning for : static Value null_value
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wpadded"
#endif
// Simple class to represent JSON object
class Value {
public:
typedef std::vector<Value> Array;
typedef std::map<std::string, Value> Object;
Value() : type_(NULL_TYPE) {
}
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(const std::string& s) : type_(STRING_TYPE) {
string_value_ = s;
}
explicit Value(const unsigned char* p, size_t n) : type_(BINARY_TYPE) {
binary_value_.resize(n);
memcpy(binary_value_.data(), p, n);
}
explicit Value(const Array& a) : type_(ARRAY_TYPE) {
array_value_ = Array(a);
}
explicit Value(const Object& o) : type_(OBJECT_TYPE) {
object_value_ = Object(o);
}
char Type() const {
return static_cast<const char>(type_);
}
bool IsBool() const {
return (type_ == BOOL_TYPE);
}
bool IsInt() const {
return (type_ == INT_TYPE);
}
bool IsNumber() const {
return (type_ == NUMBER_TYPE);
}
bool IsString() const {
return (type_ == STRING_TYPE);
}
bool IsBinary() const {
return (type_ == BINARY_TYPE);
}
bool IsArray() const {
return (type_ == ARRAY_TYPE);
}
bool IsObject() const {
return (type_ == OBJECT_TYPE);
}
// Accessor
template <typename T>
const T& Get() const;
template <typename T>
T& Get();
// Lookup value from an array
const Value& Get(int idx) const {
static Value null_value;
assert(IsArray());
assert(idx >= 0);
return (static_cast<size_t>(idx) < array_value_.size()) ? array_value_[static_cast<size_t>(idx)] : null_value;
}
// Lookup value from a key-value pair
const Value& Get(const std::string& key) const {
static Value null_value;
assert(IsObject());
Object::const_iterator it = object_value_.find(key);
return (it != object_value_.end()) ? it->second : null_value;
}
size_t ArrayLen() const {
if (!IsArray())
return 0;
return array_value_.size();
}
// Valid only for object type.
bool Has(const std::string& key) const {
if (!IsObject())
return false;
Object::const_iterator it = object_value_.find(key);
return (it != object_value_.end()) ? true : false;
}
// List keys
std::vector<std::string> Keys() const {
std::vector<std::string> keys;
if (!IsObject())
return keys; // empty
for (Object::const_iterator it = object_value_.begin(); it != object_value_.end(); ++it) {
keys.push_back(it->first);
}
return keys;
}
size_t Size() const {
return (IsArray() ? ArrayLen() : Keys().size());
}
protected:
int type_;
int int_value_;
double number_value_;
std::string string_value_;
std::vector<unsigned char> binary_value_;
Array array_value_;
Object object_value_;
bool boolean_value_;
};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#define TINYGLTF_VALUE_GET(ctype, var) \
template <> \
inline const ctype& Value::Get<ctype>() const \
{ \
return var; \
} \
template <> \
inline ctype& Value::Get<ctype>() \
{ \
return var; \
}
TINYGLTF_VALUE_GET(bool, boolean_value_)
TINYGLTF_VALUE_GET(double, number_value_)
TINYGLTF_VALUE_GET(int, int_value_)
TINYGLTF_VALUE_GET(std::string, string_value_)
TINYGLTF_VALUE_GET(std::vector<unsigned char>, binary_value_)
TINYGLTF_VALUE_GET(Value::Array, array_value_)
TINYGLTF_VALUE_GET(Value::Object, object_value_)
#undef TINYGLTF_VALUE_GET
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++98-compat"
#pragma clang diagnostic ignored "-Wpadded"
#endif
/// Agregate object for representing a color
using ColorValue = std::array<double, 4>;
struct Parameter {
bool bool_value;
std::string string_value;
std::vector<double> number_array;
std::map<std::string, double> json_double_value;
// context sensitive methods. depending the type of the Parameter you are
// accessing, these are either valid or not
// If this parameter represent a texture map in a material, will return the
// texture index
/// Return the index of a texture if this Parameter is a texture map.
/// Returned value is only valid if the parameter represent a texture from a
/// material
int TextureIndex() const {
const auto it = json_double_value.find("index");
if (it != std::end(json_double_value)) {
return int(it->second);
}
return -1;
}
/// Material factor, like the roughness or metalness of a material
/// Returned value is only valid if the parameter represent a texture from a
/// material
double Factor() const {
return number_array[0];
}
/// Return the color of a material
/// Returned value is only valid if the parameter represent a texture from a
/// material
ColorValue ColorFactor() const {
return {{// this agregate intialize the std::array object, and uses C++11 RVO.
number_array[0], number_array[1], number_array[2], (number_array.size() > 3 ? number_array[3] : 1.0)
}};
}
};
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif
typedef std::map<std::string, Parameter> ParameterMap;
typedef std::map<std::string, Value> ExtensionMap;
struct AnimationChannel {
int sampler; // required
int target_node; // required (index of the node to target)
std::string target_path; // required in ["translation", "rotation", "scale",
// "weights"]
Value extras;
AnimationChannel() : sampler(-1), target_node(-1) {
}
};
struct AnimationSampler {
int input; // required
int output; // required
std::string interpolation; // in ["LINEAR", "STEP", "CATMULLROMSPLINE",
// "CUBICSPLINE"], default "LINEAR"
AnimationSampler() : input(-1), output(-1), interpolation("LINEAR") {
}
};
struct Animation {
std::string name;
std::vector<AnimationChannel> channels;
std::vector<AnimationSampler> samplers;
Value extras;
};
struct Skin {
std::string name;
int inverseBindMatrices; // required here but not in the spec
int skeleton; // The index of the node used as a skeleton root
std::vector<int> joints; // Indices of skeleton nodes
Skin() {
inverseBindMatrices = -1;
skeleton = -1;
}
};
struct Sampler {
std::string name;
int minFilter; // ["NEAREST", "LINEAR", "NEAREST_MIPMAP_LINEAR",
// "LINEAR_MIPMAP_NEAREST", "NEAREST_MIPMAP_LINEAR",
// "LINEAR_MIPMAP_LINEAR"]
int magFilter; // ["NEAREST", "LINEAR"]
int wrapS; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT", "REPEAT"], default
// "REPEAT"
int wrapT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT", "REPEAT"], default
// "REPEAT"
int wrapR; // TinyGLTF extension
Value extras;
Sampler() : wrapS(TINYGLTF_TEXTURE_WRAP_REPEAT), wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT) {
}
};
struct Image {
std::string name;
int width;
int height;
int component;
std::vector<unsigned char> image;
int bufferView; // (required if no uri)
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png",
// "image/bmp", "image/gif"]
std::string uri; // (required if no mimeType)
Value extras;
Image() {
bufferView = -1;
}
};
struct KHRExtension {
std::string name;
Value extras;
};
struct Texture {
int sampler;
int source; // Required (not specified in the spec ?)
Value extras;
ExtensionMap extensions;
Texture() : sampler(-1), source(-1) {
}
};
// Each extension should be stored in a ParameterMap.
// members not in the values could be included in the ParameterMap
// to keep a single material model
struct Material {
std::string name;
ParameterMap values; // PBR metal/roughness workflow
ParameterMap additionalValues; // normal/occlusion/emissive values
ExtensionMap extensions;
Value extras;
};
struct BufferView {
std::string name;
int buffer; // Required
size_t byteOffset; // minimum 0, default 0
size_t byteLength; // required, minimum 1
size_t byteStride; // minimum 4, maximum 252 (multiple of 4), default 0 =
// understood to be tightly packed
int target; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"]
Value extras;
BufferView() : byteOffset(0), byteStride(0) {
}
};
struct Accessor {
int bufferView; // optional in spec but required here since sparse accessor
// are not supported
std::string name;
size_t byteOffset;
bool normalized; // optinal.
int componentType; // (required) One of TINYGLTF_COMPONENT_TYPE_***
size_t count; // required
int type; // (required) One of TINYGLTF_TYPE_*** ..
Value extras;
std::vector<double> minValues; // optional
std::vector<double> maxValues; // optional
// TODO(syoyo): "sparse"
///
/// Utility function to compute byteStride for a given bufferView object.
/// Returns -1 upon invalid glTF value or parameter configuration.
///
int ByteStride(const BufferView& bufferViewObject) const {
if (bufferViewObject.byteStride == 0) {
// Assume data is tightly packed.
int componentSizeInBytes = GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
if (componentSizeInBytes <= 0) {
return -1;
}
int typeSizeInBytes = GetTypeSizeInBytes(static_cast<uint32_t>(type));
if (typeSizeInBytes <= 0) {
return -1;
}
return componentSizeInBytes * typeSizeInBytes;
} else {
// Check if byteStride is a mulple of the size of the accessor's component
// type.
int componentSizeInBytes = GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
if (componentSizeInBytes <= 0) {
return -1;
}
if ((bufferViewObject.byteStride % uint32_t(componentSizeInBytes)) != 0) {
return -1;
}
return static_cast<int>(bufferViewObject.byteStride);
}
return 0;
}
Accessor() {
bufferView = -1;
}
};
struct PerspectiveCamera {
float aspectRatio; // min > 0
float yfov; // required. min > 0
float zfar; // min > 0
float znear; // required. min > 0
PerspectiveCamera() :
aspectRatio(0.0f),
yfov(0.0f),
zfar(0.0f) // 0 = use infinite projecton matrix
,
znear(0.0f) {
}
ExtensionMap extensions;
Value extras;
};
struct OrthographicCamera {
float xmag; // required. must not be zero.
float ymag; // required. must not be zero.
float zfar; // required. `zfar` must be greater than `znear`.
float znear; // required
OrthographicCamera() : xmag(0.0f), ymag(0.0f), zfar(0.0f), znear(0.0f) {
}
ExtensionMap extensions;
Value extras;
};
struct Camera {
std::string type; // required. "perspective" or "orthographic"
std::string name;
PerspectiveCamera perspective;
OrthographicCamera orthographic;
Camera() {
}
ExtensionMap extensions;
Value extras;
};
struct Primitive {
std::map<std::string, int> attributes; // (required) A dictionary object of
// integer, where each integer
// is the index of the accessor
// containing an attribute.
int material; // The index of the material to apply to this primitive
// when rendering.
int indices; // The index of the accessor that contains the indices.
int mode; // one of TINYGLTF_MODE_***
std::vector<std::map<std::string, int> > targets; // array of morph targets,
// where each target is a dict with attribues in ["POSITION, "NORMAL",
// "TANGENT"] pointing
// to their corresponding accessors
Value extras;
Primitive() {
material = -1;
indices = -1;
}
};
struct Mesh {
std::string name;
std::vector<Primitive> primitives;
std::vector<double> weights; // weights to be applied to the Morph Targets
std::vector<std::map<std::string, int> > targets;
ExtensionMap extensions;
Value extras;
};
class Node {
public:
Node() : camera(-1), skin(-1), mesh(-1) {
}
Node(const Node& rhs) {
camera = rhs.camera;
name = rhs.name;
skin = rhs.skin;
mesh = rhs.mesh;
children = rhs.children;
rotation = rhs.rotation;
scale = rhs.scale;
translation = rhs.translation;
matrix = rhs.matrix;
weights = rhs.weights;
extensions = rhs.extensions;
extras = rhs.extras;
}
~Node() {
}
int camera; // the index of the camera referenced by this node
std::string name;
int skin;
int mesh;
std::vector<int> children;
std::vector<double> rotation; // length must be 0 or 4
std::vector<double> scale; // length must be 0 or 3
std::vector<double> translation; // length must be 0 or 3
std::vector<double> matrix; // length must be 0 or 16
std::vector<double> weights; // The weights of the instantiated Morph Target
ExtensionMap extensions;
Value extras;
};
struct Buffer {
std::string name;
std::vector<unsigned char> data;
std::string uri; // considered as required here but not in the spec (need to clarify)
Value extras;
};
#ifdef USE_MESH_DRACO_EXTENSION
struct DracoData {
std::vector<unsigned char> data; //compressed data
std::string uri;
double byteLength = -1;
double draco_buffer_view = -1;
double buffer_id = -1;
std::map<std::string, int> draco_attributes;
int mesh_index = 0;
int prim_index = 0;
};
#endif
struct Asset {
std::string version; // required
std::string generator;
std::string minVersion;
std::string copyright;
ExtensionMap extensions;
Value extras;
};
struct Scene {
std::string name;
std::vector<int> nodes;
ExtensionMap extensions;
Value extras;
};
struct Light {
std::string name;
std::vector<double> color;
std::string type;
};
class Model {
public:
Model() {
}
~Model() {
}
std::vector<Accessor> accessors;
std::vector<Animation> animations;
std::vector<Buffer> buffers;
std::vector<BufferView> bufferViews;
std::vector<Material> materials;
std::vector<Mesh> meshes;
std::vector<Node> nodes;
std::vector<Texture> textures;
std::vector<Image> images;
std::vector<Skin> skins;
std::vector<Sampler> samplers;
std::vector<Camera> cameras;
std::vector<Scene> scenes;
std::vector<Light> lights;
#ifdef USE_MESH_DRACO_EXTENSION
std::vector<DracoData> dracomeshes;
#endif
ExtensionMap extensions;
int defaultScene;
std::vector<std::string> extensionsUsed;
std::vector<std::string> extensionsRequired;
Asset asset;
Value extras;
};
enum SectionCheck {
NO_REQUIRE = 0x00,
REQUIRE_SCENE = 0x01,
REQUIRE_SCENES = 0x02,
REQUIRE_NODES = 0x04,
REQUIRE_ACCESSORS = 0x08,
REQUIRE_BUFFERS = 0x10,
REQUIRE_BUFFER_VIEWS = 0x20,
REQUIRE_ALL = 0x3f
};
///
/// LoadImageDataFunction type. Signature for custom image loading callbacks.
///
typedef bool (*LoadImageDataFunction)(Image*, std::string*, int, int, const unsigned char*, int, void*);
///
/// WriteImageDataFunction type. Signature for custom image writing callbacks.
///
typedef bool (*WriteImageDataFunction)(const std::string*, const std::string*, Image*, bool, void*);
#ifndef TINYGLTF_NO_STB_IMAGE
// Declaration of default image loader callback
bool LoadImageData(Image* image, std::string* err, int req_width, int req_height, const unsigned char* bytes, int size, void*);
#endif
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
// Declaration of default image writer callback
bool WriteImageData(const std::string* basepath, const std::string* filename, Image* image, bool embedImages, void*);
#endif
class TinyGLTF {
public:
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++98-compat"
#endif
TinyGLTF() : bin_data_(nullptr), bin_size_(0), is_binary_(false) {
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
~TinyGLTF() {
}
///
/// Loads glTF ASCII asset from a file.
/// Returns false and set error string to `err` if there's an error.
///
bool LoadASCIIFromFile(Model* model, std::string* err, const std::string& filename, bool use_draco_encode,
unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF ASCII asset from string(memory).
/// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error.
///
bool LoadASCIIFromString(Model* model, std::string* err, const char* str, const unsigned int length, const std::string& base_dir,
bool use_draco_encode, unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF binary asset from a file.
/// Returns false and set error string to `err` if there's an error.
///
bool LoadBinaryFromFile(Model* model, std::string* err, const std::string& filename, unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF binary asset from memory.
/// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error.
///
bool LoadBinaryFromMemory(Model* model, std::string* err, const unsigned char* bytes, const unsigned int length,
const std::string& base_dir = "", unsigned int check_sections = REQUIRE_ALL);
///
/// Write glTF to file.
///
bool WriteGltfSceneToFile(Model* model, std::string* err, const std::string& filename, CMP_CompressOptions& option, bool decodedDraco = false,
bool use_draco_encode = false, bool embedImages = false, bool embedBuffers = false /*, bool writeBinary*/);
///
/// Set callback to use for loading image data
///
void SetImageLoader(LoadImageDataFunction LoadImageData, void* user_data);
///
/// Set callback to use for writing image data
///
void SetImageWriter(WriteImageDataFunction WriteImageData, void* user_data);
private:
///
/// Loads glTF asset from string(memory).
/// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error.
///
bool LoadFromString(Model* model, std::string* err, const char* str, const unsigned int length, const std::string& base_dir,
bool use_draco_encode, unsigned int check_sections);
const unsigned char* bin_data_;
size_t bin_size_;
bool is_binary_;
LoadImageDataFunction LoadImageData =
#ifndef TINYGLTF_NO_STB_IMAGE
&tinygltf2::LoadImageData;
#else
nullptr;
#endif
void* load_image_user_data_ = nullptr;
WriteImageDataFunction WriteImageData =
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
&tinygltf2::WriteImageData;
#else
nullptr;
#endif
void* write_image_user_data_ = nullptr;
};
#ifdef __clang__
#pragma clang diagnostic pop // -Wpadded
#endif
} // namespace tinygltf2
#endif // TINY_GLTF_H_