mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 11:13:50 +00:00
Compare commits
2 Commits
copilot/re
...
anim-dump
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94c47b15c3 | ||
|
|
48b3422925 |
@@ -62,6 +62,7 @@ v2.0.0 release(22 Aug, 2018)!
|
||||
|
||||
## TODOs
|
||||
|
||||
* [ ] Sparse accesors(e.g. for efficient morph targets)
|
||||
* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing.
|
||||
* [ ] Mesh Compression/decompression(Open3DGC, etc)
|
||||
* [ ] Load Draco compressed mesh
|
||||
|
||||
6
examples/anim-dump/Makefile
Normal file
6
examples/anim-dump/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# Use this for strict compilation check(will work on clang 3.8+)
|
||||
#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long -Wno-c++98-compat
|
||||
|
||||
all:
|
||||
clang++ -I../../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o anim-dump anim-dump.cc
|
||||
|
||||
2
examples/anim-dump/README.md
Normal file
2
examples/anim-dump/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Simple animation value dumper
|
||||
|
||||
178
examples/anim-dump/anim-dump.cc
Normal file
178
examples/anim-dump/anim-dump.cc
Normal file
@@ -0,0 +1,178 @@
|
||||
//
|
||||
// TODO(syoyo): Print extensions and extras for each glTF object.
|
||||
//
|
||||
#include "tiny_gltf_util.h"
|
||||
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "tiny_gltf.h"
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
static 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 Indent(const int indent) {
|
||||
std::string s;
|
||||
for (int i = 0; i < indent; i++) {
|
||||
s += " ";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ProcessAnimation(const tinygltf::Animation &animation, const tinygltf::Model &model)
|
||||
{
|
||||
#if 0
|
||||
if (animaton_channel.target_path.compare("translation") == 0) {
|
||||
} else if (animaton_channel.target_path.compare("rotation") == 0) {
|
||||
} else if (animaton_channel.target_path.compare("scale") == 0) {
|
||||
} else if (animaton_channel.target_path.compare("weights") == 0) {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
for (size_t j = 0; j < animation.samplers.size(); j++) {
|
||||
std::cout << "== samplers[" << j << "] ===============" << std::endl;
|
||||
const tinygltf::AnimationSampler &sampler = animation.samplers[j];
|
||||
std::cout << Indent(1) << "interpolation = " << sampler.interpolation<< std::endl;
|
||||
std::cout << Indent(1) << "input = " << sampler.input << std::endl;
|
||||
std::cout << Indent(1) << "output = " << sampler.output << std::endl;
|
||||
|
||||
// input accessor must have min/max property.
|
||||
const tinygltf::Accessor &accessor = model.accessors[sampler.input];
|
||||
|
||||
for (size_t i = 0; i < accessor.minValues.size(); i++) {
|
||||
std::cout << Indent(1) << "input min[" << i << "] = " << accessor.minValues[i] << std::endl;
|
||||
}
|
||||
for (size_t i = 0; i < accessor.maxValues.size(); i++) {
|
||||
std::cout << Indent(1) << "input max[" << i << "] = " << accessor.maxValues[i] << std::endl;
|
||||
}
|
||||
|
||||
std::cout << Indent(1) << "input count = " << accessor.count << std::endl;
|
||||
|
||||
for (size_t i = 0; i < accessor.count; i++) {
|
||||
if (accessor.type == TINYGLTF_TYPE_SCALAR) {
|
||||
float v;
|
||||
if (tinygltf::util::DecodeScalarAnimationValue(i, accessor, model, &v)) {
|
||||
std::cout << Indent(2) << "input value[" << i << "] = " << v << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//const tinygltf::Accessor &accessor = model.accessors[sampler.output];
|
||||
//std::cout << Indent(2) << "output : " << sampler.output
|
||||
// << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void DumpAnim(const tinygltf::Model &model) {
|
||||
std::cout << "=== Dump glTF ===" << std::endl;
|
||||
std::cout << "asset.copyright : " << model.asset.copyright
|
||||
<< std::endl;
|
||||
std::cout << "asset.generator : " << model.asset.generator
|
||||
<< std::endl;
|
||||
std::cout << "asset.version : " << model.asset.version
|
||||
<< std::endl;
|
||||
std::cout << "asset.minVersion : " << model.asset.minVersion
|
||||
<< std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "=== Dump scene ===" << std::endl;
|
||||
std::cout << "defaultScene: " << model.defaultScene << std::endl;
|
||||
|
||||
{
|
||||
std::cout << "animations(items=" << model.animations.size() << ")"
|
||||
<< std::endl;
|
||||
for (size_t i = 0; i < model.animations.size(); i++) {
|
||||
const tinygltf::Animation &animation = model.animations[i];
|
||||
std::cout << Indent(1) << "name : " << animation.name
|
||||
<< std::endl;
|
||||
|
||||
std::cout << Indent(1) << "channels : [ " << std::endl;
|
||||
for (size_t j = 0; i < animation.channels.size(); i++) {
|
||||
std::cout << Indent(2)
|
||||
<< "sampler : " << animation.channels[j].sampler
|
||||
<< std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "target.id : " << animation.channels[j].target_node
|
||||
<< std::endl;
|
||||
std::cout << Indent(2)
|
||||
<< "target.path : " << animation.channels[j].target_path
|
||||
<< std::endl;
|
||||
std::cout << ((i != (animation.channels.size() - 1)) ? " , " : "");
|
||||
}
|
||||
std::cout << " ]" << std::endl;
|
||||
|
||||
std::cout << Indent(1) << "samplers(items=" << animation.samplers.size()
|
||||
<< ")" << std::endl;
|
||||
for (size_t j = 0; j < animation.samplers.size(); j++) {
|
||||
const tinygltf::AnimationSampler &sampler = animation.samplers[j];
|
||||
std::cout << Indent(2) << "input : " << sampler.input
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "interpolation : " << sampler.interpolation
|
||||
<< std::endl;
|
||||
std::cout << Indent(2) << "output : " << sampler.output
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
ProcessAnimation(animation, model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
printf("Needs input.gltf\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tinygltf::Model model;
|
||||
tinygltf::TinyGLTF gltf_ctx;
|
||||
std::string err;
|
||||
std::string warn;
|
||||
std::string input_filename(argv[1]);
|
||||
std::string ext = GetFilePathExtension(input_filename);
|
||||
|
||||
bool ret = false;
|
||||
if (ext.compare("glb") == 0) {
|
||||
std::cout << "Reading binary glTF" << std::endl;
|
||||
// assume binary glTF.
|
||||
ret = gltf_ctx.LoadBinaryFromFile(&model, &err, &warn, input_filename.c_str());
|
||||
} else {
|
||||
std::cout << "Reading ASCII glTF" << std::endl;
|
||||
// assume ascii glTF.
|
||||
ret = gltf_ctx.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
|
||||
}
|
||||
|
||||
if (!warn.empty()) {
|
||||
printf("Warn: %s\n", warn.c_str());
|
||||
}
|
||||
|
||||
|
||||
if (!err.empty()) {
|
||||
printf("Err: %s\n", err.c_str());
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
printf("Failed to parse glTF\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DumpAnim(model);
|
||||
|
||||
return 0;
|
||||
}
|
||||
51
tiny_gltf.h
51
tiny_gltf.h
@@ -56,6 +56,7 @@ namespace tinygltf {
|
||||
#define TINYGLTF_MODE_TRIANGLE_STRIP (5)
|
||||
#define TINYGLTF_MODE_TRIANGLE_FAN (6)
|
||||
|
||||
#define TINYGLTF_COMPONENT_TYPE_INVALID (-1)
|
||||
#define TINYGLTF_COMPONENT_TYPE_BYTE (5120)
|
||||
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE (5121)
|
||||
#define TINYGLTF_COMPONENT_TYPE_SHORT (5122)
|
||||
@@ -106,6 +107,7 @@ namespace tinygltf {
|
||||
|
||||
// End parameter types
|
||||
|
||||
#define TINYGLTF_TYPE_INVALID (-1)
|
||||
#define TINYGLTF_TYPE_VEC2 (2)
|
||||
#define TINYGLTF_TYPE_VEC3 (3)
|
||||
#define TINYGLTF_TYPE_VEC4 (4)
|
||||
@@ -416,6 +418,7 @@ struct AnimationSampler {
|
||||
|
||||
AnimationSampler() : input(-1), output(-1), interpolation("LINEAR") {}
|
||||
bool operator==(const AnimationSampler &) const;
|
||||
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
@@ -535,11 +538,11 @@ struct Accessor {
|
||||
int bufferView; // optional in spec but required here since sparse accessor
|
||||
// are not supported
|
||||
std::string name;
|
||||
size_t byteOffset;
|
||||
bool normalized; // optinal.
|
||||
int componentType; // (required) One of TINYGLTF_COMPONENT_TYPE_***
|
||||
size_t count; // required
|
||||
int type; // (required) One of TINYGLTF_TYPE_*** ..
|
||||
size_t byteOffset = 0;
|
||||
bool normalized = false; // optinal.
|
||||
int componentType = TINYGLTF_COMPONENT_TYPE_INVALID; // (required) One of TINYGLTF_COMPONENT_TYPE_***
|
||||
size_t count = 0; // required
|
||||
int type = TINYGLTF_TYPE_INVALID; // (required) One of TINYGLTF_TYPE_*** ..
|
||||
Value extras;
|
||||
|
||||
std::vector<double> minValues; // optional
|
||||
@@ -588,6 +591,7 @@ struct Accessor {
|
||||
bool operator==(const tinygltf::Accessor &) const;
|
||||
};
|
||||
|
||||
|
||||
struct PerspectiveCamera {
|
||||
double aspectRatio; // min > 0
|
||||
double yfov; // required. min > 0
|
||||
@@ -775,6 +779,14 @@ class Model {
|
||||
Value extras;
|
||||
};
|
||||
|
||||
///
|
||||
/// Utility function to get an address of underlying buffer for i'th element.
|
||||
/// Returns nullptr for invalid parameter or invalid data.
|
||||
/// Assume `buffer` parameter = model.buffers[bufferViewObject.buffer]
|
||||
///
|
||||
const uint8_t *GetBufferAddress(const int i, const Accessor &accessor, const BufferView &bufferViewObject, const Buffer &buffer);
|
||||
|
||||
|
||||
enum SectionCheck {
|
||||
NO_REQUIRE = 0x00,
|
||||
REQUIRE_SCENE = 0x01,
|
||||
@@ -2008,6 +2020,21 @@ bool DecodeDataURI(std::vector<unsigned char> *out, std::string &mime_type,
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t *GetBufferAddress(const int i, const Accessor &accessor, const BufferView &bufferViewObject, const Buffer &buffer) {
|
||||
|
||||
if (i >= int(accessor.count)) return nullptr;
|
||||
|
||||
int byte_stride = accessor.ByteStride(bufferViewObject);
|
||||
if (byte_stride == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(syoyo): Bounds check.
|
||||
const uint8_t *base_addr = buffer.data.data() + bufferViewObject.byteOffset + accessor.byteOffset;
|
||||
const uint8_t *addr = base_addr + i * byte_stride;
|
||||
return addr;
|
||||
}
|
||||
|
||||
static bool ParseJsonAsValue(Value *ret, const json &o) {
|
||||
Value val{};
|
||||
switch (o.type()) {
|
||||
@@ -3488,7 +3515,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
||||
{
|
||||
if (primitive.indices > -1) // has indices from parsing step, must be Element Array Buffer
|
||||
{
|
||||
model->bufferViews[model->accessors[primitive.indices].bufferView]
|
||||
model->bufferViews[size_t(model->accessors[size_t(primitive.indices)].bufferView)]
|
||||
.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
|
||||
// we could optionally check if acessors' bufferView type is Scalar, as it should be
|
||||
}
|
||||
@@ -4575,23 +4602,23 @@ static void WriteBinaryGltfFile(const std::string &output,
|
||||
const int padding_size = content.size() % 4;
|
||||
|
||||
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info, padding
|
||||
const int length = 12 + 8 + content.size() + padding_size;
|
||||
const int length = 12 + 8 + int(content.size()) + padding_size;
|
||||
|
||||
gltfFile.write(header.c_str(), header.size());
|
||||
gltfFile.write(header.c_str(), std::streamsize(header.size()));
|
||||
gltfFile.write(reinterpret_cast<const char *>(&version), sizeof(version));
|
||||
gltfFile.write(reinterpret_cast<const char *>(&length), sizeof(length));
|
||||
|
||||
// JSON chunk info, then JSON data
|
||||
const int model_length = content.size() + padding_size;
|
||||
const int model_length = int(content.size()) + padding_size;
|
||||
const int model_format = 0x4E4F534A;
|
||||
gltfFile.write(reinterpret_cast<const char *>(&model_length), sizeof(model_length));
|
||||
gltfFile.write(reinterpret_cast<const char *>(&model_format), sizeof(model_format));
|
||||
gltfFile.write(content.c_str(), content.size());
|
||||
gltfFile.write(content.c_str(), std::streamsize(content.size()));
|
||||
|
||||
// Chunk must be multiplies of 4, so pad with spaces
|
||||
if (padding_size > 0) {
|
||||
const std::string padding = std::string(padding_size, ' ');
|
||||
gltfFile.write(padding.c_str(), padding.size());
|
||||
const std::string padding = std::string(size_t(padding_size), ' ');
|
||||
gltfFile.write(padding.c_str(), std::streamsize(padding.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
294
tiny_gltf_util.h
Normal file
294
tiny_gltf_util.h
Normal file
@@ -0,0 +1,294 @@
|
||||
//
|
||||
// TinyGLTF utility functions
|
||||
//
|
||||
//
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 - 2018 Syoyo Fujita, Aurélien Chatelain and many
|
||||
// contributors.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "tiny_gltf.h"
|
||||
|
||||
namespace tinygltf {
|
||||
|
||||
namespace util {
|
||||
|
||||
static std::string PrintMode(int mode) {
|
||||
if (mode == TINYGLTF_MODE_POINTS) {
|
||||
return "POINTS";
|
||||
} else if (mode == TINYGLTF_MODE_LINE) {
|
||||
return "LINE";
|
||||
} else if (mode == TINYGLTF_MODE_LINE_LOOP) {
|
||||
return "LINE_LOOP";
|
||||
} else if (mode == TINYGLTF_MODE_TRIANGLES) {
|
||||
return "TRIANGLES";
|
||||
} else if (mode == TINYGLTF_MODE_TRIANGLE_FAN) {
|
||||
return "TRIANGLE_FAN";
|
||||
} else if (mode == TINYGLTF_MODE_TRIANGLE_STRIP) {
|
||||
return "TRIANGLE_STRIP";
|
||||
}
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintTarget(int target) {
|
||||
if (target == 34962) {
|
||||
return "GL_ARRAY_BUFFER";
|
||||
} else if (target == 34963) {
|
||||
return "GL_ELEMENT_ARRAY_BUFFER";
|
||||
} else {
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
}
|
||||
|
||||
static std::string PrintType(int ty) {
|
||||
if (ty == TINYGLTF_TYPE_SCALAR) {
|
||||
return "SCALAR";
|
||||
} else if (ty == TINYGLTF_TYPE_VECTOR) {
|
||||
return "VECTOR";
|
||||
} else if (ty == TINYGLTF_TYPE_VEC2) {
|
||||
return "VEC2";
|
||||
} else if (ty == TINYGLTF_TYPE_VEC3) {
|
||||
return "VEC3";
|
||||
} else if (ty == TINYGLTF_TYPE_VEC4) {
|
||||
return "VEC4";
|
||||
} else if (ty == TINYGLTF_TYPE_MATRIX) {
|
||||
return "MATRIX";
|
||||
} else if (ty == TINYGLTF_TYPE_MAT2) {
|
||||
return "MAT2";
|
||||
} else if (ty == TINYGLTF_TYPE_MAT3) {
|
||||
return "MAT3";
|
||||
} else if (ty == TINYGLTF_TYPE_MAT4) {
|
||||
return "MAT4";
|
||||
}
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintComponentType(int ty) {
|
||||
if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) {
|
||||
return "BYTE";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
|
||||
return "UNSIGNED_BYTE";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_SHORT) {
|
||||
return "SHORT";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
|
||||
return "UNSIGNED_SHORT";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_INT) {
|
||||
return "INT";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) {
|
||||
return "UNSIGNED_INT";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
return "FLOAT";
|
||||
} else if (ty == TINYGLTF_COMPONENT_TYPE_DOUBLE) {
|
||||
return "DOUBLE";
|
||||
}
|
||||
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintWrapMode(int mode) {
|
||||
if (mode == TINYGLTF_TEXTURE_WRAP_REPEAT) {
|
||||
return "REPEAT";
|
||||
} else if (mode == TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE) {
|
||||
return "CLAMP_TO_EDGE";
|
||||
} else if (mode == TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT) {
|
||||
return "MIRRORED_REPEAT";
|
||||
}
|
||||
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static std::string PrintFilterMode(int mode) {
|
||||
if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST) {
|
||||
return "NEAREST";
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR) {
|
||||
return "LINEAR";
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST) {
|
||||
return "NEAREST_MIPMAP_NEAREST";
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR) {
|
||||
return "NEAREST_MIPMAP_LINEAR";
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST) {
|
||||
return "LINEAR_MIPMAP_NEAREST";
|
||||
} else if (mode == TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR) {
|
||||
return "LINEAR_MIPMAP_LINEAR";
|
||||
}
|
||||
return "**UNKNOWN**";
|
||||
}
|
||||
|
||||
static int GetAnimationSamplerInputCount(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model)
|
||||
{
|
||||
const tinygltf::Accessor &accessor = model.accessors[sampler.input];
|
||||
return accessor.count;
|
||||
}
|
||||
|
||||
static int GetAnimationSamplerOutputCount(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model)
|
||||
{
|
||||
const tinygltf::Accessor &accessor = model.accessors[sampler.output];
|
||||
return accessor.count;
|
||||
}
|
||||
|
||||
static bool GetAnimationSamplerInputMinMax(const tinygltf::AnimationSampler &sampler, const tinygltf::Model &model, float *min_value, float *max_value)
|
||||
{
|
||||
const tinygltf::Accessor &accessor = model.accessors[sampler.input];
|
||||
|
||||
// Assume scalar value.
|
||||
if ((accessor.minValues.size() > 0) &&
|
||||
(accessor.maxValues.size() > 0)) {
|
||||
(*min_value) = accessor.minValues[0];
|
||||
(*max_value) = accessor.maxValues[0];
|
||||
return true;
|
||||
} else {
|
||||
(*min_value) = 0.0f;
|
||||
(*max_value) = 0.0f;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function for decoding animation value
|
||||
static inline float DecodeAnimationChannelValue(int8_t c) {
|
||||
return std::max(float(c) / 127.0f, -1.0f);
|
||||
}
|
||||
static inline float DecodeAnimationChannelValue(uint8_t c) {
|
||||
return float(c) / 255.0f;
|
||||
}
|
||||
static inline float DecodeAnimationChannelValue(int16_t c) {
|
||||
return std::max(float(c) / 32767.0f, -1.0f);
|
||||
}
|
||||
static inline float DecodeAnimationChannelValue(uint16_t c) {
|
||||
return float(c) / 65525.0f;
|
||||
}
|
||||
|
||||
static bool DecodeScalarAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *scalar)
|
||||
{
|
||||
const BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||
const Buffer &buffer = model.buffers[bufferView.buffer];
|
||||
|
||||
const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer);
|
||||
if (addr == nullptr) {
|
||||
std::cerr << "Invalid glTF data?" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
float value = 0.0f;
|
||||
|
||||
if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE) {
|
||||
value = DecodeAnimationChannelValue(*(reinterpret_cast<const int8_t*>(addr)));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
|
||||
value = DecodeAnimationChannelValue(*(reinterpret_cast<const uint8_t*>(addr)));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT) {
|
||||
value = DecodeAnimationChannelValue(*(reinterpret_cast<const int16_t*>(addr)));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
|
||||
value = DecodeAnimationChannelValue(*(reinterpret_cast<const uint16_t*>(addr)));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
value = *(reinterpret_cast<const float*>(addr));
|
||||
} else {
|
||||
std::cerr << "??? Unknown componentType : " << PrintComponentType(accessor.componentType) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
(*scalar) = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DecodeTranslationAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyz)
|
||||
{
|
||||
if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
std::cerr << "`translation` must be float type." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||
const Buffer &buffer = model.buffers[bufferView.buffer];
|
||||
|
||||
const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer);
|
||||
if (addr == nullptr) {
|
||||
std::cerr << "Invalid glTF data?" << std::endl;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const float *ptr = reinterpret_cast<const float*>(addr);
|
||||
|
||||
xyz[0] = *(ptr + 0);
|
||||
xyz[1] = *(ptr + 1);
|
||||
xyz[2] = *(ptr + 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DecodeScaleAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyz)
|
||||
{
|
||||
if (accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
std::cerr << "`scale` must be float type." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||
const Buffer &buffer = model.buffers[bufferView.buffer];
|
||||
|
||||
const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer);
|
||||
if (addr == nullptr) {
|
||||
std::cerr << "Invalid glTF data?" << std::endl;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const float *ptr = reinterpret_cast<const float*>(addr);
|
||||
|
||||
xyz[0] = *(ptr + 0);
|
||||
xyz[1] = *(ptr + 1);
|
||||
xyz[2] = *(ptr + 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DecodeRotationAnimationValue(const size_t i, const tinygltf::Accessor &accessor, const tinygltf::Model &model, float *xyzw)
|
||||
{
|
||||
const BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||
const Buffer &buffer = model.buffers[bufferView.buffer];
|
||||
|
||||
const uint8_t *addr = GetBufferAddress(i, accessor, bufferView, buffer);
|
||||
if (addr == nullptr) {
|
||||
std::cerr << "Invalid glTF data?" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
float value = 0.0f;
|
||||
|
||||
if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_BYTE) {
|
||||
xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast<const int8_t*>(addr) + 0));
|
||||
xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast<const int8_t*>(addr) + 1));
|
||||
xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast<const int8_t*>(addr) + 2));
|
||||
xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast<const int8_t*>(addr) + 3));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
|
||||
xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint8_t*>(addr) + 0));
|
||||
xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint8_t*>(addr) + 1));
|
||||
xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint8_t*>(addr) + 2));
|
||||
xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint8_t*>(addr) + 3));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_SHORT) {
|
||||
xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast<const int16_t*>(addr) + 0));
|
||||
xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast<const int16_t*>(addr) + 1));
|
||||
xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast<const int16_t*>(addr) + 2));
|
||||
xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast<const int16_t*>(addr) + 3));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
|
||||
xyzw[0] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint16_t*>(addr) + 0));
|
||||
xyzw[1] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint16_t*>(addr) + 1));
|
||||
xyzw[2] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint16_t*>(addr) + 2));
|
||||
xyzw[3] = DecodeAnimationChannelValue(*(reinterpret_cast<const uint16_t*>(addr) + 3));
|
||||
} else if (accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||
xyzw[0] = *(reinterpret_cast<const float*>(addr) + 0);
|
||||
xyzw[1] = *(reinterpret_cast<const float*>(addr) + 1);
|
||||
xyzw[2] = *(reinterpret_cast<const float*>(addr) + 2);
|
||||
xyzw[3] = *(reinterpret_cast<const float*>(addr) + 3);
|
||||
} else {
|
||||
std::cerr << "??? Unknown componentType : " << PrintComponentType(accessor.componentType) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
} // namespace tinygltf
|
||||
Reference in New Issue
Block a user