diff --git a/BUILD.gn b/BUILD.gn
index fe7e68a..14e7cbb 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -762,17 +762,6 @@
     ]
   }
 
-  dawn_sample("glTFViewer") {
-    sources = [
-      "examples/glTFViewer/Camera.inc",
-      "examples/glTFViewer/glTFViewer.cpp",
-    ]
-    deps = [
-      "third_party:glm",
-      "third_party:tiny_gltf_loader",
-    ]
-  }
-
   group("dawn_samples") {
     deps = [
       ":Animometer",
@@ -780,7 +769,6 @@
       ":ComputeBoids",
       ":CppHelloTriangle",
       ":CubeReflection",
-      ":glTFViewer",
     ]
   }
 }
diff --git a/DEPS b/DEPS
index ebc5bbb..741f57b 100644
--- a/DEPS
+++ b/DEPS
@@ -78,11 +78,7 @@
     'condition': 'dawn_standalone',
   },
 
-  # Dependencies for samples: stb and GLM
-  'third_party/stb': {
-    'url': '{github_git}/nothings/stb.git@c7110588a4d24c4bb5155c184fbb77dd90b3116e',
-    'condition': 'dawn_standalone',
-  },
+  # Dependencies for samples: GLM
   'third_party/glm': {
     'url': '{github_git}/g-truc/glm.git@06f084063fd6d9aa2ef6904517650700ae47b63d',
     'condition': 'dawn_standalone',
diff --git a/examples/glTFViewer/Camera.inc b/examples/glTFViewer/Camera.inc
deleted file mode 100644
index 530e8b1..0000000
--- a/examples/glTFViewer/Camera.inc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-class Camera {
-    public:
-        Camera()
-            : _azimuth(glm::radians(45.f)),
-              _altitude(glm::radians(30.f)),
-              _radius(10.f),
-              _center(0, 0, 0),
-              _dirty(true) {
-            recalculate();
-        }
-
-        void rotate(float dAzimuth, float dAltitude) {
-            _dirty = true;
-            _azimuth = glm::mod(_azimuth + dAzimuth, glm::radians(360.f));
-            _altitude = glm::clamp(_altitude + dAltitude, glm::radians(-89.f), glm::radians(89.f));
-        }
-
-        void pan(float dX, float dY) {
-            recalculate();
-            glm::vec3 vX = glm::normalize(glm::cross(-_eyeDir, glm::vec3(0, 1, 0)));
-            glm::vec3 vY = glm::normalize(glm::cross(_eyeDir, vX));
-            _center += vX * dX * _radius + vY * dY * _radius;
-        }
-
-        void zoom(float factor) {
-            _dirty = true;
-            _radius = _radius * glm::exp(-factor);
-        }
-
-        glm::mat4 view() {
-            if (_dirty) {
-                recalculate();
-            }
-            return _view;
-        }
-    private:
-        void recalculate() {
-            glm::vec4 eye4 = glm::vec4(1, 0, 0, 1);
-            eye4 = glm::rotate(glm::mat4(), _altitude, glm::vec3(0, 0, 1)) * eye4;
-            eye4 = glm::rotate(glm::mat4(), _azimuth, glm::vec3(0, 1, 0)) * eye4;
-            _eyeDir = glm::vec3(eye4);
-
-            _view = glm::lookAt(_center + _eyeDir * _radius, _center, glm::vec3(0, -1, 0));
-            _dirty = false;
-        }
-        float _azimuth;
-        float _altitude;
-        float _radius;
-        glm::vec3 _center;
-        glm::vec3 _eyeDir;
-        bool _dirty;
-        glm::mat4 _view;
-};
diff --git a/examples/glTFViewer/README.md b/examples/glTFViewer/README.md
deleted file mode 100644
index d1ddf6b..0000000
--- a/examples/glTFViewer/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Dawn glTF Viewer
-
-This is a barebones glTF model viewer using the Dawn API. It is intended as a
-proof of concept for the API and is not a robust model viewer. It can load
-basic mesh/texture data from a few
-[glTF sample models](https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/1.0),
-such as:
-
-* 2CylinderEngine
-* BoxWithoutIndices
-* Cesium Man
-* Duck
-* Monster
-* VC (Virtual City)
-
-## Usage
-
-`build/examples/glTFViewer/glTFViewer path/to/Duck.gltf`
-
-`build/examples/glTFViewer/glTFViewer path/to/Duck.gltf --backend metal`
-
-## Screenshots
-
-Duck:
-
-![Duck](img/nxt-gltf-duck.jpg)
-
-VC (Virtual City):
-
-![Virtual City](img/nxt-gltf-vc.jpg)
diff --git a/examples/glTFViewer/glTFViewer.cpp b/examples/glTFViewer/glTFViewer.cpp
deleted file mode 100644
index 5dc6d09..0000000
--- a/examples/glTFViewer/glTFViewer.cpp
+++ /dev/null
@@ -1,686 +0,0 @@
-// Copyright 2017 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Enable this before including any headers as we want inttypes.h to define
-// format macros such as PRId64 that are used in picojson.
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
-
-#include "../SampleUtils.h"
-
-#include "common/Assert.h"
-#include "common/Math.h"
-#include "common/Constants.h"
-#include "utils/ComboRenderPipelineDescriptor.h"
-#include "utils/DawnHelpers.h"
-#include "utils/SystemUtils.h"
-
-#include <bitset>
-#define GLM_FORCE_DEPTH_ZERO_TO_ONE
-#include <glm/mat4x4.hpp>
-#include <glm/gtc/matrix_inverse.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/type_ptr.hpp>
-
-#define TINYGLTF_LOADER_IMPLEMENTATION
-#define STB_IMAGE_IMPLEMENTATION
-#define PICOJSON_ASSERT ASSERT
-#undef __STDC_FORMAT_MACROS
-#include <tinygltfloader/tiny_gltf_loader.h>
-
-#include "GLFW/glfw3.h"
-
-#include "Camera.inc"
-
-namespace gl {
-    enum {
-        Triangles = 0x0004,
-        UnsignedShort = 0x1403,
-        UnsignedInt = 0x1405,
-        Float = 0x1406,
-        RGBA = 0x1908,
-        Nearest = 0x2600,
-        Linear = 0x2601,
-        NearestMipmapNearest = 0x2700,
-        LinearMipmapNearest = 0x2701,
-        NearestMipmapLinear = 0x2702,
-        LinearMipmapLinear = 0x2703,
-        ArrayBuffer = 0x8892,
-        ElementArrayBuffer = 0x8893,
-        FragmentShader = 0x8B30,
-        VertexShader = 0x8B31,
-        FloatVec2 = 0x8B50,
-        FloatVec3 = 0x8B51,
-        FloatVec4 = 0x8B52,
-    };
-}
-
-struct MaterialInfo {
-    dawn::RenderPipeline pipeline;
-    dawn::BindGroup bindGroup0;
-    std::map<uint32_t, std::string> slotSemantics;
-};
-
-struct u_transform_block {
-    glm::mat4 modelViewProj;
-    glm::mat4 modelInvTr;
-};
-
-dawn::Device device;
-dawn::Queue queue;
-dawn::SwapChain swapchain;
-dawn::TextureView depthStencilView;
-
-dawn::Buffer defaultBuffer;
-std::map<std::string, dawn::Buffer> buffers;
-std::map<std::string, dawn::CommandBuffer> commandBuffers;
-std::map<uint32_t, std::string> slotSemantics = {{0, "POSITION"}, {1, "NORMAL"}, {2, "TEXCOORD_0"}};
-
-std::map<std::string, dawn::Sampler> samplers;
-std::map<std::string, dawn::TextureView> textures;
-
-tinygltf::Scene scene;
-glm::mat4 projection = glm::perspective(glm::radians(60.f), 640.f/480, 0.1f, 2000.f);
-Camera camera;
-
-// Helpers
-namespace {
-    std::string getFilePathExtension(const std::string &FileName) {
-        if (FileName.find_last_of(".") != std::string::npos) {
-            return FileName.substr(FileName.find_last_of(".") + 1);
-        }
-        return "";
-    }
-
-    bool techniqueParameterTypeToVertexFormat(int type, dawn::VertexFormat *format) {
-        switch (type) {
-            case gl::FloatVec2:
-                *format = dawn::VertexFormat::Float2;
-                return true;
-            case gl::FloatVec3:
-                *format = dawn::VertexFormat::Float3;
-                return true;
-            case gl::FloatVec4:
-                *format = dawn::VertexFormat::Float4;
-                return true;
-            default:
-                return false;
-        }
-    }
-}
-
-// Initialization
-namespace {
-    void initBuffers() {
-        dawn::BufferDescriptor descriptor;
-        descriptor.size = 256;
-        descriptor.usage = dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::Index;
-        defaultBuffer = device.CreateBuffer(&descriptor);
-
-        for (const auto& bv : scene.bufferViews) {
-            const auto& iBufferViewID = bv.first;
-            const auto& iBufferView = bv.second;
-
-            dawn::BufferUsageBit usage = dawn::BufferUsageBit::None;
-            switch (iBufferView.target) {
-                case gl::ArrayBuffer:
-                    usage |= dawn::BufferUsageBit::Vertex;
-                    break;
-                case gl::ElementArrayBuffer:
-                    usage |= dawn::BufferUsageBit::Index;
-                    break;
-                case 0:
-                    fprintf(stderr, "TODO: buffer view has no target; skipping\n");
-                    continue;
-                default:
-                    fprintf(stderr, "unsupported buffer view target %d\n", iBufferView.target);
-                    continue;
-            }
-            const auto& iBuffer = scene.buffers.at(iBufferView.buffer);
-
-            size_t iBufferViewSize =
-                iBufferView.byteLength ? iBufferView.byteLength :
-                (iBuffer.data.size() - iBufferView.byteOffset);
-            auto oBuffer = utils::CreateBufferFromData(device, &iBuffer.data.at(iBufferView.byteOffset), static_cast<uint32_t>(iBufferViewSize), usage);
-            buffers[iBufferViewID] = std::move(oBuffer);
-        }
-    }
-
-    const MaterialInfo& getMaterial(const std::string& iMaterialID, size_t stridePos, size_t strideNor, size_t strideTxc) {
-        static std::map<std::tuple<std::string, size_t, size_t, size_t>, MaterialInfo> materials;
-        auto key = make_tuple(iMaterialID, stridePos, strideNor, strideTxc);
-        auto materialIterator = materials.find(key);
-        if (materialIterator != materials.end()) {
-            return materialIterator->second;
-        }
-
-        const auto& iMaterial = scene.materials.at(iMaterialID);
-        const auto& iTechnique = scene.techniques.at(iMaterial.technique);
-
-        bool hasTexture = false;
-        std::string iTextureID;
-        {
-            auto it = iMaterial.values.find("diffuse");
-            if (it != iMaterial.values.end() && !it->second.string_value.empty()) {
-                hasTexture = true;
-                iTextureID = it->second.string_value;
-            }
-        }
-
-        auto oVSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
-            #version 450
-
-            layout(push_constant) uniform u_transform_block {
-                mat4 modelViewProj;
-                mat4 modelInvTr;
-            } u_transform;
-
-            layout(location = 0) in vec4 a_position;
-            layout(location = 1) in vec3 a_normal;
-            layout(location = 2) in vec2 a_texcoord;
-
-            layout(location = 0) out vec3 v_normal;
-            layout(location = 1) out vec2 v_texcoord;
-
-            void main() {
-                v_normal = (u_transform.modelInvTr * vec4(normalize(a_normal), 0)).rgb;
-                v_texcoord = a_texcoord;
-                gl_Position = u_transform.modelViewProj * a_position;
-            })");
-
-        auto oFSSourceTextured = R"(
-            #version 450
-
-            layout(set = 0, binding = 0) uniform sampler u_samp;
-            layout(set = 0, binding = 1) uniform texture2D u_tex;
-
-            layout(location = 0) in vec3 v_normal;
-            layout(location = 1) in vec2 v_texcoord;
-
-            layout(location = 0) out vec4 fragcolor;
-
-            void main() {
-                const vec3 lightdir = normalize(vec3(-1, -2, 3));
-                vec3 normal = normalize(v_normal);
-                float diffuse = abs(dot(lightdir, normal));
-                float diffamb = diffuse * 0.85 + 0.15;
-                vec3 albedo = texture(sampler2D(u_tex, u_samp), v_texcoord).rgb;
-                fragcolor = vec4(diffamb * albedo, 1);
-            })";
-        auto oFSSourceUntextured = R"(
-            #version 450
-
-            layout(location = 0) in vec3 v_normal;
-            layout(location = 1) in vec2 v_texcoord;
-
-            layout(location = 0) out vec4 fragcolor;
-
-            void main() {
-                const vec3 lightdir = normalize(vec3(-1, -2, 3));
-                vec3 normal = normalize(v_normal);
-                float diffuse = abs(dot(lightdir, normal));
-                float diffamb = diffuse * 0.85 + 0.15;
-                fragcolor = vec4(vec3(diffamb), 1);
-            })";
-
-        auto oFSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, hasTexture ? oFSSourceTextured : oFSSourceUntextured);
-
-        utils::ComboRenderPipelineDescriptor descriptor(device);
-        descriptor.cInputState.indexFormat = dawn::IndexFormat::Uint16;
-        uint32_t numAttributes = 0;
-        uint32_t numInputs = 0;
-        std::bitset<3> slotsSet;
-        for (const auto& a : iTechnique.attributes) {
-            const auto iAttributeName = a.first;
-            const auto iParameter = iTechnique.parameters.at(a.second);
-            dawn::VertexFormat format;
-            if (!techniqueParameterTypeToVertexFormat(iParameter.type, &format)) {
-                fprintf(stderr, "unsupported technique parameter type %d\n", iParameter.type);
-                continue;
-            }
-            descriptor.cInputState.cAttributes[numAttributes].format = format;
-
-            if (iParameter.semantic == "POSITION") {
-                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(stridePos);
-                numAttributes++;
-                numInputs++;
-                slotsSet.set(0);
-            } else if (iParameter.semantic == "NORMAL") {
-                descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 1;
-                descriptor.cInputState.cAttributes[numAttributes].inputSlot = 1;
-                descriptor.cInputState.cInputs[numInputs].inputSlot = 1;
-                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(strideNor);
-                numAttributes++;
-                numInputs++;
-                slotsSet.set(1);
-            } else if (iParameter.semantic == "TEXCOORD_0") {
-                descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 2;
-                descriptor.cInputState.cAttributes[numAttributes].inputSlot = 2;
-                descriptor.cInputState.cInputs[numInputs].inputSlot = 2;
-                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(strideTxc);
-                numAttributes++;
-                numInputs++;
-                slotsSet.set(2);
-            } else {
-                fprintf(stderr, "unsupported technique attribute semantic %s\n", iParameter.semantic.c_str());
-            }
-        }
-        for (uint32_t i = 0; i < slotsSet.size(); i++) {
-            if (slotsSet[i]) {
-                continue;
-            }
-            descriptor.cInputState.cAttributes[numAttributes].shaderLocation = i;
-            descriptor.cInputState.cAttributes[numAttributes].inputSlot = i;
-            descriptor.cInputState.cAttributes[numAttributes].format = dawn::VertexFormat::Float4;
-
-            descriptor.cInputState.cInputs[numInputs].inputSlot = i;
-
-            numAttributes++;
-            numInputs++;
-        }
-        descriptor.cInputState.numAttributes = numAttributes;
-        descriptor.cInputState.numInputs = numInputs;
-
-        constexpr dawn::ShaderStageBit kNoStages{};
-        dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
-            device, {
-                        {0, hasTexture ? dawn::ShaderStageBit::Fragment : kNoStages,
-                         dawn::BindingType::Sampler},
-                        {1, hasTexture ? dawn::ShaderStageBit::Fragment : kNoStages,
-                         dawn::BindingType::SampledTexture},
-                    });
-
-        auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
-
-        descriptor.layout = pipelineLayout;
-        descriptor.cVertexStage.module = oVSModule;
-        descriptor.cFragmentStage.module = oFSModule;
-        descriptor.depthStencilState = &descriptor.cDepthStencilState;
-        descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
-        descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
-        descriptor.cDepthStencilState.depthWriteEnabled = true;
-        descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;
-
-        dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
-
-        dawn::BindGroup bindGroup;
-
-        if (hasTexture) {
-            const auto& textureView = textures[iTextureID];
-            const auto& iSamplerID = scene.textures[iTextureID].sampler;
-            bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {
-                {0, samplers[iSamplerID]},
-                {1, textureView}
-            });
-        } else {
-            bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {});
-        }
-
-        MaterialInfo material = {
-            pipeline,
-            bindGroup,
-            std::map<uint32_t, std::string>(),
-        };
-        materials[key] = std::move(material);
-        return materials.at(key);
-    }
-
-    void initSamplers() {
-        for (const auto& s : scene.samplers) {
-            const auto& iSamplerID = s.first;
-            const auto& iSampler = s.second;
-
-            dawn::SamplerDescriptor desc = utils::GetDefaultSamplerDescriptor();
-            // TODO: wrap modes
-
-            switch (iSampler.magFilter) {
-                case gl::Nearest:
-                    desc.magFilter = dawn::FilterMode::Nearest;
-                    break;
-                case gl::Linear:
-                    desc.magFilter = dawn::FilterMode::Linear;
-                    break;
-                default:
-                    fprintf(stderr, "unsupported magFilter %d\n", iSampler.magFilter);
-                    break;
-            }
-            switch (iSampler.minFilter) {
-                case gl::Nearest:
-                case gl::NearestMipmapNearest:
-                case gl::NearestMipmapLinear:
-                    desc.minFilter = dawn::FilterMode::Nearest;
-                    break;
-                case gl::Linear:
-                case gl::LinearMipmapNearest:
-                case gl::LinearMipmapLinear:
-                    desc.minFilter = dawn::FilterMode::Linear;
-                    break;
-                default:
-                    fprintf(stderr, "unsupported minFilter %d\n", iSampler.magFilter);
-                    break;
-            }
-            switch (iSampler.minFilter) {
-                case gl::NearestMipmapNearest:
-                case gl::LinearMipmapNearest:
-                    desc.mipmapFilter = dawn::FilterMode::Nearest;
-                    break;
-                case gl::NearestMipmapLinear:
-                case gl::LinearMipmapLinear:
-                    desc.mipmapFilter = dawn::FilterMode::Linear;
-                    break;
-            }
-
-            samplers[iSamplerID] = device.CreateSampler(&desc);
-        }
-    }
-
-    void initTextures() {
-        for (const auto& t : scene.textures) {
-            const auto& iTextureID = t.first;
-            const auto& iTexture = t.second;
-            const auto& iImage = scene.images[iTexture.source];
-
-            dawn::TextureFormat format = dawn::TextureFormat::R8G8B8A8Unorm;
-            switch (iTexture.format) {
-                case gl::RGBA:
-                    format = dawn::TextureFormat::R8G8B8A8Unorm;
-                    break;
-                default:
-                    fprintf(stderr, "unsupported texture format %d\n", iTexture.format);
-                    continue;
-            }
-
-            dawn::TextureDescriptor descriptor;
-            descriptor.dimension = dawn::TextureDimension::e2D;
-            descriptor.size.width = iImage.width;
-            descriptor.size.height = iImage.height;
-            descriptor.size.depth = 1;
-            descriptor.arrayLayerCount = 1;
-            descriptor.sampleCount = 1;
-            descriptor.format = format;
-            descriptor.mipLevelCount = 1;
-            descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled;
-            auto oTexture = device.CreateTexture(&descriptor);
-                // TODO: release this texture
-
-            const uint8_t* origData = iImage.image.data();
-            const uint8_t* data = nullptr;
-            std::vector<uint8_t> newData;
-
-            uint32_t width = static_cast<uint32_t>(iImage.width);
-            uint32_t height = static_cast<uint32_t>(iImage.height);
-            uint32_t rowSize = width * 4;
-            uint32_t rowPitch = Align(rowSize, kTextureRowPitchAlignment);
-
-            if (iImage.component == 3 || iImage.component == 4) {
-                if (rowSize != rowPitch || iImage.component == 3) {
-                    newData.resize(rowPitch * height);
-                    uint32_t pixelsPerRow = rowPitch / 4;
-                    for (uint32_t y = 0; y < height; ++y) {
-                        for (uint32_t x = 0; x < width; ++x) {
-                            size_t oldIndex = x + y * height;
-                            size_t newIndex = x + y * pixelsPerRow;
-                            if (iImage.component == 4) {
-                                newData[4 * newIndex + 0] = origData[4 * oldIndex + 0];
-                                newData[4 * newIndex + 1] = origData[4 * oldIndex + 1];
-                                newData[4 * newIndex + 2] = origData[4 * oldIndex + 2];
-                                newData[4 * newIndex + 3] = origData[4 * oldIndex + 3];
-                            } else if (iImage.component == 3) {
-                                newData[4 * newIndex + 0] = origData[3 * oldIndex + 0];
-                                newData[4 * newIndex + 1] = origData[3 * oldIndex + 1];
-                                newData[4 * newIndex + 2] = origData[3 * oldIndex + 2];
-                                newData[4 * newIndex + 3] = 255;
-                            }
-                        }
-                    }
-                    data = newData.data();
-                } else {
-                    data = origData;
-                }
-            } else {
-                fprintf(stderr, "unsupported image.component %d\n", iImage.component);
-            }
-
-            dawn::Buffer staging = utils::CreateBufferFromData(device, data, rowPitch * iImage.height, dawn::BufferUsageBit::TransferSrc);
-            dawn::BufferCopyView bufferCopyView =
-                utils::CreateBufferCopyView(staging, 0, rowPitch, 0);
-            dawn::TextureCopyView textureCopyView =
-                utils::CreateTextureCopyView(oTexture, 0, 0, {0, 0, 0});
-            dawn::Extent3D copySize = {iImage.width, iImage.height, 1};
-
-            dawn::CommandEncoder encoder = device.CreateCommandEncoder();
-            encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);
-
-            dawn::CommandBuffer cmdbuf = encoder.Finish();
-            queue.Submit(1, &cmdbuf);
-
-            textures[iTextureID] = oTexture.CreateDefaultView();
-        }
-    }
-
-    void init() {
-        device = CreateCppDawnDevice();
-
-        queue = device.CreateQueue();
-        swapchain = GetSwapChain(device);
-        swapchain.Configure(GetPreferredSwapChainTextureFormat(),
-                            dawn::TextureUsageBit::OutputAttachment, 640, 480);
-
-        depthStencilView = CreateDefaultDepthStencilView(device);
-
-        initBuffers();
-        initSamplers();
-        initTextures();
-    }
-}
-
-// Drawing
-namespace {
-    void drawMesh(dawn::RenderPassEncoder& pass, const tinygltf::Mesh& iMesh, const glm::mat4& model) {
-        for (const auto& iPrim : iMesh.primitives) {
-            if (iPrim.mode != gl::Triangles) {
-                fprintf(stderr, "unsupported primitive mode %d\n", iPrim.mode);
-                continue;
-            }
-
-            u_transform_block transforms = {
-                (projection * camera.view() * model),
-                glm::inverseTranspose(model),
-            };
-
-            size_t strides[3] = {0};
-            for (const auto& s : slotSemantics) {
-                if (s.first < 3) {
-                    auto it = iPrim.attributes.find(s.second);
-                    if (it == iPrim.attributes.end()) {
-                        continue;
-                    }
-                    const auto& iAccessorName = it->second;
-                    strides[s.first] = scene.accessors.at(iAccessorName).byteStride;
-                }
-            }
-            const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]);
-            pass.SetPipeline(material.pipeline);
-            pass.SetBindGroup(0, material.bindGroup0, 0, nullptr);
-            pass.SetPushConstants(dawn::ShaderStageBit::Vertex,
-                    0, sizeof(u_transform_block) / sizeof(uint32_t),
-                    reinterpret_cast<const uint32_t*>(&transforms));
-
-            uint32_t vertexCount = 0;
-            for (const auto& s : slotSemantics) {
-                uint32_t slot = s.first;
-                auto it = iPrim.attributes.find(s.second);
-                if (it == iPrim.attributes.end()) {
-                    uint64_t zero = 0;
-                    pass.SetVertexBuffers(slot, 1, &defaultBuffer, &zero);
-                    continue;
-                }
-                const auto& iAccessor = scene.accessors.at(it->second);
-                if (iAccessor.componentType != gl::Float ||
-                        (iAccessor.type != TINYGLTF_TYPE_VEC4 && iAccessor.type != TINYGLTF_TYPE_VEC3 && iAccessor.type != TINYGLTF_TYPE_VEC2)) {
-                    fprintf(stderr, "unsupported vertex accessor component type %d and type %d\n", iAccessor.componentType, iAccessor.type);
-                    continue;
-                }
-
-                if (vertexCount == 0) {
-                    vertexCount = static_cast<uint32_t>(iAccessor.count);
-                }
-                const auto& oBuffer = buffers.at(iAccessor.bufferView);
-                uint64_t iBufferOffset = static_cast<uint64_t>(iAccessor.byteOffset);
-                pass.SetVertexBuffers(slot, 1, &oBuffer, &iBufferOffset);
-            }
-
-            if (!iPrim.indices.empty()) {
-                const auto& iIndices = scene.accessors.at(iPrim.indices);
-                // DrawElements
-                if (iIndices.componentType != gl::UnsignedShort || iIndices.type != TINYGLTF_TYPE_SCALAR) {
-                    fprintf(stderr, "unsupported index accessor component type %d and type %d\n", iIndices.componentType, iIndices.type);
-                    continue;
-                }
-                const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
-                pass.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
-                pass.DrawIndexed(static_cast<uint32_t>(iIndices.count), 1, 0, 0, 0);
-            } else {
-                // DrawArrays
-                pass.Draw(vertexCount, 1, 0, 0);
-            }
-        }
-    }
-
-    void drawNode(dawn::RenderPassEncoder& pass, const tinygltf::Node& node, const glm::mat4& parent = glm::mat4()) {
-        glm::mat4 model;
-        if (node.matrix.size() == 16) {
-            model = glm::make_mat4(node.matrix.data());
-        } else {
-            if (node.scale.size() == 3) {
-                glm::vec3 scale = glm::make_vec3(node.scale.data());
-                model = glm::scale(model, scale);
-            }
-            if (node.rotation.size() == 4) {
-                glm::quat rotation = glm::make_quat(node.rotation.data());
-                model = glm::mat4_cast(rotation) * model;
-            }
-            if (node.translation.size() == 3) {
-                glm::vec3 translation = glm::make_vec3(node.translation.data());
-                model = glm::translate(model, translation);
-            }
-        }
-        model = parent * model;
-
-        for (const auto& meshID : node.meshes) {
-            drawMesh(pass, scene.meshes[meshID], model);
-        }
-        for (const auto& child : node.children) {
-            drawNode(pass, scene.nodes.at(child), model);
-        }
-    }
-
-    void frame() {
-        dawn::Texture backbuffer = swapchain.GetNextTexture();
-
-        const auto& defaultSceneNodes = scene.scenes.at(scene.defaultScene);
-        dawn::CommandEncoder encoder = device.CreateCommandEncoder();
-        {
-            utils::ComboRenderPassDescriptor renderPass({backbuffer.CreateDefaultView()},
-                                                        depthStencilView);
-            dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
-            for (const auto& n : defaultSceneNodes) {
-                const auto& node = scene.nodes.at(n);
-                drawNode(pass, node);
-            }
-            pass.EndPass();
-        }
-
-        dawn::CommandBuffer commands = encoder.Finish();
-        queue.Submit(1, &commands);
-
-        swapchain.Present(backbuffer);
-        DoFlush();
-    }
-}
-
-// Mouse camera control
-namespace {
-    bool buttons[GLFW_MOUSE_BUTTON_LAST + 1] = {0};
-
-    void mouseButtonCallback(GLFWwindow*, int button, int action, int) {
-        buttons[button] = (action == GLFW_PRESS);
-    }
-
-    void cursorPosCallback(GLFWwindow*, double mouseX, double mouseY) {
-        static double oldX, oldY;
-        float dX = static_cast<float>(mouseX - oldX);
-        float dY = static_cast<float>(mouseY - oldY);
-        oldX = mouseX;
-        oldY = mouseY;
-
-        if (buttons[2] || (buttons[0] && buttons[1])) {
-            camera.pan(-dX * 0.002f, dY * 0.002f);
-        } else if (buttons[0]) {
-            camera.rotate(dX * 0.01f, dY * 0.01f);
-        } else if (buttons[1]) {
-            camera.zoom(dY * -0.005f);
-        }
-    }
-
-    void scrollCallback(GLFWwindow*, double, double yoffset) {
-        camera.zoom(static_cast<float>(yoffset) * 0.04f);
-    }
-}
-
-int main(int argc, const char* argv[]) {
-    if (!InitSample(argc, argv)) {
-        return 1;
-    }
-    if (argc < 2) {
-        fprintf(stderr, "Usage: %s model.gltf [... Dawn Options]\n", argv[0]);
-        return 1;
-    }
-
-    tinygltf::TinyGLTFLoader loader;
-    std::string err;
-    std::string input_filename(argv[1]);
-    std::string ext = getFilePathExtension(input_filename);
-
-    bool ret = false;
-    if (ext.compare("glb") == 0) {
-        // assume binary glTF.
-        ret = loader.LoadBinaryFromFile(&scene, &err, input_filename.c_str());
-    } else {
-        // assume ascii glTF.
-        ret = loader.LoadASCIIFromFile(&scene, &err, input_filename.c_str());
-    }
-    if (!err.empty()) {
-        fprintf(stderr, "ERR: %s\n", err.c_str());
-    }
-    if (!ret) {
-        fprintf(stderr, "Failed to load .glTF : %s\n", argv[1]);
-        exit(-1);
-    }
-
-    init();
-
-    GLFWwindow* window = GetGLFWWindow();
-    glfwSetMouseButtonCallback(window, mouseButtonCallback);
-    glfwSetCursorPosCallback(window, cursorPosCallback);
-    glfwSetScrollCallback(window, scrollCallback);
-
-    while (!ShouldQuit()) {
-        frame();
-        utils::USleep(16000);
-    }
-
-    // TODO release stuff
-}
diff --git a/examples/glTFViewer/img/nxt-gltf-duck.jpg b/examples/glTFViewer/img/nxt-gltf-duck.jpg
deleted file mode 100644
index da78162..0000000
--- a/examples/glTFViewer/img/nxt-gltf-duck.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/glTFViewer/img/nxt-gltf-vc.jpg b/examples/glTFViewer/img/nxt-gltf-vc.jpg
deleted file mode 100644
index 29f9694..0000000
--- a/examples/glTFViewer/img/nxt-gltf-vc.jpg
+++ /dev/null
Binary files differ
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 319a3dc..c17a3f0 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -353,45 +353,4 @@
 
     # GLM is header only but has too many files to list them.
   }
-
-  # STB
-  config("stb_public_config") {
-    include_dirs = [ "stb" ]
-
-    if (!is_msvc) {
-      cflags_cc = [ "-Wno-implicit-fallthrough" ]
-    }
-  }
-  source_set("stb") {
-    public_configs = [ ":stb_public_config" ]
-    sources = [
-      "stb/stb_image.h",
-    ]
-  }
-
-  # PicoJSON
-  config("picojson_public_config") {
-    include_dirs = [ "." ]
-  }
-  source_set("picojson") {
-    public_configs = [ ":picojson_public_config" ]
-    sources = [
-      "picojson/picojson.h",
-    ]
-  }
-
-  # Tiny glTF Loader
-  config("tiny_gltf_loader_public_config") {
-    include_dirs = [ "." ]
-  }
-  source_set("tiny_gltf_loader") {
-    public_configs = [ ":tiny_gltf_loader_public_config" ]
-    public_deps = [
-      ":picojson",
-      ":stb",
-    ]
-    sources = [
-      "tinygltfloader/tiny_gltf_loader.h",
-    ]
-  }
 }
diff --git a/third_party/picojson/picojson.h b/third_party/picojson/picojson.h
deleted file mode 100644
index 2180497..0000000
--- a/third_party/picojson/picojson.h
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- * Copyright 2009-2010 Cybozu Labs, Inc.
- * Copyright 2011-2014 Kazuho Oku
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef picojson_h
-#define picojson_h
-
-#include <algorithm>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cstddef>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <map>
-#include <stdexcept>
-#include <string>
-#include <vector>
-
-// for isnan/isinf
-#if __cplusplus>=201103L
-# include <cmath>
-#else
-extern "C" {
-# ifdef _MSC_VER
-#  include <float.h>
-# elif defined(__INTEL_COMPILER)
-#  include <mathimf.h>
-# else
-#  include <math.h>
-# endif
-}
-#endif
-
-#ifndef PICOJSON_USE_RVALUE_REFERENCE
-# if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
-#  define PICOJSON_USE_RVALUE_REFERENCE 1
-# else
-#  define PICOJSON_USE_RVALUE_REFERENCE 0
-# endif
-#endif//PICOJSON_USE_RVALUE_REFERENCE
-
-
-// experimental support for int64_t (see README.mkdn for detail)
-#ifdef PICOJSON_USE_INT64
-# define __STDC_FORMAT_MACROS
-# include <errno.h>
-# include <inttypes.h>
-#endif
-
-// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
-#ifndef PICOJSON_USE_LOCALE
-# define PICOJSON_USE_LOCALE 1
-#endif
-#if PICOJSON_USE_LOCALE
-extern "C" {
-# include <locale.h>
-}
-#endif
-
-#ifndef PICOJSON_ASSERT
-# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0)
-#endif
-
-#ifdef _MSC_VER
-    #define SNPRINTF _snprintf_s
-    #pragma warning(push)
-    #pragma warning(disable : 4244) // conversion from int to char
-    #pragma warning(disable : 4127) // conditional expression is constant
-    #pragma warning(disable : 4702) // unreachable code
-#else
-    #define SNPRINTF snprintf
-#endif
-
-namespace picojson {
-  
-  enum {
-    null_type,
-    boolean_type,
-    number_type,
-    string_type,
-    array_type,
-    object_type
-#ifdef PICOJSON_USE_INT64
-    , int64_type
-#endif
-  };
-  
-  enum {
-    INDENT_WIDTH = 2
-  };
-
-  struct null {};
-  
-  class value {
-  public:
-    typedef std::vector<value> array;
-    typedef std::map<std::string, value> object;
-    union _storage {
-      bool boolean_;
-      double number_;
-#ifdef PICOJSON_USE_INT64
-      int64_t int64_;
-#endif
-      std::string* string_;
-      array* array_;
-      object* object_;
-    };
-  protected:
-    int type_;
-    _storage u_;
-  public:
-    value();
-    value(int type, bool);
-    explicit value(bool b);
-#ifdef PICOJSON_USE_INT64
-    explicit value(int64_t i);
-#endif
-    explicit value(double n);
-    explicit value(const std::string& s);
-    explicit value(const array& a);
-    explicit value(const object& o);
-    explicit value(const char* s);
-    value(const char* s, size_t len);
-    ~value();
-    value(const value& x);
-    value& operator=(const value& x);
-#if PICOJSON_USE_RVALUE_REFERENCE 
-    value(value&& x)throw();
-    value& operator=(value&& x)throw();
-#endif
-    void swap(value& x)throw();
-    template <typename T> bool is() const;
-    template <typename T> const T& get() const;
-    template <typename T> T& get();
-    bool evaluate_as_boolean() const;
-    const value& get(size_t idx) const;
-    const value& get(const std::string& key) const;
-    value& get(size_t idx);
-    value& get(const std::string& key);
-
-    bool contains(size_t idx) const;
-    bool contains(const std::string& key) const;
-    std::string to_str() const;
-    template <typename Iter> void serialize(Iter os, bool prettify = false) const;
-    std::string serialize(bool prettify = false) const;
-  private:
-    template <typename T> value(const T*); // intentionally defined to block implicit conversion of pointer to bool
-    template <typename Iter> static void _indent(Iter os, int indent);
-    template <typename Iter> void _serialize(Iter os, int indent) const;
-    std::string _serialize(int indent) const;
-  };
-  
-  typedef value::array array;
-  typedef value::object object;
-  
-  inline value::value() : type_(null_type) {}
-  
-  inline value::value(int type, bool) : type_(type) {
-    switch (type) {
-#define INIT(p, v) case p##type: u_.p = v; break
-      INIT(boolean_, false);
-      INIT(number_, 0.0);
-#ifdef PICOJSON_USE_INT64
-      INIT(int64_, 0);
-#endif
-      INIT(string_, new std::string());
-      INIT(array_, new array());
-      INIT(object_, new object());
-#undef INIT
-    default: break;
-    }
-  }
-  
-  inline value::value(bool b) : type_(boolean_type) {
-    u_.boolean_ = b;
-  }
-
-#ifdef PICOJSON_USE_INT64
-  inline value::value(int64_t i) : type_(int64_type) {
-    u_.int64_ = i;
-  }
-#endif
-
-  inline value::value(double n) : type_(number_type) {
-    if (
-#ifdef _MSC_VER
-        ! _finite(n)
-#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
-		std::isnan(n) || std::isinf(n)
-#else
-        isnan(n) || isinf(n)
-#endif
-        ) {
-      // throw std::overflow_error("");
-      PICOJSON_ASSERT(false);
-    }
-    u_.number_ = n;
-  }
-  
-  inline value::value(const std::string& s) : type_(string_type) {
-    u_.string_ = new std::string(s);
-  }
-  
-  inline value::value(const array& a) : type_(array_type) {
-    u_.array_ = new array(a);
-  }
-  
-  inline value::value(const object& o) : type_(object_type) {
-    u_.object_ = new object(o);
-  }
-  
-  inline value::value(const char* s) : type_(string_type) {
-    u_.string_ = new std::string(s);
-  }
-  
-  inline value::value(const char* s, size_t len) : type_(string_type) {
-    u_.string_ = new std::string(s, len);
-  }
-  
-  inline value::~value() {
-    switch (type_) {
-#define DEINIT(p) case p##type: delete u_.p; break
-      DEINIT(string_);
-      DEINIT(array_);
-      DEINIT(object_);
-#undef DEINIT
-    default: break;
-    }
-  }
-  
-  inline value::value(const value& x) : type_(x.type_) {
-    switch (type_) {
-#define INIT(p, v) case p##type: u_.p = v; break
-      INIT(string_, new std::string(*x.u_.string_));
-      INIT(array_, new array(*x.u_.array_));
-      INIT(object_, new object(*x.u_.object_));
-#undef INIT
-    default:
-      u_ = x.u_;
-      break;
-    }
-  }
-  
-  inline value& value::operator=(const value& x) {
-    if (this != &x) {
-      value t(x);
-      swap(t);
-    }
-    return *this;
-  }
-
-#if PICOJSON_USE_RVALUE_REFERENCE 
-  inline value::value(value&& x)throw() : type_(null_type) {
-    swap(x);
-  }
-  inline value& value::operator=(value&& x)throw() {
-    swap(x);
-    return *this;
-  }
-#endif
-  inline void value::swap(value& x)throw() {
-    std::swap(type_, x.type_);
-    std::swap(u_, x.u_);
-  }
-  
-#define IS(ctype, jtype)			     \
-  template <> inline bool value::is<ctype>() const { \
-    return type_ == jtype##_type;		     \
-  }
-  IS(null, null)
-  IS(bool, boolean)
-#ifdef PICOJSON_USE_INT64
-  IS(int64_t, int64)
-#endif
-  IS(std::string, string)
-  IS(array, array)
-  IS(object, object)
-#undef IS
-  template <> inline bool value::is<double>() const {
-    return type_ == number_type
-#ifdef PICOJSON_USE_INT64
-      || type_ == int64_type
-#endif
-      ;
-  }
-  
-#define GET(ctype, var)						\
-  template <> inline const ctype& value::get<ctype>() const {	\
-    PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
-	   && is<ctype>());				        \
-    return var;							\
-  }								\
-  template <> inline ctype& value::get<ctype>() {		\
-    PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()"	\
-	   && is<ctype>());					\
-    return var;							\
-  }
-  GET(bool, u_.boolean_)
-  GET(std::string, *u_.string_)
-  GET(array, *u_.array_)
-  GET(object, *u_.object_)
-#ifdef PICOJSON_USE_INT64
-  GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_))
-  GET(int64_t, u_.int64_)
-#else
-  GET(double, u_.number_)
-#endif
-#undef GET
-  
-  inline bool value::evaluate_as_boolean() const {
-    switch (type_) {
-    case null_type:
-      return false;
-    case boolean_type:
-      return u_.boolean_;
-    case number_type:
-      return u_.number_ != 0;
-#ifdef PICOJSON_USE_INT64
-    case int64_type:
-      return u_.int64_ != 0;
-#endif
-    case string_type:
-      return ! u_.string_->empty();
-    default:
-      return true;
-    }
-  }
-  
-  inline const value& value::get(size_t idx) const {
-    static value s_null;
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
-  }
-
-  inline value& value::get(size_t idx) {
-    static value s_null;
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
-  }
-
-  inline const value& value::get(const std::string& key) const {
-    static value s_null;
-    PICOJSON_ASSERT(is<object>());
-    object::const_iterator i = u_.object_->find(key);
-    return i != u_.object_->end() ? i->second : s_null;
-  }
-
-  inline value& value::get(const std::string& key) {
-    static value s_null;
-    PICOJSON_ASSERT(is<object>());
-    object::iterator i = u_.object_->find(key);
-    return i != u_.object_->end() ? i->second : s_null;
-  }
-
-  inline bool value::contains(size_t idx) const {
-    PICOJSON_ASSERT(is<array>());
-    return idx < u_.array_->size();
-  }
-
-  inline bool value::contains(const std::string& key) const {
-    PICOJSON_ASSERT(is<object>());
-    object::const_iterator i = u_.object_->find(key);
-    return i != u_.object_->end();
-  }
-  
-  inline std::string value::to_str() const {
-    switch (type_) {
-    case null_type:      return "null";
-    case boolean_type:   return u_.boolean_ ? "true" : "false";
-#ifdef PICOJSON_USE_INT64
-    case int64_type: {
-      char buf[sizeof("-9223372036854775808")];
-      SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
-      return buf;
-    }
-#endif
-    case number_type:    {
-      char buf[256];
-      double tmp;
-      SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
-#if PICOJSON_USE_LOCALE
-      char *decimal_point = localeconv()->decimal_point;
-      if (strcmp(decimal_point, ".") != 0) {
-        size_t decimal_point_len = strlen(decimal_point);
-        for (char *p = buf; *p != '\0'; ++p) {
-          if (strncmp(p, decimal_point, decimal_point_len) == 0) {
-            return std::string(buf, p) + "." + (p + decimal_point_len);
-          }
-        }
-      }
-#endif
-      return buf;
-    }
-    case string_type:    return *u_.string_;
-    case array_type:     return "array";
-    case object_type:    return "object";
-    default:             PICOJSON_ASSERT(0);
-#ifdef _MSC_VER
-      __assume(0);
-#endif
-    }
-    return std::string();
-  }
-  
-  template <typename Iter> void copy(const std::string& s, Iter oi) {
-    std::copy(s.begin(), s.end(), oi);
-  }
-  
-  template <typename Iter> void serialize_str(const std::string& s, Iter oi) {
-    *oi++ = '"';
-    for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
-      switch (*i) {
-#define MAP(val, sym) case val: copy(sym, oi); break
-	MAP('"', "\\\"");
-	MAP('\\', "\\\\");
-	MAP('/', "\\/");
-	MAP('\b', "\\b");
-	MAP('\f', "\\f");
-	MAP('\n', "\\n");
-	MAP('\r', "\\r");
-	MAP('\t', "\\t");
-#undef MAP
-      default:
-	if (static_cast<unsigned char>(*i) < 0x20 || *i == 0x7f) {
-	  char buf[7];
-	  SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff);
-	  copy(buf, buf + 6, oi);
-	  } else {
-	  *oi++ = *i;
-	}
-	break;
-      }
-    }
-    *oi++ = '"';
-  }
-
-  template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
-    return _serialize(oi, prettify ? 0 : -1);
-  }
-  
-  inline std::string value::serialize(bool prettify) const {
-    return _serialize(prettify ? 0 : -1);
-  }
-
-  template <typename Iter> void value::_indent(Iter oi, int indent) {
-    *oi++ = '\n';
-    for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
-      *oi++ = ' ';
-    }
-  }
-
-  template <typename Iter> void value::_serialize(Iter oi, int indent) const {
-    switch (type_) {
-    case string_type:
-      serialize_str(*u_.string_, oi);
-      break;
-    case array_type: {
-      *oi++ = '[';
-      if (indent != -1) {
-        ++indent;
-      }
-      for (array::const_iterator i = u_.array_->begin();
-           i != u_.array_->end();
-           ++i) {
-	if (i != u_.array_->begin()) {
-	  *oi++ = ',';
-	}
-        if (indent != -1) {
-          _indent(oi, indent);
-        }
-	i->_serialize(oi, indent);
-      }
-      if (indent != -1) {
-        --indent;
-        if (! u_.array_->empty()) {
-          _indent(oi, indent);
-        }
-      }
-      *oi++ = ']';
-      break;
-    }
-    case object_type: {
-      *oi++ = '{';
-      if (indent != -1) {
-        ++indent;
-      }
-      for (object::const_iterator i = u_.object_->begin();
-	   i != u_.object_->end();
-	   ++i) {
-	if (i != u_.object_->begin()) {
-	  *oi++ = ',';
-	}
-        if (indent != -1) {
-          _indent(oi, indent);
-        }
-	serialize_str(i->first, oi);
-	*oi++ = ':';
-        if (indent != -1) {
-          *oi++ = ' ';
-        }
-        i->second._serialize(oi, indent);
-      }
-      if (indent != -1) {
-        --indent;
-        if (! u_.object_->empty()) {
-          _indent(oi, indent);
-        }
-      }
-      *oi++ = '}';
-      break;
-    }
-    default:
-      copy(to_str(), oi);
-      break;
-    }
-    if (indent == 0) {
-      *oi++ = '\n';
-    }
-  }
-  
-  inline std::string value::_serialize(int indent) const {
-    std::string s;
-    _serialize(std::back_inserter(s), indent);
-    return s;
-  }
-  
-  template <typename Iter> class input {
-  protected:
-    Iter cur_, end_;
-    int last_ch_;
-    bool ungot_;
-    int line_;
-  public:
-    input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {}
-    int getc() {
-      if (ungot_) {
-	ungot_ = false;
-	return last_ch_;
-      }
-      if (cur_ == end_) {
-	last_ch_ = -1;
-	return -1;
-      }
-      if (last_ch_ == '\n') {
-	line_++;
-      }
-      last_ch_ = *cur_ & 0xff;
-      ++cur_;
-      return last_ch_;
-    }
-    void ungetc() {
-      if (last_ch_ != -1) {
-	PICOJSON_ASSERT(! ungot_);
-	ungot_ = true;
-      }
-    }
-    Iter cur() const { return cur_; }
-    int line() const { return line_; }
-    void skip_ws() {
-      while (1) {
-	int ch = getc();
-	if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
-	  ungetc();
-	  break;
-	}
-      }
-    }
-    bool expect(int expect) {
-      skip_ws();
-      if (getc() != expect) {
-	ungetc();
-	return false;
-      }
-      return true;
-    }
-    bool match(const std::string& pattern) {
-      for (std::string::const_iterator pi(pattern.begin());
-	   pi != pattern.end();
-	   ++pi) {
-	if (getc() != *pi) {
-	  ungetc();
-	  return false;
-	}
-      }
-      return true;
-    }
-  };
-  
-  template<typename Iter> inline int _parse_quadhex(input<Iter> &in) {
-    int uni_ch = 0, hex;
-    for (int i = 0; i < 4; i++) {
-      if ((hex = in.getc()) == -1) {
-	return -1;
-      }
-      if ('0' <= hex && hex <= '9') {
-	hex -= '0';
-      } else if ('A' <= hex && hex <= 'F') {
-	hex -= 'A' - 0xa;
-      } else if ('a' <= hex && hex <= 'f') {
-	hex -= 'a' - 0xa;
-      } else {
-	in.ungetc();
-	return -1;
-      }
-      uni_ch = uni_ch * 16 + hex;
-    }
-    return uni_ch;
-  }
-  
-  template<typename String, typename Iter> inline bool _parse_codepoint(String& out, input<Iter>& in) {
-    int uni_ch;
-    if ((uni_ch = _parse_quadhex(in)) == -1) {
-      return false;
-    }
-    if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
-      if (0xdc00 <= uni_ch) {
-	// a second 16-bit of a surrogate pair appeared
-	return false;
-      }
-      // first 16-bit of surrogate pair, get the next one
-      if (in.getc() != '\\' || in.getc() != 'u') {
-	in.ungetc();
-	return false;
-      }
-      int second = _parse_quadhex(in);
-      if (! (0xdc00 <= second && second <= 0xdfff)) {
-	return false;
-      }
-      uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
-      uni_ch += 0x10000;
-    }
-    if (uni_ch < 0x80) {
-      out.push_back(uni_ch);
-    } else {
-      if (uni_ch < 0x800) {
-	out.push_back(0xc0 | (uni_ch >> 6));
-      } else {
-	if (uni_ch < 0x10000) {
-	  out.push_back(0xe0 | (uni_ch >> 12));
-	} else {
-	  out.push_back(0xf0 | (uni_ch >> 18));
-	  out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
-	}
-	out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
-      }
-      out.push_back(0x80 | (uni_ch & 0x3f));
-    }
-    return true;
-  }
-  
-  template<typename String, typename Iter> inline bool _parse_string(String& out, input<Iter>& in) {
-    while (1) {
-      int ch = in.getc();
-      if (ch < ' ') {
-	in.ungetc();
-	return false;
-      } else if (ch == '"') {
-	return true;
-      } else if (ch == '\\') {
-	if ((ch = in.getc()) == -1) {
-	  return false;
-	}
-	switch (ch) {
-#define MAP(sym, val) case sym: out.push_back(val); break
-	  MAP('"', '\"');
-	  MAP('\\', '\\');
-	  MAP('/', '/');
-	  MAP('b', '\b');
-	  MAP('f', '\f');
-	  MAP('n', '\n');
-	  MAP('r', '\r');
-	  MAP('t', '\t');
-#undef MAP
-	case 'u':
-	  if (! _parse_codepoint(out, in)) {
-	    return false;
-	  }
-	  break;
-	default:
-	  return false;
-	}
-      } else {
-	out.push_back(ch);
-      }
-    }
-    return false;
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse_array(Context& ctx, input<Iter>& in) {
-    if (! ctx.parse_array_start()) {
-      return false;
-    }
-    size_t idx = 0;
-    if (in.expect(']')) {
-      return ctx.parse_array_stop(idx);
-    }
-    do {
-      if (! ctx.parse_array_item(in, idx)) {
-	return false;
-      }
-      idx++;
-    } while (in.expect(','));
-    return in.expect(']') && ctx.parse_array_stop(idx);
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse_object(Context& ctx, input<Iter>& in) {
-    if (! ctx.parse_object_start()) {
-      return false;
-    }
-    if (in.expect('}')) {
-      return true;
-    }
-    do {
-      std::string key;
-      if (! in.expect('"')
-	  || ! _parse_string(key, in)
-	  || ! in.expect(':')) {
-	return false;
-      }
-      if (! ctx.parse_object_item(in, key)) {
-	return false;
-      }
-    } while (in.expect(','));
-    return in.expect('}');
-  }
-  
-  template <typename Iter> inline std::string _parse_number(input<Iter>& in) {
-    std::string num_str;
-    while (1) {
-      int ch = in.getc();
-      if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-'
-          || ch == 'e' || ch == 'E') {
-        num_str.push_back(ch);
-      } else if (ch == '.') {
-#if PICOJSON_USE_LOCALE
-        num_str += localeconv()->decimal_point;
-#else
-        num_str.push_back('.');
-#endif
-      } else {
-	in.ungetc();
-	break;
-      }
-    }
-    return num_str;
-  }
-  
-  template <typename Context, typename Iter> inline bool _parse(Context& ctx, input<Iter>& in) {
-    in.skip_ws();
-    int ch = in.getc();
-    switch (ch) {
-#define IS(ch, text, op) case ch: \
-      if (in.match(text) && op) { \
-	return true; \
-      } else { \
-	return false; \
-      }
-      IS('n', "ull", ctx.set_null());
-      IS('f', "alse", ctx.set_bool(false));
-      IS('t', "rue", ctx.set_bool(true));
-#undef IS
-    case '"':
-      return ctx.parse_string(in);
-    case '[':
-      return _parse_array(ctx, in);
-    case '{':
-      return _parse_object(ctx, in);
-    default:
-      if (('0' <= ch && ch <= '9') || ch == '-') {
-        double f;
-        char *endp;
-	in.ungetc();
-        std::string num_str = _parse_number(in);
-        if (num_str.empty()) {
-          return false;
-        }
-#ifdef PICOJSON_USE_INT64
-        {
-          errno = 0;
-          intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
-          if (errno == 0
-              && std::numeric_limits<int64_t>::min() <= ival
-              && ival <= std::numeric_limits<int64_t>::max()
-              && endp == num_str.c_str() + num_str.size()) {
-            ctx.set_int64(ival);
-            return true;
-          }
-        }
-#endif
-        f = strtod(num_str.c_str(), &endp);
-        if (endp == num_str.c_str() + num_str.size()) {
-          ctx.set_number(f);
-          return true;
-        }
-        return false;
-      }
-      break;
-    }
-    in.ungetc();
-    return false;
-  }
-  
-  class deny_parse_context {
-  public:
-    bool set_null() { return false; }
-    bool set_bool(bool) { return false; }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t) { return false; }
-#endif
-    bool set_number(double) { return false; }
-    template <typename Iter> bool parse_string(input<Iter>&) { return false; }
-    bool parse_array_start() { return false; }
-    template <typename Iter> bool parse_array_item(input<Iter>&, size_t) {
-      return false;
-    }
-    bool parse_array_stop(size_t) { return false; }
-    bool parse_object_start() { return false; }
-    template <typename Iter> bool parse_object_item(input<Iter>&, const std::string&) {
-      return false;
-    }
-  };
-  
-  class default_parse_context {
-  protected:
-    value* out_;
-  public:
-    default_parse_context(value* out) : out_(out) {}
-    bool set_null() {
-      *out_ = value();
-      return true;
-    }
-    bool set_bool(bool b) {
-      *out_ = value(b);
-      return true;
-    }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t i) {
-      *out_ = value(i);
-      return true;
-    }
-#endif
-    bool set_number(double f) {
-      *out_ = value(f);
-      return true;
-    }
-    template<typename Iter> bool parse_string(input<Iter>& in) {
-      *out_ = value(string_type, false);
-      return _parse_string(out_->get<std::string>(), in);
-    }
-    bool parse_array_start() {
-      *out_ = value(array_type, false);
-      return true;
-    }
-    template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
-      array& a = out_->get<array>();
-      a.push_back(value());
-      default_parse_context ctx(&a.back());
-      return _parse(ctx, in);
-    }
-    bool parse_array_stop(size_t) { return true; }
-    bool parse_object_start() {
-      *out_ = value(object_type, false);
-      return true;
-    }
-    template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string& key) {
-      object& o = out_->get<object>();
-      default_parse_context ctx(&o[key]);
-      return _parse(ctx, in);
-    }
-  private:
-    default_parse_context(const default_parse_context&);
-    default_parse_context& operator=(const default_parse_context&);
-  };
-
-  class null_parse_context {
-  public:
-    struct dummy_str {
-      void push_back(int) {}
-    };
-  public:
-    null_parse_context() {}
-    bool set_null() { return true; }
-    bool set_bool(bool) { return true; }
-#ifdef PICOJSON_USE_INT64
-    bool set_int64(int64_t) { return true; }
-#endif
-    bool set_number(double) { return true; }
-    template <typename Iter> bool parse_string(input<Iter>& in) {
-      dummy_str s;
-      return _parse_string(s, in);
-    }
-    bool parse_array_start() { return true; }
-    template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
-      return _parse(*this, in);
-    }
-    bool parse_array_stop(size_t) { return true; }
-    bool parse_object_start() { return true; }
-    template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string&) {
-      return _parse(*this, in);
-    }
-  private:
-    null_parse_context(const null_parse_context&);
-    null_parse_context& operator=(const null_parse_context&);
-  };
-  
-  // obsolete, use the version below
-  template <typename Iter> inline std::string parse(value& out, Iter& pos, const Iter& last) {
-    std::string err;
-    pos = parse(out, pos, last, &err);
-    return err;
-  }
-  
-  template <typename Context, typename Iter> inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) {
-    input<Iter> in(first, last);
-    if (! _parse(ctx, in) && err != NULL) {
-      char buf[64];
-      SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
-      *err = buf;
-      while (1) {
-	int ch = in.getc();
-	if (ch == -1 || ch == '\n') {
-	  break;
-	} else if (ch >= ' ') {
-	  err->push_back(ch);
-	}
-      }
-    }
-    return in.cur();
-  }
-  
-  template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) {
-    default_parse_context ctx(&out);
-    return _parse(ctx, first, last, err);
-  }
-  
-  inline std::string parse(value& out, const std::string& s) {
-    std::string err;
-    parse(out, s.begin(), s.end(), &err);
-    return err;
-  }
-
-  inline std::string parse(value& out, std::istream& is) {
-    std::string err;
-    parse(out, std::istreambuf_iterator<char>(is.rdbuf()),
-	  std::istreambuf_iterator<char>(), &err);
-    return err;
-  }
-  
-  template <typename T> struct last_error_t {
-    static std::string s;
-  };
-  template <typename T> std::string last_error_t<T>::s;
-  
-  inline void set_last_error(const std::string& s) {
-    last_error_t<bool>::s = s;
-  }
-  
-  inline const std::string& get_last_error() {
-    return last_error_t<bool>::s;
-  }
-
-  inline bool operator==(const value& x, const value& y) {
-    if (x.is<null>())
-      return y.is<null>();
-#define PICOJSON_CMP(type)					\
-    if (x.is<type>())						\
-      return y.is<type>() && x.get<type>() == y.get<type>()
-    PICOJSON_CMP(bool);
-    PICOJSON_CMP(double);
-    PICOJSON_CMP(std::string);
-    PICOJSON_CMP(array);
-    PICOJSON_CMP(object);
-#undef PICOJSON_CMP
-    PICOJSON_ASSERT(0);
-#ifdef _MSC_VER
-    __assume(0);
-#endif
-    return false;
-  }
-  
-  inline bool operator!=(const value& x, const value& y) {
-    return ! (x == y);
-  }
-}
-
-#if !PICOJSON_USE_RVALUE_REFERENCE 
-namespace std {
-  template<> inline void swap(picojson::value& x, picojson::value& y)
-    {
-      x.swap(y);
-    }
-}
-#endif
-
-inline std::istream& operator>>(std::istream& is, picojson::value& x)
-{
-  picojson::set_last_error(std::string());
-  std::string err = picojson::parse(x, is);
-  if (! err.empty()) {
-    picojson::set_last_error(err);
-    is.setstate(std::ios::failbit);
-  }
-  return is;
-}
-
-inline std::ostream& operator<<(std::ostream& os, const picojson::value& x)
-{
-  x.serialize(std::ostream_iterator<char>(os));
-  return os;
-}
-#ifdef _MSC_VER
-    #pragma warning(pop)
-#endif
-
-#endif
diff --git a/third_party/tinygltfloader/tiny_gltf_loader.h b/third_party/tinygltfloader/tiny_gltf_loader.h
deleted file mode 100644
index 4792721..0000000
--- a/third_party/tinygltfloader/tiny_gltf_loader.h
+++ /dev/null
@@ -1,2656 +0,0 @@
-//
-// Tiny glTF loader.
-//
-//
-// The MIT License (MIT)
-//
-// Copyright (c) 2015 - 2016 Syoyo Fujita 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.
-
-// Version:
-//  - v0.9.5 Support parsing `extras` parameter.
-//  - v0.9.4 Support parsing `shader`, `program` and `tecnique` thanks to
-//  @lukesanantonio
-//  - v0.9.3 Support binary glTF
-//  - v0.9.2 Support parsing `texture`
-//  - v0.9.1 Support loading glTF asset from memory
-//  - v0.9.0 Initial
-//
-// Tiny glTF loader is using following third party libraries:
-//
-//  - picojson: C++ JSON library.
-//  - base64: base64 decode/encode library.
-//  - stb_image: Image loading library.
-//
-#ifndef TINY_GLTF_LOADER_H_
-#define TINY_GLTF_LOADER_H_
-
-#include <cassert>
-#include <cstring>
-#include <map>
-#include <string>
-#include <vector>
-
-namespace tinygltf {
-
-#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 (5127)
-
-#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_RPEAT (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;
-
-// 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 = *(new 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 = *(new 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;
-  }
-
- 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_;
-  char pad[3];
-
-  int pad0;
-};
-
-#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
-
-typedef struct {
-  std::string string_value;
-  std::vector<double> number_array;
-} Parameter;
-
-typedef std::map<std::string, Parameter> ParameterMap;
-
-typedef struct {
-  std::string sampler;
-  std::string target_id;
-  std::string target_path;
-  Value extras;
-} AnimationChannel;
-
-typedef struct {
-  std::string input;
-  std::string interpolation;
-  std::string output;
-  Value extras;
-} AnimationSampler;
-
-typedef struct {
-  std::string name;
-  std::vector<AnimationChannel> channels;
-  std::map<std::string, AnimationSampler> samplers;
-  ParameterMap parameters;
-  Value extras;
-} Animation;
-
-typedef struct {
-  std::string name;
-  int minFilter;
-  int magFilter;
-  int wrapS;
-  int wrapT;
-  int wrapR;  // TinyGLTF extension
-  int pad0;
-  Value extras;
-} Sampler;
-
-typedef struct {
-  std::string name;
-  int width;
-  int height;
-  int component;
-  int pad0;
-  std::vector<unsigned char> image;
-
-  std::string bufferView;  // KHR_binary_glTF extenstion.
-  std::string mimeType;    // KHR_binary_glTF extenstion.
-
-  Value extras;
-} Image;
-
-typedef struct {
-  int format;
-  int internalFormat;
-  std::string sampler;  // Required
-  std::string source;   // Required
-  int target;
-  int type;
-  std::string name;
-  Value extras;
-} Texture;
-
-typedef struct {
-  std::string name;
-  std::string technique;
-  ParameterMap values;
-
-  Value extras;
-} Material;
-
-typedef struct {
-  std::string name;
-  std::string buffer;  // Required
-  size_t byteOffset;   // Required
-  size_t byteLength;   // default: 0
-  int target;
-  int pad0;
-  Value extras;
-} BufferView;
-
-typedef struct {
-  std::string bufferView;
-  std::string name;
-  size_t byteOffset;
-  size_t byteStride;
-  int componentType;  // One of TINYGLTF_COMPONENT_TYPE_***
-  int pad0;
-  size_t count;
-  int type;  // One of TINYGLTF_TYPE_***
-  int pad1;
-  std::vector<double> minValues;  // Optional
-  std::vector<double> maxValues;  // Optional
-  Value extras;
-} Accessor;
-
-class Camera {
- public:
-  Camera() {}
-  ~Camera() {}
-
-  std::string name;
-  bool isOrthographic;  // false = perspective.
-
-  // Some common properties.
-  float aspectRatio;
-  float yFov;
-  float zFar;
-  float zNear;
-};
-
-typedef struct {
-  std::map<std::string, std::string> attributes;  // A dictionary object of
-                                                  // strings, where each string
-                                                  // is the ID of the accessor
-                                                  // containing an attribute.
-  std::string material;  // The ID of the material to apply to this primitive
-                         // when rendering.
-  std::string indices;   // The ID of the accessor that contains the indices.
-  int mode;              // one of TINYGLTF_MODE_***
-  int pad0;
-
-  Value extras;  // "extra" property
-} Primitive;
-
-typedef struct {
-  std::string name;
-  std::vector<Primitive> primitives;
-  Value extras;
-} Mesh;
-
-class Node {
- public:
-  Node() {}
-  ~Node() {}
-
-  std::string camera;  // camera object referenced by this node.
-
-  std::string name;
-  std::vector<std::string> 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<std::string> meshes;
-
-  Value extras;
-};
-
-typedef struct {
-  std::string name;
-  std::vector<unsigned char> data;
-  Value extras;
-} Buffer;
-
-typedef struct {
-  std::string name;
-  int type;
-  int pad0;
-  std::vector<unsigned char> source;
-
-  Value extras;
-} Shader;
-
-typedef struct {
-  std::string name;
-  std::string vertexShader;
-  std::string fragmentShader;
-  std::vector<std::string> attributes;
-
-  Value extras;
-} Program;
-
-typedef struct {
-  int count;
-  int pad0;
-  std::string node;
-  std::string semantic;
-  int type;
-  int pad1;
-  Parameter value;
-} TechniqueParameter;
-
-typedef struct {
-  std::string name;
-  std::string program;
-  std::map<std::string, TechniqueParameter> parameters;
-  std::map<std::string, std::string> attributes;
-  std::map<std::string, std::string> uniforms;
-
-  Value extras;
-} Technique;
-
-typedef struct {
-  std::string generator;
-  std::string version;
-  std::string profile_api;
-  std::string profile_version;
-  bool premultipliedAlpha;
-  char pad[7];
-  Value extras;
-} Asset;
-
-class Scene {
- public:
-  Scene() {}
-  ~Scene() {}
-
-  std::map<std::string, Accessor> accessors;
-  std::map<std::string, Animation> animations;
-  std::map<std::string, Buffer> buffers;
-  std::map<std::string, BufferView> bufferViews;
-  std::map<std::string, Material> materials;
-  std::map<std::string, Mesh> meshes;
-  std::map<std::string, Node> nodes;
-  std::map<std::string, Texture> textures;
-  std::map<std::string, Image> images;
-  std::map<std::string, Shader> shaders;
-  std::map<std::string, Program> programs;
-  std::map<std::string, Technique> techniques;
-  std::map<std::string, Sampler> samplers;
-  std::map<std::string, std::vector<std::string> > scenes;  // list of nodes
-
-  std::string defaultScene;
-
-  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
-};
-
-class TinyGLTFLoader {
- public:
-  TinyGLTFLoader() : bin_data_(NULL), bin_size_(0), is_binary_(false) {
-    pad[0] = pad[1] = pad[2] = pad[3] = pad[4] = pad[5] = pad[6] = 0;
-  }
-  ~TinyGLTFLoader() {}
-
-  /// Loads glTF ASCII asset from a file.
-  /// Returns false and set error string to `err` if there's an error.
-  bool LoadASCIIFromFile(Scene *scene, std::string *err,
-                         const std::string &filename,
-                         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(Scene *scene, std::string *err, const char *str,
-                           const unsigned int length,
-                           const std::string &base_dir,
-                           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(Scene *scene, 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(Scene *scene, std::string *err,
-                            const unsigned char *bytes,
-                            const unsigned int length,
-                            const std::string &base_dir = "",
-                            unsigned int check_sections = REQUIRE_ALL);
-
- 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(Scene *scene, std::string *err, const char *str,
-                      const unsigned int length, const std::string &base_dir,
-                      unsigned int check_sections);
-
-  const unsigned char *bin_data_;
-  size_t bin_size_;
-  bool is_binary_;
-  char pad[7];
-};
-
-}  // namespace tinygltf
-
-#ifdef TINYGLTF_LOADER_IMPLEMENTATION
-#include <algorithm>
-//#include <cassert>
-#include <fstream>
-#include <sstream>
-
-#ifdef __clang__
-// Disable some warnings for external files.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wfloat-equal"
-#pragma clang diagnostic ignored "-Wexit-time-destructors"
-#pragma clang diagnostic ignored "-Wconversion"
-#pragma clang diagnostic ignored "-Wold-style-cast"
-#pragma clang diagnostic ignored "-Wdouble-promotion"
-#pragma clang diagnostic ignored "-Wglobal-constructors"
-#pragma clang diagnostic ignored "-Wreserved-id-macro"
-#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
-
-#define PICOJSON_USE_INT64
-#include "picojson/picojson.h"
-#include "stb/stb_image.h"
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-#ifdef _WIN32
-#include <Windows.h>
-#else
-#include <wordexp.h>
-#endif
-
-#if defined(__sparcv9)
-// Big endian
-#else
-#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
-#define TINYGLTF_LITTLE_ENDIAN 1
-#endif
-#endif
-
-namespace tinygltf {
-
-static void swap4(unsigned int *val) {
-#ifdef TINYGLTF_LITTLE_ENDIAN
-  (void)val;
-#else
-  unsigned int tmp = *val;
-  unsigned char *dst = reinterpret_cast<unsigned char *>(val);
-  unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
-
-  dst[0] = src[3];
-  dst[1] = src[2];
-  dst[2] = src[1];
-  dst[3] = src[0];
-#endif
-}
-
-static bool FileExists(const std::string &abs_filename) {
-  bool ret;
-#ifdef _WIN32
-  FILE *fp;
-  errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb");
-  if (err != 0) {
-    return false;
-  }
-#else
-  FILE *fp = fopen(abs_filename.c_str(), "rb");
-#endif
-  if (fp) {
-    ret = true;
-    fclose(fp);
-  } else {
-    ret = false;
-  }
-
-  return ret;
-}
-
-static std::string ExpandFilePath(const std::string &filepath) {
-#ifdef _WIN32
-  DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0);
-  char *str = new char[len];
-  ExpandEnvironmentStringsA(filepath.c_str(), str, len);
-
-  std::string s(str);
-
-  delete[] str;
-
-  return s;
-#else
-
-#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR)
-  // no expansion
-  std::string s = filepath;
-#else
-  std::string s;
-  wordexp_t p;
-
-  if (filepath.empty()) {
-    return "";
-  }
-
-  // char** w;
-  int ret = wordexp(filepath.c_str(), &p, 0);
-  if (ret) {
-    // err
-    s = filepath;
-    return s;
-  }
-
-  // Use first element only.
-  if (p.we_wordv) {
-    s = std::string(p.we_wordv[0]);
-    wordfree(&p);
-  } else {
-    s = filepath;
-  }
-
-#endif
-
-  return s;
-#endif
-}
-
-static std::string JoinPath(const std::string &path0,
-                            const std::string &path1) {
-  if (path0.empty()) {
-    return path1;
-  } else {
-    // check '/'
-    char lastChar = *path0.rbegin();
-    if (lastChar != '/') {
-      return path0 + std::string("/") + path1;
-    } else {
-      return path0 + path1;
-    }
-  }
-}
-
-static std::string FindFile(const std::vector<std::string> &paths,
-                            const std::string &filepath) {
-  for (size_t i = 0; i < paths.size(); i++) {
-    std::string absPath = ExpandFilePath(JoinPath(paths[i], filepath));
-    if (FileExists(absPath)) {
-      return absPath;
-    }
-  }
-
-  return std::string();
-}
-
-// std::string GetFilePathExtension(const std::string& FileName)
-//{
-//    if(FileName.find_last_of(".") != std::string::npos)
-//        return FileName.substr(FileName.find_last_of(".")+1);
-//    return "";
-//}
-
-static std::string GetBaseDir(const std::string &filepath) {
-  if (filepath.find_last_of("/\\") != std::string::npos)
-    return filepath.substr(0, filepath.find_last_of("/\\"));
-  return "";
-}
-
-// std::string base64_encode(unsigned char const* , unsigned int len);
-std::string base64_decode(std::string const &s);
-
-/*
-   base64.cpp and base64.h
-
-   Copyright (C) 2004-2008 René Nyffenegger
-
-   This source code is provided 'as-is', without any express or implied
-   warranty. In no event will the author be held liable for any damages
-   arising from the use of this software.
-
-   Permission is granted to anyone to use this software for any purpose,
-   including commercial applications, and to alter it and redistribute it
-   freely, subject to the following restrictions:
-
-   1. The origin of this source code must not be misrepresented; you must not
-      claim that you wrote the original source code. If you use this source code
-      in a product, an acknowledgment in the product documentation would be
-      appreciated but is not required.
-
-   2. Altered source versions must be plainly marked as such, and must not be
-      misrepresented as being the original source code.
-
-   3. This notice may not be removed or altered from any source distribution.
-
-   René Nyffenegger rene.nyffenegger@adp-gmbh.ch
-
-*/
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wexit-time-destructors"
-#pragma clang diagnostic ignored "-Wglobal-constructors"
-#pragma clang diagnostic ignored "-Wsign-conversion"
-#pragma clang diagnostic ignored "-Wconversion"
-#endif
-static const std::string base64_chars =
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "abcdefghijklmnopqrstuvwxyz"
-    "0123456789+/";
-
-static inline bool is_base64(unsigned char c) {
-  return (isalnum(c) || (c == '+') || (c == '/'));
-}
-
-std::string base64_decode(std::string const &encoded_string) {
-  int in_len = static_cast<int>(encoded_string.size());
-  int i = 0;
-  int j = 0;
-  int in_ = 0;
-  unsigned char char_array_4[4], char_array_3[3];
-  std::string ret;
-
-  while (in_len-- && (encoded_string[in_] != '=') &&
-         is_base64(encoded_string[in_])) {
-    char_array_4[i++] = encoded_string[in_];
-    in_++;
-    if (i == 4) {
-      for (i = 0; i < 4; i++)
-        char_array_4[i] =
-            static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
-
-      char_array_3[0] =
-          (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-      char_array_3[1] =
-          ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-      for (i = 0; (i < 3); i++) ret += char_array_3[i];
-      i = 0;
-    }
-  }
-
-  if (i) {
-    for (j = i; j < 4; j++) char_array_4[j] = 0;
-
-    for (j = 0; j < 4; j++)
-      char_array_4[j] =
-          static_cast<unsigned char>(base64_chars.find(char_array_4[j]));
-
-    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
-    char_array_3[1] =
-        ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
-    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
-
-    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
-  }
-
-  return ret;
-}
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
-                             const std::string &filename,
-                             const std::string &basedir, size_t reqBytes,
-                             bool checkSize) {
-  out->clear();
-
-  std::vector<std::string> paths;
-  paths.push_back(basedir);
-  paths.push_back(".");
-
-  std::string filepath = FindFile(paths, filename);
-  if (filepath.empty()) {
-    if (err) {
-      (*err) += "File not found : " + filename + "\n";
-    }
-    return false;
-  }
-
-  std::ifstream f(filepath.c_str(), std::ifstream::binary);
-  if (!f) {
-    if (err) {
-      (*err) += "File open error : " + filepath + "\n";
-    }
-    return false;
-  }
-
-  f.seekg(0, f.end);
-  size_t sz = static_cast<size_t>(f.tellg());
-  std::vector<unsigned char> buf(sz);
-
-  f.seekg(0, f.beg);
-  f.read(reinterpret_cast<char *>(&buf.at(0)),
-         static_cast<std::streamsize>(sz));
-  f.close();
-
-  if (checkSize) {
-    if (reqBytes == sz) {
-      out->swap(buf);
-      return true;
-    } else {
-      std::stringstream ss;
-      ss << "File size mismatch : " << filepath << ", requestedBytes "
-         << reqBytes << ", but got " << sz << std::endl;
-      if (err) {
-        (*err) += ss.str();
-      }
-      return false;
-    }
-  }
-
-  out->swap(buf);
-  return true;
-}
-
-static bool LoadImageData(Image *image, std::string *err, int req_width,
-                          int req_height, const unsigned char *bytes,
-                          int size) {
-  int w, h, comp;
-  unsigned char *data = stbi_load_from_memory(bytes, size, &w, &h, &comp, 0);
-  if (!data) {
-    if (err) {
-      (*err) += "Unknown image format.\n";
-    }
-    return false;
-  }
-
-  if (w < 1 || h < 1) {
-    free(data);
-    if (err) {
-      (*err) += "Unknown image format.\n";
-    }
-    return false;
-  }
-
-  if (req_width > 0) {
-    if (req_width != w) {
-      free(data);
-      if (err) {
-        (*err) += "Image width mismatch.\n";
-      }
-      return false;
-    }
-  }
-
-  if (req_height > 0) {
-    if (req_height != h) {
-      free(data);
-      if (err) {
-        (*err) += "Image height mismatch.\n";
-      }
-      return false;
-    }
-  }
-
-  image->width = w;
-  image->height = h;
-  image->component = comp;
-  image->image.resize(static_cast<size_t>(w * h * comp));
-  std::copy(data, data + w * h * comp, image->image.begin());
-
-  free(data);
-
-  return true;
-}
-
-static bool IsDataURI(const std::string &in) {
-  std::string header = "data:application/octet-stream;base64,";
-  if (in.find(header) == 0) {
-    return true;
-  }
-
-  header = "data:image/png;base64,";
-  if (in.find(header) == 0) {
-    return true;
-  }
-
-  header = "data:image/jpeg;base64,";
-  if (in.find(header) == 0) {
-    return true;
-  }
-
-  header = "data:text/plain;base64,";
-  if (in.find(header) == 0) {
-    return true;
-  }
-
-  return false;
-}
-
-static bool DecodeDataURI(std::vector<unsigned char> *out,
-                          const std::string &in, size_t reqBytes,
-                          bool checkSize) {
-  std::string header = "data:application/octet-stream;base64,";
-  std::string data;
-  if (in.find(header) == 0) {
-    data = base64_decode(in.substr(header.size()));  // cut mime string.
-  }
-
-  if (data.empty()) {
-    header = "data:image/jpeg;base64,";
-    if (in.find(header) == 0) {
-      data = base64_decode(in.substr(header.size()));  // cut mime string.
-    }
-  }
-
-  if (data.empty()) {
-    header = "data:image/png;base64,";
-    if (in.find(header) == 0) {
-      data = base64_decode(in.substr(header.size()));  // cut mime string.
-    }
-  }
-
-  if (data.empty()) {
-    header = "data:text/plain;base64,";
-    if (in.find(header) == 0) {
-      data = base64_decode(in.substr(header.size()));
-    }
-  }
-
-  if (data.empty()) {
-    return false;
-  }
-
-  if (checkSize) {
-    if (data.size() != reqBytes) {
-      return false;
-    }
-    out->resize(reqBytes);
-  } else {
-    out->resize(data.size());
-  }
-  std::copy(data.begin(), data.end(), out->begin());
-  return true;
-}
-
-static void ParseObjectProperty(Value *ret, const picojson::object &o) {
-  tinygltf::Value::Object vo;
-  picojson::object::const_iterator it(o.begin());
-  picojson::object::const_iterator itEnd(o.end());
-
-  for (; it != itEnd; it++) {
-    picojson::value v = it->second;
-
-    if (v.is<bool>()) {
-      vo[it->first] = tinygltf::Value(v.get<bool>());
-    } else if (v.is<double>()) {
-      vo[it->first] = tinygltf::Value(v.get<double>());
-    } else if (v.is<int64_t>()) {
-      vo[it->first] =
-          tinygltf::Value(static_cast<int>(v.get<int64_t>()));  // truncate
-    } else if (v.is<std::string>()) {
-      vo[it->first] = tinygltf::Value(v.get<std::string>());
-    } else if (v.is<picojson::object>()) {
-      tinygltf::Value child_value;
-      ParseObjectProperty(&child_value, v.get<picojson::object>());
-    }
-    // TODO(syoyo) binary, array
-  }
-
-  (*ret) = tinygltf::Value(vo);
-}
-
-static bool ParseExtrasProperty(Value *ret, const picojson::object &o) {
-  picojson::object::const_iterator it = o.find("extras");
-  if (it == o.end()) {
-    return false;
-  }
-
-  // FIXME(syoyo) Currently we only support `object` type for extras property.
-  if (!it->second.is<picojson::object>()) {
-    return false;
-  }
-
-  ParseObjectProperty(ret, it->second.get<picojson::object>());
-
-  return true;
-}
-
-static bool ParseBooleanProperty(bool *ret, std::string *err,
-                                 const picojson::object &o,
-                                 const std::string &property, bool required) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing.\n";
-      }
-    }
-    return false;
-  }
-
-  if (!it->second.is<bool>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not a bool type.\n";
-      }
-    }
-    return false;
-  }
-
-  if (ret) {
-    (*ret) = it->second.get<bool>();
-  }
-
-  return true;
-}
-
-static bool ParseNumberProperty(double *ret, std::string *err,
-                                const picojson::object &o,
-                                const std::string &property, bool required) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing.\n";
-      }
-    }
-    return false;
-  }
-
-  if (!it->second.is<double>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not a number type.\n";
-      }
-    }
-    return false;
-  }
-
-  if (ret) {
-    (*ret) = it->second.get<double>();
-  }
-
-  return true;
-}
-
-static bool ParseNumberArrayProperty(std::vector<double> *ret, std::string *err,
-                                     const picojson::object &o,
-                                     const std::string &property,
-                                     bool required) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing.\n";
-      }
-    }
-    return false;
-  }
-
-  if (!it->second.is<picojson::array>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not an array.\n";
-      }
-    }
-    return false;
-  }
-
-  ret->clear();
-  const picojson::array &arr = it->second.get<picojson::array>();
-  for (size_t i = 0; i < arr.size(); i++) {
-    if (!arr[i].is<double>()) {
-      if (required) {
-        if (err) {
-          (*err) += "'" + property + "' property is not a number.\n";
-        }
-      }
-      return false;
-    }
-    ret->push_back(arr[i].get<double>());
-  }
-
-  return true;
-}
-
-static bool ParseStringProperty(
-    std::string *ret, std::string *err, const picojson::object &o,
-    const std::string &property, bool required,
-    const std::string &parent_node = std::string()) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing";
-        if (parent_node.empty()) {
-          (*err) += ".\n";
-        } else {
-          (*err) += " in `" + parent_node + "'.\n";
-        }
-      }
-    }
-    return false;
-  }
-
-  if (!it->second.is<std::string>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not a string type.\n";
-      }
-    }
-    return false;
-  }
-
-  if (ret) {
-    (*ret) = it->second.get<std::string>();
-  }
-
-  return true;
-}
-
-static bool ParseStringArrayProperty(std::vector<std::string> *ret,
-                                     std::string *err,
-                                     const picojson::object &o,
-                                     const std::string &property,
-                                     bool required) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing.\n";
-      }
-    }
-    return false;
-  }
-
-  if (!it->second.is<picojson::array>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not an array.\n";
-      }
-    }
-    return false;
-  }
-
-  ret->clear();
-  const picojson::array &arr = it->second.get<picojson::array>();
-  for (size_t i = 0; i < arr.size(); i++) {
-    if (!arr[i].is<std::string>()) {
-      if (required) {
-        if (err) {
-          (*err) += "'" + property + "' property is not a string.\n";
-        }
-      }
-      return false;
-    }
-    ret->push_back(arr[i].get<std::string>());
-  }
-
-  return true;
-}
-
-static bool ParseStringMapProperty(std::map<std::string, std::string> *ret,
-                                   std::string *err, const picojson::object &o,
-                                   const std::string &property, bool required) {
-  picojson::object::const_iterator it = o.find(property);
-  if (it == o.end()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is missing.\n";
-      }
-    }
-    return false;
-  }
-
-  // Make sure we are dealing with an object / dictionary.
-  if (!it->second.is<picojson::object>()) {
-    if (required) {
-      if (err) {
-        (*err) += "'" + property + "' property is not an object.\n";
-      }
-    }
-    return false;
-  }
-
-  ret->clear();
-  const picojson::object &dict = it->second.get<picojson::object>();
-
-  picojson::object::const_iterator dictIt(dict.begin());
-  picojson::object::const_iterator dictItEnd(dict.end());
-
-  for (; dictIt != dictItEnd; ++dictIt) {
-    // Check that the value is a string.
-    if (!dictIt->second.is<std::string>()) {
-      if (required) {
-        if (err) {
-          (*err) += "'" + property + "' value is not a string.\n";
-        }
-      }
-      return false;
-    }
-
-    // Insert into the list.
-    (*ret)[dictIt->first] = dictIt->second.get<std::string>();
-  }
-  return true;
-}
-
-static bool ParseKHRBinaryExtension(const picojson::object &o, std::string *err,
-                                    std::string *buffer_view,
-                                    std::string *mime_type, int *image_width,
-                                    int *image_height) {
-  picojson::object j = o;
-
-  if (j.find("extensions") == j.end()) {
-    if (err) {
-      (*err) += "`extensions' property is missing.\n";
-    }
-    return false;
-  }
-
-  if (!(j["extensions"].is<picojson::object>())) {
-    if (err) {
-      (*err) += "Invalid `extensions' property.\n";
-    }
-    return false;
-  }
-
-  picojson::object ext = j["extensions"].get<picojson::object>();
-
-  if (ext.find("KHR_binary_glTF") == ext.end()) {
-    if (err) {
-      (*err) +=
-          "`KHR_binary_glTF' property is missing in extension property.\n";
-    }
-    return false;
-  }
-
-  if (!(ext["KHR_binary_glTF"].is<picojson::object>())) {
-    if (err) {
-      (*err) += "Invalid `KHR_binary_glTF' property.\n";
-    }
-    return false;
-  }
-
-  picojson::object k = ext["KHR_binary_glTF"].get<picojson::object>();
-
-  if (!ParseStringProperty(buffer_view, err, k, "bufferView", true)) {
-    return false;
-  }
-
-  if (mime_type) {
-    ParseStringProperty(mime_type, err, k, "mimeType", false);
-  }
-
-  if (image_width) {
-    double width = 0.0;
-    if (ParseNumberProperty(&width, err, k, "width", false)) {
-      (*image_width) = static_cast<int>(width);
-    }
-  }
-
-  if (image_height) {
-    double height = 0.0;
-    if (ParseNumberProperty(&height, err, k, "height", false)) {
-      (*image_height) = static_cast<int>(height);
-    }
-  }
-
-  return true;
-}
-
-static bool ParseAsset(Asset *asset, std::string *err,
-                       const picojson::object &o) {
-  ParseStringProperty(&asset->generator, err, o, "generator", false);
-  ParseBooleanProperty(&asset->premultipliedAlpha, err, o, "premultipliedAlpha",
-                       false);
-
-  ParseStringProperty(&asset->version, err, o, "version", false);
-
-  picojson::object::const_iterator profile = o.find("profile");
-  if (profile != o.end()) {
-    const picojson::value &v = profile->second;
-    if (v.contains("api") & v.get("api").is<std::string>()) {
-      asset->profile_api = v.get("api").get<std::string>();
-    }
-    if (v.contains("version") & v.get("version").is<std::string>()) {
-      asset->profile_version = v.get("version").get<std::string>();
-    }
-  }
-
-  return true;
-}
-
-static bool ParseImage(Image *image, std::string *err,
-                       const picojson::object &o, const std::string &basedir,
-                       bool is_binary, const unsigned char *bin_data,
-                       size_t bin_size) {
-  std::string uri;
-  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
-    return false;
-  }
-
-  ParseStringProperty(&image->name, err, o, "name", false);
-
-  std::vector<unsigned char> img;
-
-  if (is_binary) {
-    // Still binary glTF accepts external dataURI. First try external resources.
-    bool loaded = false;
-    if (IsDataURI(uri)) {
-      loaded = DecodeDataURI(&img, uri, 0, false);
-    } else {
-      // Assume external .bin file.
-      loaded = LoadExternalFile(&img, err, uri, basedir, 0, false);
-    }
-
-    if (!loaded) {
-      // load data from (embedded) binary data
-
-      if ((bin_size == 0) || (bin_data == NULL)) {
-        if (err) {
-          (*err) += "Invalid binary data.\n";
-        }
-        return false;
-      }
-
-      // There should be "extensions" property.
-      // "extensions":{"KHR_binary_glTF":{"bufferView": "id", ...
-
-      std::string buffer_view;
-      std::string mime_type;
-      int image_width;
-      int image_height;
-      bool ret = ParseKHRBinaryExtension(o, err, &buffer_view, &mime_type,
-                                         &image_width, &image_height);
-      if (!ret) {
-        return false;
-      }
-
-      if (uri.compare("data:,") == 0) {
-        // ok
-      } else {
-        if (err) {
-          (*err) += "Invalid URI for binary data.\n";
-        }
-        return false;
-      }
-
-      // Just only save some information here. Loading actual image data from
-      // bufferView is done in other place.
-      image->bufferView = buffer_view;
-      image->mimeType = mime_type;
-      image->width = image_width;
-      image->height = image_height;
-
-      return true;
-    }
-  } else {
-    if (IsDataURI(uri)) {
-      if (!DecodeDataURI(&img, uri, 0, false)) {
-        if (err) {
-          (*err) += "Failed to decode 'uri' for image parameter.\n";
-        }
-        return false;
-      }
-    } else {
-      // Assume external file
-      if (!LoadExternalFile(&img, err, uri, basedir, 0, false)) {
-        if (err) {
-          (*err) += "Failed to load external 'uri'. for image parameter\n";
-        }
-        return false;
-      }
-      if (img.empty()) {
-        if (err) {
-          (*err) += "Image is empty.\n";
-        }
-        return false;
-      }
-    }
-  }
-
-  return LoadImageData(image, err, 0, 0, &img.at(0),
-                       static_cast<int>(img.size()));
-}
-
-static bool ParseTexture(Texture *texture, std::string *err,
-                         const picojson::object &o,
-                         const std::string &basedir) {
-  (void)basedir;
-
-  if (!ParseStringProperty(&texture->sampler, err, o, "sampler", true)) {
-    return false;
-  }
-
-  if (!ParseStringProperty(&texture->source, err, o, "source", true)) {
-    return false;
-  }
-
-  ParseStringProperty(&texture->name, err, o, "name", false);
-
-  double format = TINYGLTF_TEXTURE_FORMAT_RGBA;
-  ParseNumberProperty(&format, err, o, "format", false);
-
-  double internalFormat = TINYGLTF_TEXTURE_FORMAT_RGBA;
-  ParseNumberProperty(&internalFormat, err, o, "internalFormat", false);
-
-  double target = TINYGLTF_TEXTURE_TARGET_TEXTURE2D;
-  ParseNumberProperty(&target, err, o, "target", false);
-
-  double type = TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE;
-  ParseNumberProperty(&type, err, o, "type", false);
-
-  texture->format = static_cast<int>(format);
-  texture->internalFormat = static_cast<int>(internalFormat);
-  texture->target = static_cast<int>(target);
-  texture->type = static_cast<int>(type);
-
-  return true;
-}
-
-static bool ParseBuffer(Buffer *buffer, std::string *err,
-                        const picojson::object &o, const std::string &basedir,
-                        bool is_binary = false,
-                        const unsigned char *bin_data = NULL,
-                        size_t bin_size = 0) {
-  double byteLength;
-  if (!ParseNumberProperty(&byteLength, err, o, "byteLength", true)) {
-    return false;
-  }
-
-  std::string uri;
-  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
-    return false;
-  }
-
-  picojson::object::const_iterator type = o.find("type");
-  if (type != o.end()) {
-    if (type->second.is<std::string>()) {
-      const std::string &ty = (type->second).get<std::string>();
-      if (ty.compare("arraybuffer") == 0) {
-        // buffer.type = "arraybuffer";
-      }
-    }
-  }
-
-  size_t bytes = static_cast<size_t>(byteLength);
-  if (is_binary) {
-    // Still binary glTF accepts external dataURI. First try external resources.
-    bool loaded = false;
-    if (IsDataURI(uri)) {
-      loaded = DecodeDataURI(&buffer->data, uri, bytes, true);
-    } else {
-      // Assume external .bin file.
-      loaded = LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true);
-    }
-
-    if (!loaded) {
-      // load data from (embedded) binary data
-
-      if ((bin_size == 0) || (bin_data == NULL)) {
-        if (err) {
-          (*err) += "Invalid binary data.\n";
-        }
-        return false;
-      }
-
-      if (byteLength > bin_size) {
-        if (err) {
-          std::stringstream ss;
-          ss << "Invalid `byteLength'. Must be equal or less than binary size: "
-                "`byteLength' = "
-             << byteLength << ", binary size = " << bin_size << std::endl;
-          (*err) += ss.str();
-        }
-        return false;
-      }
-
-      if (uri.compare("data:,") == 0) {
-        // @todo { check uri }
-        buffer->data.resize(static_cast<size_t>(byteLength));
-        memcpy(&(buffer->data.at(0)), bin_data,
-               static_cast<size_t>(byteLength));
-
-      } else {
-        if (err) {
-          (*err) += "Invalid URI for binary data.\n";
-        }
-        return false;
-      }
-    }
-
-  } else {
-    if (IsDataURI(uri)) {
-      if (!DecodeDataURI(&buffer->data, uri, bytes, true)) {
-        if (err) {
-          (*err) += "Failed to decode 'uri'.\n";
-        }
-        return false;
-      }
-    } else {
-      // Assume external .bin file.
-      if (!LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true)) {
-        return false;
-      }
-    }
-  }
-
-  ParseStringProperty(&buffer->name, err, o, "name", false);
-
-  return true;
-}
-
-static bool ParseBufferView(BufferView *bufferView, std::string *err,
-                            const picojson::object &o) {
-  std::string buffer;
-  if (!ParseStringProperty(&buffer, err, o, "buffer", true)) {
-    return false;
-  }
-
-  double byteOffset;
-  if (!ParseNumberProperty(&byteOffset, err, o, "byteOffset", true)) {
-    return false;
-  }
-
-  double byteLength = 0.0;
-  ParseNumberProperty(&byteLength, err, o, "byteLength", false);
-
-  double target = 0.0;
-  ParseNumberProperty(&target, err, o, "target", false);
-  int targetValue = static_cast<int>(target);
-  if ((targetValue == TINYGLTF_TARGET_ARRAY_BUFFER) ||
-      (targetValue == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER)) {
-    // OK
-  } else {
-    targetValue = 0;
-  }
-  bufferView->target = targetValue;
-
-  ParseStringProperty(&bufferView->name, err, o, "name", false);
-
-  bufferView->buffer = buffer;
-  bufferView->byteOffset = static_cast<size_t>(byteOffset);
-  bufferView->byteLength = static_cast<size_t>(byteLength);
-
-  return true;
-}
-
-static bool ParseAccessor(Accessor *accessor, std::string *err,
-                          const picojson::object &o) {
-  std::string bufferView;
-  if (!ParseStringProperty(&bufferView, err, o, "bufferView", true)) {
-    return false;
-  }
-
-  double byteOffset;
-  if (!ParseNumberProperty(&byteOffset, err, o, "byteOffset", true)) {
-    return false;
-  }
-
-  double componentType;
-  if (!ParseNumberProperty(&componentType, err, o, "componentType", true)) {
-    return false;
-  }
-
-  double count = 0.0;
-  if (!ParseNumberProperty(&count, err, o, "count", true)) {
-    return false;
-  }
-
-  std::string type;
-  if (!ParseStringProperty(&type, err, o, "type", true)) {
-    return false;
-  }
-
-  if (type.compare("SCALAR") == 0) {
-    accessor->type = TINYGLTF_TYPE_SCALAR;
-  } else if (type.compare("VEC2") == 0) {
-    accessor->type = TINYGLTF_TYPE_VEC2;
-  } else if (type.compare("VEC3") == 0) {
-    accessor->type = TINYGLTF_TYPE_VEC3;
-  } else if (type.compare("VEC4") == 0) {
-    accessor->type = TINYGLTF_TYPE_VEC4;
-  } else if (type.compare("MAT2") == 0) {
-    accessor->type = TINYGLTF_TYPE_MAT2;
-  } else if (type.compare("MAT3") == 0) {
-    accessor->type = TINYGLTF_TYPE_MAT3;
-  } else if (type.compare("MAT4") == 0) {
-    accessor->type = TINYGLTF_TYPE_MAT4;
-  } else {
-    std::stringstream ss;
-    ss << "Unsupported `type` for accessor object. Got \"" << type << "\"\n";
-    if (err) {
-      (*err) += ss.str();
-    }
-    return false;
-  }
-
-  double byteStride = 0.0;
-  ParseNumberProperty(&byteStride, err, o, "byteStride", false);
-
-  ParseStringProperty(&accessor->name, err, o, "name", false);
-
-  accessor->minValues.clear();
-  accessor->maxValues.clear();
-  ParseNumberArrayProperty(&accessor->minValues, err, o, "min", false);
-  ParseNumberArrayProperty(&accessor->maxValues, err, o, "max", false);
-
-  accessor->count = static_cast<size_t>(count);
-  accessor->bufferView = bufferView;
-  accessor->byteOffset = static_cast<size_t>(byteOffset);
-  accessor->byteStride = static_cast<size_t>(byteStride);
-
-  {
-    int comp = static_cast<int>(componentType);
-    if (comp >= TINYGLTF_COMPONENT_TYPE_BYTE &&
-        comp <= TINYGLTF_COMPONENT_TYPE_DOUBLE) {
-      // OK
-      accessor->componentType = comp;
-    } else {
-      std::stringstream ss;
-      ss << "Invalid `componentType` in accessor. Got " << comp << "\n";
-      if (err) {
-        (*err) += ss.str();
-      }
-      return false;
-    }
-  }
-
-  ParseExtrasProperty(&(accessor->extras), o);
-
-  return true;
-}
-
-static bool ParsePrimitive(Primitive *primitive, std::string *err,
-                           const picojson::object &o) {
-  if (!ParseStringProperty(&primitive->material, err, o, "material", true,
-                           "mesh.primitive")) {
-    return false;
-  }
-
-  double mode = static_cast<double>(TINYGLTF_MODE_TRIANGLES);
-  ParseNumberProperty(&mode, err, o, "mode", false);
-
-  int primMode = static_cast<int>(mode);
-  primitive->mode = primMode;
-
-  primitive->indices = "";
-  ParseStringProperty(&primitive->indices, err, o, "indices", false);
-
-  ParseStringMapProperty(&primitive->attributes, err, o, "attributes", false);
-
-  ParseExtrasProperty(&(primitive->extras), o);
-
-  return true;
-}
-
-static bool ParseMesh(Mesh *mesh, std::string *err, const picojson::object &o) {
-  ParseStringProperty(&mesh->name, err, o, "name", false);
-
-  mesh->primitives.clear();
-  picojson::object::const_iterator primObject = o.find("primitives");
-  if ((primObject != o.end()) && (primObject->second).is<picojson::array>()) {
-    const picojson::array &primArray =
-        (primObject->second).get<picojson::array>();
-    for (size_t i = 0; i < primArray.size(); i++) {
-      Primitive primitive;
-      if (ParsePrimitive(&primitive, err,
-                         primArray[i].get<picojson::object>())) {
-        // Only add the primitive if the parsing succeeds.
-        mesh->primitives.push_back(primitive);
-      }
-    }
-  }
-
-  ParseExtrasProperty(&(mesh->extras), o);
-
-  return true;
-}
-
-static bool ParseNode(Node *node, std::string *err, const picojson::object &o) {
-  ParseStringProperty(&node->name, err, o, "name", false);
-
-  ParseNumberArrayProperty(&node->rotation, err, o, "rotation", false);
-  ParseNumberArrayProperty(&node->scale, err, o, "scale", false);
-  ParseNumberArrayProperty(&node->translation, err, o, "translation", false);
-  ParseNumberArrayProperty(&node->matrix, err, o, "matrix", false);
-  ParseStringArrayProperty(&node->meshes, err, o, "meshes", false);
-
-  node->children.clear();
-  picojson::object::const_iterator childrenObject = o.find("children");
-  if ((childrenObject != o.end()) &&
-      (childrenObject->second).is<picojson::array>()) {
-    const picojson::array &childrenArray =
-        (childrenObject->second).get<picojson::array>();
-    for (size_t i = 0; i < childrenArray.size(); i++) {
-      if (!childrenArray[i].is<std::string>()) {
-        if (err) {
-          (*err) += "Invalid `children` array.\n";
-        }
-        return false;
-      }
-      const std::string &childrenNode = childrenArray[i].get<std::string>();
-      node->children.push_back(childrenNode);
-    }
-  }
-
-  ParseExtrasProperty(&(node->extras), o);
-
-  return true;
-}
-
-static bool ParseParameterProperty(Parameter *param, std::string *err,
-                                   const picojson::object &o,
-                                   const std::string &prop, bool required) {
-  double num_val;
-
-  // A parameter value can either be a string or an array of either a boolean or
-  // a number. Booleans of any kind aren't supported here. Granted, it
-  // complicates the Parameter structure and breaks it semantically in the sense
-  // that the client probably works off the assumption that if the string is
-  // empty the vector is used, etc. Would a tagged union work?
-  if (ParseStringProperty(&param->string_value, err, o, prop, false)) {
-    // Found string property.
-    return true;
-  } else if (ParseNumberArrayProperty(&param->number_array, err, o, prop,
-                                      false)) {
-    // Found a number array.
-    return true;
-  } else if (ParseNumberProperty(&num_val, err, o, prop, false)) {
-    param->number_array.push_back(num_val);
-    return true;
-  } else {
-    if (required) {
-      if (err) {
-        (*err) += "parameter must be a string or number / number array.\n";
-      }
-    }
-    return false;
-  }
-}
-
-static bool ParseMaterial(Material *material, std::string *err,
-                          const picojson::object &o) {
-  ParseStringProperty(&material->name, err, o, "name", false);
-  ParseStringProperty(&material->technique, err, o, "technique", false);
-
-  material->values.clear();
-  picojson::object::const_iterator valuesIt = o.find("values");
-
-  if ((valuesIt != o.end()) && (valuesIt->second).is<picojson::object>()) {
-    const picojson::object &values_object =
-        (valuesIt->second).get<picojson::object>();
-
-    picojson::object::const_iterator it(values_object.begin());
-    picojson::object::const_iterator itEnd(values_object.end());
-
-    for (; it != itEnd; it++) {
-      Parameter param;
-      if (ParseParameterProperty(&param, err, values_object, it->first,
-                                 false)) {
-        material->values[it->first] = param;
-      }
-    }
-  }
-
-  ParseExtrasProperty(&(material->extras), o);
-
-  return true;
-}
-
-static bool ParseShader(Shader *shader, std::string *err,
-                        const picojson::object &o, const std::string &basedir,
-                        bool is_binary = false,
-                        const unsigned char *bin_data = NULL,
-                        size_t bin_size = 0) {
-  std::string uri;
-  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
-    return false;
-  }
-
-  if (is_binary) {
-    // Still binary glTF accepts external dataURI. First try external resources.
-    bool loaded = false;
-    if (IsDataURI(uri)) {
-      loaded = DecodeDataURI(&shader->source, uri, 0, false);
-    } else {
-      // Assume external .bin file.
-      loaded = LoadExternalFile(&shader->source, err, uri, basedir, 0, false);
-    }
-
-    if (!loaded) {
-      // load data from (embedded) binary data
-
-      if ((bin_size == 0) || (bin_data == NULL)) {
-        if (err) {
-          (*err) += "Invalid binary data.\n";
-        }
-        return false;
-      }
-
-      // There should be "extensions" property.
-      // "extensions":{"KHR_binary_glTF":{"bufferView": "id", ...
-
-      std::string buffer_view;
-      std::string mime_type;
-      int image_width;
-      int image_height;
-      bool ret = ParseKHRBinaryExtension(o, err, &buffer_view, &mime_type,
-                                         &image_width, &image_height);
-      if (!ret) {
-        return false;
-      }
-
-      if (uri.compare("data:,") == 0) {
-        // ok
-      } else {
-        if (err) {
-          (*err) += "Invalid URI for binary data.\n";
-        }
-        return false;
-      }
-    }
-  } else {
-    // Load shader source from data uri
-    // TODO(syoyo): Support ascii or utf-8 data uris.
-    if (IsDataURI(uri)) {
-      if (!DecodeDataURI(&shader->source, uri, 0, false)) {
-        if (err) {
-          (*err) += "Failed to decode 'uri' for shader parameter.\n";
-        }
-        return false;
-      }
-    } else {
-      // Assume external file
-      if (!LoadExternalFile(&shader->source, err, uri, basedir, 0, false)) {
-        if (err) {
-          (*err) += "Failed to load external 'uri' for shader parameter.\n";
-        }
-        return false;
-      }
-      if (shader->source.empty()) {
-        if (err) {
-          (*err) += "shader is empty.\n";  // This may be OK?
-        }
-        return false;
-      }
-    }
-  }
-
-  double type;
-  if (!ParseNumberProperty(&type, err, o, "type", true)) {
-    return false;
-  }
-
-  shader->type = static_cast<int>(type);
-
-  ParseExtrasProperty(&(shader->extras), o);
-
-  return true;
-}
-
-static bool ParseProgram(Program *program, std::string *err,
-                         const picojson::object &o) {
-  ParseStringProperty(&program->name, err, o, "name", false);
-
-  if (!ParseStringProperty(&program->vertexShader, err, o, "vertexShader",
-                           true)) {
-    return false;
-  }
-  if (!ParseStringProperty(&program->fragmentShader, err, o, "fragmentShader",
-                           true)) {
-    return false;
-  }
-
-  // I suppose the list of attributes isn't needed, but a technique doesn't
-  // really make sense without it.
-  ParseStringArrayProperty(&program->attributes, err, o, "attributes", false);
-
-  ParseExtrasProperty(&(program->extras), o);
-
-  return true;
-}
-
-static bool ParseTechniqueParameter(TechniqueParameter *param, std::string *err,
-                                    const picojson::object &o) {
-  double count = 1;
-  ParseNumberProperty(&count, err, o, "count", false);
-
-  double type;
-  if (!ParseNumberProperty(&type, err, o, "type", true)) {
-    return false;
-  }
-
-  ParseStringProperty(&param->node, err, o, "node", false);
-  ParseStringProperty(&param->semantic, err, o, "semantic", false);
-
-  ParseParameterProperty(&param->value, err, o, "value", false);
-
-  param->count = static_cast<int>(count);
-  param->type = static_cast<int>(type);
-
-  return true;
-}
-
-static bool ParseTechnique(Technique *technique, std::string *err,
-                           const picojson::object &o) {
-  ParseStringProperty(&technique->name, err, o, "name", false);
-
-  if (!ParseStringProperty(&technique->program, err, o, "program", true)) {
-    return false;
-  }
-
-  ParseStringMapProperty(&technique->attributes, err, o, "attributes", false);
-  ParseStringMapProperty(&technique->uniforms, err, o, "uniforms", false);
-
-  technique->parameters.clear();
-  picojson::object::const_iterator paramsIt = o.find("parameters");
-
-  // Verify parameters is an object
-  if ((paramsIt != o.end()) && (paramsIt->second).is<picojson::object>()) {
-    // For each parameter in params_object.
-    const picojson::object &params_object =
-        (paramsIt->second).get<picojson::object>();
-
-    picojson::object::const_iterator it(params_object.begin());
-    picojson::object::const_iterator itEnd(params_object.end());
-
-    for (; it != itEnd; it++) {
-      TechniqueParameter param;
-
-      // Skip non-objects
-      if (!it->second.is<picojson::object>()) continue;
-
-      // Parse the technique parameter
-      const picojson::object &param_obj = it->second.get<picojson::object>();
-      if (ParseTechniqueParameter(&param, err, param_obj)) {
-        // Add if successful
-        technique->parameters[it->first] = param;
-      }
-    }
-  }
-
-  ParseExtrasProperty(&(technique->extras), o);
-
-  return true;
-}
-
-static bool ParseAnimationChannel(AnimationChannel *channel, std::string *err,
-                                  const picojson::object &o) {
-  if (!ParseStringProperty(&channel->sampler, err, o, "sampler", true)) {
-    if (err) {
-      (*err) += "`sampler` field is missing in animation channels\n";
-    }
-    return false;
-  }
-
-  picojson::object::const_iterator targetIt = o.find("target");
-  if ((targetIt != o.end()) && (targetIt->second).is<picojson::object>()) {
-    const picojson::object &target_object =
-        (targetIt->second).get<picojson::object>();
-
-    if (!ParseStringProperty(&channel->target_id, err, target_object, "id",
-                             true)) {
-      if (err) {
-        (*err) += "`id` field is missing in animation.channels.target\n";
-      }
-      return false;
-    }
-
-    if (!ParseStringProperty(&channel->target_path, err, target_object, "path",
-                             true)) {
-      if (err) {
-        (*err) += "`path` field is missing in animation.channels.target\n";
-      }
-      return false;
-    }
-  }
-
-  ParseExtrasProperty(&(channel->extras), o);
-
-  return true;
-}
-
-static bool ParseAnimation(Animation *animation, std::string *err,
-                           const picojson::object &o) {
-  {
-    picojson::object::const_iterator channelsIt = o.find("channels");
-    if ((channelsIt != o.end()) && (channelsIt->second).is<picojson::array>()) {
-      const picojson::array &channelArray =
-          (channelsIt->second).get<picojson::array>();
-      for (size_t i = 0; i < channelArray.size(); i++) {
-        AnimationChannel channel;
-        if (ParseAnimationChannel(&channel, err,
-                                  channelArray[i].get<picojson::object>())) {
-          // Only add the channel if the parsing succeeds.
-          animation->channels.push_back(channel);
-        }
-      }
-    }
-  }
-
-  {
-    picojson::object::const_iterator samplerIt = o.find("samplers");
-    if ((samplerIt != o.end()) && (samplerIt->second).is<picojson::object>()) {
-      const picojson::object &sampler_object =
-          (samplerIt->second).get<picojson::object>();
-
-      picojson::object::const_iterator it = sampler_object.begin();
-      picojson::object::const_iterator itEnd = sampler_object.end();
-
-      for (; it != itEnd; it++) {
-        // Skip non-objects
-        if (!it->second.is<picojson::object>()) continue;
-
-        const picojson::object &s = it->second.get<picojson::object>();
-
-        AnimationSampler sampler;
-        if (!ParseStringProperty(&sampler.input, err, s, "input", true)) {
-          if (err) {
-            (*err) += "`input` field is missing in animation.sampler\n";
-          }
-          return false;
-        }
-        if (!ParseStringProperty(&sampler.interpolation, err, s,
-                                 "interpolation", true)) {
-          if (err) {
-            (*err) += "`interpolation` field is missing in animation.sampler\n";
-          }
-          return false;
-        }
-        if (!ParseStringProperty(&sampler.output, err, s, "output", true)) {
-          if (err) {
-            (*err) += "`output` field is missing in animation.sampler\n";
-          }
-          return false;
-        }
-
-        animation->samplers[it->first] = sampler;
-      }
-    }
-  }
-
-  picojson::object::const_iterator parametersIt = o.find("parameters");
-  if ((parametersIt != o.end()) &&
-      (parametersIt->second).is<picojson::object>()) {
-    const picojson::object &parameters_object =
-        (parametersIt->second).get<picojson::object>();
-
-    picojson::object::const_iterator it(parameters_object.begin());
-    picojson::object::const_iterator itEnd(parameters_object.end());
-
-    for (; it != itEnd; it++) {
-      Parameter param;
-      if (ParseParameterProperty(&param, err, parameters_object, it->first,
-                                 false)) {
-        animation->parameters[it->first] = param;
-      }
-    }
-  }
-  ParseStringProperty(&animation->name, err, o, "name", false);
-
-  ParseExtrasProperty(&(animation->extras), o);
-
-  return true;
-}
-
-static bool ParseSampler(Sampler *sampler, std::string *err,
-                         const picojson::object &o) {
-  ParseStringProperty(&sampler->name, err, o, "name", false);
-
-  double minFilter =
-      static_cast<double>(TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR);
-  double magFilter = static_cast<double>(TINYGLTF_TEXTURE_FILTER_LINEAR);
-  double wrapS = static_cast<double>(TINYGLTF_TEXTURE_WRAP_RPEAT);
-  double wrapT = static_cast<double>(TINYGLTF_TEXTURE_WRAP_RPEAT);
-  ParseNumberProperty(&minFilter, err, o, "minFilter", false);
-  ParseNumberProperty(&magFilter, err, o, "magFilter", false);
-  ParseNumberProperty(&wrapS, err, o, "wrapS", false);
-  ParseNumberProperty(&wrapT, err, o, "wrapT", false);
-
-  sampler->minFilter = static_cast<int>(minFilter);
-  sampler->magFilter = static_cast<int>(magFilter);
-  sampler->wrapS = static_cast<int>(wrapS);
-  sampler->wrapT = static_cast<int>(wrapT);
-
-  ParseExtrasProperty(&(sampler->extras), o);
-
-  return true;
-}
-
-bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err,
-                                    const char *str, unsigned int length,
-                                    const std::string &base_dir,
-                                    unsigned int check_sections) {
-  picojson::value v;
-  std::string perr = picojson::parse(v, str, str + length);
-
-  if (!perr.empty()) {
-    if (err) {
-      (*err) = perr;
-    }
-    return false;
-  }
-
-  if (v.contains("scene") && v.get("scene").is<std::string>()) {
-    // OK
-  } else if (check_sections & REQUIRE_SCENE) {
-    if (err) {
-      (*err) += "\"scene\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  if (v.contains("scenes") && v.get("scenes").is<picojson::object>()) {
-    // OK
-  } else if (check_sections & REQUIRE_SCENES) {
-    if (err) {
-      (*err) += "\"scenes\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  if (v.contains("nodes") && v.get("nodes").is<picojson::object>()) {
-    // OK
-  } else if (check_sections & REQUIRE_NODES) {
-    if (err) {
-      (*err) += "\"nodes\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  if (v.contains("accessors") && v.get("accessors").is<picojson::object>()) {
-    // OK
-  } else if (check_sections & REQUIRE_ACCESSORS) {
-    if (err) {
-      (*err) += "\"accessors\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  if (v.contains("buffers") && v.get("buffers").is<picojson::object>()) {
-    // OK
-  } else if (check_sections & REQUIRE_BUFFERS) {
-    if (err) {
-      (*err) += "\"buffers\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  if (v.contains("bufferViews") &&
-      v.get("bufferViews").is<picojson::object>()) {
-    // OK
-  } else if (check_sections & REQUIRE_BUFFER_VIEWS) {
-    if (err) {
-      (*err) += "\"bufferViews\" object not found in .gltf\n";
-    }
-    return false;
-  }
-
-  scene->buffers.clear();
-  scene->bufferViews.clear();
-  scene->accessors.clear();
-  scene->meshes.clear();
-  scene->nodes.clear();
-  scene->defaultScene = "";
-
-  // 0. Parse Asset
-  if (v.contains("asset") && v.get("asset").is<picojson::object>()) {
-    const picojson::object &root = v.get("asset").get<picojson::object>();
-
-    ParseAsset(&scene->asset, err, root);
-  }
-
-  // 1. Parse Buffer
-  if (v.contains("buffers") && v.get("buffers").is<picojson::object>()) {
-    const picojson::object &root = v.get("buffers").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Buffer buffer;
-      if (!ParseBuffer(&buffer, err, (it->second).get<picojson::object>(),
-                       base_dir, is_binary_, bin_data_, bin_size_)) {
-        return false;
-      }
-
-      scene->buffers[it->first] = buffer;
-    }
-  }
-
-  // 2. Parse BufferView
-  if (v.contains("bufferViews") &&
-      v.get("bufferViews").is<picojson::object>()) {
-    const picojson::object &root = v.get("bufferViews").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      BufferView bufferView;
-      if (!ParseBufferView(&bufferView, err,
-                           (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->bufferViews[it->first] = bufferView;
-    }
-  }
-
-  // 3. Parse Accessor
-  if (v.contains("accessors") && v.get("accessors").is<picojson::object>()) {
-    const picojson::object &root = v.get("accessors").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Accessor accessor;
-      if (!ParseAccessor(&accessor, err,
-                         (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->accessors[it->first] = accessor;
-    }
-  }
-
-  // 4. Parse Mesh
-  if (v.contains("meshes") && v.get("meshes").is<picojson::object>()) {
-    const picojson::object &root = v.get("meshes").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Mesh mesh;
-      if (!ParseMesh(&mesh, err, (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->meshes[it->first] = mesh;
-    }
-  }
-
-  // 5. Parse Node
-  if (v.contains("nodes") && v.get("nodes").is<picojson::object>()) {
-    const picojson::object &root = v.get("nodes").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Node node;
-      if (!ParseNode(&node, err, (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->nodes[it->first] = node;
-    }
-  }
-
-  // 6. Parse scenes.
-  if (v.contains("scenes") && v.get("scenes").is<picojson::object>()) {
-    const picojson::object &root = v.get("scenes").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      if (!((it->second).is<picojson::object>())) {
-        if (err) {
-          (*err) += "`scenes' does not contain an object.";
-        }
-        return false;
-      }
-      const picojson::object &o = (it->second).get<picojson::object>();
-      std::vector<std::string> nodes;
-      if (!ParseStringArrayProperty(&nodes, err, o, "nodes", false)) {
-        return false;
-      }
-
-      scene->scenes[it->first] = nodes;
-    }
-  }
-
-  // 7. Parse default scenes.
-  if (v.contains("scene") && v.get("scene").is<std::string>()) {
-    const std::string defaultScene = v.get("scene").get<std::string>();
-
-    scene->defaultScene = defaultScene;
-  }
-
-  // 8. Parse Material
-  if (v.contains("materials") && v.get("materials").is<picojson::object>()) {
-    const picojson::object &root = v.get("materials").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Material material;
-      if (!ParseMaterial(&material, err,
-                         (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->materials[it->first] = material;
-    }
-  }
-
-  // 9. Parse Image
-  if (v.contains("images") && v.get("images").is<picojson::object>()) {
-    const picojson::object &root = v.get("images").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Image image;
-      if (!ParseImage(&image, err, (it->second).get<picojson::object>(),
-                      base_dir, is_binary_, bin_data_, bin_size_)) {
-        return false;
-      }
-
-      if (!image.bufferView.empty()) {
-        // Load image from the buffer view.
-        if (scene->bufferViews.find(image.bufferView) ==
-            scene->bufferViews.end()) {
-          if (err) {
-            std::stringstream ss;
-            ss << "bufferView \"" << image.bufferView
-               << "\" not found in the scene." << std::endl;
-            (*err) += ss.str();
-          }
-          return false;
-        }
-
-        const BufferView &bufferView = scene->bufferViews[image.bufferView];
-        const Buffer &buffer = scene->buffers[bufferView.buffer];
-
-        bool ret = LoadImageData(&image, err, image.width, image.height,
-                                 &buffer.data[bufferView.byteOffset],
-                                 static_cast<int>(bufferView.byteLength));
-        if (!ret) {
-          return false;
-        }
-      }
-
-      scene->images[it->first] = image;
-    }
-  }
-
-  // 10. Parse Texture
-  if (v.contains("textures") && v.get("textures").is<picojson::object>()) {
-    const picojson::object &root = v.get("textures").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; it++) {
-      Texture texture;
-      if (!ParseTexture(&texture, err, (it->second).get<picojson::object>(),
-                        base_dir)) {
-        return false;
-      }
-
-      scene->textures[it->first] = texture;
-    }
-  }
-
-  // 11. Parse Shader
-  if (v.contains("shaders") && v.get("shaders").is<picojson::object>()) {
-    const picojson::object &root = v.get("shaders").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; ++it) {
-      Shader shader;
-      if (!ParseShader(&shader, err, (it->second).get<picojson::object>(),
-                       base_dir, is_binary_, bin_data_, bin_size_)) {
-        return false;
-      }
-
-      scene->shaders[it->first] = shader;
-    }
-  }
-
-  // 12. Parse Program
-  if (v.contains("programs") && v.get("programs").is<picojson::object>()) {
-    const picojson::object &root = v.get("programs").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; ++it) {
-      Program program;
-      if (!ParseProgram(&program, err, (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->programs[it->first] = program;
-    }
-  }
-
-  // 13. Parse Technique
-  if (v.contains("techniques") && v.get("techniques").is<picojson::object>()) {
-    const picojson::object &root = v.get("techniques").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; ++it) {
-      Technique technique;
-      if (!ParseTechnique(&technique, err,
-                          (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->techniques[it->first] = technique;
-    }
-  }
-
-  // 14. Parse Animation
-  if (v.contains("animations") && v.get("animations").is<picojson::object>()) {
-    const picojson::object &root = v.get("animations").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; ++it) {
-      Animation animation;
-      if (!ParseAnimation(&animation, err,
-                          (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->animations[it->first] = animation;
-    }
-  }
-
-  // 15. Parse Sampler
-  if (v.contains("samplers") && v.get("samplers").is<picojson::object>()) {
-    const picojson::object &root = v.get("samplers").get<picojson::object>();
-
-    picojson::object::const_iterator it(root.begin());
-    picojson::object::const_iterator itEnd(root.end());
-    for (; it != itEnd; ++it) {
-      Sampler sampler;
-      if (!ParseSampler(&sampler, err, (it->second).get<picojson::object>())) {
-        return false;
-      }
-
-      scene->samplers[it->first] = sampler;
-    }
-  }
-  return true;
-}
-
-bool TinyGLTFLoader::LoadASCIIFromString(Scene *scene, std::string *err,
-                                         const char *str, unsigned int length,
-                                         const std::string &base_dir,
-                                         unsigned int check_sections) {
-  is_binary_ = false;
-  bin_data_ = NULL;
-  bin_size_ = 0;
-
-  return LoadFromString(scene, err, str, length, base_dir, check_sections);
-}
-
-bool TinyGLTFLoader::LoadASCIIFromFile(Scene *scene, std::string *err,
-                                       const std::string &filename,
-                                       unsigned int check_sections) {
-  std::stringstream ss;
-
-  std::ifstream f(filename.c_str());
-  if (!f) {
-    ss << "Failed to open file: " << filename << std::endl;
-    if (err) {
-      (*err) = ss.str();
-    }
-    return false;
-  }
-
-  f.seekg(0, f.end);
-  size_t sz = static_cast<size_t>(f.tellg());
-  std::vector<char> buf(sz);
-
-  if (sz == 0) {
-    if (err) {
-      (*err) = "Empty file.";
-    }
-    return false;
-  }
-
-  f.seekg(0, f.beg);
-  f.read(&buf.at(0), static_cast<std::streamsize>(sz));
-  f.close();
-
-  std::string basedir = GetBaseDir(filename);
-
-  bool ret = LoadASCIIFromString(scene, err, &buf.at(0),
-                                 static_cast<unsigned int>(buf.size()), basedir,
-                                 check_sections);
-
-  return ret;
-}
-
-bool TinyGLTFLoader::LoadBinaryFromMemory(Scene *scene, std::string *err,
-                                          const unsigned char *bytes,
-                                          unsigned int size,
-                                          const std::string &base_dir,
-                                          unsigned int check_sections) {
-  if (size < 20) {
-    if (err) {
-      (*err) = "Too short data size for glTF Binary.";
-    }
-    return false;
-  }
-
-  if (bytes[0] == 'g' && bytes[1] == 'l' && bytes[2] == 'T' &&
-      bytes[3] == 'F') {
-    // ok
-  } else {
-    if (err) {
-      (*err) = "Invalid magic.";
-    }
-    return false;
-  }
-
-  unsigned int version;       // 4 bytes
-  unsigned int length;        // 4 bytes
-  unsigned int scene_length;  // 4 bytes
-  unsigned int scene_format;  // 4 bytes;
-
-  // @todo { Endian swap for big endian machine. }
-  memcpy(&version, bytes + 4, 4);
-  swap4(&version);
-  memcpy(&length, bytes + 8, 4);
-  swap4(&length);
-  memcpy(&scene_length, bytes + 12, 4);
-  swap4(&scene_length);
-  memcpy(&scene_format, bytes + 16, 4);
-  swap4(&scene_format);
-
-  if ((20 + scene_length >= size) || (scene_length < 1) ||
-      (scene_format != 0)) {  // 0 = JSON format.
-    if (err) {
-      (*err) = "Invalid glTF binary.";
-    }
-    return false;
-  }
-
-  // Extract JSON string.
-  std::string jsonString(reinterpret_cast<const char *>(&bytes[20]),
-                         scene_length);
-
-  is_binary_ = true;
-  bin_data_ = bytes + 20 + scene_length;
-  bin_size_ =
-      length - (20 + scene_length);  // extract header + JSON scene data.
-
-  bool ret =
-      LoadFromString(scene, err, reinterpret_cast<const char *>(&bytes[20]),
-                     scene_length, base_dir, check_sections);
-  if (!ret) {
-    return ret;
-  }
-
-  return true;
-}
-
-bool TinyGLTFLoader::LoadBinaryFromFile(Scene *scene, std::string *err,
-                                        const std::string &filename,
-                                        unsigned int check_sections) {
-  std::stringstream ss;
-
-  std::ifstream f(filename.c_str(), std::ios::binary);
-  if (!f) {
-    ss << "Failed to open file: " << filename << std::endl;
-    if (err) {
-      (*err) = ss.str();
-    }
-    return false;
-  }
-
-  f.seekg(0, f.end);
-  size_t sz = static_cast<size_t>(f.tellg());
-  std::vector<char> buf(sz);
-
-  f.seekg(0, f.beg);
-  f.read(&buf.at(0), static_cast<std::streamsize>(sz));
-  f.close();
-
-  std::string basedir = GetBaseDir(filename);
-
-  bool ret = LoadBinaryFromMemory(
-      scene, err, reinterpret_cast<unsigned char *>(&buf.at(0)),
-      static_cast<unsigned int>(buf.size()), basedir, check_sections);
-
-  return ret;
-}
-
-}  // namespace tinygltf
-
-#endif  // TINYGLTF_LOADER_IMPLEMENTATION
-
-#endif  // TINY_GLTF_LOADER_H_
