Rename filename/define/class name.

This commit is contained in:
Syoyo Fujita 2017-06-21 02:52:11 +09:00
parent 73cd7b9c1d
commit 2840a0eb48
2 changed files with 296 additions and 340 deletions

View File

@ -1,6 +1,6 @@
#define TINYGLTF_LOADER_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "tiny_gltf_loader.h" #include "tiny_gltf.h"
#include <cstdio> #include <cstdio>
#include <fstream> #include <fstream>
@ -507,7 +507,7 @@ int main(int argc, char **argv) {
} }
tinygltf::Model model; tinygltf::Model model;
tinygltf::TinyGLTFLoader loader; tinygltf::TinyGLTF gltf_ctx;
std::string err; std::string err;
std::string input_filename(argv[1]); std::string input_filename(argv[1]);
std::string ext = GetFilePathExtension(input_filename); std::string ext = GetFilePathExtension(input_filename);
@ -516,11 +516,11 @@ int main(int argc, char **argv) {
if (ext.compare("glb") == 0) { if (ext.compare("glb") == 0) {
std::cout << "Reading binary glTF" << std::endl; std::cout << "Reading binary glTF" << std::endl;
// assume binary glTF. // assume binary glTF.
ret = loader.LoadBinaryFromFile(&model, &err, input_filename.c_str()); ret = gltf_ctx.LoadBinaryFromFile(&model, &err, input_filename.c_str());
} else { } else {
std::cout << "Reading ASCII glTF" << std::endl; std::cout << "Reading ASCII glTF" << std::endl;
// assume ascii glTF. // assume ascii glTF.
ret = loader.LoadASCIIFromFile(&model, &err, input_filename.c_str()); ret = gltf_ctx.LoadASCIIFromFile(&model, &err, input_filename.c_str());
} }
if (!err.empty()) { if (!err.empty()) {

View File

@ -34,8 +34,8 @@
// - base64: base64 decode/encode library. // - base64: base64 decode/encode library.
// - stb_image: Image loading library. // - stb_image: Image loading library.
// //
#ifndef TINY_GLTF_LOADER_H_ #ifndef TINY_GLTF_H_
#define TINY_GLTF_LOADER_H_ #define TINY_GLTF_H_
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
@ -240,9 +240,7 @@ class Value {
return keys; return keys;
} }
size_t Size() const { size_t Size() const { return (IsArray() ? ArrayLen() : Keys().size()); }
return (IsArray() ? ArrayLen() : Keys().size());
}
protected: protected:
int type_; int type_;
@ -322,8 +320,7 @@ struct Skin {
int skeleton; // The index of the node used as a skeleton root int skeleton; // The index of the node used as a skeleton root
std::vector<int> joints; // Indices of skeleton nodes std::vector<int> joints; // Indices of skeleton nodes
Skin() Skin() {
{
inverseBindMatrices = -1; inverseBindMatrices = -1;
skeleton = -1; skeleton = -1;
} }
@ -552,48 +549,64 @@ enum SectionCheck {
REQUIRE_ALL = 0x3f REQUIRE_ALL = 0x3f
}; };
class TinyGLTFLoader { class TinyGLTF {
public: public:
TinyGLTFLoader() : bin_data_(NULL), bin_size_(0), is_binary_(false) { TinyGLTF() : bin_data_(NULL), bin_size_(0), is_binary_(false) {
pad[0] = pad[1] = pad[2] = pad[3] = pad[4] = pad[5] = pad[6] = 0; pad[0] = pad[1] = pad[2] = pad[3] = pad[4] = pad[5] = pad[6] = 0;
} }
~TinyGLTFLoader() {} ~TinyGLTF() {}
///
/// Loads glTF ASCII asset from a file. /// Loads glTF ASCII asset from a file.
/// Returns false and set error string to `err` if there's an error. /// Returns false and set error string to `err` if there's an error.
///
bool LoadASCIIFromFile(Model *model, std::string *err, bool LoadASCIIFromFile(Model *model, std::string *err,
const std::string &filename, const std::string &filename,
unsigned int check_sections = REQUIRE_ALL); unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF ASCII asset from string(memory). /// Loads glTF ASCII asset from string(memory).
/// `length` = strlen(str); /// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error. /// Returns false and set error string to `err` if there's an error.
///
bool LoadASCIIFromString(Model *model, std::string *err, const char *str, bool LoadASCIIFromString(Model *model, std::string *err, const char *str,
const unsigned int length, const unsigned int length,
const std::string &base_dir, const std::string &base_dir,
unsigned int check_sections = REQUIRE_ALL); unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF binary asset from a file. /// Loads glTF binary asset from a file.
/// Returns false and set error string to `err` if there's an error. /// Returns false and set error string to `err` if there's an error.
///
bool LoadBinaryFromFile(Model *model, std::string *err, bool LoadBinaryFromFile(Model *model, std::string *err,
const std::string &filename, const std::string &filename,
unsigned int check_sections = REQUIRE_ALL); unsigned int check_sections = REQUIRE_ALL);
///
/// Loads glTF binary asset from memory. /// Loads glTF binary asset from memory.
/// `length` = strlen(str); /// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error. /// Returns false and set error string to `err` if there's an error.
///
bool LoadBinaryFromMemory(Model *model, std::string *err, bool LoadBinaryFromMemory(Model *model, std::string *err,
const unsigned char *bytes, const unsigned char *bytes,
const unsigned int length, const unsigned int length,
const std::string &base_dir = "", const std::string &base_dir = "",
unsigned int check_sections = REQUIRE_ALL); unsigned int check_sections = REQUIRE_ALL);
bool WriteGltfSceneToFile(Model *model, const std::string &filename/*, bool embedImages, bool embedBuffers, bool writeBinary*/); ///
/// Write glTF to file.
///
bool WriteGltfSceneToFile(
Model *model,
const std::string &
filename /*, bool embedImages, bool embedBuffers, bool writeBinary*/);
private: private:
///
/// Loads glTF asset from string(memory). /// Loads glTF asset from string(memory).
/// `length` = strlen(str); /// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error. /// Returns false and set error string to `err` if there's an error.
///
bool LoadFromString(Model *model, std::string *err, const char *str, bool LoadFromString(Model *model, std::string *err, const char *str,
const unsigned int length, const std::string &base_dir, const unsigned int length, const std::string &base_dir,
unsigned int check_sections); unsigned int check_sections);
@ -606,9 +619,9 @@ class TinyGLTFLoader {
} // namespace tinygltf } // namespace tinygltf
#endif // TINY_GLTF_LOADER_H_ #endif // TINY_GLTF_H_
#ifdef TINYGLTF_LOADER_IMPLEMENTATION #ifdef TINYGLTF_IMPLEMENTATION
#include <algorithm> #include <algorithm>
//#include <cassert> //#include <cassert>
#include <fstream> #include <fstream>
@ -1481,8 +1494,7 @@ static bool ParseBuffer(Buffer *buffer, std::string *err,
ParseStringProperty(&uri, err, o, "uri", false, "Buffer"); ParseStringProperty(&uri, err, o, "uri", false, "Buffer");
// having an empty uri for a non embedded image should not be valid // having an empty uri for a non embedded image should not be valid
if(!is_binary && uri.empty()) if (!is_binary && uri.empty()) {
{
if (err) { if (err) {
(*err) += "'uri' is missing from non binary glTF file buffer.\n"; (*err) += "'uri' is missing from non binary glTF file buffer.\n";
} }
@ -1502,13 +1514,10 @@ static bool ParseBuffer(Buffer *buffer, std::string *err,
if (is_binary) { if (is_binary) {
// Still binary glTF accepts external dataURI. First try external resources. // Still binary glTF accepts external dataURI. First try external resources.
if(!uri.empty()) if (!uri.empty()) {
{
// External .bin file. // External .bin file.
LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true); LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true);
} } else {
else
{
// load data from (embedded) binary data // load data from (embedded) binary data
if ((bin_size == 0) || (bin_data == NULL)) { if ((bin_size == 0) || (bin_data == NULL)) {
@ -1531,8 +1540,7 @@ static bool ParseBuffer(Buffer *buffer, std::string *err,
// Read buffer data // Read buffer data
buffer->data.resize(static_cast<size_t>(byteLength)); buffer->data.resize(static_cast<size_t>(byteLength));
memcpy(&(buffer->data.at(0)), bin_data, memcpy(&(buffer->data.at(0)), bin_data, static_cast<size_t>(byteLength));
static_cast<size_t>(byteLength));
} }
} else { } else {
@ -1711,7 +1719,8 @@ static bool ParsePrimitive(Primitive *primitive, std::string *err,
// Look for morph targets // Look for morph targets
picojson::object::const_iterator targetsObject = o.find("targets"); picojson::object::const_iterator targetsObject = o.find("targets");
if ((targetsObject != o.end()) && (targetsObject->second).is<picojson::array>()) { if ((targetsObject != o.end()) &&
(targetsObject->second).is<picojson::array>()) {
const picojson::array &targetArray = const picojson::array &targetArray =
(targetsObject->second).get<picojson::array>(); (targetsObject->second).get<picojson::array>();
for (size_t i = 0; i < targetArray.size(); i++) { for (size_t i = 0; i < targetArray.size(); i++) {
@ -1722,7 +1731,8 @@ static bool ParsePrimitive(Primitive *primitive, std::string *err,
picojson::object::const_iterator dictItEnd(dict.end()); picojson::object::const_iterator dictItEnd(dict.end());
for (; dictIt != dictItEnd; ++dictIt) { for (; dictIt != dictItEnd; ++dictIt) {
targetAttribues[dictIt->first] = static_cast<int>(dictIt->second.get<double>()); targetAttribues[dictIt->first] =
static_cast<int>(dictIt->second.get<double>());
} }
primitive->targets.push_back(targetAttribues); primitive->targets.push_back(targetAttribues);
} }
@ -2076,9 +2086,8 @@ static bool ParseSkin(Skin *skin, std::string *err, const picojson::object &o) {
return true; return true;
} }
bool TinyGLTFLoader::LoadFromString(Model *model, std::string *err, bool TinyGLTF::LoadFromString(Model *model, std::string *err, const char *str,
const char *str, unsigned int length, unsigned int length, const std::string &base_dir,
const std::string &base_dir,
unsigned int check_sections) { unsigned int check_sections) {
picojson::value v; picojson::value v;
std::string perr = picojson::parse(v, str, str + length); std::string perr = picojson::parse(v, str, str + length);
@ -2163,10 +2172,11 @@ bool TinyGLTFLoader::LoadFromString(Model *model, std::string *err,
model->extensionsUsed.push_back(root[i].get<std::string>()); model->extensionsUsed.push_back(root[i].get<std::string>());
} }
} }
if (v.contains("extensionsRequired") && v.get("extensionsRequired").is<picojson::array>()) { if (v.contains("extensionsRequired") &&
const picojson::array &root = v.get("extensionsRequired").get<picojson::array>(); v.get("extensionsRequired").is<picojson::array>()) {
for(unsigned int i=0; i< root.size(); ++i) const picojson::array &root =
{ v.get("extensionsRequired").get<picojson::array>();
for (unsigned int i = 0; i < root.size(); ++i) {
model->extensionsRequired.push_back(root[i].get<std::string>()); model->extensionsRequired.push_back(root[i].get<std::string>());
} }
} }
@ -2416,7 +2426,7 @@ bool TinyGLTFLoader::LoadFromString(Model *model, std::string *err,
return true; return true;
} }
bool TinyGLTFLoader::LoadASCIIFromString(Model *model, std::string *err, bool TinyGLTF::LoadASCIIFromString(Model *model, std::string *err,
const char *str, unsigned int length, const char *str, unsigned int length,
const std::string &base_dir, const std::string &base_dir,
unsigned int check_sections) { unsigned int check_sections) {
@ -2427,7 +2437,7 @@ bool TinyGLTFLoader::LoadASCIIFromString(Model *model, std::string *err,
return LoadFromString(model, err, str, length, base_dir, check_sections); return LoadFromString(model, err, str, length, base_dir, check_sections);
} }
bool TinyGLTFLoader::LoadASCIIFromFile(Model *model, std::string *err, bool TinyGLTF::LoadASCIIFromFile(Model *model, std::string *err,
const std::string &filename, const std::string &filename,
unsigned int check_sections) { unsigned int check_sections) {
std::stringstream ss; std::stringstream ss;
@ -2465,7 +2475,7 @@ bool TinyGLTFLoader::LoadASCIIFromFile(Model *model, std::string *err,
return ret; return ret;
} }
bool TinyGLTFLoader::LoadBinaryFromMemory(Model *model, std::string *err, bool TinyGLTF::LoadBinaryFromMemory(Model *model, std::string *err,
const unsigned char *bytes, const unsigned char *bytes,
unsigned int size, unsigned int size,
const std::string &base_dir, const std::string &base_dir,
@ -2515,7 +2525,8 @@ bool TinyGLTFLoader::LoadBinaryFromMemory(Model *model, std::string *err,
model_length); model_length);
is_binary_ = true; is_binary_ = true;
bin_data_ = bytes + 20 + model_length + 8; // 4 bytes (buffer_length) + 4 bytes(buffer_format) bin_data_ = bytes + 20 + model_length +
8; // 4 bytes (buffer_length) + 4 bytes(buffer_format)
bin_size_ = bin_size_ =
length - (20 + model_length); // extract header + JSON scene data. length - (20 + model_length); // extract header + JSON scene data.
@ -2529,7 +2540,7 @@ bool TinyGLTFLoader::LoadBinaryFromMemory(Model *model, std::string *err,
return true; return true;
} }
bool TinyGLTFLoader::LoadBinaryFromFile(Model *model, std::string *err, bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err,
const std::string &filename, const std::string &filename,
unsigned int check_sections) { unsigned int check_sections) {
std::stringstream ss; std::stringstream ss;
@ -2567,113 +2578,107 @@ bool TinyGLTFLoader::LoadBinaryFromFile(Model *model, std::string *err,
typedef std::pair<std::string, picojson::value> json_object_pair; typedef std::pair<std::string, picojson::value> json_object_pair;
template <typename T> template <typename T>
static void SerializeNumberProperty(const std::string &key, T number, picojson::object &obj) static void SerializeNumberProperty(const std::string &key, T number,
{ picojson::object &obj) {
obj.insert(json_object_pair(key, picojson::value(static_cast<double>(number)))); obj.insert(
json_object_pair(key, picojson::value(static_cast<double>(number))));
} }
template <typename T> template <typename T>
static void SerializeNumberArrayProperty(const std::string &key, const std::vector<T> &value, picojson::object &obj) static void SerializeNumberArrayProperty(const std::string &key,
{ const std::vector<T> &value,
picojson::object &obj) {
picojson::object o; picojson::object o;
picojson::array vals; picojson::array vals;
for(unsigned int i = 0; i < value.size() ; ++i) for (unsigned int i = 0; i < value.size(); ++i) {
{
vals.push_back(picojson::value(static_cast<double>(value[i]))); vals.push_back(picojson::value(static_cast<double>(value[i])));
} }
obj.insert(json_object_pair(key, picojson::value(vals))); obj.insert(json_object_pair(key, picojson::value(vals)));
} }
static void SerializeStringProperty(const std::string &key, const std::string &value, picojson::object &obj) static void SerializeStringProperty(const std::string &key,
{ const std::string &value,
picojson::object &obj) {
picojson::value strVal(value); picojson::value strVal(value);
obj.insert(json_object_pair(key, strVal)); obj.insert(json_object_pair(key, strVal));
} }
static void SerializeStringArrayProperty(const std::string &key, const std::vector<std::string> &value, picojson::object &obj) static void SerializeStringArrayProperty(const std::string &key,
{ const std::vector<std::string> &value,
picojson::object &obj) {
picojson::object o; picojson::object o;
picojson::array vals; picojson::array vals;
for(unsigned int i = 0; i < value.size() ; ++i) for (unsigned int i = 0; i < value.size(); ++i) {
{
vals.push_back(picojson::value(value[i])); vals.push_back(picojson::value(value[i]));
} }
obj.insert(json_object_pair(key, picojson::value(vals))); obj.insert(json_object_pair(key, picojson::value(vals)));
} }
static void SerializeValue(const std::string &key, const Value &value, picojson::object &obj) static void SerializeValue(const std::string &key, const Value &value,
{ picojson::object &obj) {
if(value.IsArray()) if (value.IsArray()) {
{
picojson::array jsonValue; picojson::array jsonValue;
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));
if (elementValue.IsString()) if (elementValue.IsString())
jsonValue.push_back(picojson::value(elementValue.Get<std::string>())); jsonValue.push_back(picojson::value(elementValue.Get<std::string>()));
} }
obj.insert(json_object_pair(key, picojson::value(jsonValue))); obj.insert(json_object_pair(key, picojson::value(jsonValue)));
} } else {
else
{
picojson::object jsonValue; picojson::object jsonValue;
std::vector<std::string> valueKeys; std::vector<std::string> valueKeys;
for(unsigned int i = 0; i < valueKeys.size(); ++i) for (unsigned int i = 0; i < valueKeys.size(); ++i) {
{
Value elementValue = value.Get(valueKeys[i]); Value elementValue = value.Get(valueKeys[i]);
if (elementValue.IsInt()) if (elementValue.IsInt())
jsonValue.insert(json_object_pair(valueKeys[i], picojson::value(static_cast<double>(elementValue.Get<int>())))); jsonValue.insert(json_object_pair(
valueKeys[i],
picojson::value(static_cast<double>(elementValue.Get<int>()))));
} }
obj.insert(json_object_pair(key, picojson::value(jsonValue))); obj.insert(json_object_pair(key, picojson::value(jsonValue)));
} }
} }
static void SerializeGltfBufferData(const std::vector<unsigned char> &data, const std::string &binFilePath) static void SerializeGltfBufferData(const std::vector<unsigned char> &data,
{ const std::string &binFilePath) {
std::ofstream output(binFilePath.c_str(), std::ofstream::binary); std::ofstream output(binFilePath.c_str(), std::ofstream::binary);
output.write(reinterpret_cast<const char*>(&data[0]), std::streamsize(data.size())); output.write(reinterpret_cast<const char *>(&data[0]),
std::streamsize(data.size()));
output.close(); output.close();
} }
static void SerializeParameterMap(ParameterMap &param, picojson::object &o) static void SerializeParameterMap(ParameterMap &param, picojson::object &o) {
{ for (ParameterMap::iterator paramIt = param.begin(); paramIt != param.end();
for(ParameterMap::iterator paramIt = param.begin(); paramIt != param.end(); ++paramIt) ++paramIt) {
{ if (paramIt->second.number_array.size()) {
if(paramIt->second.number_array.size()) SerializeNumberArrayProperty<double>(paramIt->first,
{ paramIt->second.number_array, o);
SerializeNumberArrayProperty<double>(paramIt->first, paramIt->second.number_array, o); } else if (paramIt->second.json_double_value.size()) {
}
else if(paramIt->second.json_double_value.size())
{
picojson::object json_double_value; picojson::object json_double_value;
for(std::map<std::string, double>::iterator it=paramIt->second.json_double_value.begin(); it != paramIt->second.json_double_value.end(); ++it) for (std::map<std::string, double>::iterator it =
{ paramIt->second.json_double_value.begin();
json_double_value.insert(json_object_pair(it->first, picojson::value(it->second))); it != paramIt->second.json_double_value.end(); ++it) {
json_double_value.insert(
json_object_pair(it->first, picojson::value(it->second)));
} }
o.insert(json_object_pair(paramIt->first, picojson::value(json_double_value))); o.insert(
} json_object_pair(paramIt->first, picojson::value(json_double_value)));
else if(!paramIt->second.string_value.empty()) } else if (!paramIt->second.string_value.empty()) {
{
SerializeStringProperty(paramIt->first, paramIt->second.string_value, o); SerializeStringProperty(paramIt->first, paramIt->second.string_value, o);
} } else {
else o.insert(json_object_pair(paramIt->first,
{ picojson::value(paramIt->second.bool_value)));
o.insert(json_object_pair(paramIt->first, picojson::value(paramIt->second.bool_value)));
} }
} }
} }
static void SerializeGltfAccessor(Accessor &accessor, picojson::object &o) static void SerializeGltfAccessor(Accessor &accessor, picojson::object &o) {
{
SerializeNumberProperty<int>("bufferView", accessor.bufferView, o); SerializeNumberProperty<int>("bufferView", accessor.bufferView, o);
if (accessor.byteOffset != 0.0) if (accessor.byteOffset != 0.0)
@ -2684,8 +2689,7 @@ static void SerializeGltfAccessor(Accessor &accessor, picojson::object &o)
SerializeNumberArrayProperty<double>("min", accessor.minValues, o); SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o); SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
std::string type; std::string type;
switch(accessor.type) switch (accessor.type) {
{
case TINYGLTF_TYPE_SCALAR: case TINYGLTF_TYPE_SCALAR:
type = "SCALAR"; type = "SCALAR";
break; break;
@ -2712,8 +2716,8 @@ static void SerializeGltfAccessor(Accessor &accessor, picojson::object &o)
SerializeStringProperty("type", type, o); SerializeStringProperty("type", type, o);
} }
static void SerializeGltfAnimationChannel(AnimationChannel &channel, picojson::object &o) static void SerializeGltfAnimationChannel(AnimationChannel &channel,
{ picojson::object &o) {
SerializeNumberProperty("sampler", channel.sampler, o); SerializeNumberProperty("sampler", channel.sampler, o);
picojson::object target; picojson::object target;
SerializeNumberProperty("node", channel.target_node, target); SerializeNumberProperty("node", channel.target_node, target);
@ -2722,19 +2726,17 @@ static void SerializeGltfAnimationChannel(AnimationChannel &channel, picojson::o
o.insert(json_object_pair("target", picojson::value(target))); o.insert(json_object_pair("target", picojson::value(target)));
} }
static void SerializeGltfAnimationSampler(AnimationSampler &sampler, picojson::object &o) static void SerializeGltfAnimationSampler(AnimationSampler &sampler,
{ picojson::object &o) {
SerializeNumberProperty("input", sampler.input, o); SerializeNumberProperty("input", sampler.input, o);
SerializeNumberProperty("output", sampler.output, o); SerializeNumberProperty("output", sampler.output, o);
SerializeStringProperty("interpolation", sampler.interpolation, o); SerializeStringProperty("interpolation", sampler.interpolation, o);
} }
static void SerializeGltfAnimation(Animation &animation, picojson::object &o) static void SerializeGltfAnimation(Animation &animation, picojson::object &o) {
{
SerializeStringProperty("name", animation.name, o); SerializeStringProperty("name", animation.name, o);
picojson::array channels; picojson::array channels;
for(unsigned int i = 0; i < animation.channels.size(); ++i) for (unsigned int i = 0; i < animation.channels.size(); ++i) {
{
picojson::object channel; picojson::object channel;
AnimationChannel gltfChannel = animation.channels[i]; AnimationChannel gltfChannel = animation.channels[i];
SerializeGltfAnimationChannel(gltfChannel, channel); SerializeGltfAnimationChannel(gltfChannel, channel);
@ -2743,8 +2745,7 @@ static void SerializeGltfAnimation(Animation &animation, picojson::object &o)
o.insert(json_object_pair("channels", picojson::value(channels))); o.insert(json_object_pair("channels", picojson::value(channels)));
picojson::array samplers; picojson::array samplers;
for(unsigned int i = 0; i < animation.samplers.size(); ++i) for (unsigned int i = 0; i < animation.samplers.size(); ++i) {
{
picojson::object sampler; picojson::object sampler;
AnimationSampler gltfSampler = animation.samplers[i]; AnimationSampler gltfSampler = animation.samplers[i];
SerializeGltfAnimationSampler(gltfSampler, sampler); SerializeGltfAnimationSampler(gltfSampler, sampler);
@ -2754,63 +2755,53 @@ static void SerializeGltfAnimation(Animation &animation, picojson::object &o)
o.insert(json_object_pair("samplers", picojson::value(samplers))); o.insert(json_object_pair("samplers", picojson::value(samplers)));
} }
static void SerializeGltfAsset(Asset &asset, picojson::object &o) static void SerializeGltfAsset(Asset &asset, picojson::object &o) {
{ if (!asset.generator.empty()) {
if(!asset.generator.empty())
{
SerializeStringProperty("generator", asset.generator, o); SerializeStringProperty("generator", asset.generator, o);
} }
if(!asset.version.empty()) if (!asset.version.empty()) {
{
SerializeStringProperty("version", asset.version, o); SerializeStringProperty("version", asset.version, o);
} }
if(asset.extras.Keys().size()) if (asset.extras.Keys().size()) {
{
SerializeValue("extras", asset.extras, o); SerializeValue("extras", asset.extras, o);
} }
} }
static void SerializeGltfBuffer(Buffer &buffer, picojson::object &o, const std::string &binFilePath) static void SerializeGltfBuffer(Buffer &buffer, picojson::object &o,
{ const std::string &binFilePath) {
SerializeGltfBufferData(buffer.data, binFilePath); SerializeGltfBufferData(buffer.data, binFilePath);
SerializeNumberProperty("byteLength", buffer.data.size(), o); SerializeNumberProperty("byteLength", buffer.data.size(), o);
SerializeStringProperty("uri", binFilePath, o); SerializeStringProperty("uri", binFilePath, o);
if(buffer.name.size()) if (buffer.name.size()) SerializeStringProperty("name", buffer.name, o);
SerializeStringProperty("name", buffer.name, o);
} }
static void SerializeGltfBufferView(BufferView &bufferView, picojson::object &o) static void SerializeGltfBufferView(BufferView &bufferView,
{ picojson::object &o) {
SerializeNumberProperty("buffer", bufferView.buffer, o); SerializeNumberProperty("buffer", bufferView.buffer, o);
SerializeNumberProperty<size_t>("byteLength", bufferView.byteLength, o); SerializeNumberProperty<size_t>("byteLength", bufferView.byteLength, o);
SerializeNumberProperty<size_t>("byteStride", bufferView.byteStride, o); SerializeNumberProperty<size_t>("byteStride", bufferView.byteStride, o);
SerializeNumberProperty<size_t>("byteOffset", bufferView.byteOffset, o); SerializeNumberProperty<size_t>("byteOffset", bufferView.byteOffset, o);
SerializeNumberProperty("target", bufferView.target, o); SerializeNumberProperty("target", bufferView.target, o);
if(bufferView.name.size()) if (bufferView.name.size()) {
{
SerializeStringProperty("name", bufferView.name, o); SerializeStringProperty("name", bufferView.name, o);
} }
} }
// Only external textures are serialized for now // Only external textures are serialized for now
static void SerializeGltfImage(Image &image, picojson::object &o) static void SerializeGltfImage(Image &image, picojson::object &o) {
{
SerializeStringProperty("uri", image.uri, o); SerializeStringProperty("uri", image.uri, o);
if(image.name.size()) if (image.name.size()) {
{
SerializeStringProperty("name", image.name, o); SerializeStringProperty("name", image.name, o);
} }
} }
static void SerializeGltfMaterial(Material &material, picojson::object &o) static void SerializeGltfMaterial(Material &material, picojson::object &o) {
{ if (material.extPBRValues.size()) {
if(material.extPBRValues.size())
{
// Serialize PBR specular/glossiness material // Serialize PBR specular/glossiness material
picojson::object values; picojson::object values;
SerializeParameterMap(material.extPBRValues, values); SerializeParameterMap(material.extPBRValues, values);
@ -2819,51 +2810,49 @@ static void SerializeGltfMaterial(Material &material, picojson::object &o)
o.insert(json_object_pair("extensions", picojson::value(extension))); o.insert(json_object_pair("extensions", picojson::value(extension)));
} }
if(material.values.size()) if (material.values.size()) {
{
picojson::object pbrMetallicRoughness; picojson::object pbrMetallicRoughness;
SerializeParameterMap(material.values, pbrMetallicRoughness); SerializeParameterMap(material.values, pbrMetallicRoughness);
o.insert(json_object_pair("pbrMetallicRoughness", picojson::value(pbrMetallicRoughness))); o.insert(json_object_pair("pbrMetallicRoughness",
picojson::value(pbrMetallicRoughness)));
} }
picojson::object additionalValues; picojson::object additionalValues;
SerializeParameterMap(material.additionalValues, o); SerializeParameterMap(material.additionalValues, o);
if(material.name.size()) if (material.name.size()) {
{
SerializeStringProperty("name", material.name, o); SerializeStringProperty("name", material.name, o);
} }
} }
static void SerializeGltfMesh(Mesh &mesh, picojson::object &o) static void SerializeGltfMesh(Mesh &mesh, picojson::object &o) {
{
picojson::array primitives; picojson::array primitives;
for(unsigned int i=0; i < mesh.primitives.size(); ++i) for (unsigned int i = 0; i < mesh.primitives.size(); ++i) {
{
picojson::object primitive; picojson::object primitive;
picojson::object attributes; picojson::object attributes;
Primitive gltfPrimitive = mesh.primitives[i]; Primitive gltfPrimitive = mesh.primitives[i];
for(std::map<std::string, int>::iterator attrIt = gltfPrimitive.attributes.begin(); attrIt != gltfPrimitive.attributes.end(); ++attrIt) for (std::map<std::string, int>::iterator attrIt =
{ gltfPrimitive.attributes.begin();
attrIt != gltfPrimitive.attributes.end(); ++attrIt) {
SerializeNumberProperty<int>(attrIt->first, attrIt->second, attributes); SerializeNumberProperty<int>(attrIt->first, attrIt->second, attributes);
} }
primitive.insert(json_object_pair("attributes", picojson::value(attributes))); primitive.insert(
json_object_pair("attributes", picojson::value(attributes)));
SerializeNumberProperty<int>("indices", gltfPrimitive.indices, primitive); SerializeNumberProperty<int>("indices", gltfPrimitive.indices, primitive);
SerializeNumberProperty<int>("material", gltfPrimitive.material, primitive); SerializeNumberProperty<int>("material", gltfPrimitive.material, primitive);
SerializeNumberProperty<int>("mode", gltfPrimitive.mode, primitive); SerializeNumberProperty<int>("mode", gltfPrimitive.mode, primitive);
// Morph targets // Morph targets
if(gltfPrimitive.targets.size()) if (gltfPrimitive.targets.size()) {
{
picojson::array targets; picojson::array targets;
for(unsigned int k = 0; k < gltfPrimitive.targets.size(); ++k) for (unsigned int k = 0; k < gltfPrimitive.targets.size(); ++k) {
{
picojson::object targetAttributes; picojson::object targetAttributes;
std::map<std::string, int> targetData = gltfPrimitive.targets[k]; std::map<std::string, int> targetData = gltfPrimitive.targets[k];
for(std::map<std::string, int>::iterator attrIt = targetData.begin(); attrIt != targetData.end(); ++attrIt) for (std::map<std::string, int>::iterator attrIt = targetData.begin();
{ attrIt != targetData.end(); ++attrIt) {
SerializeNumberProperty<int>(attrIt->first, attrIt->second, targetAttributes); SerializeNumberProperty<int>(attrIt->first, attrIt->second,
targetAttributes);
} }
targets.push_back(picojson::value(targetAttributes)); targets.push_back(picojson::value(targetAttributes));
@ -2875,42 +2864,33 @@ static void SerializeGltfMesh(Mesh &mesh, picojson::object &o)
} }
o.insert(json_object_pair("primitives", picojson::value(primitives))); o.insert(json_object_pair("primitives", picojson::value(primitives)));
if(mesh.weights.size()) if (mesh.weights.size()) {
{
SerializeNumberArrayProperty<double>("weights", mesh.weights, o); SerializeNumberArrayProperty<double>("weights", mesh.weights, o);
} }
if(mesh.name.size()) if (mesh.name.size()) {
{
SerializeStringProperty("name", mesh.name, o); SerializeStringProperty("name", mesh.name, o);
} }
} }
static void SerializeGltfNode(Node &node, picojson::object &o) static void SerializeGltfNode(Node &node, picojson::object &o) {
{ if (node.translation.size() > 0) {
if(node.translation.size() > 0)
{
SerializeNumberArrayProperty<double>("translation", node.translation, o); SerializeNumberArrayProperty<double>("translation", node.translation, o);
} }
if(node.rotation.size() > 0) if (node.rotation.size() > 0) {
{
SerializeNumberArrayProperty<double>("rotation", node.rotation, o); SerializeNumberArrayProperty<double>("rotation", node.rotation, o);
} }
if(node.scale.size() > 0) if (node.scale.size() > 0) {
{
SerializeNumberArrayProperty<double>("scale", node.scale, o); SerializeNumberArrayProperty<double>("scale", node.scale, o);
} }
if(node.matrix.size() > 0) if (node.matrix.size() > 0) {
{
SerializeNumberArrayProperty<double>("matrix", node.matrix, o); SerializeNumberArrayProperty<double>("matrix", node.matrix, o);
} }
if(node.mesh != -1) if (node.mesh != -1) {
{
SerializeNumberProperty<int>("mesh", node.mesh, o); SerializeNumberProperty<int>("mesh", node.mesh, o);
} }
if(node.skin != -1) if (node.skin != -1) {
{
SerializeNumberProperty<int>("skin", node.skin, o); SerializeNumberProperty<int>("skin", node.skin, o);
} }
@ -2918,64 +2898,58 @@ static void SerializeGltfNode(Node &node, picojson::object &o)
SerializeNumberArrayProperty<int>("children", node.children, o); SerializeNumberArrayProperty<int>("children", node.children, o);
} }
static void SerializeGltfSampler(Sampler &sampler, picojson::object &o) static void SerializeGltfSampler(Sampler &sampler, picojson::object &o) {
{
SerializeNumberProperty("magFilter", sampler.magFilter, o); SerializeNumberProperty("magFilter", sampler.magFilter, o);
SerializeNumberProperty("minFilter", sampler.minFilter, o); SerializeNumberProperty("minFilter", sampler.minFilter, o);
SerializeNumberProperty("wrapS", sampler.wrapS, o); SerializeNumberProperty("wrapS", sampler.wrapS, o);
SerializeNumberProperty("wrapT", sampler.wrapT, o); SerializeNumberProperty("wrapT", sampler.wrapT, o);
} }
static void SerializeGltfScene(Scene &scene, picojson::object &o) static void SerializeGltfScene(Scene &scene, picojson::object &o) {
{
SerializeNumberArrayProperty<int>("nodes", scene.nodes, o); SerializeNumberArrayProperty<int>("nodes", scene.nodes, o);
if(scene.name.size()) if (scene.name.size()) {
{
SerializeStringProperty("name", scene.name, o); SerializeStringProperty("name", scene.name, o);
} }
} }
static void SerializeGltfSkin(Skin &skin, picojson::object &o) static void SerializeGltfSkin(Skin &skin, picojson::object &o) {
{
if (skin.inverseBindMatrices != -1) if (skin.inverseBindMatrices != -1)
SerializeNumberProperty("inverseBindMatrices", skin.inverseBindMatrices, o); SerializeNumberProperty("inverseBindMatrices", skin.inverseBindMatrices, o);
SerializeNumberArrayProperty<int>("joints", skin.joints, o); SerializeNumberArrayProperty<int>("joints", skin.joints, o);
SerializeNumberProperty("skeleton", skin.skeleton, o); SerializeNumberProperty("skeleton", skin.skeleton, o);
if(skin.name.size()) if (skin.name.size()) {
{
SerializeStringProperty("name", skin.name, o); SerializeStringProperty("name", skin.name, o);
} }
} }
static void SerializeGltfTexture(Texture &texture, picojson::object &o) static void SerializeGltfTexture(Texture &texture, picojson::object &o) {
{
SerializeNumberProperty("sampler", texture.sampler, o); SerializeNumberProperty("sampler", texture.sampler, o);
SerializeNumberProperty("source", texture.source, o); SerializeNumberProperty("source", texture.source, o);
if(texture.extras.Size()) if (texture.extras.Size()) {
{
picojson::object extras; picojson::object extras;
SerializeValue("extras", texture.extras, o); SerializeValue("extras", texture.extras, o);
o.insert(json_object_pair("extras", picojson::value(extras))); o.insert(json_object_pair("extras", picojson::value(extras)));
} }
} }
static void WriteGltfFile(const std::string& output, const std::string& content) static void WriteGltfFile(const std::string &output,
{ const std::string &content) {
std::ofstream gltfFile(output.c_str()); std::ofstream gltfFile(output.c_str());
gltfFile << content << std::endl; gltfFile << content << std::endl;
} }
bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filename/*, bool embedImages, bool embedBuffers, bool writeBinary*/) bool TinyGLTF::WriteGltfSceneToFile(
{ Model *model,
const std::string
&filename /*, bool embedImages, bool embedBuffers, bool writeBinary*/) {
picojson::object output; picojson::object output;
// ACCESSORS // ACCESSORS
picojson::array accessors; picojson::array accessors;
for(unsigned int i=0; i < model->accessors.size(); ++i) for (unsigned int i = 0; i < model->accessors.size(); ++i) {
{
picojson::object accessor; picojson::object accessor;
SerializeGltfAccessor(model->accessors[i], accessor); SerializeGltfAccessor(model->accessors[i], accessor);
accessors.push_back(picojson::value(accessor)); accessors.push_back(picojson::value(accessor));
@ -2983,13 +2957,10 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
output.insert(json_object_pair("accessors", picojson::value(accessors))); output.insert(json_object_pair("accessors", picojson::value(accessors)));
// ANIMATIONS // ANIMATIONS
if(model->animations.size()) if (model->animations.size()) {
{
picojson::array animations; picojson::array animations;
for(unsigned int i=0; i < model->animations.size(); ++i) for (unsigned int i = 0; i < model->animations.size(); ++i) {
{ if (model->animations[i].channels.size()) {
if(model->animations[i].channels.size())
{
picojson::object animation; picojson::object animation;
SerializeGltfAnimation(model->animations[i], animation); SerializeGltfAnimation(model->animations[i], animation);
animations.push_back(picojson::value(animation)); animations.push_back(picojson::value(animation));
@ -3007,19 +2978,15 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
std::string ext = ".bin"; std::string ext = ".bin";
std::string::size_type pos = binFilePath.rfind('.', binFilePath.length()); std::string::size_type pos = binFilePath.rfind('.', binFilePath.length());
if (pos != std::string::npos) if (pos != std::string::npos) {
{
binFilePath = binFilePath.substr(0, pos) + ext; binFilePath = binFilePath.substr(0, pos) + ext;
} } else {
else
{
binFilePath = "./" + binFilePath + ".bin"; binFilePath = "./" + binFilePath + ".bin";
} }
// BUFFERS (We expect only one buffer here) // BUFFERS (We expect only one buffer here)
picojson::array buffers; picojson::array buffers;
for(unsigned int i=0; i < model->buffers.size(); ++i) for (unsigned int i = 0; i < model->buffers.size(); ++i) {
{
picojson::object buffer; picojson::object buffer;
SerializeGltfBuffer(model->buffers[i], buffer, binFilePath); SerializeGltfBuffer(model->buffers[i], buffer, binFilePath);
buffers.push_back(picojson::value(buffer)); buffers.push_back(picojson::value(buffer));
@ -3028,8 +2995,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// BUFFERVIEWS // BUFFERVIEWS
picojson::array bufferViews; picojson::array bufferViews;
for(unsigned int i=0; i < model->bufferViews.size(); ++i) for (unsigned int i = 0; i < model->bufferViews.size(); ++i) {
{
picojson::object bufferView; picojson::object bufferView;
SerializeGltfBufferView(model->bufferViews[i], bufferView); SerializeGltfBufferView(model->bufferViews[i], bufferView);
bufferViews.push_back(picojson::value(bufferView)); bufferViews.push_back(picojson::value(bufferView));
@ -3037,21 +3003,20 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
output.insert(json_object_pair("bufferViews", picojson::value(bufferViews))); output.insert(json_object_pair("bufferViews", picojson::value(bufferViews)));
// Extensions used // Extensions used
if(model->extensionsUsed.size()) if (model->extensionsUsed.size()) {
{ SerializeStringArrayProperty("extensionsUsed", model->extensionsUsed,
SerializeStringArrayProperty("extensionsUsed", model->extensionsUsed, output); output);
} }
// Extensions required // Extensions required
if(model->extensionsRequired.size()) if (model->extensionsRequired.size()) {
{ SerializeStringArrayProperty("extensionsRequired",
SerializeStringArrayProperty("extensionsRequired", model->extensionsRequired, output); model->extensionsRequired, output);
} }
// IMAGES // IMAGES
picojson::array images; picojson::array images;
for(unsigned int i=0; i < model->images.size(); ++i) for (unsigned int i = 0; i < model->images.size(); ++i) {
{
picojson::object image; picojson::object image;
SerializeGltfImage(model->images[i], image); SerializeGltfImage(model->images[i], image);
images.push_back(picojson::value(image)); images.push_back(picojson::value(image));
@ -3060,8 +3025,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// MATERIALS // MATERIALS
picojson::array materials; picojson::array materials;
for(unsigned int i=0; i < model->materials.size(); ++i) for (unsigned int i = 0; i < model->materials.size(); ++i) {
{
picojson::object material; picojson::object material;
SerializeGltfMaterial(model->materials[i], material); SerializeGltfMaterial(model->materials[i], material);
materials.push_back(picojson::value(material)); materials.push_back(picojson::value(material));
@ -3070,8 +3034,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// MESHES // MESHES
picojson::array meshes; picojson::array meshes;
for(unsigned int i=0; i < model->meshes.size(); ++i) for (unsigned int i = 0; i < model->meshes.size(); ++i) {
{
picojson::object mesh; picojson::object mesh;
SerializeGltfMesh(model->meshes[i], mesh); SerializeGltfMesh(model->meshes[i], mesh);
meshes.push_back(picojson::value(mesh)); meshes.push_back(picojson::value(mesh));
@ -3080,8 +3043,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// NODES // NODES
picojson::array nodes; picojson::array nodes;
for(unsigned int i=0; i < model->nodes.size(); ++i) for (unsigned int i = 0; i < model->nodes.size(); ++i) {
{
picojson::object node; picojson::object node;
SerializeGltfNode(model->nodes[i], node); SerializeGltfNode(model->nodes[i], node);
nodes.push_back(picojson::value(node)); nodes.push_back(picojson::value(node));
@ -3093,8 +3055,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// SCENES // SCENES
picojson::array scenes; picojson::array scenes;
for(unsigned int i=0; i < model->scenes.size(); ++i) for (unsigned int i = 0; i < model->scenes.size(); ++i) {
{
picojson::object currentScene; picojson::object currentScene;
SerializeGltfScene(model->scenes[i], currentScene); SerializeGltfScene(model->scenes[i], currentScene);
scenes.push_back(picojson::value(currentScene)); scenes.push_back(picojson::value(currentScene));
@ -3102,11 +3063,9 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
output.insert(json_object_pair("scenes", picojson::value(scenes))); output.insert(json_object_pair("scenes", picojson::value(scenes)));
// SKINS // SKINS
if(model->skins.size()) if (model->skins.size()) {
{
picojson::array skins; picojson::array skins;
for(unsigned int i=0; i < model->skins.size(); ++i) for (unsigned int i = 0; i < model->skins.size(); ++i) {
{
picojson::object skin; picojson::object skin;
SerializeGltfSkin(model->skins[i], skin); SerializeGltfSkin(model->skins[i], skin);
skins.push_back(picojson::value(picojson::value(skin))); skins.push_back(picojson::value(picojson::value(skin)));
@ -3116,8 +3075,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// TEXTURES // TEXTURES
picojson::array textures; picojson::array textures;
for(unsigned int i=0; i < model->textures.size(); ++i) for (unsigned int i = 0; i < model->textures.size(); ++i) {
{
picojson::object texture; picojson::object texture;
SerializeGltfTexture(model->textures[i], texture); SerializeGltfTexture(model->textures[i], texture);
textures.push_back(picojson::value(texture)); textures.push_back(picojson::value(texture));
@ -3126,8 +3084,7 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
// SAMPLERS // SAMPLERS
picojson::array samplers; picojson::array samplers;
for(unsigned int i=0; i < model->samplers.size(); ++i) for (unsigned int i = 0; i < model->samplers.size(); ++i) {
{
picojson::object sampler; picojson::object sampler;
SerializeGltfSampler(model->samplers[i], sampler); SerializeGltfSampler(model->samplers[i], sampler);
samplers.push_back(picojson::value(sampler)); samplers.push_back(picojson::value(sampler));
@ -3138,7 +3095,6 @@ bool TinyGLTFLoader::WriteGltfSceneToFile(Model *model, const std::string &filen
return true; return true;
} }
} // namespace tinygltf } // namespace tinygltf
#endif // TINYGLTF_LOADER_IMPLEMENTATION #endif // TINYGLTF_IMPLEMENTATION