mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-07-05 06:45:11 +08:00
Merge branch 'devel' of github.com:syoyo/tinygltf into devel
This commit is contained in:
commit
d800c88d09
48
.gitignore
vendored
Normal file
48
.gitignore
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# CMake
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
loader_example
|
||||||
|
tests/tester
|
||||||
|
tests/tester_noexcept
|
||||||
|
|
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# Use this for strict compilation check(will work on clang 3.8+)
|
# Use this for strict compilation check(will work on clang 3.8+)
|
||||||
#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long -DTINYGLTF_APPLY_CLANG_WEVERYTHING
|
#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long
|
||||||
|
|
||||||
all:
|
all:
|
||||||
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc
|
clang++ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o loader_example loader_example.cc
|
||||||
|
34
README.md
34
README.md
@ -22,6 +22,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
|||||||
* [x] iOS + clang
|
* [x] iOS + clang
|
||||||
* [x] Linux + gcc/clang
|
* [x] Linux + gcc/clang
|
||||||
* [x] Windows + MinGW
|
* [x] Windows + MinGW
|
||||||
|
* [x] Windows + Visual Studio 2015 or later.
|
||||||
|
* Visual Studio 2013 is not supported since they have limited C++11 support and failed to compile `json.hpp`.
|
||||||
* [x] Android + CrystaX(NDK drop-in replacement) GCC
|
* [x] Android + CrystaX(NDK drop-in replacement) GCC
|
||||||
* [x] Web using Emscripten(LLVM)
|
* [x] Web using Emscripten(LLVM)
|
||||||
* Moderate parsing time and memory consumption.
|
* Moderate parsing time and memory consumption.
|
||||||
@ -77,10 +79,11 @@ Copy `stb_image.h`, `json.hpp` and `tiny_gltf.h` to your project.
|
|||||||
|
|
||||||
### Loading glTF 2.0 model
|
### Loading glTF 2.0 model
|
||||||
|
|
||||||
```
|
```c++
|
||||||
// Define these only in *one* .cc file.
|
// Define these only in *one* .cc file.
|
||||||
#define TINYGLTF_IMPLEMENTATION
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
|
||||||
#include "tiny_gltf.h"
|
#include "tiny_gltf.h"
|
||||||
|
|
||||||
using namespace tinygltf;
|
using namespace tinygltf;
|
||||||
@ -101,19 +104,42 @@ if (!ret) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Compile options
|
||||||
|
|
||||||
|
* `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF.
|
||||||
|
|
||||||
### Saving gltTF 2.0 model
|
### Saving gltTF 2.0 model
|
||||||
|
|
||||||
T.B.W.
|
T.B.W.
|
||||||
|
|
||||||
## Running tests.
|
## Running tests.
|
||||||
|
|
||||||
### Setup
|
### glTF parsing test
|
||||||
|
|
||||||
|
#### Setup
|
||||||
|
|
||||||
Python 2.6 or 2.7 required.
|
Python 2.6 or 2.7 required.
|
||||||
Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir.
|
Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir.
|
||||||
|
|
||||||
### Run test
|
#### Run parsing test
|
||||||
|
|
||||||
After building `loader_example`, edit `test_runner.py`, then,
|
After building `loader_example`, edit `test_runner.py`, then,
|
||||||
|
|
||||||
$ python test_runner.py
|
```bash
|
||||||
|
$ python test_runner.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unit tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ cd tests
|
||||||
|
$ make
|
||||||
|
$ ./tester
|
||||||
|
$ ./tester_noexcept
|
||||||
|
```
|
||||||
|
|
||||||
|
## Third party licenses
|
||||||
|
|
||||||
|
* json.hpp : Licensed under the MIT License <http://opensource.org/licenses/MIT>. Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||||
|
* stb_image : Public domain.
|
||||||
|
* catch : Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. Distributed under the Boost Software License, Version 1.0.
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
version: 0.9.{build}
|
version: 0.9.{build}
|
||||||
|
|
||||||
|
image:
|
||||||
|
- Visual Studio 2015
|
||||||
|
|
||||||
# scripts that runs after repo cloning.
|
# scripts that runs after repo cloning.
|
||||||
install:
|
install:
|
||||||
- vcsetup.bat
|
- vcsetup.bat
|
||||||
|
@ -4,7 +4,9 @@ Simple OpenGL viewer for glTF geometry.
|
|||||||
|
|
||||||
* premake4 : Requires recent `premake4` for macosx and linux, `premake5` for windows.
|
* premake4 : Requires recent `premake4` for macosx and linux, `premake5` for windows.
|
||||||
* GLEW
|
* GLEW
|
||||||
|
* Ubuntu 16.04: sudo apt install libglew-dev
|
||||||
* glfw3
|
* glfw3
|
||||||
|
* Ubuntu 16.04: sudo apt install libglfw3-dev
|
||||||
|
|
||||||
### MacOSX and Linux
|
### MacOSX and Linux
|
||||||
|
|
||||||
|
@ -546,9 +546,12 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
|
|||||||
(it->first.compare("NORMAL") == 0) ||
|
(it->first.compare("NORMAL") == 0) ||
|
||||||
(it->first.compare("TEXCOORD_0") == 0)) {
|
(it->first.compare("TEXCOORD_0") == 0)) {
|
||||||
if (gGLProgramState.attribs[it->first] >= 0) {
|
if (gGLProgramState.attribs[it->first] >= 0) {
|
||||||
|
// Compute byteStride from Accessor + BufferView combination.
|
||||||
|
int byteStride = accessor.ByteStride(model.bufferViews[accessor.bufferView]);
|
||||||
|
assert(byteStride != -1);
|
||||||
glVertexAttribPointer(gGLProgramState.attribs[it->first], size,
|
glVertexAttribPointer(gGLProgramState.attribs[it->first], size,
|
||||||
accessor.componentType, accessor.normalized ? GL_TRUE : GL_FALSE,
|
accessor.componentType, accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||||
model.bufferViews[accessor.bufferView].byteStride,
|
byteStride,
|
||||||
BUFFER_OFFSET(accessor.byteOffset));
|
BUFFER_OFFSET(accessor.byteOffset));
|
||||||
CheckErrors("vertex attrib pointer");
|
CheckErrors("vertex attrib pointer");
|
||||||
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
|
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
|
||||||
|
@ -9,6 +9,22 @@ Experimental. W.I.P.
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* C++11 compiler
|
* C++11 compiler
|
||||||
|
* CMake
|
||||||
|
|
||||||
|
## How to build
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mkdir build
|
||||||
|
$ cd build
|
||||||
|
$ cmake ..
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
```
|
||||||
|
$ gltf-validator /path/to/file.gltf /path/to/gltf-schema
|
||||||
|
```
|
||||||
|
|
||||||
## Third party licenses
|
## Third party licenses
|
||||||
|
|
||||||
|
6
tests/Makefile
Normal file
6
tests/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 -DTINYGLTF_APPLY_CLANG_WEVERYTHING
|
||||||
|
|
||||||
|
all: ../tiny_gltf.h
|
||||||
|
clang++ -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester tester.cc
|
||||||
|
clang++ -DTINYGLTF_NOEXCEPTION -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester_noexcept tester.cc
|
10445
tests/catch.hpp
Normal file
10445
tests/catch.hpp
Normal file
File diff suppressed because it is too large
Load Diff
26
tests/tester.cc
Normal file
26
tests/tester.cc
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "tiny_gltf.h"
|
||||||
|
|
||||||
|
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
TEST_CASE("parse-error", "[parse]") {
|
||||||
|
|
||||||
|
tinygltf::Model model;
|
||||||
|
tinygltf::TinyGLTF ctx;
|
||||||
|
std::string err;
|
||||||
|
|
||||||
|
bool ret = ctx.LoadASCIIFromString(&model, &err, "bora", strlen("bora"), /* basedir*/ "");
|
||||||
|
|
||||||
|
REQUIRE(false == ret);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
277
tiny_gltf.h
277
tiny_gltf.h
@ -37,11 +37,13 @@
|
|||||||
#ifndef TINY_GLTF_H_
|
#ifndef TINY_GLTF_H_
|
||||||
#define TINY_GLTF_H_
|
#define TINY_GLTF_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace tinygltf {
|
namespace tinygltf {
|
||||||
|
|
||||||
@ -59,7 +61,7 @@ namespace tinygltf {
|
|||||||
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
|
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
|
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
|
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
|
||||||
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5127)
|
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5130)
|
||||||
|
|
||||||
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
|
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
|
||||||
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
|
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
|
||||||
@ -143,11 +145,58 @@ typedef enum {
|
|||||||
OBJECT_TYPE = 7
|
OBJECT_TYPE = 7
|
||||||
} Type;
|
} Type;
|
||||||
|
|
||||||
|
static inline int32_t GetComponentSizeInBytes(uint32_t componentType)
|
||||||
|
{
|
||||||
|
if (componentType == TINYGLTF_COMPONENT_TYPE_BYTE) {
|
||||||
|
return 1;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
|
||||||
|
return 1;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_SHORT) {
|
||||||
|
return 2;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT) {
|
||||||
|
return 2;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_INT) {
|
||||||
|
return 4;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT) {
|
||||||
|
return 4;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) {
|
||||||
|
return 4;
|
||||||
|
} else if (componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE) {
|
||||||
|
return 8;
|
||||||
|
} else {
|
||||||
|
// Unknown componenty type
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int32_t GetTypeSizeInBytes(uint32_t ty)
|
||||||
|
{
|
||||||
|
if (ty == TINYGLTF_TYPE_SCALAR) {
|
||||||
|
return 1;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_VEC2) {
|
||||||
|
return 2;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_VEC3) {
|
||||||
|
return 3;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_VEC4) {
|
||||||
|
return 4;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_MAT2) {
|
||||||
|
return 4;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_MAT3) {
|
||||||
|
return 9;
|
||||||
|
} else if (ty == TINYGLTF_TYPE_MAT4) {
|
||||||
|
return 16;
|
||||||
|
} else {
|
||||||
|
// Unknown componenty type
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
// Suppress warning for : static Value null_value
|
// Suppress warning for : static Value null_value
|
||||||
// https://stackoverflow.com/questions/15708411/how-to-deal-with-global-constructor-warning-in-clang
|
// https://stackoverflow.com/questions/15708411/how-to-deal-with-global-constructor-warning-in-clang
|
||||||
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
#pragma clang diagnostic ignored "-Wexit-time-destructors"
|
||||||
|
#pragma clang diagnostic ignored "-Wpadded"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Simple class to represent JSON object
|
// Simple class to represent JSON object
|
||||||
@ -252,15 +301,13 @@ class Value {
|
|||||||
Array array_value_;
|
Array array_value_;
|
||||||
Object object_value_;
|
Object object_value_;
|
||||||
bool boolean_value_;
|
bool boolean_value_;
|
||||||
char pad[3];
|
|
||||||
|
|
||||||
int pad0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define TINYGLTF_VALUE_GET(ctype, var) \
|
#define TINYGLTF_VALUE_GET(ctype, var) \
|
||||||
template <> \
|
template <> \
|
||||||
inline const ctype &Value::Get<ctype>() const { \
|
inline const ctype &Value::Get<ctype>() const { \
|
||||||
@ -279,12 +326,63 @@ TINYGLTF_VALUE_GET(Value::Array, array_value_)
|
|||||||
TINYGLTF_VALUE_GET(Value::Object, object_value_)
|
TINYGLTF_VALUE_GET(Value::Object, object_value_)
|
||||||
#undef TINYGLTF_VALUE_GET
|
#undef TINYGLTF_VALUE_GET
|
||||||
|
|
||||||
typedef struct {
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
|
#pragma clang diagnostic ignored "-Wpadded"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///Agregate object for representing a color
|
||||||
|
using ColorValue = std::array<double, 4>;
|
||||||
|
|
||||||
|
struct Parameter {
|
||||||
bool bool_value;
|
bool bool_value;
|
||||||
std::string string_value;
|
std::string string_value;
|
||||||
std::vector<double> number_array;
|
std::vector<double> number_array;
|
||||||
std::map<std::string, double> json_double_value;
|
std::map<std::string, double> json_double_value;
|
||||||
} Parameter;
|
|
||||||
|
//context sensitive methods. depending the type of the Parameter you are accessing, these are either valid or not
|
||||||
|
//If this parameter represent a texture map in a material, will return the texture index
|
||||||
|
|
||||||
|
///Return the index of a texture if this Parameter is a texture map.
|
||||||
|
///Returned value is only valid if the parameter represent a texture from a material
|
||||||
|
int TextureIndex() const {
|
||||||
|
const auto it = json_double_value.find("index");
|
||||||
|
if (it != std::end(json_double_value))
|
||||||
|
{
|
||||||
|
return int(it->second);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Material factor, like the roughness or metalness of a material
|
||||||
|
///Returned value is only valid if the parameter represent a texture from a material
|
||||||
|
double Factor() const {
|
||||||
|
return number_array[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
///Return the color of a material
|
||||||
|
///Returned value is only valid if the parameter represent a texture from a material
|
||||||
|
ColorValue ColorFactor() const {
|
||||||
|
return {
|
||||||
|
{ // this agregate intialize the std::array object, and uses C++11 RVO.
|
||||||
|
number_array[0],
|
||||||
|
number_array[1],
|
||||||
|
number_array[2],
|
||||||
|
(number_array.size() > 3 ? number_array[3] : 1.0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wpadded"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef std::map<std::string, Parameter> ParameterMap;
|
typedef std::map<std::string, Parameter> ParameterMap;
|
||||||
|
|
||||||
@ -337,7 +435,6 @@ struct Sampler {
|
|||||||
int wrapT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT", "REPEAT"], default
|
int wrapT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT", "REPEAT"], default
|
||||||
// "REPEAT"
|
// "REPEAT"
|
||||||
int wrapR; // TinyGLTF extension
|
int wrapR; // TinyGLTF extension
|
||||||
int pad0;
|
|
||||||
Value extras;
|
Value extras;
|
||||||
|
|
||||||
Sampler()
|
Sampler()
|
||||||
@ -350,10 +447,9 @@ struct Image {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int component;
|
int component;
|
||||||
int pad0;
|
|
||||||
std::vector<unsigned char> image;
|
std::vector<unsigned char> image;
|
||||||
int bufferView; // (required if no uri)
|
int bufferView; // (required if no uri)
|
||||||
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png"]
|
std::string mimeType; // (required if no uri) ["image/jpeg", "image/png", "image/bmp", "image/gif"]
|
||||||
std::string uri; // (reqiored if no mimeType)
|
std::string uri; // (reqiored if no mimeType)
|
||||||
Value extras;
|
Value extras;
|
||||||
|
|
||||||
@ -389,7 +485,6 @@ struct BufferView {
|
|||||||
size_t byteStride; // minimum 4, maximum 252 (multiple of 4), default 0 =
|
size_t byteStride; // minimum 4, maximum 252 (multiple of 4), default 0 =
|
||||||
// understood to be tightly packed
|
// understood to be tightly packed
|
||||||
int target; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"]
|
int target; // ["ARRAY_BUFFER", "ELEMENT_ARRAY_BUFFER"]
|
||||||
int pad0;
|
|
||||||
Value extras;
|
Value extras;
|
||||||
|
|
||||||
BufferView() : byteOffset(0), byteStride(0) {}
|
BufferView() : byteOffset(0), byteStride(0) {}
|
||||||
@ -411,6 +506,40 @@ struct Accessor {
|
|||||||
|
|
||||||
// TODO(syoyo): "sparse"
|
// TODO(syoyo): "sparse"
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Utility function to compute byteStride for a given bufferView object.
|
||||||
|
/// Returns -1 upon invalid glTF value or parameter configuration.
|
||||||
|
///
|
||||||
|
int ByteStride(const BufferView &bufferViewObject) const {
|
||||||
|
if (bufferViewObject.byteStride == 0) {
|
||||||
|
// Assume data is tightly packed.
|
||||||
|
int componentSizeInBytes = GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
|
||||||
|
if (componentSizeInBytes <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int typeSizeInBytes = GetTypeSizeInBytes(static_cast<uint32_t>(type));
|
||||||
|
if (typeSizeInBytes <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentSizeInBytes * typeSizeInBytes;
|
||||||
|
} else {
|
||||||
|
// Check if byteStride is a mulple of the size of the accessor's component type.
|
||||||
|
int componentSizeInBytes = GetComponentSizeInBytes(static_cast<uint32_t>(componentType));
|
||||||
|
if (componentSizeInBytes <= 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bufferViewObject.byteStride % uint32_t(componentSizeInBytes)) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return static_cast<int>(bufferViewObject.byteStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Accessor() { bufferView = -1; }
|
Accessor() { bufferView = -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -490,6 +619,23 @@ class Node {
|
|||||||
public:
|
public:
|
||||||
Node() : camera(-1), skin(-1), mesh(-1) {}
|
Node() : camera(-1), skin(-1), mesh(-1) {}
|
||||||
|
|
||||||
|
Node(const Node &rhs) {
|
||||||
|
camera = rhs.camera;
|
||||||
|
|
||||||
|
name = rhs.name;
|
||||||
|
skin = rhs.skin;
|
||||||
|
mesh = rhs.mesh;
|
||||||
|
children = rhs.children;
|
||||||
|
rotation = rhs.rotation;
|
||||||
|
scale = rhs.scale;
|
||||||
|
translation = rhs.translation;
|
||||||
|
matrix = rhs.matrix;
|
||||||
|
weights = rhs.weights;
|
||||||
|
|
||||||
|
extras = rhs.extras;
|
||||||
|
extLightsValues = rhs.extLightsValues;
|
||||||
|
}
|
||||||
|
|
||||||
~Node() {}
|
~Node() {}
|
||||||
|
|
||||||
int camera; // the index of the camera referenced by this node
|
int camera; // the index of the camera referenced by this node
|
||||||
@ -579,11 +725,22 @@ enum SectionCheck {
|
|||||||
REQUIRE_ALL = 0x3f
|
REQUIRE_ALL = 0x3f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TinyGLTF {
|
class TinyGLTF {
|
||||||
public:
|
public:
|
||||||
TinyGLTF() : bin_data_(NULL), bin_size_(0), is_binary_(false) {
|
|
||||||
pad[0] = pad[1] = pad[2] = pad[3] = pad[4] = pad[5] = pad[6] = 0;
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TinyGLTF() : bin_data_(nullptr), bin_size_(0), is_binary_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
~TinyGLTF() {}
|
~TinyGLTF() {}
|
||||||
|
|
||||||
///
|
///
|
||||||
@ -644,9 +801,12 @@ class TinyGLTF {
|
|||||||
const unsigned char *bin_data_;
|
const unsigned char *bin_data_;
|
||||||
size_t bin_size_;
|
size_t bin_size_;
|
||||||
bool is_binary_;
|
bool is_binary_;
|
||||||
char pad[7];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop // -Wpadded
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace tinygltf
|
} // namespace tinygltf
|
||||||
|
|
||||||
#endif // TINY_GLTF_H_
|
#endif // TINY_GLTF_H_
|
||||||
@ -673,9 +833,17 @@ class TinyGLTF {
|
|||||||
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
|
#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
|
||||||
#pragma clang diagnostic ignored "-Wswitch-enum"
|
#pragma clang diagnostic ignored "-Wswitch-enum"
|
||||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||||
|
#pragma clang diagnostic ignored "-Wweak-vtables"
|
||||||
|
#pragma clang diagnostic ignored "-Wcovered-switch-default"
|
||||||
#if __has_warning("-Wcomma")
|
#if __has_warning("-Wcomma")
|
||||||
#pragma clang diagnostic ignored "-Wcomma"
|
#pragma clang diagnostic ignored "-Wcomma"
|
||||||
#endif
|
#endif
|
||||||
|
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||||
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
|
#endif
|
||||||
|
#if __has_warning("-Wcast-qual")
|
||||||
|
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "./json.hpp"
|
#include "./json.hpp"
|
||||||
@ -700,10 +868,15 @@ class TinyGLTF {
|
|||||||
|
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
#if __APPLE__
|
#ifdef __APPLE__
|
||||||
#include "TargetConditionals.h"
|
#include "TargetConditionals.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tinygltf {
|
namespace tinygltf {
|
||||||
|
|
||||||
static void swap4(unsigned int *val) {
|
static void swap4(unsigned int *val) {
|
||||||
@ -1003,7 +1176,7 @@ static bool LoadImageData(Image *image, std::string *err, int req_width,
|
|||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Unknown image format.\n";
|
(*err) += "Unknown image format.\n";
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w < 1 || h < 1) {
|
if (w < 1 || h < 1) {
|
||||||
@ -1011,7 +1184,7 @@ static bool LoadImageData(Image *image, std::string *err, int req_width,
|
|||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Invalid image data.\n";
|
(*err) += "Invalid image data.\n";
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req_width > 0) {
|
if (req_width > 0) {
|
||||||
@ -1051,13 +1224,23 @@ static bool IsDataURI(const std::string &in) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header = "data:image/jpeg;base64,";
|
||||||
|
if (in.find(header) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
header = "data:image/png;base64,";
|
header = "data:image/png;base64,";
|
||||||
if (in.find(header) == 0) {
|
if (in.find(header) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header = "data:image/bmp;base64,";
|
||||||
|
if(in.find(header) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
header = "data:image/jpeg;base64,";
|
header = "data:image/gif;base64,";
|
||||||
if (in.find(header) == 0) {
|
if(in.find(header) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,6 +1274,20 @@ static bool DecodeDataURI(std::vector<unsigned char> *out,
|
|||||||
data = base64_decode(in.substr(header.size())); // cut mime string.
|
data = base64_decode(in.substr(header.size())); // cut mime string.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.empty()) {
|
||||||
|
header = "data:image/bmp;base64,";
|
||||||
|
if (in.find(header) == 0) {
|
||||||
|
data = base64_decode(in.substr(header.size())); // cut mime string.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.empty()) {
|
||||||
|
header = "data:image/gif;base64,";
|
||||||
|
if (in.find(header) == 0) {
|
||||||
|
data = base64_decode(in.substr(header.size())); // cut mime string.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data.empty()) {
|
if (data.empty()) {
|
||||||
header = "data:text/plain;base64,";
|
header = "data:text/plain;base64,";
|
||||||
@ -1446,7 +1643,7 @@ static bool ParseImage(Image *image, std::string *err,
|
|||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
// load data from (embedded) binary data
|
// load data from (embedded) binary data
|
||||||
|
|
||||||
if ((bin_size == 0) || (bin_data == NULL)) {
|
if ((bin_size == 0) || (bin_data == nullptr)) {
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Invalid binary data.\n";
|
(*err) += "Invalid binary data.\n";
|
||||||
}
|
}
|
||||||
@ -1529,7 +1726,7 @@ static bool ParseTexture(Texture *texture, std::string *err,
|
|||||||
static bool ParseBuffer(Buffer *buffer, std::string *err,
|
static bool ParseBuffer(Buffer *buffer, std::string *err,
|
||||||
const json &o, const std::string &basedir,
|
const json &o, const std::string &basedir,
|
||||||
bool is_binary = false,
|
bool is_binary = false,
|
||||||
const unsigned char *bin_data = NULL,
|
const unsigned char *bin_data = nullptr,
|
||||||
size_t bin_size = 0) {
|
size_t bin_size = 0) {
|
||||||
double byteLength;
|
double byteLength;
|
||||||
if (!ParseNumberProperty(&byteLength, err, o, "byteLength", true, "Buffer")) {
|
if (!ParseNumberProperty(&byteLength, err, o, "byteLength", true, "Buffer")) {
|
||||||
@ -1567,7 +1764,7 @@ static bool ParseBuffer(Buffer *buffer, std::string *err,
|
|||||||
} else {
|
} else {
|
||||||
// load data from (embedded) binary data
|
// load data from (embedded) binary data
|
||||||
|
|
||||||
if ((bin_size == 0) || (bin_data == NULL)) {
|
if ((bin_size == 0) || (bin_data == nullptr)) {
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) += "Invalid binary data in `Buffer'.\n";
|
(*err) += "Invalid binary data in `Buffer'.\n";
|
||||||
}
|
}
|
||||||
@ -1934,24 +2131,24 @@ static bool ParseNode(Node *node, std::string *err, const json &o) {
|
|||||||
json::const_iterator extensions_object = o.find("extensions");
|
json::const_iterator extensions_object = o.find("extensions");
|
||||||
if ((extensions_object != o.end()) &&
|
if ((extensions_object != o.end()) &&
|
||||||
extensions_object.value().is_object()) {
|
extensions_object.value().is_object()) {
|
||||||
const json &values_object =
|
const json &ext_values_object =
|
||||||
extensions_object.value();
|
extensions_object.value();
|
||||||
|
|
||||||
json::const_iterator it(values_object.begin());
|
json::const_iterator it(ext_values_object.begin());
|
||||||
json::const_iterator itEnd(values_object.end());
|
json::const_iterator itEnd(ext_values_object.end());
|
||||||
|
|
||||||
for (; it != itEnd; it++) {
|
for (; it != itEnd; it++) {
|
||||||
if ((it.key().compare("KHR_lights_cmn") == 0) &&
|
if ((it.key().compare("KHR_lights_cmn") == 0) &&
|
||||||
it.value().is_object()) {
|
it.value().is_object()) {
|
||||||
const json &values_object =
|
const json &light_values_object =
|
||||||
it.value();
|
it.value();
|
||||||
|
|
||||||
json::const_iterator itVal(values_object.begin());
|
json::const_iterator itVal(light_values_object.begin());
|
||||||
json::const_iterator itValEnd(values_object.end());
|
json::const_iterator itValEnd(light_values_object.end());
|
||||||
|
|
||||||
for (; itVal != itValEnd; itVal++) {
|
for (; itVal != itValEnd; itVal++) {
|
||||||
Parameter param;
|
Parameter param;
|
||||||
if (ParseParameterProperty(¶m, err, values_object, itVal.key(),
|
if (ParseParameterProperty(¶m, err, light_values_object, itVal.key(),
|
||||||
false)) {
|
false)) {
|
||||||
node->extLightsValues[itVal.key()] = param;
|
node->extLightsValues[itVal.key()] = param;
|
||||||
}
|
}
|
||||||
@ -2325,17 +2522,31 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, const char *str,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(syoyo): Add feature not using exception handling.
|
|
||||||
json v;
|
json v;
|
||||||
|
|
||||||
|
#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && not defined(TINYGLTF_NOEXCEPTION)
|
||||||
try {
|
try {
|
||||||
v = json::parse(str, str + length);
|
v = json::parse(str, str + length);
|
||||||
|
|
||||||
} catch (std::exception e) {
|
} catch (const std::exception &e) {
|
||||||
if (err) {
|
if (err) {
|
||||||
(*err) = e.what();
|
(*err) = e.what();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
v = json::parse(str, str + length, nullptr, /* exception */false);
|
||||||
|
|
||||||
|
if (!v.is_object()) {
|
||||||
|
// Assume parsing was failed.
|
||||||
|
if (err) {
|
||||||
|
(*err) = "Failed to parse JSON object\n";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!v.is_object()) {
|
if (!v.is_object()) {
|
||||||
// root is not an object.
|
// root is not an object.
|
||||||
@ -2869,7 +3080,7 @@ bool TinyGLTF::LoadASCIIFromString(Model *model, std::string *err,
|
|||||||
const std::string &base_dir,
|
const std::string &base_dir,
|
||||||
unsigned int check_sections) {
|
unsigned int check_sections) {
|
||||||
is_binary_ = false;
|
is_binary_ = false;
|
||||||
bin_data_ = NULL;
|
bin_data_ = nullptr;
|
||||||
bin_size_ = 0;
|
bin_size_ = 0;
|
||||||
|
|
||||||
return LoadFromString(model, err, str, length, base_dir, check_sections);
|
return LoadFromString(model, err, str, length, base_dir, check_sections);
|
||||||
@ -3606,4 +3817,8 @@ bool TinyGLTF::WriteGltfSceneToFile(
|
|||||||
|
|
||||||
} // namespace tinygltf
|
} // namespace tinygltf
|
||||||
|
|
||||||
|
#ifdef __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // TINYGLTF_IMPLEMENTATION
|
#endif // TINYGLTF_IMPLEMENTATION
|
||||||
|
@ -1 +1 @@
|
|||||||
.\\tools\\windows\\premake5.exe vs2013
|
.\\tools\\windows\\premake5.exe vs2015
|
||||||
|
Loading…
x
Reference in New Issue
Block a user