Compare commits

...

59 Commits

Author SHA1 Message Date
Syoyo Fujita
cfab524125 VS2019 seems gone. Use VS2022. 2022-02-25 01:39:02 +09:00
Syoyo Fujita
9229971bcb Print cmake help 2022-02-25 01:25:15 +09:00
Syoyo Fujita
051149311c Specify x64 for MSVC build. 2022-02-25 01:11:51 +09:00
Syoyo Fujita
4749b0989d Merge pull request #342 from brlcad/patch-1
add missing switch case for binary
2022-02-24 03:34:58 +09:00
Christopher Sean Morrison
0bfcb4f49e add missing switch case for binary
with warnings cranked up and warnings-as-errors enabled, the compiler throws an error due to this switch missing a case for binary.  this makes the ignore explicit in order for compilation to proceed.
2022-02-23 10:02:49 -05:00
Syoyo Fujita
17e6e310ce Merge pull request #341 from mushrom/loopfix
Fixing loop index
2022-02-14 17:10:31 +09:00
My Name
07ceb4c313 Fixing loop index 2022-02-13 16:31:27 -05:00
Syoyo Fujita
e7f1ff5c59 Merge pull request #339 from yslking/yslking-update-json-hpp-3-10-4
update json.hpp to v3.10.4 to compile with c++20 compilers
2021-11-28 22:25:34 +09:00
yslking
fd904063c9 update json.hpp to v3.10.4 2021-11-28 15:08:05 +08:00
Syoyo Fujita
38398cc2da Fix typo from PR #320 2021-11-21 18:59:10 +09:00
Syoyo Fujita
ed1a294bc4 Merge branch 'master' of github.com:syoyo/tinygltf 2021-11-21 18:58:39 +09:00
Syoyo Fujita
b86eb6c079 Merge pull request #331 from abwood/so-updates
Remove stackoverflow references from tinygltf.
2021-10-19 21:45:19 +09:00
Alexander Wood
e4bc6c7bd4 - Remove clang warning suppression. I assume this stackoverflow reference can just be removed as it isn't a code snippet but a repost of clang documentation of ignoring warning levels.
- Remove stackoverflow reference that recommends the use of dlib. There's no source that was pulled from this s.o. post, only a recommendation on a library, I wouldn't think a link to s.o. is necessary here. Per the Boost License, I've included a copy of the license along with the snippet
2021-10-14 08:54:59 -04:00
Alexander Wood
13803659f8 Build fix. 2021-10-08 20:13:07 -04:00
Alexander Wood
a3d5d5d1c9 Build fix. 2021-10-08 20:09:08 -04:00
Alexander Wood
9e3d1f6db5 Build fix. 2021-10-08 16:57:56 -04:00
Alexander Wood
190382aecd GetBaseFilename contained a logic error in that a filename that does not contain a path separator would result in a crash.
Removed the roundUp lambda, as this generalization is not necessary; the caller always attempts 4 byte alignment.
2021-10-08 12:19:13 -04:00
Syoyo Fujita
c6501530e3 Merge branch 'master' of github.com:syoyo/tinygltf 2021-09-24 17:11:07 +09:00
Syoyo Fujita
ed48224f4b Describe current status(its stable) 2021-09-24 17:10:29 +09:00
Syoyo Fujita
19a41d20ec Merge pull request #330 from cgdae/master
Fix for OpenBSD - wordexp.h not available.
2021-08-25 20:25:03 +09:00
Julian Smith
0598a20cce Fix for OpenBSD - wordexp.h not available. 2021-08-25 12:06:08 +01:00
Syoyo Fujita
514167b475 Merge pull request #329 from syoyo/cmake-add-subdirectory
Cmake add subdirectory
2021-07-03 22:09:26 +09:00
Syoyo Fujita
0f76561ebf Add readme to use tinygtf through cmake + add_subdirectory. 2021-07-03 22:06:29 +09:00
Syoyo Fujita
f3dc4acaa4 Merge branch 'master' into cmake-add-subdirectory 2021-07-03 22:01:46 +09:00
Syoyo Fujita
1588e75e26 Merge branch 'master' of github.com:syoyo/tinygltf 2021-06-09 21:23:57 +09:00
Syoyo Fujita
d1453b5e5e GLEW_LIBRARY -> GLEW_LIBRARIES 2021-06-09 21:23:37 +09:00
Syoyo Fujita
7e83ef9fb4 Merge pull request #327 from CppProgrammer23/master
update enum Type
2021-05-20 20:44:16 +09:00
Idriss Chaouch
425195bf9c update enum Type
the first element in an enum is 0, so it's not necessarily to affect values from 0 to 7.
2021-05-20 12:11:00 +01:00
Syoyo Fujita
ce3a30e612 Merge pull request #326 from xzrunner/master
Fix comment on minFilter
2021-05-14 15:06:07 +09:00
zz
8a35b8f6fe Fix comment on minFilter 2021-05-14 13:49:33 +08:00
Syoyo Fujita
f66f3bfeb3 Merge pull request #325 from iceydee/scene-extras
Store scene extras and extensions on the scene
2021-05-11 19:01:25 +09:00
Mio Nilsson
e29ba7c49a 🐛 Store scene extras and exteions on the scene
This was being stored in the wrong place
2021-05-11 11:50:35 +02:00
Syoyo Fujita
bc753d4ac5 Merge pull request #322 from syoyo/fix-negative-skeleton-id
Do not serialize skeleton id -1
2021-04-29 16:20:42 +09:00
Syoyo Fujita
688ba8a60e Add regression test for issue 321 2021-04-29 16:04:52 +09:00
Syoyo Fujita
d07b976d59 Do not write negative skeleton id(skeleton is not assigned).
Also ensure `inverseBindMatrices` should not be -2 or other negative values.
2021-04-28 19:15:16 +09:00
Syoyo Fujita
08a7dd8dad Merge pull request #317 from Snowapril/master
Delete unused variable initialization code
2021-03-30 03:15:26 +09:00
snowapril
87da1e775f Delete unused variable initialization code
Line 4536 in tinygltf.h file, there is unused variable initialization code like below.
```c++
    const auto pBuffer = pAttribute->buffer();
```

gcc compiler complain about that unused variable. 

I found there is no side-effect in  `pAttribute->buffer()` call and also pBuffer variable is never used. Therefore I delete that line entirely.
2021-03-30 00:16:04 +09:00
Syoyo Fujita
151495558e Merge pull request #314 from Snowapril/master
Add (void)err for handling unused variable warning
2021-03-20 19:59:44 +09:00
snowapril
84e15260ba add (void)err for handling unused variable warning
I saw in the `ParseExtensionsProperty`(3667) function,
unused variable err argument is wrapped with (void) keword.

I think err argument in the `ParseDracoExtension`(4472) is exactly
same situation with the above one.

For consistency, I think it need to be added (void)err in the
`ParseDracoExtension` function.
2021-03-20 19:25:58 +09:00
Syoyo Fujita
03cdef430d Merge pull request #312 from AlvaroBarua/no_include_rapidjson
Added TINYGLTF_NO_INCLUDE_RAPIDJSON
2021-03-19 14:32:35 +09:00
AlvaroBarua
fb4bd82e2c Updated Readme.md 2021-03-18 18:40:09 +00:00
Alvaro Barua
3ddf8301f6 Added TINYGLTF_NO_INCLUDE_RAPIDJSON for consistency and because my project already used rapidjson/ 2021-03-18 00:21:23 +00:00
Syoyo Fujita
298c37a954 Merge pull request #310 from syoyo/write-assert-version
`asset.version` is a required field
2021-03-03 00:35:55 +09:00
Syoyo Fujita
b702de755f asset.version is a required field so write "2.0" when asset.version is empty. Fixes #308 2021-03-02 19:08:29 +09:00
Syoyo Fujita
58ceed1d89 Add CMake file and Makefile for examples/build-gltf 2021-02-26 18:34:00 +09:00
Dov Grobgeld
d1b6b3a5aa Add example for creating a triangle gltf file from scratch 2021-02-26 09:30:05 +02:00
Syoyo Fujita
c56d069726 Merge pull request #306 from mahiuchun/const
Drop an unnecessary 'const'.
2021-02-21 16:07:51 +09:00
Hill Ma
d1e32865f1 Drop an unnecessary 'const'. 2021-02-20 22:30:44 -08:00
Syoyo Fujita
869a9d273c Merge pull request #305 from Selmar/patch-2
check correct `extensionsUsed` for serialization
2021-02-02 14:17:34 +09:00
Selmar
1208f057d6 check correct extensionsUsed for serialization 2021-02-01 19:24:41 +01:00
Syoyo Fujita
f684dde9f1 Merge pull request #303 from syoyo/int-minmax-serialize
Issue #301. Serialize accessor min/vax value as int
2021-01-22 03:40:52 +09:00
Syoyo Fujita
7905a5b4dc Issue #301. Serialize accessor min/vax value as int if its component type is an integer. 2021-01-21 20:33:11 +09:00
Syoyo Fujita
f161782001 Merge pull request #299 from DethRaid/patch-1
Add my project to the README
2020-12-23 15:46:32 +09:00
David Dubois
654bcf733c Add my project to the README
My personal project uses tinygltf so i want to add it to the "Projects using TinyGLTF" section of the README
2020-12-22 22:32:59 -08:00
syoyo
001c870051 Make cmake script add_subdirectory friendly. 2020-12-18 01:10:21 +09:00
Syoyo Fujita
2c521b3432 Remove sampler.wrapR parameter(unused tinygltf extension). Fixes #287
Suppress clang `-Wdocumentation-unknown-command` warning.
2020-12-04 00:50:46 +09:00
Syoyo Fujita
a159945db9 Add document for TinyGLTF::SetPreserveimageChannels. 2020-10-31 19:40:33 +09:00
Syoyo Fujita
010ee9c67b Add SetPreserveImageChannels feature(preserve image channels in stored image file. Only effective when using builtin ImageLoad function(STB image load)). 2020-10-31 19:35:55 +09:00
Syoyo Fujita
a23971c603 Merge pull request #295 from syoyo/empty-material
Empty material
2020-10-23 04:05:19 +09:00
13 changed files with 13190 additions and 6267 deletions

View File

@@ -47,7 +47,8 @@ jobs:
sudo apt-get install -y mingw-w64 sudo apt-get install -y mingw-w64
x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc
# Windows(x64) + Visual Studio 2019 build # Windows(x64) + Visual Studio 2022 build
# Assume windows-latest have VS2022 installed
build-windows-msvc: build-windows-msvc:
runs-on: windows-latest runs-on: windows-latest
@@ -62,7 +63,8 @@ jobs:
run: | run: |
mkdir build mkdir build
cd build cd build
cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On .. cmake --help
cmake -G "Visual Studio 17 2022" -A x64 -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On ..
cd .. cd ..
- name: Build - name: Build
run: cmake --build build --config Release run: cmake --build build --config Release

View File

@@ -4,9 +4,12 @@ PROJECT (tinygltf)
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD 11)
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON) option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example(load glTF and dump infos)" ON)
option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF) option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF)
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF) option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF)
option(TINYGLTF_BUILD_BUILDER_EXAMPLE "Build glTF builder example" OFF)
option(TINYGLTF_HEADER_ONLY "On: header-only mode. Off: create tinygltf library(No TINYGLTF_IMPLEMENTATION required in your project)" OFF)
option(TINYGLTF_INSTALL "Install tinygltf files during install step. Usually set to OFF if you include tinygltf through add_subdirectory()" ON)
if (TINYGLTF_BUILD_LOADER_EXAMPLE) if (TINYGLTF_BUILD_LOADER_EXAMPLE)
ADD_EXECUTABLE ( loader_example ADD_EXECUTABLE ( loader_example
@@ -22,20 +25,52 @@ endif (TINYGLTF_BUILD_GL_EXAMPLES)
if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
ADD_SUBDIRECTORY ( examples/validator ) ADD_SUBDIRECTORY ( examples/validator )
endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
if (TINYGLTF_BUILD_BUILDER_EXAMPLE)
ADD_SUBDIRECTORY ( examples/build-gltf )
endif (TINYGLTF_BUILD_BUILDER_EXAMPLE)
# #
# TinuGLTF is a header-only library, so no library build. just install header files. # for add_subdirectory and standalone build
# #
INSTALL ( FILES if (TINYGLTF_HEADER_ONLY)
json.hpp add_library(tinygltf INTERFACE)
stb_image.h
stb_image_write.h target_include_directories(tinygltf
tiny_gltf.h INTERFACE
DESTINATION $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
include $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
) )
INSTALL ( FILES else (TINYGLTF_HEADER_ONLY)
cmake/TinyGLTFConfig.cmake add_library(tinygltf)
DESTINATION target_sources(tinygltf PRIVATE
cmake ${CMAKE_CURRENT_SOURCE_DIR}/tiny_gltf.cc)
) target_include_directories(tinygltf
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
endif (TINYGLTF_HEADER_ONLY)
if (TINYGLTF_INSTALL)
# Do not install .lib even if !TINYGLTF_HEADER_ONLY
INSTALL ( FILES
json.hpp
stb_image.h
stb_image_write.h
tiny_gltf.h
${TINYGLTF_EXTRA_SOUECES}
DESTINATION
include
)
INSTALL ( FILES
cmake/TinyGLTFConfig.cmake
DESTINATION
cmake
)
endif(TINYGLTF_INSTALL)

View File

@@ -7,6 +7,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch(bu
## Status ## Status
Currently TinyGLTF is stable and maintainance mode. No drastic changes and feature addition planned.
- v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance) - v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance)
- v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class) - v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class)
- v2.2.0 release(Support loading 16bit PNG. Sparse accessor support) - v2.2.0 release(Support loading 16bit PNG. Sparse accessor support)
@@ -77,6 +79,7 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [glview](examples/glview) : Simple glTF geometry viewer. * [glview](examples/glview) : Simple glTF geometry viewer.
* [validator](examples/validator) : Simple glTF validator with JSON schema. * [validator](examples/validator) : Simple glTF validator with JSON schema.
* [basic](examples/basic) : Basic glTF viewer with texturing support. * [basic](examples/basic) : Basic glTF viewer with texturing support.
* [build-gltf](examples/build-gltf) : Build simple glTF scene from a scratch.
## Projects using TinyGLTF ## Projects using TinyGLTF
@@ -90,6 +93,7 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
* [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux * [GlslViewer](https://github.com/patriciogonzalezvivo/glslViewer) - live GLSL coding for MacOS and Linux
* [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications. * [Vulkan-Samples](https://github.com/KhronosGroup/Vulkan-Samples) - The Vulkan Samples is collection of resources to help you develop optimized Vulkan applications.
* [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11 * [TDME2](https://github.com/andreasdr/tdme2) - TDME2 - ThreeDeeMiniEngine2 is a lightweight 3D engine including tools suited for 3D game development using C++11
* [SanityEngine](https://github.com/DethRaid/SanityEngine) - A C++/D3D12 renderer focused on the personal and proessional development of its developer
* Your projects here! (Please send PR) * Your projects here! (Please send PR)
## TODOs ## TODOs
@@ -155,6 +159,10 @@ if (!ret) {
} }
``` ```
#### Loader options
* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader).
## Compile options ## 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. * `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.
@@ -164,11 +172,26 @@ if (!ret) {
* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand. * `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand.
* `TINYGLTF_ENABLE_DRACO`: Enable Draco compression. User must provide include path and link correspnding libraries in your project file. * `TINYGLTF_ENABLE_DRACO`: Enable Draco compression. User must provide include path and link correspnding libraries in your project file.
* `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. * `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_RAPIDJSON `: Disable including RapidJson's header files from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. * `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. * `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`.
* `TINYGLTF_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this featrure. * `TINYGLTF_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this feature.
* `TINYGLTF_USE_CPP14` : Use C++14 feature(requires C++14 compiler). This may give better performance than C++11. * `TINYGLTF_USE_CPP14` : Use C++14 feature(requires C++14 compiler). This may give better performance than C++11.
## CMake options
You can add tinygltf using `add_subdirectory` feature.
If you add tinygltf to your project using `add_subdirectory`, it would be better to set `TINYGLTF_HEADER_ONLY` on(just add an include path to tinygltf) and `TINYGLTF_INSTALL` off(Which does not install tinygltf files).
```
// Your project's CMakeLists.txt
...
set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE)
set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE)
add_subdirectory(/path/to/tinygltf)
```
### Saving gltTF 2.0 model ### Saving gltTF 2.0 model

View File

@@ -0,0 +1,2 @@
all:
$(CXX) -o create_triangle_gltf -I../../ create_triangle_gltf.cpp

View File

@@ -0,0 +1,121 @@
// An example of how to generate a gltf file from scratch. This example
// was translated from the pygltlib documentation in the pypi project page,
// which in turn is based on the Khronos Sample Models at:
//
// https://github.com/KhronosGroup/glTF-Sample-Models
//
// This example is released under the MIT license.
//
// 2021-02-25 Thu
// Dov Grobgeld <dov.grobgeld@gmail.com>
// Define these only in *one* .cc file.
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling.
#include "tiny_gltf.h"
int main(int argc, char **argv)
{
// Create a model with a single mesh and save it as a gltf file
tinygltf::Model m;
tinygltf::Scene scene;
tinygltf::Mesh mesh;
tinygltf::Primitive primitive;
tinygltf::Node node;
tinygltf::Buffer buffer;
tinygltf::BufferView bufferView1;
tinygltf::BufferView bufferView2;
tinygltf::Accessor accessor1;
tinygltf::Accessor accessor2;
tinygltf::Asset asset;
// This is the raw data buffer.
buffer.data = {
// 6 bytes of indices and two bytes of padding
0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
// 36 bytes of floating point numbers
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,
0x00,0x00,0x00,0x00};
// "The indices of the vertices (ELEMENT_ARRAY_BUFFER) take up 6 bytes in the
// start of the buffer.
bufferView1.buffer = 0;
bufferView1.byteOffset=0;
bufferView1.byteLength=6;
bufferView1.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER;
// The vertices take up 36 bytes (3 vertices * 3 floating points * 4 bytes)
// at position 8 in the buffer and are of type ARRAY_BUFFER
bufferView2.buffer = 0;
bufferView2.byteOffset=8;
bufferView2.byteLength=36;
bufferView2.target = TINYGLTF_TARGET_ARRAY_BUFFER;
// Describe the layout of bufferView1, the indices of the vertices
accessor1.bufferView = 0;
accessor1.byteOffset = 0;
accessor1.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT;
accessor1.count = 3;
accessor1.type = TINYGLTF_TYPE_SCALAR;
accessor1.maxValues.push_back(2);
accessor1.minValues.push_back(0);
// Describe the layout of bufferView2, the vertices themself
accessor2.bufferView = 1;
accessor2.byteOffset = 0;
accessor2.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT;
accessor2.count = 3;
accessor2.type = TINYGLTF_TYPE_VEC3;
accessor2.maxValues = {1.0, 1.0, 0.0};
accessor2.minValues = {0.0, 0.0, 0.0};
// Build the mesh primitive and add it to the mesh
primitive.indices = 0; // The index of the accessor for the vertex indices
primitive.attributes["POSITION"] = 1; // The index of the accessor for positions
primitive.material = 0;
primitive.mode = TINYGLTF_MODE_TRIANGLES;
mesh.primitives.push_back(primitive);
// Other tie ups
node.mesh = 0;
scene.nodes.push_back(0); // Default scene
// Define the asset. The version is required
asset.version = "2.0";
asset.generator = "tinygltf";
// Now all that remains is to tie back all the loose objects into the
// our single model.
m.scenes.push_back(scene);
m.meshes.push_back(mesh);
m.nodes.push_back(node);
m.buffers.push_back(buffer);
m.bufferViews.push_back(bufferView1);
m.bufferViews.push_back(bufferView2);
m.accessors.push_back(accessor1);
m.accessors.push_back(accessor2);
m.asset = asset;
// Create a simple material
tinygltf::Material mat;
mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f};
mat.doubleSided = true;
m.materials.push_back(mat);
// Save it to a file
tinygltf::TinyGLTF gltf;
gltf.WriteGltfSceneToFile(&m, "triangle.gltf",
true, // embedImages
true, // embedBuffers
true, // pretty print
false); // write binary
exit(0);
}

View File

@@ -610,7 +610,7 @@ void Viewer::buildSamplerDescs() {
samplerDesc.AddressU = toTextureAddressMode(glTFSampler.wrapS); samplerDesc.AddressU = toTextureAddressMode(glTFSampler.wrapS);
samplerDesc.AddressV = toTextureAddressMode(glTFSampler.wrapT); samplerDesc.AddressV = toTextureAddressMode(glTFSampler.wrapT);
samplerDesc.AddressW = toTextureAddressMode(glTFSampler.wrapR); samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
samplerDesc.MaxLOD = 256; samplerDesc.MaxLOD = 256;
samplerDescs_.push_back(samplerDesc); samplerDescs_.push_back(samplerDesc);

View File

@@ -51,7 +51,7 @@ add_executable(glview
target_link_libraries ( glview target_link_libraries ( glview
${DRACO_LIBRARY} ${DRACO_LIBRARY}
${GLFW3_UNIX_LINK_LIBRARIES} ${GLFW3_UNIX_LINK_LIBRARIES}
${GLEW_LIBRARY} ${GLEW_LIBRARIES}
${GLFW3_glfw_LIBRARY} ${GLFW3_glfw_LIBRARY}
${OPENGL_gl_LIBRARY} ${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY} ${OPENGL_glu_LIBRARY}

18613
json.hpp

File diff suppressed because it is too large Load Diff

View File

@@ -524,7 +524,7 @@ static void Dump(const tinygltf::Model &model) {
<< std::endl; << std::endl;
std::cout << Indent(1) << "channels : [ " << std::endl; std::cout << Indent(1) << "channels : [ " << std::endl;
for (size_t j = 0; i < animation.channels.size(); i++) { for (size_t j = 0; j < animation.channels.size(); j++) {
std::cout << Indent(2) std::cout << Indent(2)
<< "sampler : " << animation.channels[j].sampler << "sampler : " << animation.channels[j].sampler
<< std::endl; << std::endl;

File diff suppressed because one or more lines are too long

View File

@@ -432,11 +432,40 @@ TEST_CASE("serialize-empty-material", "[issue-294]") {
nlohmann::json j = nlohmann::json::parse(os.str()); nlohmann::json j = nlohmann::json::parse(os.str());
REQUIRE(1 == j["materials"].size()); REQUIRE(1 == j["materials"].size());
REQUIRE(j["asset"].is_null());
REQUIRE(j["materials"][0].is_object()); REQUIRE(j["materials"][0].is_object());
} }
TEST_CASE("empty-skeleton-id", "[issue-321]") {
tinygltf::Model model;
tinygltf::TinyGLTF ctx;
std::string err;
std::string warn;
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/regression/unassigned-skeleton.gltf");
if (!err.empty()) {
std::cerr << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(model.skins.size() == 1);
REQUIRE(model.skins[0].skeleton == -1); // unassigned
std::stringstream os;
ctx.WriteGltfSceneToStream(&model, os, false, false);
// use nlohmann json
nlohmann::json j = nlohmann::json::parse(os.str());
// Ensure `skeleton` property is not written to .gltf(was serialized as -1)
REQUIRE(1 == j["skins"].size());
REQUIRE(j["skins"][0].is_object());
REQUIRE(j["skins"][0].count("skeleton") == 0);
}
#ifndef TINYGLTF_NO_FS #ifndef TINYGLTF_NO_FS
TEST_CASE("expandpath-utf-8", "[pr-226]") { TEST_CASE("expandpath-utf-8", "[pr-226]") {

4
tiny_gltf.cc Normal file
View File

@@ -0,0 +1,4 @@
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"

View File

@@ -4,7 +4,7 @@
// //
// The MIT License (MIT) // The MIT License (MIT)
// //
// Copyright (c) 2015 - 2020 Syoyo Fujita, Aurélien Chatelain and many // Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many
// contributors. // contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -26,7 +26,9 @@
// THE SOFTWARE. // THE SOFTWARE.
// Version: // Version:
// - v2.4.3 Fix null object output when when material has all default parameters. // - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
// - v2.4.3 Fix null object output when when material has all default
// parameters.
// - v2.4.2 Decode percent-encoded URI. // - v2.4.2 Decode percent-encoded URI.
// - v2.4.1 Fix some glTF object class does not have `extensions` and/or // - v2.4.1 Fix some glTF object class does not have `extensions` and/or
// `extras` property. // `extras` property.
@@ -189,14 +191,14 @@ AAssetManager *asset_manager = nullptr;
#endif #endif
typedef enum { typedef enum {
NULL_TYPE = 0, NULL_TYPE,
REAL_TYPE = 1, REAL_TYPE,
INT_TYPE = 2, INT_TYPE,
BOOL_TYPE = 3, BOOL_TYPE,
STRING_TYPE = 4, STRING_TYPE,
ARRAY_TYPE = 5, ARRAY_TYPE,
BINARY_TYPE = 6, BINARY_TYPE,
OBJECT_TYPE = 7 OBJECT_TYPE
} Type; } Type;
static inline int32_t GetComponentSizeInBytes(uint32_t componentType) { static inline int32_t GetComponentSizeInBytes(uint32_t componentType) {
@@ -251,7 +253,6 @@ bool DecodeDataURI(std::vector<unsigned char> *out, std::string &mime_type,
#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
#pragma clang diagnostic ignored "-Wexit-time-destructors" #pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wpadded" #pragma clang diagnostic ignored "-Wpadded"
#endif #endif
@@ -296,7 +297,7 @@ class Value {
DEFAULT_METHODS(Value) DEFAULT_METHODS(Value)
char Type() const { return static_cast<const char>(type_); } char Type() const { return static_cast<char>(type_); }
bool IsBool() const { return (type_ == BOOL_TYPE); } bool IsBool() const { return (type_ == BOOL_TYPE); }
@@ -602,7 +603,7 @@ struct Sampler {
// `magFilter`. Set -1 in TinyGLTF(issue #186) // `magFilter`. Set -1 in TinyGLTF(issue #186)
int minFilter = int minFilter =
-1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR", -1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR",
// "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_NEAREST", // "NEAREST_MIPMAP_NEAREST", "LINEAR_MIPMAP_NEAREST",
// "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"] // "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"]
int magFilter = int magFilter =
-1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR"] -1; // optional. -1 = no filter defined. ["NEAREST", "LINEAR"]
@@ -612,7 +613,7 @@ struct Sampler {
int wrapT = int wrapT =
TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT", TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
// "REPEAT"], default "REPEAT" // "REPEAT"], default "REPEAT"
int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension //int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently not used.
Value extras; Value extras;
ExtensionMap extensions; ExtensionMap extensions;
@@ -625,8 +626,7 @@ struct Sampler {
: minFilter(-1), : minFilter(-1),
magFilter(-1), magFilter(-1),
wrapS(TINYGLTF_TEXTURE_WRAP_REPEAT), wrapS(TINYGLTF_TEXTURE_WRAP_REPEAT),
wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT), wrapT(TINYGLTF_TEXTURE_WRAP_REPEAT) {}
wrapR(TINYGLTF_TEXTURE_WRAP_REPEAT) {}
DEFAULT_METHODS(Sampler) DEFAULT_METHODS(Sampler)
bool operator==(const Sampler &) const; bool operator==(const Sampler &) const;
}; };
@@ -849,8 +849,10 @@ struct Accessor {
std::string extras_json_string; std::string extras_json_string;
std::string extensions_json_string; std::string extensions_json_string;
std::vector<double> minValues; // optional std::vector<double>
std::vector<double> maxValues; // optional minValues; // optional. integer value is promoted to double
std::vector<double>
maxValues; // optional. integer value is promoted to double
struct { struct {
int count; int count;
@@ -1068,7 +1070,7 @@ struct Buffer {
}; };
struct Asset { struct Asset {
std::string version; // required std::string version = "2.0"; // required
std::string generator; std::string generator;
std::string minVersion; std::string minVersion;
std::string copyright; std::string copyright;
@@ -1190,7 +1192,8 @@ enum SectionCheck {
/// ///
typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *, typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *,
std::string *, int, int, std::string *, int, int,
const unsigned char *, int, void *); const unsigned char *, int,
void *user_pointer);
/// ///
/// WriteImageDataFunction type. Signature for custom image writing callbacks. /// WriteImageDataFunction type. Signature for custom image writing callbacks.
@@ -1255,7 +1258,7 @@ bool FileExists(const std::string &abs_filename, void *);
/// ///
/// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to /// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to
/// `C:\Users\tinygltf\AppData`) /// `C:\\Users\\tinygltf\\AppData`)
/// ///
/// @param[in] filepath File path string. Assume UTF-8 /// @param[in] filepath File path string. Assume UTF-8
/// @param[in] userdata User data. Set to `nullptr` if you don't need it. /// @param[in] userdata User data. Set to `nullptr` if you don't need it.
@@ -1346,6 +1349,11 @@ class TinyGLTF {
/// ///
void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data); void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
///
/// Unset(remove) callback of loading image data
///
void RemoveImageLoader();
/// ///
/// Set callback to use for writing image data /// Set callback to use for writing image data
/// ///
@@ -1384,6 +1392,16 @@ class TinyGLTF {
return store_original_json_for_extras_and_extensions_; return store_original_json_for_extras_and_extensions_;
} }
///
/// Specify whether preserve image channales when loading images or not.
/// (Not effective when the user suppy their own LoadImageData callbacks)
///
void SetPreserveImageChannels(bool onoff) {
preserve_image_channels_ = onoff;
}
bool GetPreserveImageChannels() const { return preserve_image_channels_; }
private: private:
/// ///
/// Loads glTF asset from string(memory). /// Loads glTF asset from string(memory).
@@ -1403,6 +1421,9 @@ class TinyGLTF {
bool store_original_json_for_extras_and_extensions_ = false; bool store_original_json_for_extras_and_extensions_ = false;
bool preserve_image_channels_ = false; /// Default false(expand channels to
/// RGBA) for backward compatibility.
FsCallbacks fs = { FsCallbacks fs = {
#ifndef TINYGLTF_NO_FS #ifndef TINYGLTF_NO_FS
&tinygltf::FileExists, &tinygltf::ExpandFilePath, &tinygltf::FileExists, &tinygltf::ExpandFilePath,
@@ -1422,7 +1443,8 @@ class TinyGLTF {
#else #else
nullptr; nullptr;
#endif #endif
void *load_image_user_data_ = reinterpret_cast<void *>(&fs); void *load_image_user_data_{nullptr};
bool user_image_loader_{false};
WriteImageDataFunction WriteImageData = WriteImageDataFunction WriteImageData =
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE #ifndef TINYGLTF_NO_STB_IMAGE_WRITE
@@ -1430,7 +1452,7 @@ class TinyGLTF {
#else #else
nullptr; nullptr;
#endif #endif
void *write_image_user_data_ = reinterpret_cast<void *>(&fs); void *write_image_user_data_{nullptr};
}; };
#ifdef __clang__ #ifdef __clang__
@@ -1515,6 +1537,7 @@ class TinyGLTF {
#ifndef TINYGLTF_USE_RAPIDJSON #ifndef TINYGLTF_USE_RAPIDJSON
#include "json.hpp" #include "json.hpp"
#else #else
#ifndef TINYGLTF_NO_INCLUDE_RAPIDJSON
#include "document.h" #include "document.h"
#include "prettywriter.h" #include "prettywriter.h"
#include "rapidjson.h" #include "rapidjson.h"
@@ -1522,6 +1545,7 @@ class TinyGLTF {
#include "writer.h" #include "writer.h"
#endif #endif
#endif #endif
#endif
#ifdef TINYGLTF_ENABLE_DRACO #ifdef TINYGLTF_ENABLE_DRACO
#include "draco/compression/decode.h" #include "draco/compression/decode.h"
@@ -1580,7 +1604,7 @@ class TinyGLTF {
#endif #endif
#elif !defined(__ANDROID__) #elif !defined(__ANDROID__) && !defined(__OpenBSD__)
#include <wordexp.h> #include <wordexp.h>
#endif #endif
@@ -1684,6 +1708,19 @@ void JsonParse(JsonDocument &doc, const char *str, size_t length,
namespace tinygltf { namespace tinygltf {
///
/// Internal LoadImageDataOption struct.
/// This struct is passed through `user_pointer` in LoadImageData.
/// The struct is not passed when the user supply their own LoadImageData
/// callbacks.
///
struct LoadImageDataOption {
// true: preserve image channels(e.g. load as RGB image if the image has RGB
// channels) default `false`(channels are expanded to RGBA for backward
// compatiblity).
bool preserve_channels{false};
};
// Equals function for Value, for recursivity // Equals function for Value, for recursivity
static bool Equals(const tinygltf::Value &one, const tinygltf::Value &other) { static bool Equals(const tinygltf::Value &one, const tinygltf::Value &other) {
if (one.Type() != other.Type()) return false; if (one.Type() != other.Type()) return false;
@@ -1896,8 +1933,9 @@ bool Sampler::operator==(const Sampler &other) const {
return this->extensions == other.extensions && this->extras == other.extras && return this->extensions == other.extensions && this->extras == other.extras &&
this->magFilter == other.magFilter && this->magFilter == other.magFilter &&
this->minFilter == other.minFilter && this->name == other.name && this->minFilter == other.minFilter && this->name == other.name &&
this->wrapR == other.wrapR && this->wrapS == other.wrapS &&
this->wrapT == other.wrapT; this->wrapT == other.wrapT;
//this->wrapR == other.wrapR && this->wrapS == other.wrapS &&
} }
bool Scene::operator==(const Scene &other) const { bool Scene::operator==(const Scene &other) const {
return this->extensions == other.extensions && this->extras == other.extras && return this->extensions == other.extensions && this->extras == other.extras &&
@@ -2001,9 +2039,12 @@ static std::string GetBaseDir(const std::string &filepath) {
return ""; return "";
} }
// https://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path
static std::string GetBaseFilename(const std::string &filepath) { static std::string GetBaseFilename(const std::string &filepath) {
return filepath.substr(filepath.find_last_of("/\\") + 1); constexpr char path_separators[2] = { '/', '\\' };
auto idx = filepath.find_last_of(path_separators);
if (idx != std::string::npos)
return filepath.substr(idx + 1);
return filepath;
} }
std::string base64_encode(unsigned char const *, unsigned int len); std::string base64_encode(unsigned char const *, unsigned int len);
@@ -2149,47 +2190,35 @@ std::string base64_decode(std::string const &encoded_string) {
// TODO(syoyo): Use uriparser https://uriparser.github.io/ for stricter Uri // TODO(syoyo): Use uriparser https://uriparser.github.io/ for stricter Uri
// decoding? // decoding?
// //
// https://stackoverflow.com/questions/18307429/encode-decode-url-in-c // Uri Decoding from DLIB
// http://dlib.net/dlib/server/server_http.cpp.html // http://dlib.net/dlib/server/server_http.cpp.html
// --- dlib begin ------------------------------------------------------------
// --- dlib beign ------------------------------------------------------------
// Copyright (C) 2003 Davis E. King (davis@dlib.net) // Copyright (C) 2003 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license. // License: Boost Software License
// Boost Software License - Version 1.0 - August 17th, 2003
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
namespace dlib { namespace dlib {
#if 0
inline unsigned char to_hex( unsigned char x )
{
return x + (x > 9 ? ('A'-10) : '0');
}
const std::string urlencode( const std::string& s )
{
std::ostringstream os;
for ( std::string::const_iterator ci = s.begin(); ci != s.end(); ++ci )
{
if ( (*ci >= 'a' && *ci <= 'z') ||
(*ci >= 'A' && *ci <= 'Z') ||
(*ci >= '0' && *ci <= '9') )
{ // allowed
os << *ci;
}
else if ( *ci == ' ')
{
os << '+';
}
else
{
os << '%' << to_hex(static_cast<unsigned char>(*ci >> 4)) << to_hex(static_cast<unsigned char>(*ci % 16));
}
}
return os.str();
}
#endif
inline unsigned char from_hex(unsigned char ch) { inline unsigned char from_hex(unsigned char ch) {
if (ch <= '9' && ch >= '0') if (ch <= '9' && ch >= '0')
ch -= '0'; ch -= '0';
@@ -2298,22 +2327,40 @@ static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) { void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) {
LoadImageData = func; LoadImageData = func;
load_image_user_data_ = user_data; load_image_user_data_ = user_data;
user_image_loader_ = true;
}
void TinyGLTF::RemoveImageLoader() {
LoadImageData =
#ifndef TINYGLTF_NO_STB_IMAGE
&tinygltf::LoadImageData;
#else
nullptr;
#endif
load_image_user_data_ = nullptr;
user_image_loader_ = false;
} }
#ifndef TINYGLTF_NO_STB_IMAGE #ifndef TINYGLTF_NO_STB_IMAGE
bool LoadImageData(Image *image, const int image_idx, std::string *err, bool LoadImageData(Image *image, const int image_idx, std::string *err,
std::string *warn, int req_width, int req_height, std::string *warn, int req_width, int req_height,
const unsigned char *bytes, int size, void *user_data) { const unsigned char *bytes, int size, void *user_data) {
(void)user_data;
(void)warn; (void)warn;
LoadImageDataOption option;
if (user_data) {
option = *reinterpret_cast<LoadImageDataOption *>(user_data);
}
int w = 0, h = 0, comp = 0, req_comp = 0; int w = 0, h = 0, comp = 0, req_comp = 0;
unsigned char *data = nullptr; unsigned char *data = nullptr;
// force 32-bit textures for common Vulkan compatibility. It appears that // preserve_channels true: Use channels stored in the image file.
// some GPU drivers do not support 24-bit images for Vulkan // false: force 32-bit textures for common Vulkan compatibility. It appears
req_comp = 4; // that some GPU drivers do not support 24-bit images for Vulkan
req_comp = option.preserve_channels ? 0 : 4;
int bits = 8; int bits = 8;
int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE; int pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
@@ -2385,13 +2432,18 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err,
} }
} }
if (req_comp != 0) {
// loaded data has `req_comp` channels(components)
comp = req_comp;
}
image->width = w; image->width = w;
image->height = h; image->height = h;
image->component = req_comp; image->component = comp;
image->bits = bits; image->bits = bits;
image->pixel_type = pixel_type; image->pixel_type = pixel_type;
image->image.resize(static_cast<size_t>(w * h * req_comp) * size_t(bits / 8)); image->image.resize(static_cast<size_t>(w * h * comp) * size_t(bits / 8));
std::copy(data, data + w * h * req_comp * (bits / 8), image->image.begin()); std::copy(data, data + w * h * comp * (bits / 8), image->image.begin());
stbi_image_free(data); stbi_image_free(data);
return true; return true;
@@ -2567,7 +2619,7 @@ std::string ExpandFilePath(const std::string &filepath, void *) {
#else #else
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \ #if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \
defined(__ANDROID__) || defined(__EMSCRIPTEN__) defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__OpenBSD__)
// no expansion // no expansion
std::string s = filepath; std::string s = filepath;
#else #else
@@ -3140,6 +3192,7 @@ static bool ParseJsonAsValue(Value *ret, const json &o) {
break; break;
case json::value_t::null: case json::value_t::null:
case json::value_t::discarded: case json::value_t::discarded:
case json::value_t::binary:
// default: // default:
break; break;
} }
@@ -4410,6 +4463,7 @@ static bool GetAttributeForAllPoints(uint32_t componentType, draco::Mesh *mesh,
static bool ParseDracoExtension(Primitive *primitive, Model *model, static bool ParseDracoExtension(Primitive *primitive, Model *model,
std::string *err, std::string *err,
const Value &dracoExtensionValue) { const Value &dracoExtensionValue) {
(void)err;
auto bufferViewValue = dracoExtensionValue.Get("bufferView"); auto bufferViewValue = dracoExtensionValue.Get("bufferView");
if (!bufferViewValue.IsInt()) return false; if (!bufferViewValue.IsInt()) return false;
auto attributesValue = dracoExtensionValue.Get("attributes"); auto attributesValue = dracoExtensionValue.Get("attributes");
@@ -4470,7 +4524,6 @@ static bool ParseDracoExtension(Primitive *primitive, Model *model,
int dracoAttributeIndex = attribute.second.Get<int>(); int dracoAttributeIndex = attribute.second.Get<int>();
const auto pAttribute = mesh->GetAttributeByUniqueId(dracoAttributeIndex); const auto pAttribute = mesh->GetAttributeByUniqueId(dracoAttributeIndex);
const auto pBuffer = pAttribute->buffer();
const auto componentType = const auto componentType =
model->accessors[primitiveAttribute->second].componentType; model->accessors[primitiveAttribute->second].componentType;
@@ -5029,12 +5082,12 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
int magFilter = -1; int magFilter = -1;
int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT; int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT; int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; //int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
ParseIntegerProperty(&minFilter, err, o, "minFilter", false); ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
ParseIntegerProperty(&magFilter, err, o, "magFilter", false); ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
ParseIntegerProperty(&wrapS, err, o, "wrapS", false); ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
ParseIntegerProperty(&wrapT, err, o, "wrapT", false); ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension //ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
// TODO(syoyo): Check the value is alloed one. // TODO(syoyo): Check the value is alloed one.
// (e.g. we allow 9728(NEAREST), but don't allow 9727) // (e.g. we allow 9728(NEAREST), but don't allow 9727)
@@ -5043,7 +5096,7 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
sampler->magFilter = magFilter; sampler->magFilter = magFilter;
sampler->wrapS = wrapS; sampler->wrapS = wrapS;
sampler->wrapT = wrapT; sampler->wrapT = wrapT;
sampler->wrapR = wrapR; //sampler->wrapR = wrapR;
ParseExtensionsProperty(&(sampler->extensions), err, o); ParseExtensionsProperty(&(sampler->extensions), err, o);
ParseExtrasProperty(&(sampler->extras), o); ParseExtrasProperty(&(sampler->extras), o);
@@ -5770,13 +5823,13 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
{ {
json_const_iterator it; json_const_iterator it;
if (FindMember(o, "extensions", it)) { if (FindMember(o, "extensions", it)) {
model->extensions_json_string = JsonToString(GetValue(it)); scene.extensions_json_string = JsonToString(GetValue(it));
} }
} }
{ {
json_const_iterator it; json_const_iterator it;
if (FindMember(o, "extras", it)) { if (FindMember(o, "extras", it)) {
model->extras_json_string = JsonToString(GetValue(it)); scene.extras_json_string = JsonToString(GetValue(it));
} }
} }
} }
@@ -5826,6 +5879,18 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
} }
// 11. Parse Image // 11. Parse Image
void *load_image_user_data{nullptr};
LoadImageDataOption load_image_option;
if (user_image_loader_) {
// Use user supplied pointer
load_image_user_data = load_image_user_data_;
} else {
load_image_option.preserve_channels = preserve_image_channels_;
load_image_user_data = reinterpret_cast<void *>(&load_image_option);
}
{ {
int idx = 0; int idx = 0;
bool success = ForEachInArray(v, "images", [&](const json &o) { bool success = ForEachInArray(v, "images", [&](const json &o) {
@@ -5838,7 +5903,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
Image image; Image image;
if (!ParseImage(&image, idx, err, warn, o, if (!ParseImage(&image, idx, err, warn, o,
store_original_json_for_extras_and_extensions_, base_dir, store_original_json_for_extras_and_extensions_, base_dir,
&fs, &this->LoadImageData, load_image_user_data_)) { &fs, &this->LoadImageData, load_image_user_data)) {
return false; return false;
} }
@@ -5876,7 +5941,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
bool ret = LoadImageData( bool ret = LoadImageData(
&image, idx, err, warn, image.width, image.height, &image, idx, err, warn, image.width, image.height,
&buffer.data[bufferView.byteOffset], &buffer.data[bufferView.byteOffset],
static_cast<int>(bufferView.byteLength), load_image_user_data_); static_cast<int>(bufferView.byteLength), load_image_user_data);
if (!ret) { if (!ret) {
return false; return false;
} }
@@ -6552,8 +6617,33 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
SerializeNumberProperty<int>("componentType", accessor.componentType, o); SerializeNumberProperty<int>("componentType", accessor.componentType, o);
SerializeNumberProperty<size_t>("count", accessor.count, o); SerializeNumberProperty<size_t>("count", accessor.count, o);
SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o); if ((accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT) ||
(accessor.componentType == TINYGLTF_COMPONENT_TYPE_DOUBLE)) {
SerializeNumberArrayProperty<double>("min", accessor.minValues, o);
SerializeNumberArrayProperty<double>("max", accessor.maxValues, o);
} else {
// Issue #301. Serialize as integer.
// Assume int value is within [-2**31-1, 2**31-1]
{
std::vector<int> values;
std::transform(accessor.minValues.begin(), accessor.minValues.end(),
std::back_inserter(values),
[](double v) { return static_cast<int>(v); });
SerializeNumberArrayProperty<int>("min", values, o);
}
{
std::vector<int> values;
std::transform(accessor.maxValues.begin(), accessor.maxValues.end(),
std::back_inserter(values),
[](double v) { return static_cast<int>(v); });
SerializeNumberArrayProperty<int>("max", values, o);
}
}
if (accessor.normalized) if (accessor.normalized)
SerializeValue("normalized", Value(accessor.normalized), o); SerializeValue("normalized", Value(accessor.normalized), o);
std::string type; std::string type;
@@ -6663,10 +6753,15 @@ static void SerializeGltfAsset(Asset &asset, json &o) {
SerializeStringProperty("copyright", asset.copyright, o); SerializeStringProperty("copyright", asset.copyright, o);
} }
if (!asset.version.empty()) { if (asset.version.empty()) {
SerializeStringProperty("version", asset.version, o); // Just in case
// `version` must be defined
asset.version = "2.0";
} }
// TODO(syoyo): Do we need to check if `version` is greater or equal to 2.0?
SerializeStringProperty("version", asset.version, o);
if (asset.extras.Keys().size()) { if (asset.extras.Keys().size()) {
SerializeValue("extras", asset.extras, o); SerializeValue("extras", asset.extras, o);
} }
@@ -7064,7 +7159,7 @@ static void SerializeGltfSampler(Sampler &sampler, json &o) {
if (sampler.minFilter != -1) { if (sampler.minFilter != -1) {
SerializeNumberProperty("minFilter", sampler.minFilter, o); SerializeNumberProperty("minFilter", sampler.minFilter, o);
} }
SerializeNumberProperty("wrapR", sampler.wrapR, o); //SerializeNumberProperty("wrapR", sampler.wrapR, o);
SerializeNumberProperty("wrapS", sampler.wrapS, o); SerializeNumberProperty("wrapS", sampler.wrapS, o);
SerializeNumberProperty("wrapT", sampler.wrapT, o); SerializeNumberProperty("wrapT", sampler.wrapT, o);
@@ -7139,11 +7234,17 @@ static void SerializeGltfScene(Scene &scene, json &o) {
} }
static void SerializeGltfSkin(Skin &skin, json &o) { static void SerializeGltfSkin(Skin &skin, json &o) {
if (skin.inverseBindMatrices != -1) // required
SerializeNumberProperty("inverseBindMatrices", skin.inverseBindMatrices, o);
SerializeNumberArrayProperty<int>("joints", skin.joints, o); SerializeNumberArrayProperty<int>("joints", skin.joints, o);
SerializeNumberProperty("skeleton", skin.skeleton, o);
if (skin.inverseBindMatrices >= 0) {
SerializeNumberProperty("inverseBindMatrices", skin.inverseBindMatrices, o);
}
if (skin.skeleton >= 0) {
SerializeNumberProperty("skeleton", skin.skeleton, o);
}
if (skin.name.size()) { if (skin.name.size()) {
SerializeStringProperty("name", skin.name, o); SerializeStringProperty("name", skin.name, o);
} }
@@ -7230,7 +7331,8 @@ static void SerializeGltfModel(Model *model, json &o) {
if (JsonIsNull(material)) { if (JsonIsNull(material)) {
// Issue 294. // Issue 294.
// `material` does not have any required parameters // `material` does not have any required parameters
// so the result may be null(unmodified) when all material parameters have default value. // so the result may be null(unmodified) when all material parameters
// have default value.
// //
// null is not allowed thus we create an empty JSON object. // null is not allowed thus we create an empty JSON object.
JsonSetObject(material); JsonSetObject(material);
@@ -7373,7 +7475,7 @@ static void SerializeGltfModel(Model *model, json &o) {
} }
// Extensions used // Extensions used
if (model->extensionsUsed.size()) { if (extensionsUsed.size()) {
SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o); SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o);
} }
@@ -7417,31 +7519,24 @@ static void WriteBinaryGltfStream(std::ostream &stream,
const std::string header = "glTF"; const std::string header = "glTF";
const int version = 2; const int version = 2;
// https://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number const uint32_t content_size = uint32_t(content.size());
auto roundUp = [](uint32_t numToRound, uint32_t multiple) { const uint32_t binBuffer_size = uint32_t(binBuffer.size());
if (multiple == 0) return numToRound; // determine number of padding bytes required to ensure 4 byte alignment
const uint32_t content_padding_size = content_size % 4 == 0 ? 0 : 4 - content_size % 4;
uint32_t remainder = numToRound % multiple; const uint32_t bin_padding_size = binBuffer_size % 4 == 0 ? 0 : 4 - binBuffer_size % 4;
if (remainder == 0) return numToRound;
return numToRound + multiple - remainder;
};
const uint32_t padding_size =
roundUp(uint32_t(content.size()), 4) - uint32_t(content.size());
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info. // 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
// Chunk data must be located at 4-byte boundary. // Chunk data must be located at 4-byte boundary, which may require padding
const uint32_t length = const uint32_t length =
12 + 8 + roundUp(uint32_t(content.size()), 4) + 12 + 8 + content_size + content_padding_size +
(binBuffer.size() ? (8 + roundUp(uint32_t(binBuffer.size()), 4)) : 0); (binBuffer_size ? (8 + binBuffer_size + bin_padding_size) : 0);
stream.write(header.c_str(), std::streamsize(header.size())); stream.write(header.c_str(), std::streamsize(header.size()));
stream.write(reinterpret_cast<const char *>(&version), sizeof(version)); stream.write(reinterpret_cast<const char *>(&version), sizeof(version));
stream.write(reinterpret_cast<const char *>(&length), sizeof(length)); stream.write(reinterpret_cast<const char *>(&length), sizeof(length));
// JSON chunk info, then JSON data // JSON chunk info, then JSON data
const uint32_t model_length = uint32_t(content.size()) + padding_size; const uint32_t model_length = uint32_t(content.size()) + content_padding_size;
const uint32_t model_format = 0x4E4F534A; const uint32_t model_format = 0x4E4F534A;
stream.write(reinterpret_cast<const char *>(&model_length), stream.write(reinterpret_cast<const char *>(&model_length),
sizeof(model_length)); sizeof(model_length));
@@ -7450,13 +7545,11 @@ static void WriteBinaryGltfStream(std::ostream &stream,
stream.write(content.c_str(), std::streamsize(content.size())); stream.write(content.c_str(), std::streamsize(content.size()));
// Chunk must be multiplies of 4, so pad with spaces // Chunk must be multiplies of 4, so pad with spaces
if (padding_size > 0) { if (content_padding_size > 0) {
const std::string padding = std::string(size_t(padding_size), ' '); const std::string padding = std::string(size_t(content_padding_size), ' ');
stream.write(padding.c_str(), std::streamsize(padding.size())); stream.write(padding.c_str(), std::streamsize(padding.size()));
} }
if (binBuffer.size() > 0) { if (binBuffer.size() > 0) {
const uint32_t bin_padding_size =
roundUp(uint32_t(binBuffer.size()), 4) - uint32_t(binBuffer.size());
// BIN chunk info, then BIN data // BIN chunk info, then BIN data
const uint32_t bin_length = uint32_t(binBuffer.size()) + bin_padding_size; const uint32_t bin_length = uint32_t(binBuffer.size()) + bin_padding_size;
const uint32_t bin_format = 0x004e4942; const uint32_t bin_format = 0x004e4942;