mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-23 16:23:14 +08:00
Merge branch 'separate-serializer' into sajson
This commit is contained in:
commit
6fcee26d0f
165
.github/workflows/c-cpp.yml
vendored
Normal file
165
.github/workflows/c-cpp.yml
vendored
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
name: C/C++ CI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# compile with older gcc4.8
|
||||||
|
build-gcc48:
|
||||||
|
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
name: Build with gcc 4.8
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y build-essential
|
||||||
|
sudo apt-get install -y gcc-4.8 g++-4.8
|
||||||
|
g++-4.8 -std=c++11 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
- name: NoexceptBuild
|
||||||
|
run: |
|
||||||
|
g++-4.8 -DTINYGLTF_NOEXCEPTION -std=c++11 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
- name: RapidjsonBuild
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/Tencent/rapidjson
|
||||||
|
g++-4.8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
# compile with mingw gcc cross
|
||||||
|
build-mingw-cross:
|
||||||
|
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
name: Build with MinGW gcc cross
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y build-essential
|
||||||
|
sudo apt-get install -y mingw-w64
|
||||||
|
x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
# Windows(x64) + Visual Studio 2019 build
|
||||||
|
build-windows-msvc:
|
||||||
|
|
||||||
|
runs-on: windows-latest
|
||||||
|
name: Build for Windows(x64, MSVC)
|
||||||
|
|
||||||
|
# Use system installed cmake
|
||||||
|
# https://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: Configure
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -G "Visual Studio 16 2019" -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On ..
|
||||||
|
cd ..
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --config Release
|
||||||
|
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Buld with gcc
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
g++ -std=c++11 -o loader_example loader_example.cc
|
||||||
|
- name: test
|
||||||
|
run: |
|
||||||
|
./loader_example models/Cube/Cube.gltf
|
||||||
|
|
||||||
|
- name: tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
g++ -I../ -std=c++11 -g -O0 -o tester tester.cc
|
||||||
|
./tester
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- name: noexcept_tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc
|
||||||
|
./tester_noexcept
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
|
||||||
|
build-rapidjson-linux:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Buld with gcc + rapidjson
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
git clone https://github.com/Tencent/rapidjson
|
||||||
|
g++ -v
|
||||||
|
g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
- name: loader_example_test
|
||||||
|
run: |
|
||||||
|
./loader_example models/Cube/Cube.gltf
|
||||||
|
|
||||||
|
- name: tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc
|
||||||
|
./tester
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- name: noexcept_tests
|
||||||
|
run: |
|
||||||
|
cd tests
|
||||||
|
g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc
|
||||||
|
./tester_noexcept
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Cross-compile for aarch64 linux target
|
||||||
|
build-cross-aarch64:
|
||||||
|
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
name: Build on cross aarch64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y build-essential
|
||||||
|
sudo apt-get install -y gcc-8-aarch64-linux-gnu g++-8-aarch64-linux-gnu
|
||||||
|
|
||||||
|
git clone https://github.com/Tencent/rapidjson
|
||||||
|
aarch64-linux-gnu-g++-8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc
|
||||||
|
|
||||||
|
# macOS clang
|
||||||
|
build-macos:
|
||||||
|
|
||||||
|
runs-on: macos-latest
|
||||||
|
name: Build on macOS
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
clang++ -std=c++11 -g -O0 -o loader_example loader_example.cc
|
||||||
|
./loader_example models/Cube/Cube.gltf
|
||||||
|
|
||||||
|
git clone https://github.com/Tencent/rapidjson
|
||||||
|
clang++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc
|
||||||
|
|
@ -4,18 +4,24 @@ PROJECT (tinygltf)
|
|||||||
|
|
||||||
SET(CMAKE_CXX_STANDARD 11)
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
option(TINYGLTF_BUILD_EXAMPLES "Build examples" ON)
|
option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example" ON)
|
||||||
|
option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF)
|
||||||
|
option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF)
|
||||||
|
|
||||||
if (TINYGLTF_BUILD_EXAMPLES)
|
if (TINYGLTF_BUILD_LOADER_EXAMPLE)
|
||||||
ADD_EXECUTABLE ( loader_example
|
ADD_EXECUTABLE ( loader_example
|
||||||
loader_example.cc
|
loader_example.cc
|
||||||
)
|
)
|
||||||
|
endif (TINYGLTF_BUILD_LOADER_EXAMPLE)
|
||||||
|
|
||||||
|
if (TINYGLTF_BUILD_GL_EXAMPLES)
|
||||||
ADD_SUBDIRECTORY ( examples/gltfutil )
|
ADD_SUBDIRECTORY ( examples/gltfutil )
|
||||||
ADD_SUBDIRECTORY ( examples/glview )
|
ADD_SUBDIRECTORY ( examples/glview )
|
||||||
ADD_SUBDIRECTORY ( examples/validator )
|
endif (TINYGLTF_BUILD_GL_EXAMPLES)
|
||||||
endif (TINYGLTF_BUILD_EXAMPLES)
|
|
||||||
|
|
||||||
|
if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
|
||||||
|
ADD_SUBDIRECTORY ( examples/validator )
|
||||||
|
endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE)
|
||||||
#
|
#
|
||||||
# TinuGLTF is a header-only library, so no library build. just install header files.
|
# TinuGLTF is a header-only library, so no library build. just install header files.
|
||||||
#
|
#
|
||||||
|
@ -19,6 +19,8 @@ If you are looking for old, C++03 version, please use `devel-picojson` branch.
|
|||||||
|
|
||||||
[](https://ci.appveyor.com/project/syoyo/tinygltf)
|
[](https://ci.appveyor.com/project/syoyo/tinygltf)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Written in portable C++. C++-11 with STL dependency only.
|
* Written in portable C++. C++-11 with STL dependency only.
|
||||||
@ -83,6 +85,7 @@ In extension(`ExtensionMap`), JSON number value is parsed as int or float(number
|
|||||||
* [QuickLook GLTF](https://github.com/toshiks/glTF-quicklook) - quicklook plugin for macos. Also SceneKit wrapper for tinygltf.
|
* [QuickLook GLTF](https://github.com/toshiks/glTF-quicklook) - quicklook plugin for macos. Also SceneKit wrapper for tinygltf.
|
||||||
* [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
|
||||||
* Your projects here! (Please send PR)
|
* Your projects here! (Please send PR)
|
||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
@ -150,6 +153,7 @@ if (!ret) {
|
|||||||
|
|
||||||
## Compile options
|
## Compile options
|
||||||
|
|
||||||
|
* `TINYGLTF_ENABLE_SERIALIZER` : Enable glTF serialization feature.
|
||||||
* `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.
|
||||||
* `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images.
|
* `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images.
|
||||||
* `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images.
|
* `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images.
|
||||||
|
BIN
models/Extensions-overwrite-issue261/issue-261.bin
Normal file
BIN
models/Extensions-overwrite-issue261/issue-261.bin
Normal file
Binary file not shown.
376
models/Extensions-overwrite-issue261/issue-261.gltf
Normal file
376
models/Extensions-overwrite-issue261/issue-261.gltf
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
{
|
||||||
|
"accessors": [
|
||||||
|
{
|
||||||
|
"bufferView": 0,
|
||||||
|
"componentType": 5126,
|
||||||
|
"count": 8,
|
||||||
|
"max": [
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
0.5
|
||||||
|
],
|
||||||
|
"min": [
|
||||||
|
-0.5,
|
||||||
|
-0.5,
|
||||||
|
-0.5
|
||||||
|
],
|
||||||
|
"type": "VEC3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bufferView": 1,
|
||||||
|
"componentType": 5125,
|
||||||
|
"count": 36,
|
||||||
|
"type": "SCALAR"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asset": {
|
||||||
|
"copyright": "NVIDIA Corporation",
|
||||||
|
"generator": "Iray glTF plugin",
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"bufferViews": [
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 96,
|
||||||
|
"byteStride": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"buffer": 0,
|
||||||
|
"byteLength": 144,
|
||||||
|
"byteOffset": 96
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buffers": [
|
||||||
|
{
|
||||||
|
"byteLength": 240,
|
||||||
|
"uri": "issue-261.bin"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cameras": [
|
||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"NV_Iray": {
|
||||||
|
"mip_burn_highlights": 0.699999988079071,
|
||||||
|
"mip_burn_highlights_per_component": false,
|
||||||
|
"mip_camera_shutter": 4.0,
|
||||||
|
"mip_cm2_factor": 1.0,
|
||||||
|
"mip_crush_blacks": 0.5,
|
||||||
|
"mip_f_number": 1.0,
|
||||||
|
"mip_film_iso": 100.0,
|
||||||
|
"mip_gamma": 2.200000047683716,
|
||||||
|
"mip_saturation": 1.0,
|
||||||
|
"mip_vignetting": 0.00019999999494757503,
|
||||||
|
"mip_whitepoint": [
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"tm_enable_tonemapper": true,
|
||||||
|
"tm_tonemapper": "mia_exposure_photographic"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extras": {
|
||||||
|
"resolution": [
|
||||||
|
640,
|
||||||
|
480
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "default",
|
||||||
|
"perspective": {
|
||||||
|
"aspectRatio": 1.3333333730697632,
|
||||||
|
"yfov": 0.9272952079772949,
|
||||||
|
"zfar": 1000.0,
|
||||||
|
"znear": 0.1
|
||||||
|
},
|
||||||
|
"type": "perspective"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"extensions": {
|
||||||
|
"KHR_lights_punctual": {
|
||||||
|
"lights": [
|
||||||
|
{
|
||||||
|
"color": [
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"intensity": 1000.0,
|
||||||
|
"name": "light",
|
||||||
|
"type": "point"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NV_MDL": {
|
||||||
|
"modules": [
|
||||||
|
"mdl::base",
|
||||||
|
"mdl::nvidia::core_definitions",
|
||||||
|
"mdl::state"
|
||||||
|
],
|
||||||
|
"shaders": [
|
||||||
|
{
|
||||||
|
"definition": "mdl::base::environment_spherical(texture_2d)",
|
||||||
|
"name": "env_shd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": {
|
||||||
|
"base_color": [
|
||||||
|
0.0055217444896698,
|
||||||
|
0.36859095096588135,
|
||||||
|
0.0041161770932376385
|
||||||
|
],
|
||||||
|
"normal=": 2
|
||||||
|
},
|
||||||
|
"definition": "mdl::nvidia::core_definitions::flex_material",
|
||||||
|
"name": "cube_instance_material"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"definition": "mdl::state::normal()",
|
||||||
|
"name": "mdl::state::normal_341"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arguments": {
|
||||||
|
"base_color": [
|
||||||
|
0.0055217444896698,
|
||||||
|
0.36859095096588135,
|
||||||
|
0.0041161770932376385
|
||||||
|
],
|
||||||
|
"normal=": 4
|
||||||
|
},
|
||||||
|
"definition": "mdl::nvidia::core_definitions::flex_material",
|
||||||
|
"name": "cube_instance_material"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"definition": "mdl::state::normal()",
|
||||||
|
"name": "mdl::state::normal_341"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extensionsUsed": [
|
||||||
|
"NV_MDL",
|
||||||
|
"NV_Iray",
|
||||||
|
"KHR_lights_punctual"
|
||||||
|
],
|
||||||
|
"materials": [
|
||||||
|
{
|
||||||
|
"doubleSided": true,
|
||||||
|
"extras": {
|
||||||
|
"mdl_shader": 1
|
||||||
|
},
|
||||||
|
"name": "cube_instance_material",
|
||||||
|
"pbrMetallicRoughness": {
|
||||||
|
"baseColorFactor": [
|
||||||
|
0.0055217444896698,
|
||||||
|
0.36859095096588135,
|
||||||
|
0.0041161770932376385,
|
||||||
|
1.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"meshes": [
|
||||||
|
{
|
||||||
|
"name": "cube",
|
||||||
|
"primitives": [
|
||||||
|
{
|
||||||
|
"attributes": {
|
||||||
|
"POSITION": 0
|
||||||
|
},
|
||||||
|
"indices": 1,
|
||||||
|
"material": 0,
|
||||||
|
"mode": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"camera": 0,
|
||||||
|
"extensions": {
|
||||||
|
"NV_Iray": {
|
||||||
|
"iview:fkey": -1,
|
||||||
|
"iview:fov": 53.130104064941406,
|
||||||
|
"iview:interest": [
|
||||||
|
0.1342654824256897,
|
||||||
|
-0.14356137812137604,
|
||||||
|
0.037264324724674225
|
||||||
|
],
|
||||||
|
"iview:position": [
|
||||||
|
0.9729073643684387,
|
||||||
|
1.2592438459396362,
|
||||||
|
2.4199187755584717
|
||||||
|
],
|
||||||
|
"iview:roll": 0.0,
|
||||||
|
"iview:up": [
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
0.0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"matrix": [
|
||||||
|
0.9432751389105357,
|
||||||
|
-1.1769874756875739e-16,
|
||||||
|
-0.3320120665176343,
|
||||||
|
0.0,
|
||||||
|
-0.16119596696756341,
|
||||||
|
0.8742297945345237,
|
||||||
|
-0.45797175303889276,
|
||||||
|
0.0,
|
||||||
|
0.290254840694694,
|
||||||
|
0.48551237507207207,
|
||||||
|
0.8246392308792816,
|
||||||
|
0.0,
|
||||||
|
0.9729073377709113,
|
||||||
|
1.2592438262175363,
|
||||||
|
2.419918748461627,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"name": "CamInst"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"NV_Iray": {
|
||||||
|
"caustic": true,
|
||||||
|
"caustic_cast": true,
|
||||||
|
"caustic_recv": true,
|
||||||
|
"face_back": true,
|
||||||
|
"face_front": true,
|
||||||
|
"finalgather": true,
|
||||||
|
"finalgather_cast": true,
|
||||||
|
"finalgather_recv": true,
|
||||||
|
"globillum": true,
|
||||||
|
"globillum_cast": true,
|
||||||
|
"globillum_recv": true,
|
||||||
|
"material=": 3,
|
||||||
|
"pickable": true,
|
||||||
|
"reflection_cast": true,
|
||||||
|
"reflection_recv": true,
|
||||||
|
"refraction_cast": true,
|
||||||
|
"refraction_recv": true,
|
||||||
|
"shadow_cast": true,
|
||||||
|
"shadow_recv": true,
|
||||||
|
"transparency_cast": true,
|
||||||
|
"transparency_recv": true,
|
||||||
|
"visible": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mesh": 0,
|
||||||
|
"name": "cube_instance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"KHR_lights_punctual": {
|
||||||
|
"light": 0
|
||||||
|
},
|
||||||
|
"NV_Iray": {
|
||||||
|
"shadow_cast": true,
|
||||||
|
"visible": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"matrix": [
|
||||||
|
0.6988062355563571,
|
||||||
|
-7.76042172309776e-17,
|
||||||
|
-0.7153110128800992,
|
||||||
|
-0.0,
|
||||||
|
-0.4276881690736487,
|
||||||
|
0.8015668284138362,
|
||||||
|
-0.41781987700564616,
|
||||||
|
-0.0,
|
||||||
|
0.57336957992379,
|
||||||
|
0.5979051928078428,
|
||||||
|
0.5601398979107212,
|
||||||
|
0.0,
|
||||||
|
2.3640632834071384,
|
||||||
|
2.465226204472449,
|
||||||
|
2.309515908392224,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"name": "light_inst"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"NV_Iray": {
|
||||||
|
"CP_canny_threshold1": 40,
|
||||||
|
"CP_canny_threshold2": 120,
|
||||||
|
"CP_color_quantization": 8,
|
||||||
|
"IVP_color": [
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"TM_drago_bias": 0.8500000238418579,
|
||||||
|
"TM_drago_gamma2": 2.200000047683716,
|
||||||
|
"TM_drago_saturation": 1.0,
|
||||||
|
"TM_durand_contrast": 4.0,
|
||||||
|
"TM_durand_gamma": 2.200000047683716,
|
||||||
|
"TM_durand_saturation": 1.0,
|
||||||
|
"TM_durand_sigma_color": 2.0,
|
||||||
|
"TM_durand_sigma_space": 2.0,
|
||||||
|
"TM_linear_gamma": 2.200000047683716,
|
||||||
|
"TM_reinhard_color_adapt": 0.8999999761581421,
|
||||||
|
"TM_reinhard_gamma": 1.0,
|
||||||
|
"TM_reinhard_intensity": 0.0,
|
||||||
|
"TM_reinhard_light_adapt": 1.0,
|
||||||
|
"TM_reye_Ywhite": 1000000.0,
|
||||||
|
"TM_reye_bsize": 2,
|
||||||
|
"TM_reye_bthres": 3.0,
|
||||||
|
"TM_reye_gamma": 2.200000047683716,
|
||||||
|
"TM_reye_key": 0.5,
|
||||||
|
"TM_reye_saturation": 1.0,
|
||||||
|
"TM_reye_whitebalance": [
|
||||||
|
1.0,
|
||||||
|
0.9965101480484009,
|
||||||
|
0.9805564880371094,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"environment_dome_depth": 200.0,
|
||||||
|
"environment_dome_height": 200.0,
|
||||||
|
"environment_dome_mode": "infinite",
|
||||||
|
"environment_dome_position": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0
|
||||||
|
],
|
||||||
|
"environment_dome_radius": 100.0,
|
||||||
|
"environment_dome_rotation_angle": 0.0,
|
||||||
|
"environment_dome_width": 200.0,
|
||||||
|
"environment_function=": 0,
|
||||||
|
"environment_function_intensity": 1.9900000095367432,
|
||||||
|
"iray_instancing": "off",
|
||||||
|
"iview::inline_color": [
|
||||||
|
1.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"iview::inline_width": 1.0,
|
||||||
|
"iview::magnifier_size": 300,
|
||||||
|
"iview::offset": 10.0,
|
||||||
|
"iview::outline_color": [
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
1.0
|
||||||
|
],
|
||||||
|
"iview::outline_width": 2.0,
|
||||||
|
"iview::overview": true,
|
||||||
|
"iview::zoom_factor": 1.0,
|
||||||
|
"samples": 4.0,
|
||||||
|
"shadow_cast": true,
|
||||||
|
"shadow_recv": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nodes": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -93,6 +93,59 @@ TEST_CASE("extension-with-empty-object", "[issue-97]") {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("extension-overwrite", "[issue-261]") {
|
||||||
|
|
||||||
|
tinygltf::Model model;
|
||||||
|
tinygltf::TinyGLTF ctx;
|
||||||
|
std::string err;
|
||||||
|
std::string warn;
|
||||||
|
|
||||||
|
bool ret = ctx.LoadASCIIFromFile(&model, &err, &warn, "../models/Extensions-overwrite-issue261/issue-261.gltf");
|
||||||
|
if (!err.empty()) {
|
||||||
|
std::cerr << err << std::endl;
|
||||||
|
}
|
||||||
|
REQUIRE(true == ret);
|
||||||
|
|
||||||
|
REQUIRE(model.extensionsUsed.size() == 3);
|
||||||
|
{
|
||||||
|
bool has_ext_lights = false;
|
||||||
|
has_ext_lights |= (model.extensionsUsed[0].compare("KHR_lights_punctual") == 0);
|
||||||
|
has_ext_lights |= (model.extensionsUsed[1].compare("KHR_lights_punctual") == 0);
|
||||||
|
has_ext_lights |= (model.extensionsUsed[2].compare("KHR_lights_punctual") == 0);
|
||||||
|
|
||||||
|
REQUIRE(true == has_ext_lights);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
REQUIRE(model.extensions.size() == 2);
|
||||||
|
REQUIRE(model.extensions.count("NV_MDL"));
|
||||||
|
REQUIRE(model.extensions.count("KHR_lights_punctual"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(syoyo): create temp directory.
|
||||||
|
{
|
||||||
|
ret = ctx.WriteGltfSceneToFile(&model, "issue-261.gltf", true, true);
|
||||||
|
REQUIRE(true == ret);
|
||||||
|
|
||||||
|
tinygltf::Model m;
|
||||||
|
|
||||||
|
// read back serialized glTF
|
||||||
|
bool ret = ctx.LoadASCIIFromFile(&m, &err, &warn, "issue-261.gltf");
|
||||||
|
if (!err.empty()) {
|
||||||
|
std::cerr << err << std::endl;
|
||||||
|
}
|
||||||
|
REQUIRE(true == ret);
|
||||||
|
|
||||||
|
REQUIRE(m.extensionsUsed.size() == 3);
|
||||||
|
|
||||||
|
REQUIRE(m.extensions.size() == 2);
|
||||||
|
REQUIRE(m.extensions.count("NV_MDL"));
|
||||||
|
REQUIRE(m.extensions.count("KHR_lights_punctual"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("invalid-primitive-indices", "[bounds-checking]") {
|
TEST_CASE("invalid-primitive-indices", "[bounds-checking]") {
|
||||||
tinygltf::Model model;
|
tinygltf::Model model;
|
||||||
tinygltf::TinyGLTF ctx;
|
tinygltf::TinyGLTF ctx;
|
||||||
@ -359,3 +412,19 @@ TEST_CASE("image-uri-spaces", "[issue-236]") {
|
|||||||
REQUIRE(true == ret);
|
REQUIRE(true == ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TINYGLTF_NO_FS
|
||||||
|
TEST_CASE("expandpath-utf-8", "[pr-226]") {
|
||||||
|
|
||||||
|
std::string s1 = "\xe5\xaf\xb9"; // utf-8 string
|
||||||
|
|
||||||
|
std::string ret = tinygltf::ExpandFilePath(s1, /* userdata */nullptr);
|
||||||
|
|
||||||
|
// expected: E5 AF B9
|
||||||
|
REQUIRE(3 == ret.size());
|
||||||
|
|
||||||
|
REQUIRE(0xe5 == static_cast<uint8_t>(ret[0]));
|
||||||
|
REQUIRE(0xaf == static_cast<uint8_t>(ret[1]));
|
||||||
|
REQUIRE(0xb9 == static_cast<uint8_t>(ret[2]));
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
197
tiny_gltf.h
197
tiny_gltf.h
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
// Version:
|
// Version:
|
||||||
// - v2.4.3 Experimental sajson(lightweight JSON parser) backend support.
|
// - v2.4.3 Experimental sajson(lightweight JSON parser) backend support.
|
||||||
|
// Introduce TINYGLTF_ENABLE_SERIALIZER.
|
||||||
// - 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.
|
||||||
@ -54,6 +55,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cmath> // std::fabs
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -61,7 +63,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath> // std::fabs
|
|
||||||
|
|
||||||
#ifndef TINYGLTF_USE_CPP14
|
#ifndef TINYGLTF_USE_CPP14
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -325,7 +326,8 @@ class Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use this function if you want to have number value as int.
|
// Use this function if you want to have number value as int.
|
||||||
double GetNumberAsInt() const {
|
// TODO(syoyo): Support int value larger than 32 bits
|
||||||
|
int GetNumberAsInt() const {
|
||||||
if (type_ == REAL_TYPE) {
|
if (type_ == REAL_TYPE) {
|
||||||
return int(real_value_);
|
return int(real_value_);
|
||||||
} else {
|
} else {
|
||||||
@ -1116,9 +1118,9 @@ struct SpotLight {
|
|||||||
struct Light {
|
struct Light {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<double> color;
|
std::vector<double> color;
|
||||||
double intensity;
|
double intensity{1.0};
|
||||||
std::string type;
|
std::string type;
|
||||||
double range;
|
double range{0.0}; // 0.0 = inifinite
|
||||||
SpotLight spot;
|
SpotLight spot;
|
||||||
|
|
||||||
Light() : intensity(1.0), range(0.0) {}
|
Light() : intensity(1.0), range(0.0) {}
|
||||||
@ -1250,7 +1252,13 @@ struct FsCallbacks {
|
|||||||
|
|
||||||
bool FileExists(const std::string &abs_filename, void *);
|
bool FileExists(const std::string &abs_filename, void *);
|
||||||
|
|
||||||
std::string ExpandFilePath(const std::string &filepath, void *);
|
///
|
||||||
|
/// Expand file path(e.g. `~` to home directory on posix, `%APPDATA%` to `C:\Users\tinygltf\AppData`)
|
||||||
|
///
|
||||||
|
/// @param[in] filepath File path string. Assume UTF-8
|
||||||
|
/// @param[in] userdata User data. Set to `nullptr` if you don't need it.
|
||||||
|
///
|
||||||
|
std::string ExpandFilePath(const std::string &filepath, void *userdata);
|
||||||
|
|
||||||
bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
||||||
const std::string &filepath, void *);
|
const std::string &filepath, void *);
|
||||||
@ -1318,6 +1326,8 @@ class TinyGLTF {
|
|||||||
const std::string &base_dir = "",
|
const std::string &base_dir = "",
|
||||||
unsigned int check_sections = REQUIRE_VERSION);
|
unsigned int check_sections = REQUIRE_VERSION);
|
||||||
|
|
||||||
|
#if defined(TINYGLTF_ENABLE_SERIALIZER)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Write glTF to stream, buffers and images will be embeded
|
/// Write glTF to stream, buffers and images will be embeded
|
||||||
///
|
///
|
||||||
@ -1331,16 +1341,22 @@ class TinyGLTF {
|
|||||||
bool embedImages, bool embedBuffers,
|
bool embedImages, bool embedBuffers,
|
||||||
bool prettyPrint, bool writeBinary);
|
bool prettyPrint, bool writeBinary);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set callback to use for loading image data
|
/// Set callback to use for loading image data
|
||||||
///
|
///
|
||||||
void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
|
void SetImageLoader(LoadImageDataFunction LoadImageData, void *user_data);
|
||||||
|
|
||||||
|
#if defined(TINYGLTF_ENABLE_SERIALIZER)
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set callback to use for writing image data
|
/// Set callback to use for writing image data
|
||||||
///
|
///
|
||||||
void SetImageWriter(WriteImageDataFunction WriteImageData, void *user_data);
|
void SetImageWriter(WriteImageDataFunction WriteImageData, void *user_data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set callbacks to use for filesystem (fs) access and their user data
|
/// Set callbacks to use for filesystem (fs) access and their user data
|
||||||
///
|
///
|
||||||
@ -2420,11 +2436,15 @@ bool LoadImageData(Image *image, const int image_idx, std::string *err,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TINYGLTF_ENABLE_SERIALIZER)
|
||||||
|
|
||||||
void TinyGLTF::SetImageWriter(WriteImageDataFunction func, void *user_data) {
|
void TinyGLTF::SetImageWriter(WriteImageDataFunction func, void *user_data) {
|
||||||
WriteImageData = func;
|
WriteImageData = func;
|
||||||
write_image_user_data_ = user_data;
|
write_image_user_data_ = user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
|
#ifndef TINYGLTF_NO_STB_IMAGE_WRITE
|
||||||
static void WriteToMemory_stbi(void *context, void *data, int size) {
|
static void WriteToMemory_stbi(void *context, void *data, int size) {
|
||||||
std::vector<unsigned char> *buffer =
|
std::vector<unsigned char> *buffer =
|
||||||
@ -2516,6 +2536,15 @@ static inline std::wstring UTF8ToWchar(const std::string &str) {
|
|||||||
(int)wstr.size());
|
(int)wstr.size());
|
||||||
return wstr;
|
return wstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline std::string WcharToUTF8(const std::wstring &wstr) {
|
||||||
|
int str_size = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(),
|
||||||
|
nullptr, 0, NULL, NULL);
|
||||||
|
std::string str(str_size, 0);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), (int)wstr.size(), &str[0],
|
||||||
|
(int)str.size(), NULL, NULL);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TINYGLTF_NO_FS
|
#ifndef TINYGLTF_NO_FS
|
||||||
@ -2567,15 +2596,16 @@ bool FileExists(const std::string &abs_filename, void *) {
|
|||||||
|
|
||||||
std::string ExpandFilePath(const std::string &filepath, void *) {
|
std::string ExpandFilePath(const std::string &filepath, void *) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0);
|
// Assume input `filepath` is encoded in UTF-8
|
||||||
char *str = new char[len];
|
std::wstring wfilepath = UTF8ToWchar(filepath);
|
||||||
ExpandEnvironmentStringsA(filepath.c_str(), str, len);
|
DWORD wlen = ExpandEnvironmentStringsW(wfilepath.c_str(), nullptr, 0);
|
||||||
|
wchar_t *wstr = new wchar_t[wlen];
|
||||||
|
ExpandEnvironmentStringsW(wfilepath.c_str(), wstr, wlen);
|
||||||
|
|
||||||
std::string s(str);
|
std::wstring ws(wstr);
|
||||||
|
delete[] wstr;
|
||||||
|
return WcharToUTF8(ws);
|
||||||
|
|
||||||
delete[] str;
|
|
||||||
|
|
||||||
return s;
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \
|
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \
|
||||||
@ -2651,9 +2681,11 @@ bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
|||||||
_wopen(UTF8ToWchar(filepath).c_str(), _O_RDONLY | _O_BINARY);
|
_wopen(UTF8ToWchar(filepath).c_str(), _O_RDONLY | _O_BINARY);
|
||||||
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor, std::ios_base::in);
|
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor, std::ios_base::in);
|
||||||
std::istream f(&wfile_buf);
|
std::istream f(&wfile_buf);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER) || defined(_LIBCPP_VERSION)
|
||||||
|
// For libcxx, assume _LIBCPP_HAS_OPEN_WITH_WCHAR is defined to accept `wchar_t *`
|
||||||
std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary);
|
std::ifstream f(UTF8ToWchar(filepath).c_str(), std::ifstream::binary);
|
||||||
#else // clang?
|
#else
|
||||||
|
// Unknown compiler/runtime
|
||||||
std::ifstream f(filepath.c_str(), std::ifstream::binary);
|
std::ifstream f(filepath.c_str(), std::ifstream::binary);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
@ -2695,12 +2727,10 @@ bool WriteWholeFile(std::string *err, const std::string &filepath,
|
|||||||
const std::vector<unsigned char> &contents, void *) {
|
const std::vector<unsigned char> &contents, void *) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#if defined(__GLIBCXX__) // mingw
|
#if defined(__GLIBCXX__) // mingw
|
||||||
int file_descriptor =
|
int file_descriptor = _wopen(UTF8ToWchar(filepath).c_str(),
|
||||||
_wopen(UTF8ToWchar(filepath).c_str(), _O_CREAT | _O_WRONLY |
|
_O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
|
||||||
_O_TRUNC | _O_BINARY);
|
__gnu_cxx::stdio_filebuf<char> wfile_buf(
|
||||||
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor,
|
file_descriptor, std::ios_base::out | std::ios_base::binary);
|
||||||
std::ios_base::out |
|
|
||||||
std::ios_base::binary);
|
|
||||||
std::ostream f(&wfile_buf);
|
std::ostream f(&wfile_buf);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
std::ofstream f(UTF8ToWchar(filepath).c_str(), std::ofstream::binary);
|
std::ofstream f(UTF8ToWchar(filepath).c_str(), std::ofstream::binary);
|
||||||
@ -2755,10 +2785,9 @@ static void UpdateImageObject(Image &image, std::string &baseDir, int index,
|
|||||||
if (image.uri.size()) {
|
if (image.uri.size()) {
|
||||||
filename = GetBaseFilename(image.uri);
|
filename = GetBaseFilename(image.uri);
|
||||||
ext = GetFilePathExtension(filename);
|
ext = GetFilePathExtension(filename);
|
||||||
}
|
} else if (image.bufferView != -1) {
|
||||||
else if (image.bufferView != -1) {
|
// If there's no URI and the data exists in a buffer,
|
||||||
//If there's no URI and the data exists in a buffer,
|
// don't change properties or write images
|
||||||
//don't change properties or write images
|
|
||||||
} else if (image.name.size()) {
|
} else if (image.name.size()) {
|
||||||
ext = MimeToExt(image.mimeType);
|
ext = MimeToExt(image.mimeType);
|
||||||
// Otherwise use name as filename
|
// Otherwise use name as filename
|
||||||
@ -4944,13 +4973,13 @@ static bool ParseAnimationChannel(
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ParseExtensionsProperty(&channel->target_extensions, err, target_object);
|
ParseExtensionsProperty(&channel->target_extensions, err, target_object);
|
||||||
if (store_original_json_for_extras_and_extensions) {
|
if (store_original_json_for_extras_and_extensions) {
|
||||||
json_const_iterator it;
|
json_const_iterator it;
|
||||||
if (FindMember(target_object, "extensions", it)) {
|
if (FindMember(target_object, "extensions", it)) {
|
||||||
channel->target_extensions_json_string = JsonToString(GetValue(it));
|
channel->target_extensions_json_string = JsonToString(GetValue(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->sampler = samplerIndex;
|
channel->sampler = samplerIndex;
|
||||||
@ -5761,9 +5790,11 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn,
|
|||||||
.target = TINYGLTF_TARGET_ARRAY_BUFFER;
|
.target = TINYGLTF_TARGET_ARRAY_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &target : primitive.targets) {
|
for (auto &target : primitive.targets) {
|
||||||
for(auto &attribute : target) {
|
for (auto &attribute : target) {
|
||||||
model->bufferViews[size_t(model->accessors[size_t(attribute.second)].bufferView)]
|
model
|
||||||
|
->bufferViews[size_t(
|
||||||
|
model->accessors[size_t(attribute.second)].bufferView)]
|
||||||
.target = TINYGLTF_TARGET_ARRAY_BUFFER;
|
.target = TINYGLTF_TARGET_ARRAY_BUFFER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6273,6 +6304,8 @@ bool TinyGLTF::LoadBinaryFromFile(Model *model, std::string *err,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TINYGLTF_ENABLE_SERIALIZER)
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
// GLTF Serialization
|
// GLTF Serialization
|
||||||
///////////////////////
|
///////////////////////
|
||||||
@ -6349,6 +6382,13 @@ static void SerializeNumberProperty(const std::string &key, T number,
|
|||||||
JsonAddMember(obj, key.c_str(), json(number));
|
JsonAddMember(obj, key.c_str(), json(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TINYGLTF_USE_RAPIDJSON
|
||||||
|
template <>
|
||||||
|
void SerializeNumberProperty(const std::string &key, size_t number, json &obj) {
|
||||||
|
JsonAddMember(obj, key.c_str(), json(static_cast<uint64_t>(number)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void SerializeNumberArrayProperty(const std::string &key,
|
static void SerializeNumberArrayProperty(const std::string &key,
|
||||||
const std::vector<T> &value,
|
const std::vector<T> &value,
|
||||||
@ -6499,12 +6539,10 @@ static bool SerializeGltfBufferData(const std::vector<unsigned char> &data,
|
|||||||
const std::string &binFilename) {
|
const std::string &binFilename) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#if defined(__GLIBCXX__) // mingw
|
#if defined(__GLIBCXX__) // mingw
|
||||||
int file_descriptor =
|
int file_descriptor = _wopen(UTF8ToWchar(binFilename).c_str(),
|
||||||
_wopen(UTF8ToWchar(binFilename).c_str(), _O_CREAT | _O_WRONLY |
|
_O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
|
||||||
_O_TRUNC | _O_BINARY);
|
__gnu_cxx::stdio_filebuf<char> wfile_buf(
|
||||||
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor,
|
file_descriptor, std::ios_base::out | std::ios_base::binary);
|
||||||
std::ios_base::out |
|
|
||||||
std::ios_base::binary);
|
|
||||||
std::ostream output(&wfile_buf);
|
std::ostream output(&wfile_buf);
|
||||||
if (!wfile_buf.is_open()) return false;
|
if (!wfile_buf.is_open()) return false;
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
@ -6639,7 +6677,7 @@ static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) {
|
|||||||
SerializeNumberProperty("node", channel.target_node, target);
|
SerializeNumberProperty("node", channel.target_node, target);
|
||||||
SerializeStringProperty("path", channel.target_path, target);
|
SerializeStringProperty("path", channel.target_path, target);
|
||||||
|
|
||||||
SerializeExtensionMap(channel.target_extensions, target);
|
SerializeExtensionMap(channel.target_extensions, target);
|
||||||
|
|
||||||
JsonAddMember(o, "target", std::move(target));
|
JsonAddMember(o, "target", std::move(target));
|
||||||
}
|
}
|
||||||
@ -7046,7 +7084,9 @@ static void SerializeSpotLight(SpotLight &spot, json &o) {
|
|||||||
static void SerializeGltfLight(Light &light, json &o) {
|
static void SerializeGltfLight(Light &light, json &o) {
|
||||||
if (!light.name.empty()) SerializeStringProperty("name", light.name, o);
|
if (!light.name.empty()) SerializeStringProperty("name", light.name, o);
|
||||||
SerializeNumberProperty("intensity", light.intensity, o);
|
SerializeNumberProperty("intensity", light.intensity, o);
|
||||||
SerializeNumberProperty("range", light.range, o);
|
if (light.range > 0.0) {
|
||||||
|
SerializeNumberProperty("range", light.range, o);
|
||||||
|
}
|
||||||
SerializeNumberArrayProperty("color", light.color, o);
|
SerializeNumberArrayProperty("color", light.color, o);
|
||||||
SerializeStringProperty("type", light.type, o);
|
SerializeStringProperty("type", light.type, o);
|
||||||
if (light.type == "spot") {
|
if (light.type == "spot") {
|
||||||
@ -7160,6 +7200,11 @@ static void SerializeGltfCamera(const Camera &camera, json &o) {
|
|||||||
} else {
|
} else {
|
||||||
// ???
|
// ???
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (camera.extras.Type() != NULL_TYPE) {
|
||||||
|
SerializeValue("extras", camera.extras, o);
|
||||||
|
}
|
||||||
|
SerializeExtensionMap(camera.extensions, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SerializeGltfScene(Scene &scene, json &o) {
|
static void SerializeGltfScene(Scene &scene, json &o) {
|
||||||
@ -7238,7 +7283,7 @@ static void SerializeGltfModel(Model *model, json &o) {
|
|||||||
JsonAddMember(o, "asset", std::move(asset));
|
JsonAddMember(o, "asset", std::move(asset));
|
||||||
|
|
||||||
// BUFFERVIEWS
|
// BUFFERVIEWS
|
||||||
if(model->bufferViews.size()) {
|
if (model->bufferViews.size()) {
|
||||||
json bufferViews;
|
json bufferViews;
|
||||||
JsonReserveArray(bufferViews, model->bufferViews.size());
|
JsonReserveArray(bufferViews, model->bufferViews.size());
|
||||||
for (unsigned int i = 0; i < model->bufferViews.size(); ++i) {
|
for (unsigned int i = 0; i < model->bufferViews.size(); ++i) {
|
||||||
@ -7249,11 +7294,6 @@ static void SerializeGltfModel(Model *model, json &o) {
|
|||||||
JsonAddMember(o, "bufferViews", std::move(bufferViews));
|
JsonAddMember(o, "bufferViews", std::move(bufferViews));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extensions used
|
|
||||||
if (model->extensionsUsed.size()) {
|
|
||||||
SerializeStringArrayProperty("extensionsUsed", model->extensionsUsed, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extensions required
|
// Extensions required
|
||||||
if (model->extensionsRequired.size()) {
|
if (model->extensionsRequired.size()) {
|
||||||
SerializeStringArrayProperty("extensionsRequired",
|
SerializeStringArrayProperty("extensionsRequired",
|
||||||
@ -7364,7 +7404,9 @@ static void SerializeGltfModel(Model *model, json &o) {
|
|||||||
// EXTENSIONS
|
// EXTENSIONS
|
||||||
SerializeExtensionMap(model->extensions, o);
|
SerializeExtensionMap(model->extensions, o);
|
||||||
|
|
||||||
// LIGHTS as KHR_lights_cmn
|
auto extensionsUsed = model->extensionsUsed;
|
||||||
|
|
||||||
|
// LIGHTS as KHR_lights_punctual
|
||||||
if (model->lights.size()) {
|
if (model->lights.size()) {
|
||||||
json lights;
|
json lights;
|
||||||
JsonReserveArray(lights, model->lights.size());
|
JsonReserveArray(lights, model->lights.size());
|
||||||
@ -7379,7 +7421,7 @@ static void SerializeGltfModel(Model *model, json &o) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
json_const_iterator it;
|
json_const_iterator it;
|
||||||
if (!FindMember(o, "extensions", it)) {
|
if (FindMember(o, "extensions", it)) {
|
||||||
JsonAssign(ext_j, GetValue(it));
|
JsonAssign(ext_j, GetValue(it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7387,6 +7429,23 @@ static void SerializeGltfModel(Model *model, json &o) {
|
|||||||
JsonAddMember(ext_j, "KHR_lights_punctual", std::move(khr_lights_cmn));
|
JsonAddMember(ext_j, "KHR_lights_punctual", std::move(khr_lights_cmn));
|
||||||
|
|
||||||
JsonAddMember(o, "extensions", std::move(ext_j));
|
JsonAddMember(o, "extensions", std::move(ext_j));
|
||||||
|
|
||||||
|
// Also add "KHR_lights_punctual" to `extensionsUsed`
|
||||||
|
{
|
||||||
|
auto has_khr_lights_punctual = std::find_if(
|
||||||
|
extensionsUsed.begin(), extensionsUsed.end(), [](const std::string &s) {
|
||||||
|
return (s.compare("KHR_lights_punctual") == 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (has_khr_lights_punctual == extensionsUsed.end()) {
|
||||||
|
extensionsUsed.push_back("KHR_lights_punctual");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extensions used
|
||||||
|
if (model->extensionsUsed.size()) {
|
||||||
|
SerializeStringArrayProperty("extensionsUsed", extensionsUsed, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXTRAS
|
// EXTRAS
|
||||||
@ -7406,12 +7465,10 @@ static bool WriteGltfFile(const std::string &output,
|
|||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
std::ofstream gltfFile(UTF8ToWchar(output).c_str());
|
std::ofstream gltfFile(UTF8ToWchar(output).c_str());
|
||||||
#elif defined(__GLIBCXX__)
|
#elif defined(__GLIBCXX__)
|
||||||
int file_descriptor =
|
int file_descriptor = _wopen(UTF8ToWchar(output).c_str(),
|
||||||
_wopen(UTF8ToWchar(output).c_str(), _O_CREAT | _O_WRONLY |
|
_O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
|
||||||
_O_TRUNC | _O_BINARY);
|
__gnu_cxx::stdio_filebuf<char> wfile_buf(
|
||||||
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor,
|
file_descriptor, std::ios_base::out | std::ios_base::binary);
|
||||||
std::ios_base::out |
|
|
||||||
std::ios_base::binary);
|
|
||||||
std::ostream gltfFile(&wfile_buf);
|
std::ostream gltfFile(&wfile_buf);
|
||||||
if (!wfile_buf.is_open()) return false;
|
if (!wfile_buf.is_open()) return false;
|
||||||
#else
|
#else
|
||||||
@ -7497,12 +7554,10 @@ static void WriteBinaryGltfFile(const std::string &output,
|
|||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary);
|
std::ofstream gltfFile(UTF8ToWchar(output).c_str(), std::ios::binary);
|
||||||
#elif defined(__GLIBCXX__)
|
#elif defined(__GLIBCXX__)
|
||||||
int file_descriptor =
|
int file_descriptor = _wopen(UTF8ToWchar(output).c_str(),
|
||||||
_wopen(UTF8ToWchar(output).c_str(), _O_CREAT | _O_WRONLY |
|
_O_CREAT | _O_WRONLY | _O_TRUNC | _O_BINARY);
|
||||||
_O_TRUNC | _O_BINARY);
|
__gnu_cxx::stdio_filebuf<char> wfile_buf(
|
||||||
__gnu_cxx::stdio_filebuf<char> wfile_buf(file_descriptor,
|
file_descriptor, std::ios_base::out | std::ios_base::binary);
|
||||||
std::ios_base::out |
|
|
||||||
std::ios_base::binary);
|
|
||||||
std::ostream gltfFile(&wfile_buf);
|
std::ostream gltfFile(&wfile_buf);
|
||||||
#else
|
#else
|
||||||
std::ofstream gltfFile(output.c_str(), std::ios::binary);
|
std::ofstream gltfFile(output.c_str(), std::ios::binary);
|
||||||
@ -7523,13 +7578,13 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
|||||||
|
|
||||||
// BUFFERS
|
// BUFFERS
|
||||||
std::vector<unsigned char> binBuffer;
|
std::vector<unsigned char> binBuffer;
|
||||||
if(model->buffers.size()) {
|
if (model->buffers.size()) {
|
||||||
json buffers;
|
json buffers;
|
||||||
JsonReserveArray(buffers, model->buffers.size());
|
JsonReserveArray(buffers, model->buffers.size());
|
||||||
for (unsigned int i = 0; i < model->buffers.size(); ++i) {
|
for (unsigned int i = 0; i < model->buffers.size(); ++i) {
|
||||||
json buffer;
|
json buffer;
|
||||||
if (writeBinary && i==0 && model->buffers[i].uri.empty()){
|
if (writeBinary && i == 0 && model->buffers[i].uri.empty()) {
|
||||||
SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer);
|
SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer);
|
||||||
} else {
|
} else {
|
||||||
SerializeGltfBuffer(model->buffers[i], buffer);
|
SerializeGltfBuffer(model->buffers[i], buffer);
|
||||||
}
|
}
|
||||||
@ -7546,10 +7601,11 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
|||||||
json image;
|
json image;
|
||||||
|
|
||||||
std::string dummystring = "";
|
std::string dummystring = "";
|
||||||
// UpdateImageObject need baseDir but only uses it if embeddedImages is
|
// UpdateImageObject need baseDir but only uses it if embeddedImages is
|
||||||
// enabled, since we won't write separate images when writing to a stream we
|
// enabled, since we won't write separate images when writing to a stream
|
||||||
UpdateImageObject(model->images[i], dummystring, int(i), false,
|
// we
|
||||||
&this->WriteImageData, this->write_image_user_data_);
|
UpdateImageObject(model->images[i], dummystring, int(i), false,
|
||||||
|
&this->WriteImageData, this->write_image_user_data_);
|
||||||
SerializeGltfImage(model->images[i], image);
|
SerializeGltfImage(model->images[i], image);
|
||||||
JsonPushBack(images, std::move(image));
|
JsonPushBack(images, std::move(image));
|
||||||
}
|
}
|
||||||
@ -7594,14 +7650,15 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
|||||||
JsonReserveArray(buffers, model->buffers.size());
|
JsonReserveArray(buffers, model->buffers.size());
|
||||||
for (unsigned int i = 0; i < model->buffers.size(); ++i) {
|
for (unsigned int i = 0; i < model->buffers.size(); ++i) {
|
||||||
json buffer;
|
json buffer;
|
||||||
if (writeBinary && i==0 && model->buffers[i].uri.empty()){
|
if (writeBinary && i == 0 && model->buffers[i].uri.empty()) {
|
||||||
SerializeGltfBufferBin(model->buffers[i], buffer,binBuffer);
|
SerializeGltfBufferBin(model->buffers[i], buffer, binBuffer);
|
||||||
} else if (embedBuffers) {
|
} else if (embedBuffers) {
|
||||||
SerializeGltfBuffer(model->buffers[i], buffer);
|
SerializeGltfBuffer(model->buffers[i], buffer);
|
||||||
} else {
|
} else {
|
||||||
std::string binSavePath;
|
std::string binSavePath;
|
||||||
std::string binUri;
|
std::string binUri;
|
||||||
if (!model->buffers[i].uri.empty() && !IsDataURI(model->buffers[i].uri)) {
|
if (!model->buffers[i].uri.empty() &&
|
||||||
|
!IsDataURI(model->buffers[i].uri)) {
|
||||||
binUri = model->buffers[i].uri;
|
binUri = model->buffers[i].uri;
|
||||||
} else {
|
} else {
|
||||||
binUri = defaultBinFilename + defaultBinFileExt;
|
binUri = defaultBinFilename + defaultBinFileExt;
|
||||||
@ -7627,7 +7684,7 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
|||||||
}
|
}
|
||||||
JsonPushBack(buffers, std::move(buffer));
|
JsonPushBack(buffers, std::move(buffer));
|
||||||
}
|
}
|
||||||
JsonAddMember(output, "buffers", std::move(buffers));
|
JsonAddMember(output, "buffers", std::move(buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
// IMAGES
|
// IMAGES
|
||||||
@ -7654,6 +7711,8 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // TINYGLTF_ENABLE_SERIALIZER
|
||||||
|
|
||||||
} // namespace tinygltf
|
} // namespace tinygltf
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user