mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-06-23 08:48:20 +08:00
Initial support of animation
.
This commit is contained in:
parent
330f6da818
commit
8c5ab0344f
@ -34,7 +34,7 @@
|
||||
## TODOs
|
||||
|
||||
* [ ] Support multiple scenes in `.gltf`
|
||||
* [ ] Parse `animation`, `sampler`
|
||||
* [ ] Parse `sampler`
|
||||
* [ ] Compression/decompression(Open3DGC, etc)
|
||||
* [ ] Support `extensions` and `extras` property
|
||||
* [ ] HDR image?
|
||||
|
@ -2,8 +2,8 @@
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "tiny_gltf_loader.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
static std::string GetFilePathExtension(const std::string &FileName) {
|
||||
@ -179,7 +179,7 @@ static std::string Indent(int indent) {
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string PrintParameterValue(const tinygltf::Parameter& param) {
|
||||
static std::string PrintParameterValue(const tinygltf::Parameter ¶m) {
|
||||
if (!param.number_array.empty()) {
|
||||
return PrintFloatArray(param.number_array);
|
||||
} else {
|
||||
@ -222,16 +222,14 @@ static void DumpStringMap(const std::map<std::string, std::string> &map,
|
||||
std::map<std::string, std::string>::const_iterator it(map.begin());
|
||||
std::map<std::string, std::string>::const_iterator itEnd(map.end());
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(indent) << it->first << ": " << it->second
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << it->first << ": " << it->second << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
|
||||
std::cout << Indent(indent) << "material : " << primitive.material
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "indices : " << primitive.indices
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "indices : " << primitive.indices << std::endl;
|
||||
std::cout << Indent(indent) << "mode : " << PrintMode(primitive.mode)
|
||||
<< "(" << primitive.mode << ")" << std::endl;
|
||||
std::cout << Indent(indent)
|
||||
@ -242,16 +240,13 @@ static void DumpPrimitive(const tinygltf::Primitive &primitive, int indent) {
|
||||
|
||||
static void DumpTechniqueParameter(const tinygltf::TechniqueParameter ¶m,
|
||||
int indent) {
|
||||
std::cout << Indent(indent) << "count : " << param.count
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "node : " << param.node
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "semantic : " << param.semantic
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "count : " << param.count << std::endl;
|
||||
std::cout << Indent(indent) << "node : " << param.node << std::endl;
|
||||
std::cout << Indent(indent) << "semantic : " << param.semantic << std::endl;
|
||||
std::cout << Indent(indent) << "type : " << PrintParameterType(param.type)
|
||||
<< std::endl;
|
||||
std::cout << Indent(indent) << "value : "
|
||||
<< PrintParameterValue(param.value) << std::endl;
|
||||
std::cout << Indent(indent)
|
||||
<< "value : " << PrintParameterValue(param.value) << std::endl;
|
||||
}
|
||||
|
||||
static void Dump(const tinygltf::Scene &scene) {
|
||||
@ -288,8 +283,10 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Mesh>::const_iterator it(scene.meshes.begin());
|
||||
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(scene.meshes.end());
|
||||
std::map<std::string, tinygltf::Mesh>::const_iterator it(
|
||||
scene.meshes.begin());
|
||||
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(
|
||||
scene.meshes.end());
|
||||
std::cout << "meshes(item=" << scene.meshes.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->second.name << std::endl;
|
||||
@ -304,10 +301,11 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Accessor>::const_iterator it(scene.accessors.begin());
|
||||
std::map<std::string, tinygltf::Accessor>::const_iterator it(
|
||||
scene.accessors.begin());
|
||||
std::map<std::string, tinygltf::Accessor>::const_iterator itEnd(
|
||||
scene.accessors.end());
|
||||
std::cout << "accessos(items=" << scene.accessors.size() << ")"
|
||||
std::cout << "accessors(items=" << scene.accessors.size() << ")"
|
||||
<< std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
@ -343,6 +341,64 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Animation>::const_iterator it(
|
||||
scene.animations.begin());
|
||||
std::map<std::string, tinygltf::Animation>::const_iterator itEnd(
|
||||
scene.animations.end());
|
||||
std::cout << "animations(items=" << scene.animations.size() << ")"
|
||||
<< std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
|
||||
std::cout << Indent(1) << "channels : [ " << std::endl;
|
||||
for (size_t i = 0; i < it->second.channels.size(); i++) {
|
||||
std::cout << Indent(2)
|
||||
<< "sampler : " << it->second.channels[i].sampler
|
||||
<< std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "target.id : " << it->second.channels[i].target_id
|
||||
<< std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "target.path : " << it->second.channels[i].target_path
|
||||
<< std::endl;
|
||||
std::cout << ((i != (it->second.channels.size() - 1)) ? " , " : "");
|
||||
}
|
||||
std::cout << " ]" << std::endl;
|
||||
|
||||
std::map<std::string, tinygltf::AnimationSampler>::const_iterator
|
||||
samplerIt(it->second.samplers.begin());
|
||||
std::map<std::string, tinygltf::AnimationSampler>::const_iterator
|
||||
samplerItEnd(it->second.samplers.end());
|
||||
std::cout << Indent(1) << "samplers(items=" << it->second.samplers.size()
|
||||
<< ")" << std::endl;
|
||||
for (; samplerIt != samplerItEnd; samplerIt++) {
|
||||
std::cout << Indent(1) << "name : " << samplerIt->first
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "input : " << samplerIt->second.input
|
||||
<< std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "interpolation : " << samplerIt->second.interpolation
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "output : " << samplerIt->second.output
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << Indent(1)
|
||||
<< "parameters(items=" << it->second.parameters.size() << ")"
|
||||
<< std::endl;
|
||||
tinygltf::ParameterMap::const_iterator p(it->second.parameters.begin());
|
||||
tinygltf::ParameterMap::const_iterator pEnd(
|
||||
it->second.parameters.end());
|
||||
for (; p != pEnd; p++) {
|
||||
std::cout << Indent(2) << p->first << ": "
|
||||
<< PrintParameterValue(p->second) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::BufferView>::const_iterator it(
|
||||
scene.bufferViews.begin());
|
||||
@ -358,14 +414,17 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "target : " << PrintTarget(it->second.target)
|
||||
std::cout << Indent(2)
|
||||
<< "target : " << PrintTarget(it->second.target)
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Buffer>::const_iterator it(scene.buffers.begin());
|
||||
std::map<std::string, tinygltf::Buffer>::const_iterator itEnd(scene.buffers.end());
|
||||
std::map<std::string, tinygltf::Buffer>::const_iterator it(
|
||||
scene.buffers.begin());
|
||||
std::map<std::string, tinygltf::Buffer>::const_iterator itEnd(
|
||||
scene.buffers.end());
|
||||
std::cout << "buffers(items=" << scene.buffers.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
@ -375,7 +434,8 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Material>::const_iterator it(scene.materials.begin());
|
||||
std::map<std::string, tinygltf::Material>::const_iterator it(
|
||||
scene.materials.begin());
|
||||
std::map<std::string, tinygltf::Material>::const_iterator itEnd(
|
||||
scene.materials.end());
|
||||
std::cout << "materials(items=" << scene.materials.size() << ")"
|
||||
@ -397,8 +457,10 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Node>::const_iterator it(scene.nodes.begin());
|
||||
std::map<std::string, tinygltf::Node>::const_iterator itEnd(scene.nodes.end());
|
||||
std::map<std::string, tinygltf::Node>::const_iterator it(
|
||||
scene.nodes.begin());
|
||||
std::map<std::string, tinygltf::Node>::const_iterator itEnd(
|
||||
scene.nodes.end());
|
||||
std::cout << "nodes(items=" << scene.nodes.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
@ -408,8 +470,10 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Image>::const_iterator it(scene.images.begin());
|
||||
std::map<std::string, tinygltf::Image>::const_iterator itEnd(scene.images.end());
|
||||
std::map<std::string, tinygltf::Image>::const_iterator it(
|
||||
scene.images.begin());
|
||||
std::map<std::string, tinygltf::Image>::const_iterator itEnd(
|
||||
scene.images.end());
|
||||
std::cout << "images(items=" << scene.images.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
@ -424,8 +488,10 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Texture>::const_iterator it(scene.textures.begin());
|
||||
std::map<std::string, tinygltf::Texture>::const_iterator itEnd(scene.textures.end());
|
||||
std::map<std::string, tinygltf::Texture>::const_iterator it(
|
||||
scene.textures.begin());
|
||||
std::map<std::string, tinygltf::Texture>::const_iterator itEnd(
|
||||
scene.textures.end());
|
||||
std::cout << "textures(items=" << scene.textures.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name : " << it->first << std::endl;
|
||||
@ -446,15 +512,16 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Shader>::const_iterator it(
|
||||
scene.shaders.begin());
|
||||
scene.shaders.begin());
|
||||
std::map<std::string, tinygltf::Shader>::const_iterator itEnd(
|
||||
scene.shaders.end());
|
||||
scene.shaders.end());
|
||||
|
||||
std::cout << "shaders(items=" << scene.shaders.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
std::cout << Indent(1) << "name (id) : " << it->first << std::endl;
|
||||
std::cout << Indent(2) << "type : "
|
||||
<< PrintShaderType(it->second.type) << std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "type : " << PrintShaderType(it->second.type)
|
||||
<< std::endl;
|
||||
|
||||
std::cout << Indent(2) << "name (json) : " << it->second.name
|
||||
<< std::endl;
|
||||
@ -464,9 +531,9 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
shader_source.resize(shader_source.size() + it->second.source.size());
|
||||
|
||||
std::vector<unsigned char>::const_iterator sourceIt(
|
||||
it->second.source.begin());
|
||||
it->second.source.begin());
|
||||
std::vector<unsigned char>::const_iterator sourceItEnd(
|
||||
it->second.source.end());
|
||||
it->second.source.end());
|
||||
|
||||
for (; sourceIt != sourceItEnd; ++sourceIt) {
|
||||
shader_source += *sourceIt;
|
||||
@ -474,16 +541,16 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
shader_source += Indent(3);
|
||||
}
|
||||
}
|
||||
std::cout << Indent(2) << "source :\n" << shader_source
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "source :\n"
|
||||
<< shader_source << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Program>::const_iterator it(
|
||||
scene.programs.begin());
|
||||
scene.programs.begin());
|
||||
std::map<std::string, tinygltf::Program>::const_iterator itEnd(
|
||||
scene.programs.end());
|
||||
scene.programs.end());
|
||||
|
||||
std::cout << "programs(items=" << scene.programs.size() << ")" << std::endl;
|
||||
for (; it != itEnd; it++) {
|
||||
@ -501,9 +568,9 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
|
||||
{
|
||||
std::map<std::string, tinygltf::Technique>::const_iterator it(
|
||||
scene.techniques.begin());
|
||||
scene.techniques.begin());
|
||||
std::map<std::string, tinygltf::Technique>::const_iterator itEnd(
|
||||
scene.techniques.end());
|
||||
scene.techniques.end());
|
||||
|
||||
std::cout << "techniques(items=" << scene.techniques.size() << ")"
|
||||
<< std::endl;
|
||||
@ -516,15 +583,16 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
std::cout << Indent(2) << "name (json) : " << it->second.name
|
||||
<< std::endl;
|
||||
|
||||
std::cout << Indent(2) << "parameters(items="
|
||||
<< it->second.parameters.size() << ")" << std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "parameters(items=" << it->second.parameters.size() << ")"
|
||||
<< std::endl;
|
||||
|
||||
std::map<std::string, tinygltf::TechniqueParameter>::const_iterator
|
||||
paramIt(it->second.parameters.begin());
|
||||
paramIt(it->second.parameters.begin());
|
||||
std::map<std::string, tinygltf::TechniqueParameter>::const_iterator
|
||||
paramItEnd(it->second.parameters.end());
|
||||
paramItEnd(it->second.parameters.end());
|
||||
|
||||
for(; paramIt != paramItEnd; ++paramIt) {
|
||||
for (; paramIt != paramItEnd; ++paramIt) {
|
||||
std::cout << Indent(3) << "name : " << paramIt->first << std::endl;
|
||||
DumpTechniqueParameter(paramIt->second, 4);
|
||||
}
|
||||
@ -535,13 +603,11 @@ static void Dump(const tinygltf::Scene &scene) {
|
||||
|
||||
DumpStringMap(it->second.attributes, 3);
|
||||
|
||||
std::cout << Indent(2)
|
||||
<< "uniforms(items=" << it->second.uniforms.size() << ")"
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "uniforms(items=" << it->second.uniforms.size()
|
||||
<< ")" << std::endl;
|
||||
DumpStringMap(it->second.uniforms, 3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -31,7 +31,8 @@
|
||||
//
|
||||
//
|
||||
// Version:
|
||||
// - v0.9.4 Support parsing `shader`, `program` and `tecnique` thanks to @lukesanantonio
|
||||
// - 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
|
||||
@ -130,6 +131,25 @@ typedef struct {
|
||||
|
||||
typedef std::map<std::string, Parameter> ParameterMap;
|
||||
|
||||
typedef struct {
|
||||
std::string sampler;
|
||||
std::string target_id;
|
||||
std::string target_path;
|
||||
} AnimationChannel;
|
||||
|
||||
typedef struct {
|
||||
std::string input;
|
||||
std::string interpolation;
|
||||
std::string output;
|
||||
} AnimationSampler;
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
std::vector<AnimationChannel> channels;
|
||||
std::map<std::string, AnimationSampler> samplers;
|
||||
ParameterMap parameters;
|
||||
} Animation;
|
||||
|
||||
typedef struct {
|
||||
std::string name;
|
||||
int width;
|
||||
@ -278,6 +298,7 @@ class 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;
|
||||
@ -1249,8 +1270,8 @@ static bool ParseBuffer(Buffer *buffer, std::string *err,
|
||||
if (err) {
|
||||
std::stringstream ss;
|
||||
ss << "Invalid `byteLength'. Must be equal or less than binary size: "
|
||||
"`byteLength' = " << byteLength
|
||||
<< ", binary size = " << bin_size << std::endl;
|
||||
"`byteLength' = "
|
||||
<< byteLength << ", binary size = " << bin_size << std::endl;
|
||||
(*err) += ss.str();
|
||||
}
|
||||
return false;
|
||||
@ -1720,6 +1741,121 @@ static bool ParseTechnique(Technique *technique, std::string *err,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 ¶meters_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(¶m, err, parameters_object, it->first,
|
||||
false)) {
|
||||
animation->parameters[it->first] = param;
|
||||
}
|
||||
}
|
||||
}
|
||||
ParseStringProperty(&animation->name, err, o, "name", false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err,
|
||||
const char *str, unsigned int length,
|
||||
const std::string &base_dir) {
|
||||
@ -2041,6 +2177,23 @@ bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err,
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user